Server 0.0.1
HTTP/REST server implementation

src/http/parser/parse.c File Reference

#include <stdlib.h>
#include "class.h"
#include "cbuf.h"
#include "stream.h"
#include "http/parser.h"
#include "http/header.h"
#include "http/interface/http_intro.h"
#include "utils/memory.h"
#include "commons.h"
Include dependency graph for parse.c:

Go to the source code of this file.

Defines

#define MIN(a, b)   ((a)<(b)? (a) : (b))

Functions

ssize_t httpParserParse (void *_this, Stream st)

Detailed Description

Author:
Georg Hopp

Copyright © 2012 Georg Hopp

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.

Definition in file parse.c.


Define Documentation

#define MIN (   a,
 
)    ((a)<(b)? (a) : (b))

Definition at line 36 of file parse.c.


Function Documentation

ssize_t httpParserParse ( void *  _this,
Stream  st 
)

do we have form data??

> then parse them...

enqueue current request

prepare for next request

Definition at line 40 of file parse.c.

{
        HttpParser this = _this;
        int        cont = 1;
        ssize_t    read;
        char *     line;
        char *     line_end;

        if (cbufIsLocked(this->buffer)) {
                if (FALSE == this->ourLock)
                        return 0;
        }
        else {
                cbufLock(this->buffer);
                this->ourLock = TRUE;
        }

        if (NULL != this->incomplete) {
                cbufSetData(this->buffer, this->incomplete, this->isize);
                free(this->incomplete);
                this->incomplete = NULL;
        }

        if (0 > (read = cbufRead(this->buffer, st))) {
                return read;
        }

        while (cont) {
                switch(this->state) {
                        case HTTP_MESSAGE_GARBAGE:
                                cbufSkipNonAlpha(this->buffer);
                                if (! cbufIsEmpty(this->buffer)) {
                                        this->state = HTTP_MESSAGE_START;
                                }
                                else {
                                        cbufRelease(this->buffer);
                                        this->ourLock = FALSE;
                                        cont          = 0;
                                }

                                break;

                        case HTTP_MESSAGE_START:
                                if (NULL == (line = cbufGetLine(this->buffer, &line_end))) {
                                        if (! cbufIsEmpty(this->buffer)) {
                                                this->isize = this->buffer->bused;
                                                this->incomplete = malloc(this->isize);
                                                memcpy(this->incomplete,
                                                                cbufGetData(this->buffer, this->isize),
                                                                this->isize);
                                        }
                                        cbufRelease(this->buffer);
                                        this->ourLock = FALSE;
                                        cont = 0;
                                        break;
                                }
                                
                                httpParserNewMessage(this, line, line_end);
                                if (NULL == this->current) {
                                        cbufRelease(this->buffer);
                                        this->ourLock = FALSE;
                                        return -1;
                                }
                                httpParserRequestVars(this);

                                this->state = HTTP_MESSAGE_INTRO_DONE;
                                break;

                        case HTTP_MESSAGE_INTRO_DONE:
                                if (NULL == (line = cbufGetLine(this->buffer, &line_end))) {
                                        if (! cbufIsEmpty(this->buffer)) {
                                                this->isize = this->buffer->bused;
                                                this->incomplete = malloc(this->isize);
                                                memcpy(this->incomplete,
                                                                cbufGetData(this->buffer, this->isize),
                                                                this->isize);
                                        }
                                        cbufRelease(this->buffer);
                                        this->ourLock = FALSE;
                                        cont = 0;
                                        break;
                                }

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

                                httpParserHeader(this, line, line_end);
                                break;

                        case HTTP_MESSAGE_HEADERS_DONE:
                                if (this->current->dbody == this->current->nbody) {
                                        this->state = HTTP_MESSAGE_DONE;
                                        break;
                                }

                                if (cbufIsEmpty(this->buffer)) {
                                        cbufRelease(this->buffer);
                                        this->ourLock = FALSE;
                                        cont = 0;
                                        break;
                                }

                                cbufIncRead(
                                                this->buffer,
                                                httpParserBody(
                                                        this,
                                                        cbufGetRead(this->buffer),
                                                        this->buffer->bused));
                                break;

                        case HTTP_MESSAGE_DONE:
                                {
                                        HttpHeader enc = hashGet(
                                                        this->current->header,
                                                        CSTRA("content-type"));

                                        if (NULL != enc && 0 == strncasecmp(
                                                                "application/x-www-form-urlencoded",
                                                                enc->value[0],
                                                                MIN(sizeof("application/x-www-form-urlencoded")-1,
                                                                        enc->nvalue[0]))) {
                                                httpParserPostVars(this);
                                        }

                                this->queue->msgs[(this->queue->nmsgs)++] = this->current;
                                this->current                             = NULL;

                                this->state = HTTP_MESSAGE_GARBAGE;
                                }
                                break;

                        default:
                                break;
                }
        }

        return this->queue->nmsgs;
}

Here is the call graph for this function:

Here is the caller graph for this function:

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines