10 #if defined( INC_ALL )
35 { NULL, 0, 0 }, { NULL, 0, 0 }
62 status = netStream->bufferedTransportReadFunction( stream, &
ch, 1,
84 HTTP_HEADER_INFO headerInfo;
92 assert(
isWritePtr( lineBuffer, lineBufSize ) );
100 *flags = HTTP_FLAG_NONE;
110 status = readTextLine( readCharFunction, stream, lineBuffer,
111 lineBufSize, &length, &isTextDataError );
118 sendHTTPError( stream, lineBuffer, lineBufSize,
123 return( retTextLineError( stream,
status, isTextDataError,
124 "Invalid HTTP request header line 1: ",
131 const HTTP_REQUEST_INFO *reqInfoPtr = &
httpReqInfo[ i ];
133 if( ( reqInfoPtr->reqTypeFlag & netStream->nFlags ) && \
134 length >= reqInfoPtr->reqNameLen && \
135 !
strCompare( lineBuffer, reqInfoPtr->reqName, \
136 reqInfoPtr->reqNameLen ) )
138 reqType = reqInfoPtr->reqType;
139 reqNameLen = reqInfoPtr->reqNameLen;
146 char reqNameBuffer[ 16 + 8 ];
151 sendHTTPError( stream, lineBuffer, lineBufSize, 501 );
154 "Invalid empty HTTP request" ) );
156 if( (
offset = strSkipNonWhitespace( lineBuffer, length ) ) > 0 )
158 memcpy( reqNameBuffer, lineBuffer,
min( 16, length ) );
159 sendHTTPError( stream, lineBuffer, lineBufSize, 501 );
162 "Invalid HTTP request '%s'",
163 sanitiseString( reqNameBuffer, 16, length ) ) );
165 bufPtr = lineBuffer + reqNameLen;
166 length -= reqNameLen;
169 if( length <= 0 || (
offset = strSkipWhitespace( bufPtr, length ) ) < 0 )
171 sendHTTPError( stream, lineBuffer, lineBufSize, 400 );
174 "Missing HTTP request URI" ) );
189 offset = parseUriInfo( bufPtr, length, &length, uriInfo );
197 offset = strSkipNonWhitespace( bufPtr, length );
201 sendHTTPError( stream, lineBuffer, lineBufSize, 400 );
204 "Invalid HTTP GET request URI" ) );
208 if( length <= 0 || (
offset = strSkipWhitespace( bufPtr, length ) ) < 0 )
210 sendHTTPError( stream, lineBuffer, lineBufSize, 400 );
213 "Missing HTTP request ID/version" ) );
220 sendHTTPError( stream, lineBuffer, lineBufSize, 505 );
223 "Invalid HTTP request ID/version" ) );
229 initHeaderInfo( &headerInfo, 32, httpDataInfo->bufSize, *flags );
233 headerInfo.flags |= HTTP_FLAG_GET;
235 status = readHeaderLines( stream, lineBuffer, lineBufSize,
242 sendHTTPError( stream, lineBuffer, lineBufSize,
243 headerInfo.httpStatus );
248 httpDataInfo->reqType = reqType;
250 httpDataInfo->bytesAvail = headerInfo.contentLength;
251 *flags = headerInfo.flags;
265 static
int readResponseHeader(
INOUT STREAM *stream,
275 assert(
isWritePtr( lineBuffer, lineBufSize ) );
282 *flags = HTTP_FLAG_NONE;
288 status = writeRequestHeader( stream, httpDataInfo->reqInfo,
302 HTTP_HEADER_INFO headerInfo;
307 status = readFirstHeaderLine( stream, lineBuffer, lineBufSize,
319 if( httpDataInfo->softErrors && httpStatus == 404 )
328 *flags |= HTTP_FLAG_NOOP;
329 needsSpecialHandling =
TRUE;
345 initHeaderInfo( &headerInfo, 5,
346 httpDataInfo->bufferResize ? \
348 httpDataInfo->bufSize,
350 status = readHeaderLines( stream, lineBuffer, lineBufSize,
356 *flags = headerInfo.flags & ~HTTP_FLAG_NOOP;
357 httpDataInfo->bytesAvail = headerInfo.contentLength;
367 if( !needsSpecialHandling )
370 REQUIRES( httpStatus == 100 || httpStatus == 301 || \
371 httpStatus == 302 || httpStatus == 307 );
375 if( httpStatus == 100 )
405 netStream->closeSocketFunction( stream );
406 clFree(
"readResponseHeader", netStream->host );
407 netStream->host = NULL;
408 status = parseLocation( stream, location );
414 "Unable to process HTTP %d redirect", httpStatus ) );
420 "HTTP retry/redirection loop detected" ) );
440 char headerBuffer[ HTTP_LINEBUF_SIZE + 8 ];
441 int flags = HTTP_FLAG_NONE,
status;
444 assert(
isReadPtr( buffer, maxLength ) );
445 assert(
isWritePtr( length,
sizeof(
int ) ) );
459 status = readRequestHeader( stream, headerBuffer, HTTP_LINEBUF_SIZE,
460 httpDataInfo, &flags );
464 status = readResponseHeader( stream, headerBuffer, HTTP_LINEBUF_SIZE,
465 httpDataInfo, &flags );
467 httpDataInfo->bytesAvail > httpDataInfo->bufSize )
471 REQUIRES( httpDataInfo->bytesAvail > 0 && \
476 REQUIRES( httpDataInfo->bufferResize );
480 if( ( newBuffer =
clAlloc(
"readFunction", \
481 httpDataInfo->bytesAvail ) ) == NULL )
483 zeroise( httpDataInfo->buffer, httpDataInfo->bufSize );
484 clFree(
"readFunction", httpDataInfo->buffer );
485 httpDataInfo->buffer = newBuffer;
486 httpDataInfo->bufSize = httpDataInfo->bytesAvail;
491 httpDataInfo->bufferResize =
FALSE;
496 ENSURES( httpDataInfo->bytesAvail <= httpDataInfo->bufSize );
511 status = netStream->bufferedTransportReadFunction( stream,
512 httpDataInfo->buffer, httpDataInfo->bytesAvail,
513 &httpDataInfo->bytesTransferred,
517 if( httpDataInfo->bytesTransferred < httpDataInfo->bytesAvail )
527 "HTTP read timed out before all data could be read, only "
528 "got %d of %d bytes", httpDataInfo->bytesTransferred,
529 httpDataInfo->bytesAvail ) );
533 if( flags & HTTP_FLAG_TEXTMSG )
535 BYTE *byteBufPtr = httpDataInfo->buffer;
545 if( httpDataInfo->bytesAvail < 256 || ( byteBufPtr[ 0 ] != 0x30 ) || \
546 !( byteBufPtr[ 1 ] & 0x80 ) || \
552 "HTTP server reported: '%s'",
553 sanitiseString( byteBufPtr, \
554 httpDataInfo->bufSize,
555 min( httpDataInfo->bytesTransferred, \
573 if( flags & HTTP_FLAG_CHUNKED )
575 status = readTrailerLines( stream, headerBuffer,
591 netStream->readFunction = readFunction;
592 setStreamLayerHTTPwrite( netStream );