summary refs log tree commit diff
path: root/src/request.c
blob: fd868f82cbc7807a63f3f0241b7c6054fba0fb7c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "libhttpc.h"

#include <errno.h>
#include <stddef.h>
#include <string.h>


struct LibHTTPC_Request *LibHTTPC_loadRequest(struct LibHTTPC_Request *request_buf, char *buf)
{
    char *next;
    int selfmalloc = 0;

    if (!buf)
        return NULL;

    if (!request_buf)
    {
        if (!LibHTTPC_malloc || !LibHTTPC_realloc)
            return NULL;
        request_buf = LibHTTPC_malloc(sizeof(struct LibHTTPC_Request));
        memset(request_buf, '\0', sizeof(struct LibHTTPC_Request));
        request_buf->selfalloc = 1;
        request_buf->header_count = -1;
    }

    if (request_buf->header_count == -1)
    {
        if (!LibHTTPC_malloc || !LibHTTPC_realloc)
            return NULL;
        selfmalloc = 1;
        request_buf->header_selfalloc = 1;
        request_buf->header_count = 0;
    }

    request_buf->method = request_buf->buf = buf;

    next = strchr(request_buf->method, ' ');
    *next = '\0';
    request_buf->uri = next + 1;

    next = strchr(request_buf->uri, ' ');
    *next = '\0';
    request_buf->version = next + 1;

    next = strstr(request_buf->version, "\r\n");
    *next++ = '\0';

    for (size_t i = 0; (next = strstr(next, "\r\n")); ++next, ++i)
    {
        *next = '\0';
        next += 2;

        if (strstr(next, "\r\n") == next)
            break;

        if (selfmalloc)
        {
            if (!LibHTTPC_malloc || !LibHTTPC_realloc)
                return NULL;
            ++request_buf->header_count;
            if (!request_buf->headers)
                request_buf->headers = LibHTTPC_malloc(sizeof(struct LibHTTPC_Header));
            else
                request_buf->headers = LibHTTPC_realloc(request_buf->headers, sizeof(struct LibHTTPC_Header));
        }
        if (i < request_buf->header_count)
        {
            request_buf->headers[i].name = next;
            next = strchr(next, ':');
            *next++ = '\0';
            request_buf->headers[i].value = next;
        }
    }
    request_buf->body = next + 2;

    return request_buf;
}

int LibHTTPC_Request_(struct LibHTTPC_Request *request)
{
    if (!LibHTTPC_free)
        return -1;

    if (request->header_selfalloc)
        LibHTTPC_free(request->headers);
    if (request->selfalloc)
        LibHTTPC_free(request);
    return errno;
}