"Fossies" - the Fresh Open Source Software Archive

Member "tidy-html5-5.8.0/experimental/httpio.c" (16 Jul 2021, 6084 Bytes) of package /linux/www/tidy-html5-5.8.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "httpio.c" see the Fossies "Dox" file reference documentation.

    1 #include "tmbstr.h"
    2 
    3 #include "httpio.h"
    4 
    5 int
    6 makeConnection ( HTTPInputSource *pHttp )
    7 {
    8     struct sockaddr_in sock;
    9     struct hostent *pHost;
   10 
   11     /* Get internet address of the host. */
   12     if (!(pHost = gethostbyname ( pHttp->pHostName )))
   13     {
   14         return -1;
   15     }
   16     /* Copy the address of the host to socket description.  */
   17     memcpy (&sock.sin_addr, pHost->h_addr, pHost->h_length);
   18 
   19     /* Set port and protocol */
   20     sock.sin_family = AF_INET;
   21     sock.sin_port = htons( pHttp->nPort );
   22 
   23     /* Make an internet socket, stream type.  */
   24     if ((pHttp->s = socket (AF_INET, SOCK_STREAM, 0)) == -1)
   25         return -1;
   26 
   27     /* Connect the socket to the remote host.  */
   28     if (connect (pHttp->s, (struct sockaddr *) &sock, sizeof( sock )))
   29     {
   30         if (errno == ECONNREFUSED)
   31             return ECONNREFUSED;
   32         else
   33             return -1;
   34     }
   35     return 0;
   36 }
   37 
   38 
   39 int parseURL( HTTPInputSource *pHttp, tmbstr url )
   40 {
   41   int i, j = 0;
   42   ctmbstr pStr;
   43 
   44     pStr = tmbsubstr( url, "://" );
   45 
   46     /* If protocol is there, but not http, bail out, else assume http.  */
   47     if (NULL != pStr)
   48     {
   49         if (tmbstrncasecmp( url, "http://", 7 ))
   50             return -1;
   51     }
   52 
   53     if (NULL != pStr)
   54         j = pStr - url + 3;
   55     for (i = j; url[i] && url[i] != ':' && url[i] != '/'; i++) {}
   56     if (i == j)
   57         return -1;
   58 
   59     /* Get the hostname.  */
   60     pHttp->pHostName = tmbstrndup (&url[j], i - j );
   61 
   62     if (url[i] == ':')
   63     {
   64         /* We have a colon delimiting the hostname.  It should mean that
   65         a port number is following it */
   66         pHttp->nPort = 0;
   67         if (isdigit( url[++i] ))    /* A port number */
   68         {
   69             for (; url[i] && url[i] != '/'; i++)
   70             {
   71                 if (isdigit( url[i] ))
   72                     pHttp->nPort = 10 * pHttp->nPort + (url[i] - '0');
   73                 else
   74                     return -1;
   75             }
   76             if (!pHttp->nPort)
   77                 return -1;
   78         }
   79         else                      /* or just a misformed port number */
   80             return -1;
   81     }
   82     else
   83         /* Assume default port.  */
   84         pHttp->nPort = 80;
   85 
   86     /* skip past the delimiting slash (we'll add it later )  */
   87     while (url[i] && url[i] == '/')
   88         i++;
   89     pHttp->pResource = tmbstrdup (url + i );
   90     return 0;
   91 }
   92 
   93 
   94 int fillBuffer( HTTPInputSource *in )
   95 {
   96     if (0 < in->s)
   97     {
   98         in->nBufSize = recv( in->s, in->buffer, sizeof( in->buffer ), 0);
   99         in->nextBytePos = 0;
  100         if (in->nBufSize < sizeof( in->buffer ))
  101             in->buffer[in->nBufSize] = '\0';
  102     }
  103     else
  104         in->nBufSize = 0;
  105     return in->nBufSize;
  106 }
  107 
  108 
  109 int openURL( HTTPInputSource *in, tmbstr pUrl )
  110 {
  111     int rc = -1;
  112 #ifdef WIN32    
  113     WSADATA wsaData;
  114 
  115     rc = WSAStartup( 514, &wsaData );
  116 #endif
  117 
  118     in->tis.getByte = (TidyGetByteFunc) HTTPGetByte; 
  119     in->tis.ungetByte = (TidyUngetByteFunc) HTTPUngetByte;
  120     in->tis.eof = (TidyEOFFunc) HTTPIsEOF;
  121     in->tis.sourceData = (uint) in;
  122     in->nextBytePos = in->nextUnGotBytePos = in->nBufSize = 0;
  123     parseURL( in, pUrl );
  124     if (0 == (rc = makeConnection( in )))
  125     {
  126         char ch, lastCh = '\0';
  127         int blanks = 0;
  128 
  129         char *getCmd = MemAlloc( 48 + strlen( in->pResource ));
  130         sprintf( getCmd, "GET /%s HTTP/1.0\r\nAccept: text/html\r\n\r\n", in->pResource );
  131         send( in->s, getCmd, strlen( getCmd ), 0 );
  132         MemFree( getCmd );
  133 
  134         /*  skip past the header information  */
  135         while (   in->nextBytePos >= in->nBufSize
  136                && 0 < (rc = fillBuffer( in )))
  137         {
  138             if (1 < blanks)
  139                 break;
  140             for (; in->nextBytePos < sizeof( in->buffer ) 
  141                    && 0 != in->buffer[ in->nextBytePos ]; 
  142                  in->nextBytePos++ )
  143             {
  144                 ch = in->buffer[ in->nextBytePos ];
  145                 if (ch == '\r' || ch == '\n')
  146                 {
  147                     if (ch == lastCh)
  148                     {
  149                         /*  Two carriage returns or two newlines in a row,
  150                             that's good enough */
  151                         blanks++;
  152                     }
  153                     if (lastCh == '\r' || lastCh == '\n')
  154                     {
  155                         blanks++;
  156                     }
  157                 }
  158                 else
  159                     blanks = 0;
  160                 lastCh = ch;
  161                 if (1 < blanks)
  162                 {
  163                     /* end of header, scan to first non-white and return */
  164                     while ('\0' != ch && isspace( ch ))
  165                         ch = in->buffer[ ++in->nextBytePos ];
  166                     break;
  167                 }
  168             }
  169         }
  170     }
  171     return rc;
  172 }
  173 
  174 
  175 void closeURL( HTTPInputSource *source )
  176 {
  177     if (0 < source->s)
  178         closesocket( source->s );
  179     source->s = -1;
  180     source->tis.sourceData = 0;
  181 #ifdef WIN32
  182     WSACleanup();
  183 #endif
  184 }
  185 
  186 
  187 int HTTPGetByte( HTTPInputSource *source )
  188 {
  189     if (source->nextUnGotBytePos)
  190         return source->unGetBuffer[ --source->nextUnGotBytePos ];
  191     if (0 != source->nBufSize && source->nextBytePos >= source->nBufSize)
  192     {
  193         fillBuffer( source );
  194     }
  195     if (0 == source->nBufSize)
  196         return EndOfStream;
  197     return source->buffer[ source->nextBytePos++ ];
  198 }
  199 
  200 void HTTPUngetByte( HTTPInputSource *source, uint byteValue )
  201 {
  202     if (source->nextUnGotBytePos < 16 )  /* Only you can prevent buffer overflows */
  203         source->unGetBuffer[ source->nextUnGotBytePos++ ] = (char) byteValue;
  204 }
  205 
  206 Bool HTTPIsEOF( HTTPInputSource *source )
  207 {
  208     if (source->nextUnGotBytePos)
  209         /* pending ungot bytes, not done */
  210         return no;
  211 
  212     if (   0 != source->nBufSize 
  213         && source->nextBytePos >= source->nBufSize)
  214         /* We've consumed the existing buffer, get another */
  215         fillBuffer( source );
  216 
  217     if (source->nextBytePos < source->nBufSize)
  218         /*  we have stuff in the buffer, must not be done. */
  219         return no;
  220 
  221     /* Nothing in the buffer, and the last receive failed, must be done.  */
  222     return yes;
  223 }
  224