#include #include #include #include #include "../../include/appConfig.h" #include "../../include/httpRequest.h" #include "../../include/client.h" #define SPACE 0x20 char httpRequest[8][8] = { "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT" }; /* * Gedanken zum request einlese: * der client liest stumpf daten, außerdem implementiert er eine Methode um die * erste Zeile aus dem readbuffer zu entfernen. * Des weiteren eine Methode getLine die NULL zurück gibt wenn noch keine Zeile * komplett ist, ansonsten einen Pointer auf diese. * Der servercode triggert das Daten lesen des client, versucht dann die erste * Zeile zu lesen und gibt diese im erfolgsfall an den httpCode weiter um * dann wenn dieser ein OK gibt die erste Zeile über den clientCode wieder zu entfernen. * Leere Zeile vor der request line werden ignoriert. * Ebenso leere Zailen nachdem der request komplett eingelesen ist. * Nachdem alle Header Zeile eingelesen wurden...d.H. sobald eine leere Header Zeile * gelesen wurde wird exakt bodyLength vom client versucht zu lesen...hierbei * können die Daten die von client kommen in den body buffer übertragen werden. * Dabei kann im client code der buffer immer entsprechend zurück gesetzt werden. */ int httpHeaderGetLine(tHttpHeader * header, char ** buffer, unsigned int * readPos) { return 1; } void httpHeaderParseRequestLine(tHttpHeader * header, const char * line, unsigned int len) { } int httpHeaderIsComplete(tHttpHeader * header) { if (NULL == header->req.method) { return 0; } return 1; } unsigned char httpHeaderIsStarted(tHttpHeader * header) { return 1; } static void httpRequestStrip(char ** buffer, unsigned int * readPos) { char * end = *buffer; /* remove all surrounding CRLF */ while (('\r' == *end || '\n' == *end) && *end) { end++; } if (end != *buffer) { memmove(*buffer, end, *readPos - (end - *buffer)); memset(*buffer, 0, end - *buffer); *readPos -= (end - * buffer); } } int httpHeaderGet(char ** buffer, unsigned int * readPos, tHttpHeader * request) { char * end = *buffer; unsigned int readPosNew; httpRequestStrip(buffer, readPos); end = strstr(*buffer, "\r\n\r\n"); /* get header if not already read and complete */ if (!httpHeaderIsComplete(request) && NULL != end) { /* get request line */ char * methodEnd = strchr(*buffer, SPACE); char * uriEnd = strchr(methodEnd + 1, SPACE); char * lineEnd = strstr(*buffer, "\r\n"); request->req.method = calloc(methodEnd-*buffer+1, sizeof(char)); request->req.requestUri = calloc(uriEnd-methodEnd, sizeof(char)); request->req.httpVersion = calloc(lineEnd-uriEnd, sizeof(char)); sscanf(*buffer, "%s %s %s\r\n", request->req.method, request->req.requestUri, request->req.httpVersion); readPosNew = (*buffer + *readPos) - lineEnd - 2; memmove(*buffer, lineEnd + 2, readPosNew); memset(*buffer + readPosNew, 0, *readPos - readPosNew); *readPos = readPosNew; /* get all header lines */ do { char * keyEnd = strchr(*buffer, ':'); lineEnd = strstr(*buffer, "\r\n"); if (lineEnd != *buffer) { tHttpHeaderLine * actHeader; char * actKey = NULL; request->headersCount += 1; request->headers = realloc(request->headers, request->headersCount * sizeof(tHttpHeaderLine)); actHeader = &(request->headers[request->headersCount-1]); memset(actHeader, 0, sizeof(tHttpHeaderLine)); actKey = actHeader->key = calloc(keyEnd-*buffer+1, sizeof(char)); actHeader->value = calloc(lineEnd-keyEnd-1, sizeof(char)); sscanf(*buffer, "%[^:]:%s\r\n", actHeader->key, actHeader->value); //while (NULL != actKey && *actKey != '\0' && (*actKey = tolower(*(actKey++)))); // strtolower for (; NULL != actKey && *actKey != '\0'; actKey++) { *actKey = tolower(*actKey); } if (0 == strncmp("content-length", actHeader->key, strlen(actHeader->key))) { request->bodyLength = atoi(actHeader->value); } } readPosNew = (*buffer + *readPos) - lineEnd - 2; memmove(*buffer, lineEnd + 2, readPosNew); memset(*buffer + readPosNew, 0, *readPos - readPosNew); *readPos = readPosNew; } while (lineEnd != *buffer); return request->bodyLength; } return 0; } int getHttpRequest(char ** buffer, unsigned int * readPos, tHttpRequest * request) { /* get body if header is read and body incomplete */ if (request->header.bodyLength != request->length) { size_t size = MIN( request->header.bodyLength - request->length, *readPos); if (0 != size) { if (NULL == request->body) { request->body = calloc(request->header.bodyLength, sizeof(char)); } memcpy(request->body + request->length, *buffer, size); memmove(*buffer, *buffer + size, *readPos - size); memset(*buffer + (*readPos - size), 0, size); *readPos -= size; request->length += size; } } return 0; } void freeHttpHeader(tHttpHeader * header) { unsigned int i; if (NULL != header->req.method) { free(header->req.method); } if (NULL != header->req.requestUri) { free(header->req.requestUri); } if (NULL != header->req.httpVersion) { free(header->req.httpVersion); } for (i=0; iheadersCount; i++) { if (NULL != header->headers[i].key) { free(header->headers[i].key); } if (NULL != header->headers[i].value) { free(header->headers[i].value); } } if (NULL != header->headers) { free(header->headers); } memset (header, 0, sizeof (tHttpHeader)); } void freeHttpRequest(tHttpRequest * request) { unsigned int i; if (NULL != request->header.req.method) { free(request->header.req.method); request->header.req.method = NULL; } if (NULL != request->header.req.requestUri) { free(request->header.req.requestUri); request->header.req.requestUri = NULL; } if (NULL != request->header.req.httpVersion) { free(request->header.req.httpVersion); request->header.req.httpVersion = NULL; } for (i=0; iheader.headersCount; i++) { if (NULL != request->header.headers[i].key) { free(request->header.headers[i].key); request->header.headers[i].key = NULL; } if (NULL != request->header.headers[i].value) { free(request->header.headers[i].value); request->header.headers[i].value = NULL; } } if (NULL != request->header.headers) { free(request->header.headers); request->header.headers = NULL; } if (NULL != request->body) { free(request->body); request->body = NULL; } memset (request, 0, sizeof (tHttpRequest)); }