You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
255 lines
7.4 KiB
255 lines
7.4 KiB
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
|
|
#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; i<header->headersCount; 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; i<request->header.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));
|
|
}
|