static void readAndProcessHeaders(TSession * const sessionP, time_t const deadline, const char ** const errorP, uint16_t * const httpErrorCodeP) { /*---------------------------------------------------------------------------- Read all the HTTP headers from the session *sessionP, which has at least one header coming. Update *sessionP to reflect the information in the headers. If we find an error in the headers or while trying to read them, we return a text explanation of the problem as *errorP and an appropriate HTTP error code as *httpErrorCodeP. Otherwise, we return *errorP = NULL and nothing as *httpErrorCodeP. -----------------------------------------------------------------------------*/ bool endOfHeaders; assert(!sessionP->validRequest); /* Calling us doesn't make sense if there is already a valid request */ *errorP = NULL; /* initial assumption */ endOfHeaders = false; /* Caller assures us there is at least one header */ while (!endOfHeaders && !*errorP) { char * header; bool error; readHeader(sessionP->connP, deadline, &endOfHeaders, &header, &error); if (error) { xmlrpc_asprintf(errorP, "Failed to read headers from " "client connection."); *httpErrorCodeP = 408; /* Request Timeout */ } else { if (!endOfHeaders) { char * p; char * fieldName; p = &header[0]; getFieldNameToken(&p, &fieldName, errorP, httpErrorCodeP); if (!*errorP) { char * fieldValue; NextToken((const char **)&p); fieldValue = p; TableAdd(&sessionP->requestHeaderFields, fieldName, fieldValue); processHeader(fieldName, fieldValue, sessionP, errorP, httpErrorCodeP); } } } } }
static void readAndProcessHeaders(TSession * const sessionP, time_t const deadline, uint16_t * const httpErrorCodeP) { /*---------------------------------------------------------------------------- Read all the HTTP headers from the session *sessionP, which has at least one header coming. Update *sessionP to reflect the information in the headers. If we find an error in the headers or while trying to read them, we return an appropriate HTTP error code as *httpErrorCodeP. Otherwise, we return *httpErrorCodeP = 0. -----------------------------------------------------------------------------*/ bool endOfHeaders; /* Calling us doesn't make sense if there is already a valid request */ if (sessionP->validRequest) { return; } *httpErrorCodeP = 0; /* initial assumption */ endOfHeaders = false; /* Caller assures us there is at least one header */ while (!endOfHeaders && !*httpErrorCodeP) { char * header; bool error; readHeader(sessionP->conn, deadline, &endOfHeaders, &header, &error); if (error) *httpErrorCodeP = 408; /* Request Timeout */ else { if (!endOfHeaders) { char * p; char * fieldName; p = &header[0]; getFieldNameToken(&p, &fieldName, httpErrorCodeP); if (!*httpErrorCodeP) { char * fieldValue; NextToken((const char **)&p); fieldValue = p; TableAdd(&sessionP->request_headers, fieldName, fieldValue); processHeader(fieldName, fieldValue, sessionP, httpErrorCodeP); } } } } }
abyss_bool ResponseAddField(TSession * const sessionP, const char * const name, const char * const value) { abyss_bool succeeded; if (!isValidHttpToken(name)) { TraceMsg("Supplied HTTP header field name is not a valid HTTP token"); succeeded = false; } else if (!isValidHttpText(value)) { TraceMsg("Supplied HTTP header field value is not valid HTTP text"); succeeded = false; } else { succeeded = TableAdd(&sessionP->responseHeaderFields, name, value); } return succeeded; }
LPTR AllocX( long lCount, WORD wFlags ) /************************************************************************/ { LPTR lpMemory; HGLOBAL hMem; // Round up to the next 16 byte boundary lCount++; // Protection against a possible C7.0 bug lCount = ((lCount + 15) / 16) * 16; // Allocate the memory from the global heap - NOT limited to 64K if ( !(hMem = GlobalAlloc(GMEM_MOVEABLE | wFlags, lCount)) ) return(NULL); if ( !(lpMemory = (LPTR)GlobalLock(hMem)) ) GlobalFree(hMem); #ifdef _DEBUG_MEMORY TableAdd( lpMemory ); #endif return( lpMemory ); }
bool TableAddReplace(TTable * const t, const char * const name, const char * const value) { uint16_t i=0; if (TableFindIndex(t,name,&i)) { free(t->item[i].value); if (value) t->item[i].value=strdup(value); else { free(t->item[i].name); if (--t->size>0) t->item[i]=t->item[t->size]; }; return TRUE; } else return TableAdd(t,name,value); }
LPTR AllocExtend( LPTR lpMemory, long lCount ) /************************************************************************/ { LPTR lpNewMemory; HGLOBAL hMem, hNewMem; // Round up to the next 16 byte boundary lCount++; // Protection against a possible C7.0 bug lCount = ((lCount + 15) / 16) * 16; if ( !(hMem = GlobalPtrHandle(lpMemory)) ) return(NULL); if ( !(hNewMem = GlobalReAlloc(hMem, lCount, GMEM_MOVEABLE)) ) return(NULL); if ( !(lpNewMemory = (LPTR)GlobalLock(hNewMem)) ) GlobalFree(hNewMem); #ifdef _DEBUG_MEMORY TableAdd( lpMemory ); #endif return( lpNewMemory ); }
abyss_bool RequestRead(TSession * const sessionP) { uint16_t httpErrorCode; /* zero for no error */ char * requestLine; readRequestLine(sessionP, &requestLine, &httpErrorCode); if (!httpErrorCode) { TMethod httpMethod; const char * host; const char * path; const char * query; unsigned short port; abyss_bool moreHeaders=false; parseRequestLine(requestLine, &httpMethod, &sessionP->version, &host, &port, &path, &query, &moreHeaders, &httpErrorCode); if (!httpErrorCode) initRequestInfo(&sessionP->request_info, sessionP->version, strdup(requestLine), httpMethod, host, port, path, query); while (moreHeaders && !httpErrorCode) { char * p; abyss_bool succeeded; succeeded = ConnReadHeader(sessionP->conn, &p); if (!succeeded) httpErrorCode = 408; /* Request Timeout */ else { if (!*p) /* We have reached the empty line so all the request was read. */ moreHeaders = FALSE; else { char * fieldName; getFieldNameToken(&p, &fieldName, &httpErrorCode); if (!httpErrorCode) { char * fieldValue; NextToken((const char **)&p); fieldValue = p; TableAdd(&sessionP->request_headers, fieldName, fieldValue); processHeader(fieldName, fieldValue, sessionP, &httpErrorCode); } } } } } if (httpErrorCode) ResponseStatus(sessionP, httpErrorCode); else sessionP->validRequest = true; return !httpErrorCode; }