An xmlrpc test project
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

#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));
}