server 0.0.1
basicserverinfrastructure

src/http/request/parser/parse.c File Reference

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include "http/request_parser.h"
#include "interface/class.h"
Include dependency graph for parse.c:

Go to the source code of this file.

Defines

#define REMAINS(pars, done)   ((pars)->buffer_used - ((done) - (pars)->buffer))

Functions

void httpRequestParserGetRequestLine (HttpRequest, char *)
void httpRequestParserParse (HttpRequestParser this)

Define Documentation

#define REMAINS (   pars,
  done 
)    ((pars)->buffer_used - ((done) - (pars)->buffer))

Definition at line 10 of file parse.c.


Function Documentation

void httpRequestParserGetRequestLine ( HttpRequest  ,
char *   
)

Definition at line 7 of file get_request_line.c.

{
        char * method, * uri, * version;

        method = line;

        uri    = strchr(line, ' ');
        *uri++ = 0;
        for (; *uri == ' ' && *uri != 0; uri++);

        version    = strchr(uri, ' ');
        *version++ = 0;
        for (; *version == ' ' && *version != 0; version++);

        request->method  = malloc(strlen(method) + 1);
        strcpy(request->method, method);
        request->uri     = malloc(strlen(uri) + 1);
        strcpy(request->uri, uri);
        request->version = malloc(strlen(version) + 1);
        strcpy(request->version, method);
}

Here is the caller graph for this function:

void httpRequestParserParse ( HttpRequestParser  this)

enqueue current request

remove processed stuff from input buffer.

dont continue loop if input buffer is empty

prepare for next request

Definition at line 43 of file parse.c.

{
        static HttpRequest request  = NULL;
        static char *      data; // static pointer to unprocessed data
        char *             line;
        int                cont = 1;

        while(cont) {
                switch(this->state) {
                        case HTTP_REQUEST_GARBAGE:
                                data = this->buffer; // initialize static pointer
                                httpRequestSkip(&data);
                                request = new(HttpRequest);

                                this->state = HTTP_REQUEST_START;
                                break;

                        case HTTP_REQUEST_START:
                                if (NULL == (line = httpRequestParserGetLine(&data))) {
                                        cont = 0;
                                        break;
                                }
                                
                                httpRequestParserGetRequestLine(request, line);

                                this->state = HTTP_REQUEST_REQUEST_LINE_DONE;
                                break;

                        case HTTP_REQUEST_REQUEST_LINE_DONE:
                                if (NULL == (line = httpRequestParserGetLine(&data))) {
                                        cont = 0;
                                        break;
                                }

                                if (0 == strlen(line)) {
                                        this->state = HTTP_REQUEST_HEADERS_DONE;
                                        break;
                                }

                                httpRequestParserGetHeader(request, line);
                                break;

                        case HTTP_REQUEST_HEADERS_DONE:
                                httpHeaderSort(request->header, request->nheader);

                                {
                                        char * nbody;

                                        if (0 == request->nbody) {
                                                nbody = httpHeaderGet(
                                                                request->header,
                                                                request->nheader,
                                                                "Content-Length");

                                                if (NULL == nbody) {
                                                        this->state = HTTP_REQUEST_DONE;
                                                        break;
                                                }
                                                else {
                                                        request->nbody = atoi(nbody);
                                                }
                                        }

                                        if (REMAINS(this, data) >= request->nbody) {
                                                request->body = calloc(1, request->nbody + 1);
                                                memcpy(request->body, data, request->nbody);
                                                data += request->nbody;
                                                this->state = HTTP_REQUEST_DONE;
                                        }
                                }
                                        
                                break;

                        case HTTP_REQUEST_DONE:
                                this->request_queue->requests[(this->request_queue->nrequests)++] =
                                        request;

                                memmove(this->buffer, data, REMAINS(this, data));

                                this->buffer_used -= data - this->buffer;

                                if (0 == this->buffer_used) {
                                        cont = 0;
                                }

                                this->state = HTTP_REQUEST_GARBAGE;

                                break;

                        default:
                                break;
                }
        }
}

Here is the call graph for this function:

 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines