Beispiel #1
0
static inline void handle(Server *server, int fd, fd_set *activeFDs, struct sockaddr_in *addr)
{
    int  nread;
    char buff[20480];

    if ((nread = recv(fd, buff, sizeof(buff), 0)) < 0) {
        fprintf(stderr, "error: read failed\n");
    } else if (nread > 0) {
        buff[nread] = '\0';

        Request *req = requestNew(buff);

        if (!req) {
            send(fd, "HTTP/1.0 400 Bad Request\r\n\r\nBad Request", 39, 0);
            LOG_400(addr);
        } else {
            ListCell *handler  = server->handlers;
            Response *response = NULL;

            while (handler && !response) {
                response = (*(HandlerP)handler->value)(req);
                handler  = handler->next;
            }

            if (!response) {
                send(fd, "HTTP/1.0 404 Not Found\r\n\r\nNot Found!", 36, 0);
                LOG_REQUEST(addr, METHODS[req->method], req->path, 404);
            } else {
                LOG_REQUEST(addr, METHODS[req->method], req->path,
                            response->status);

                responseWrite(response, fd);
                responseDel(response);
            }

            requestDel(req);
        }
    }

    close(fd);

    FD_CLR(fd, activeFDs);
}
Beispiel #2
0
Request *requestNew(char *buff) {
    Request *request = malloc(sizeof(Request));

    char *segment, *bs;

    request->method      = UNKNOWN_METHOD;
    request->path        = NULL;
    request->uri         = NULL;
    request->queryString = NULL;
    request->postBody    = NULL;
    request->headers     = NULL;
    request->cookies     = NULL;
    request->account     = NULL;

    // METHOD
    TOK(buff, " \t");

    if      (strcmp(segment, "OPTIONS") == 0) request->method = OPTIONS;
    else if (strcmp(segment, "GET")     == 0) request->method = GET;
    else if (strcmp(segment, "HEAD")    == 0) request->method = HEAD;
    else if (strcmp(segment, "POST")    == 0) request->method = POST;
    else if (strcmp(segment, "PUT")     == 0) request->method = PUT;
    else if (strcmp(segment, "DELETE")  == 0) request->method = DELETE;
    else if (strcmp(segment, "TRACE")   == 0) request->method = TRACE;
    else if (strcmp(segment, "CONNECT") == 0) request->method = CONNECT;
    else goto fail;

    // PATH
    TOK(NULL, " \t");

    request->path = bsNew(segment);
    request->uri  = bsNew(segment);

    if (strchr(request->path, '#') != NULL)
        goto fail;

    // VERSION
    TOK(NULL, "\n");

    if (strncmp(segment, "HTTP/1.0", 8) != 0 &&
        strncmp(segment, "HTTP/1.1", 8) != 0)
        goto fail;

    // HEADERS
    request->headers = parseHeaders(segment);

    // BODY
    bs = kvFindList(request->headers, "Content-Type");

    if (bs != NULL && strncmp(bs, "application/x-www-form-urlencoded", 33) == 0) {
        segment = strtok(NULL, "\0");

        if (segment == NULL)
            goto fail;

        request->postBody = parseQS(segment);
    }

    // QUERYSTRING
    segment = strchr(request->path, '?');

    if (segment != NULL) {
        request->uri = bsNewLen(request->path, segment - request->path);
        request->queryString = parseQS(segment + 1);

        if (request->queryString == NULL)
            goto fail;
    }

    // COOKIES
    segment = kvFindList(request->headers, "Cookie");

    if (segment != NULL) {
        request->cookies = parseCookies(segment);

        if (request->cookies == NULL)
            goto fail;
    }

    return request;

fail:
    requestDel(request);

    return NULL;
}