5 #include "http_request.h"
6 #include "http_parser.h"
8 struct http_request_s
{
10 http_parser_settings parser_settings
;
26 on_url(http_parser
*parser
, const char *at
, size_t length
)
28 http_request_t
*request
= parser
->data
;
29 int urllen
= request
->url
? strlen(request
->url
) : 0;
31 request
->url
= realloc(request
->url
, urllen
+length
+1);
34 request
->url
[urllen
] = '\0';
35 strncat(request
->url
, at
, length
);
40 on_header_field(http_parser
*parser
, const char *at
, size_t length
)
42 http_request_t
*request
= parser
->data
;
44 /* Check if our index is a value */
45 if (request
->headers_index
%2 == 1) {
46 request
->headers_index
++;
49 /* Allocate space for new field-value pair */
50 if (request
->headers_index
== request
->headers_size
) {
51 request
->headers_size
+= 2;
52 request
->headers
= realloc(request
->headers
,
53 request
->headers_size
*sizeof(char*));
54 assert(request
->headers
);
55 request
->headers
[request
->headers_index
] = NULL
;
56 request
->headers
[request
->headers_index
+1] = NULL
;
59 /* Allocate space in the current header string */
60 if (request
->headers
[request
->headers_index
] == NULL
) {
61 request
->headers
[request
->headers_index
] = calloc(1, length
+1);
63 request
->headers
[request
->headers_index
] = realloc(
64 request
->headers
[request
->headers_index
],
65 strlen(request
->headers
[request
->headers_index
])+length
+1
68 assert(request
->headers
[request
->headers_index
]);
70 strncat(request
->headers
[request
->headers_index
], at
, length
);
75 on_header_value(http_parser
*parser
, const char *at
, size_t length
)
77 http_request_t
*request
= parser
->data
;
79 /* Check if our index is a field */
80 if (request
->headers_index
%2 == 0) {
81 request
->headers_index
++;
84 /* Allocate space in the current header string */
85 if (request
->headers
[request
->headers_index
] == NULL
) {
86 request
->headers
[request
->headers_index
] = calloc(1, length
+1);
88 request
->headers
[request
->headers_index
] = realloc(
89 request
->headers
[request
->headers_index
],
90 strlen(request
->headers
[request
->headers_index
])+length
+1
93 assert(request
->headers
[request
->headers_index
]);
95 strncat(request
->headers
[request
->headers_index
], at
, length
);
100 on_body(http_parser
*parser
, const char *at
, size_t length
)
102 http_request_t
*request
= parser
->data
;
104 request
->data
= realloc(request
->data
, request
->datalen
+length
);
105 assert(request
->data
);
107 memcpy(request
->data
+request
->datalen
, at
, length
);
108 request
->datalen
+= length
;
113 on_message_complete(http_parser
*parser
)
115 http_request_t
*request
= parser
->data
;
117 request
->method
= http_method_str(request
->parser
.method
);
118 request
->complete
= 1;
123 http_request_init(int numerichost
)
125 http_request_t
*request
;
127 request
= calloc(1, sizeof(http_request_t
));
131 http_parser_init(&request
->parser
, HTTP_REQUEST
, !!numerichost
);
132 request
->parser
.data
= request
;
134 request
->parser_settings
.on_url
= &on_url
;
135 request
->parser_settings
.on_header_field
= &on_header_field
;
136 request
->parser_settings
.on_header_value
= &on_header_value
;
137 request
->parser_settings
.on_body
= &on_body
;
138 request
->parser_settings
.on_message_complete
= &on_message_complete
;
144 http_request_destroy(http_request_t
*request
)
150 for (i
=0; i
<request
->headers_size
; i
++) {
151 free(request
->headers
[i
]);
153 free(request
->headers
);
160 http_request_add_data(http_request_t
*request
, const char *data
, int datalen
)
166 ret
= http_parser_execute(&request
->parser
,
167 &request
->parser_settings
,
173 http_request_is_complete(http_request_t
*request
)
176 return request
->complete
;
180 http_request_has_error(http_request_t
*request
)
183 return (HTTP_PARSER_ERRNO(&request
->parser
) != HPE_OK
);
187 http_request_get_error_name(http_request_t
*request
)
190 return http_errno_name(HTTP_PARSER_ERRNO(&request
->parser
));
194 http_request_get_error_description(http_request_t
*request
)
197 return http_errno_description(HTTP_PARSER_ERRNO(&request
->parser
));
201 http_request_get_method(http_request_t
*request
)
204 return request
->method
;
208 http_request_get_url(http_request_t
*request
)
215 http_request_get_header(http_request_t
*request
, const char *name
)
221 for (i
=0; i
<request
->headers_size
; i
+=2) {
222 if (!strcmp(request
->headers
[i
], name
)) {
223 return request
->headers
[i
+1];
230 http_request_get_data(http_request_t
*request
, int *datalen
)
235 *datalen
= request
->datalen
;
237 return request
->data
;