commit 83c6b873873e5992ae058785c4941c9b488e6c78
parent 512410aeb0fcaad15bc7e3db54eb6e7331a22d0f
Author: finwo <finwo@pm.me>
Date: Thu, 3 Aug 2023 23:17:35 +0200
Using buffers instead of strings
Diffstat:
| M | src/http-parser.c | | | 244 | +++++++++++++++++++++++++++++++++++++------------------------------------------ |
| M | src/http-parser.h | | | 32 | +++++++++++++++----------------- |
| M | test.c | | | 71 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
3 files changed, 183 insertions(+), 164 deletions(-)
diff --git a/src/http-parser.c b/src/http-parser.c
@@ -7,6 +7,8 @@ extern "C" {
#include <string.h>
#include <strings.h>
+#include "tidwall/buf.h"
+
#include "http-parser.h"
#include "http-parser-statusses.h"
@@ -73,7 +75,7 @@ struct http_parser_header * _http_parser_header_get(struct http_parser_message *
* Searches for the given key in the list of headers
* Returns the header's value or NULL if not found
*/
-char *http_parser_header_get(struct http_parser_message *subject, const char *key) {
+const char *http_parser_header_get(struct http_parser_message *subject, const char *key) {
struct http_parser_header *header = _http_parser_header_get(subject, key);
if (!header) return NULL;
char *value = header->value;
@@ -187,22 +189,28 @@ struct http_parser_pair * http_parser_pair_init(void *udata) {
/**
- * Removed N byte from the beginning of the message body
+ * Removed N bytes from the beginning of the message body
*/
static void http_parser_message_remove_body_bytes(struct http_parser_message *message, int bytes) {
- int size = message->bodysize - bytes;
- char *buf = calloc(1, size + 1);
- memcpy(buf, message->body + bytes, size);
- free(message->body);
- message->body = buf;
- message->bodysize = size;
+ struct buf *newbuf = calloc(1, sizeof(struct buf));
+ int size = message->body->len - bytes;
+
+ if (size > 0) {
+ buf_append(newbuf, message->body->data + bytes, size);
+ }
+
+ if (message->body) {
+ buf_clear(message->body);
+ free(message->body);
+ }
+ message->body = newbuf;
}
/**
* Removes the first string from a http_message's body
*/
static void http_parser_message_remove_body_string(struct http_parser_message *message) {
- int length = strlen(message->body);
+ int length = strlen(message->body->data);
http_parser_message_remove_body_bytes(message, length + 2);
}
@@ -216,23 +224,23 @@ static int http_parser_message_read_header(struct http_parser_message *message)
char *index;
// Require more data if no line break found
- index = strstr(message->body, "\r\n");
+ index = strstr(message->body->data, "\r\n");
if (!index) return 1;
*(index) = '\0';
// Detect end of headers
- if (!strlen(message->body)) {
+ if (!strlen(message->body->data)) { // Using strlen, due to possible \r\n replacement
http_parser_message_remove_body_string(message);
return 0;
}
// Prepare new header
- header = calloc(1,sizeof(header));
- header->key = calloc(1,strlen(message->body));
- header->value = calloc(1,strlen(message->body));
+ header = calloc(1,sizeof(header));
+ header->key = calloc(1,strlen(message->body->data)); // Using strlen, due to possible \r\n replacement
+ header->value = calloc(1,strlen(message->body->data)); // Using strlen, due to possible \r\n replacement
// Detect colon
- index = strstr(message->body, ":");
+ index = strstr(message->body->data, ": ");
if (!index) {
http_parser_header_free(header);
http_parser_message_remove_body_string(message);
@@ -241,11 +249,11 @@ static int http_parser_message_read_header(struct http_parser_message *message)
// Copy key & value
*(index) = '\0';
- strcpy(header->key, message->body);
- strcpy(header->value, index + 1);
+ strcpy(header->key, message->body->data);
+ strcpy(header->value, index + 2);
// Assign to the header list
- header->next = message->headers;
+ header->next = message->headers;
message->headers = header;
// Remove the header line
@@ -267,27 +275,24 @@ static int http_parser_message_read_chunked(struct http_parser_message *message)
if (message->chunksize == -1) {
// Check if we have a line
- index = strstr(message->body, "\r\n");
+ index = strstr(message->body->data, "\r\n");
if (!index) {
return 1;
}
*(index) = '\0';
// Empty line = skip
- if (!strlen(message->body)) {
+ if (!strlen(message->body->data)) {
http_parser_message_remove_body_string(message);
return 2;
}
// Read hex chunksize
aChunkSize = calloc(1, 17);
- sscanf(message->body, "%16s", aChunkSize);
+ sscanf(message->body->data, "%16s", aChunkSize);
message->chunksize = xtoi(aChunkSize);
free(aChunkSize);
- // Add it to the total
- message->chunktotal += message->chunksize;
-
// Remove chunksize line
http_parser_message_remove_body_string(message);
@@ -302,12 +307,11 @@ static int http_parser_message_read_chunked(struct http_parser_message *message)
// Create buffer if not present yet
if (!message->buf) {
- message->buf = calloc(1,1);
- message->bufsize = 0;
+ message->buf = calloc(1,sizeof(struct buf));
}
// Ensure the body has enough data
- if (message->bodysize < message->chunksize) {
+ if (message->body->len < message->chunksize) {
return 1;
}
@@ -316,16 +320,15 @@ static int http_parser_message_read_chunked(struct http_parser_message *message)
// Call onChunk if the message has that set
ev = calloc(1,sizeof(struct http_parser_event));
ev->udata = message->udata;
- ev->chunksize = message->chunksize;
- ev->chunk = message->body;
+ ev->chunk = &((struct buf){
+ .len = message->chunksize,
+ .cap = message->chunksize,
+ .data = message->body->data,
+ });
message->onChunk(ev);
free(ev);
} else {
- // Copy data into buffer if no onChunk set
- message->buf = realloc(message->buf, message->bufsize + message->chunksize + 1);
- memcpy(message->buf + message->bufsize, message->body, message->chunksize );
- message->bufsize += message->chunksize;
- *(message->buf + message->bufsize) = '\0';
+ buf_append(message->buf, message->body->data, message->chunksize);
}
// Remove chunk from receiving data and reset chunking
@@ -336,7 +339,7 @@ static int http_parser_message_read_chunked(struct http_parser_message *message)
return 2;
}
-char * http_parser_status_message(int status) {
+const char * http_parser_status_message(int status) {
int i;
for(i=0; http_parser_statusses[i].status; i++) {
if (http_parser_statusses[i].status == status) {
@@ -346,60 +349,62 @@ char * http_parser_status_message(int status) {
return NULL;
}
-char * http_parser_sprint_pair_response(struct http_parser_pair *pair) {
+struct buf * http_parser_sprint_pair_response(struct http_parser_pair *pair) {
return http_parser_sprint_response(pair->response);
}
-char * http_parser_sprint_pair_request(struct http_parser_pair *pair) {
+struct buf * http_parser_sprint_pair_request(struct http_parser_pair *pair) {
return http_parser_sprint_request(pair->request);
}
+void _http_parser_sprint_headers(char *target, struct http_parser_header *header) {
+ if (header->next) _http_parser_sprint_headers(target, header->next);
+ strcat(target, header->key);
+ strcat(target, ": ");
+ strcat(target, header->value);
+ strcat(target, "\r\n");
+}
+
// Caution: headers should fit in 64k
-char * http_parser_sprint_response(struct http_parser_message *response) {
- char *result = calloc(1,65536);
- struct http_parser_header *header;
+struct buf * http_parser_sprint_response(struct http_parser_message *response) {
+ struct buf *result = calloc(1, sizeof(struct buf));
+ result->cap = 65536;
+ result->data = calloc(1, result->cap);
+
int index, length;
// Status
- sprintf(result,
+ sprintf(result->data,
"HTTP/%s %d %s\r\n"
, response->version
, response->status
, response->statusMessage ? response->statusMessage : http_parser_status_message(response->status)
);
- // Headers
- header = response->headers;
- while(header) {
- // Write header
- strcat(result, header->key);
- strcat(result, ": ");
- strcat(result, header->value);
- strcat(result, "\r\n");
- // Next header
- header = header->next;
+ if (response->headers) {
+ _http_parser_sprint_headers(result->data, response->headers);
}
- strcpy( result + strlen(result), "\r\n" );
+ strcat(result->data, "\r\n");
+
+ // Treat result as buffer from here
+ result->len = strlen(result->data);
- // Write body
- index = strlen(result);
- length = index + response->bodysize;
- result = realloc(result, length + 1);
- *(result + length) = '\0';
- memcpy( result + index, response->body, response->bodysize );
+ buf_append(result, response->body->data, response->body->len);
return result;
}
// Caution: headers should fit in 64k
-char * http_parser_sprint_request(struct http_parser_message *request) {
- char *result = calloc(1,65536);
- struct http_parser_header *header;
+struct buf * http_parser_sprint_request(struct http_parser_message *request) {
+ struct buf *result = calloc(1, sizeof(struct buf));
+ result->cap = 65536;
+ result->data = calloc(1, result->cap);
+
int index, length;
// Status
- sprintf(result,
+ sprintf(result->data,
"%s %s"
, request->method
, request->path
@@ -407,50 +412,37 @@ char * http_parser_sprint_request(struct http_parser_message *request) {
// Query
if (request->query) {
- *(result + strlen(result)) = '?';
- strcpy( result + strlen(result), request->query );
+ strcat(result->data, "?");
+ strcat(result->data, request->query);
}
// HTTP version
- strcpy( result + strlen(result), " HTTP/" );
- strcpy( result + strlen(result), request->version );
- strcpy( result + strlen(result), "\r\n" );
+ strcat(result->data, " HTTP/");
+ strcat(result->data, request->version);
+ strcat(result->data, "\r\n");
// Headers
- header = request->headers;
- while(header) {
- // Write header
- strcat(result, header->key);
- strcat(result, ": ");
- strcat(result, header->value);
- strcat(result, "\r\n");
- // Next header
- header = header->next;
+ if (request->headers) {
+ _http_parser_sprint_headers(result->data, request->headers);
}
- strcpy( result + strlen(result), "\r\n" );
+ strcat(result->data, "\r\n");
// Handle chunked header
- if (http_parser_header_get(request, "transfer-encoding")) {
- result = realloc(result, strlen(result) + 20);
- sprintf(result+strlen(result), "%x\r\n", request->bodysize);
+ char *aTransferEncoding = http_parser_header_get(request, "transfer-encoding");
+ int isChunked = 0;
+ if (aTransferEncoding && strcasecmp(aTransferEncoding, "chunked")) {
+ isChunked = 1;
+ sprintf(result->data + strlen(result->data), "%x\r\n", request->body->len);
}
- // Write body
- index = strlen(result);
- length = index + request->bodysize;
- result = realloc(result, length + 1);
- *(result + length) = '\0';
- memcpy( result + index, request->body, request->bodysize );
-
- if (http_parser_header_get(request, "transfer-encoding")) {
- result = realloc(result, length + 6);
- *(result+length+0) = '0';
- *(result+length+1) = '\r';
- *(result+length+2) = '\n';
- *(result+length+3) = '\r';
- *(result+length+4) = '\n';
- *(result+length+5) = '\0';
+ // Treat result as buffer from here
+ result->len = strlen(result->data);
+
+ buf_append(result, request->body->data, request->body->len);
+
+ if (isChunked) {
+ buf_append(result, "0\r\n\r\n", 5);
}
return result;
@@ -461,9 +453,9 @@ char * http_parser_sprint_request(struct http_parser_message *request) {
*
* Triggers onRequest if set
*/
-void http_parser_pair_request_data(struct http_parser_pair *pair, const char *data, int size) {
+void http_parser_pair_request_data(struct http_parser_pair *pair, const struct buf *data) {
struct http_parser_event *ev;
- http_parser_request_data(pair->request, data, size);
+ http_parser_request_data(pair->request, data);
if (pair->request->ready && pair->onRequest) {
ev = calloc(1,sizeof(struct http_parser_event));
ev->request = pair->request;
@@ -481,9 +473,9 @@ void http_parser_pair_request_data(struct http_parser_pair *pair, const char *da
*
* Triggers onRequest if set
*/
-void http_parser_pair_response_data(struct http_parser_pair *pair, const char *data, int size) {
+void http_parser_pair_response_data(struct http_parser_pair *pair, const struct buf *data) {
struct http_parser_event *ev;
- http_parser_response_data(pair->request, data, size);
+ http_parser_response_data(pair->request, data);
if (pair->request->ready && pair->onResponse) {
ev = calloc(1,sizeof(struct http_parser_event));
ev->request = pair->request;
@@ -499,7 +491,7 @@ void http_parser_pair_response_data(struct http_parser_pair *pair, const char *d
/**
* Insert data into a http_message, acting as if it's a request
*/
-void http_parser_request_data(struct http_parser_message *request, const char *data, int size) {
+void http_parser_request_data(struct http_parser_message *request, const struct buf *data) {
char *index;
char *aContentLength;
int iContentLength;
@@ -507,13 +499,8 @@ void http_parser_request_data(struct http_parser_message *request, const char *d
int res;
// Add event data to buffer
- if (!request->body) request->body = malloc(1);
- request->body = realloc(request->body, request->bodysize + size + 1);
- memcpy(request->body + request->bodysize, data, size);
- request->bodysize += size;
-
- // Make string functions not segfault
- *(request->body + request->bodysize) = '\0';
+ if (!request->body) request->body = calloc(1, sizeof(struct buf));
+ buf_append(request->body, data->data, data->len);
while(1) {
switch(request->_state) {
@@ -522,7 +509,7 @@ void http_parser_request_data(struct http_parser_message *request, const char *d
case HTTP_PARSER_STATE_INIT:
// Wait for more data if not line break found
- index = strstr(request->body, "\r\n");
+ index = strstr(request->body->data, "\r\n");
if (!index) return;
*(index) = '\0';
@@ -530,7 +517,7 @@ void http_parser_request_data(struct http_parser_message *request, const char *d
request->method = calloc(1, 16);
request->path = calloc(1, 8192);
request->version = calloc(1, 4);
- if (sscanf(request->body, "%15s %8191s HTTP/%3s", request->method, request->path, request->version) != 3) {
+ if (sscanf(request->body->data, "%15s %8191s HTTP/%3s", request->method, request->path, request->version) != 3) {
request->_state = HTTP_PARSER_STATE_PANIC;
return;
}
@@ -569,8 +556,7 @@ void http_parser_request_data(struct http_parser_message *request, const char *d
if (request->chunksize == -1) {
aChunkSize = http_parser_header_get(request, "transfer-encoding");
if (aChunkSize) {
- if (!strcmp(aChunkSize, "chunked")) {
- request->chunktotal = 0;
+ if (!strcasecmp(aChunkSize, "chunked")) {
request->_state = HTTP_PARSER_STATE_BODY_CHUNKED;
break;
}
@@ -586,12 +572,11 @@ void http_parser_request_data(struct http_parser_message *request, const char *d
iContentLength = atoi(aContentLength);
// Not enough data = skip
- if (request->bodysize < iContentLength) {
+ if (request->body->len < iContentLength) {
return;
}
// Change size to indicated size
- request->bodysize = iContentLength;
request->_state = HTTP_PARSER_STATE_DONE;
break;
@@ -614,10 +599,12 @@ void http_parser_request_data(struct http_parser_message *request, const char *d
// Temporary buffer > direct buffer
if (request->buf) {
- free(request->body);
+ if (request->body) {
+ buf_clear(request->body);
+ free(request->body);
+ }
request->body = request->buf;
request->buf = NULL;
- request->bodysize = request->chunktotal;
}
// Mark the request as ready
@@ -630,7 +617,7 @@ void http_parser_request_data(struct http_parser_message *request, const char *d
/**
* Insert data into a http_message, acting as if it's a request
*/
-void http_parser_response_data(struct http_parser_message *response, const char *data, int size) {
+void http_parser_response_data(struct http_parser_message *response, const struct buf *data) {
char *index;
char *aStatus;
int iContentLength;
@@ -639,13 +626,8 @@ void http_parser_response_data(struct http_parser_message *response, const char
int res;
// Add event data to buffer
- if (!response->body) response->body = malloc(1);
- response->body = realloc(response->body, response->bodysize + size + 1);
- memcpy(response->body + response->bodysize, data, size);
- response->bodysize += size;
-
- // Make string functions not segfault
- *(response->body + response->bodysize) = '\0';
+ if (!response->body) response->body = calloc(1, sizeof(struct buf));
+ buf_append(response->body, data->data, data->len);
while(1) {
switch(response->_state) {
@@ -654,7 +636,7 @@ void http_parser_response_data(struct http_parser_message *response, const char
case HTTP_PARSER_STATE_INIT:
// Wait for more data if not line break found
- index = strstr(response->body, "\r\n");
+ index = strstr(response->body->data, "\r\n");
if (!index) return;
*(index) = '\0';
@@ -662,7 +644,7 @@ void http_parser_response_data(struct http_parser_message *response, const char
response->version = calloc(1, 4);
response->statusMessage = calloc(1, 8192);
aStatus = calloc(1, 4);
- if (sscanf(response->body, "HTTP/%3s %3s %8191c", response->version, aStatus, response->statusMessage) != 3) {
+ if (sscanf(response->body->data, "HTTP/%3s %3s %8191c", response->version, aStatus, response->statusMessage) != 3) {
response->_state = HTTP_PARSER_STATE_PANIC;
return;
}
@@ -697,8 +679,7 @@ void http_parser_response_data(struct http_parser_message *response, const char
if (response->chunksize == -1) {
aChunkSize = http_parser_header_get(response, "transfer-encoding");
if (aChunkSize) {
- if (!strcmp(aChunkSize, "chunked")) {
- response->chunktotal = 0;
+ if (!strcasecmp(aChunkSize, "chunked")) {
response->_state = HTTP_PARSER_STATE_BODY_CHUNKED;
break;
}
@@ -714,12 +695,11 @@ void http_parser_response_data(struct http_parser_message *response, const char
iContentLength = atoi(aContentLength);
// Not enough data = skip
- if (response->bodysize < iContentLength) {
+ if (response->body->len < iContentLength) {
return;
}
// Change size to indicated size
- response->bodysize = iContentLength;
response->_state = HTTP_PARSER_STATE_DONE;
break;
@@ -742,10 +722,12 @@ void http_parser_response_data(struct http_parser_message *response, const char
// Temporary buffer > direct buffer
if (response->buf) {
- free(response->body);
+ if (response->body) {
+ buf_clear(response->body);
+ free(response->body);
+ }
response->body = response->buf;
response->buf = NULL;
- response->bodysize = response->chunktotal;
}
// Mark the request as ready
diff --git a/src/http-parser.h b/src/http-parser.h
@@ -12,6 +12,8 @@ extern "C" {
#define HTTP_PARSER_STATE_DONE 4
#define HTTP_PARSER_STATE_PANIC 666
+#include "tidwall/buf.h"
+
struct http_parser_header {
void *next;
char *key;
@@ -22,8 +24,7 @@ struct http_parser_event {
struct http_parser_message *request;
struct http_parser_message *response;
struct http_parser_pair *pair;
- const char *chunk;
- int chunksize;
+ struct buf *chunk;
void *udata;
};
@@ -36,12 +37,9 @@ struct http_parser_message {
char *query;
char *version;
struct http_parser_header *headers;
- char *body;
- char *buf;
- int bufsize;
+ struct buf *body;
+ struct buf *buf;
int chunksize;
- int bodysize;
- int chunktotal;
int _state;
void (*onChunk)(struct http_parser_event*);
void *udata;
@@ -56,7 +54,7 @@ struct http_parser_pair {
};
// Header management
-char *http_parser_header_get(struct http_parser_message *subject, const char *key);
+const char * http_parser_header_get(struct http_parser_message *subject, const char *key);
void http_parser_header_set(struct http_parser_message *subject ,const char *key, const char *value);
void http_parser_header_add(struct http_parser_message *subject ,const char *key, const char *value);
void http_parser_header_del(struct http_parser_message *subject, const char *key);
@@ -65,20 +63,20 @@ struct http_parser_pair * http_parser_pair_init(void *udata);
struct http_parser_message * http_parser_request_init();
struct http_parser_message * http_parser_response_init();
-void http_parser_request_data(struct http_parser_message *request, const char *data, int size);
-void http_parser_response_data(struct http_parser_message *response, const char *data, int size);
+void http_parser_request_data(struct http_parser_message *request, const struct buf *data);
+void http_parser_response_data(struct http_parser_message *response, const struct buf *data);
-void http_parser_pair_request_data(struct http_parser_pair *pair, const char *data, int size);
-void http_parser_pair_response_data(struct http_parser_pair *pair, const char *data, int size);
+void http_parser_pair_request_data(struct http_parser_pair *pair, const struct buf *data);
+void http_parser_pair_response_data(struct http_parser_pair *pair, const struct buf *data);
void http_parser_pair_free(struct http_parser_pair *pair);
void http_parser_message_free(struct http_parser_message *subject);
-char * http_parser_status_message(int status);
-char * http_parser_sprint_pair_response(struct http_parser_pair *pair);
-char * http_parser_sprint_pair_request(struct http_parser_pair *pair);
-char * http_parser_sprint_response(struct http_parser_message *response);
-char * http_parser_sprint_request(struct http_parser_message *request);
+const char * http_parser_status_message(int status);
+struct buf * http_parser_sprint_pair_response(struct http_parser_pair *pair);
+struct buf * http_parser_sprint_pair_request(struct http_parser_pair *pair);
+struct buf * http_parser_sprint_response(struct http_parser_message *response);
+struct buf * http_parser_sprint_request(struct http_parser_message *request);
#ifdef __cplusplus
} // extern "C"
diff --git a/test.c b/test.c
@@ -15,6 +15,13 @@
#define ASSERT(M,c) (printf(((err|=!(c),(c)) ? (T_LIME " PASS " T_NORMAL " %s\n") : (T_RED " FAIL " T_NORMAL " %s\n")),M))
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
/* static void onRequest(struct http_parser_event *ev) { */
/* // The request has been received */
/* // Answer the request directly or pass it to a route handler of sorts */
@@ -107,6 +114,8 @@ char *responseNotFoundMessage =
int main() {
struct http_parser_message *request = http_parser_request_init();
struct http_parser_message *response = http_parser_response_init();
+ struct buf *msgbuf;
+
int err = 0;
printf("# Pre-loaded request\n");
@@ -116,38 +125,56 @@ int main() {
http_parser_message_free(request);
request = http_parser_request_init();
- http_parser_request_data(request, getMessage, strlen(getMessage));
+ http_parser_request_data(request, &((struct buf){
+ .data = getMessage,
+ .len = strlen(getMessage),
+ .cap = strlen(getMessage)
+ }));
printf("# GET request\n");
ASSERT("request->version is 1.1", strcmp(request->version, "1.1") == 0);
ASSERT("request->method is GET", strcmp(request->method, "GET") == 0);
ASSERT("request->path is /foobar", strcmp(request->path, "/foobar") == 0);
- ASSERT("request->toString matches", strcmp(getMessage, http_parser_sprint_request(request)));
+ msgbuf = http_parser_sprint_request(request);
+ ASSERT("request->toString matches", strcmp(getMessage, msgbuf->data) == 0);
http_parser_message_free(request);
request = http_parser_request_init();
- http_parser_request_data(request, postMessage, strlen(postMessage));
+ http_parser_request_data(request, &((struct buf){
+ .data = postMessage,
+ .len = strlen(postMessage),
+ .cap = strlen(postMessage)
+ }));
printf("# POST request\n");
ASSERT("request->version is 1.1", strcmp(request->version, "1.1") == 0);
ASSERT("request->method is POST", strcmp(request->method, "POST") == 0);
ASSERT("request->path is /foobar", strcmp(request->path, "/foobar") == 0);
- ASSERT("request->body is \"Helo World\\r\\n\"", strcmp(request->body, "Hello World\r\n") == 0);
- ASSERT("request->toString matches", strcmp(postMessage, http_parser_sprint_request(request)));
+ ASSERT("request->body is \"Hello World\\r\\n\"", strcmp(request->body->data, "Hello World\r\n") == 0);
+ msgbuf = http_parser_sprint_request(request);
+ ASSERT("request->toString matches", strcmp(postMessage, msgbuf->data) == 0);
http_parser_message_free(request);
request = http_parser_request_init();
- http_parser_request_data(request, postChunkedMessage, strlen(postChunkedMessage));
+ http_parser_request_data(request, &((struct buf){
+ .data = postChunkedMessage,
+ .len = strlen(postChunkedMessage),
+ .cap = strlen(postChunkedMessage)
+ }));
printf("# POST request (chunked)\n");
ASSERT("request->version is 1.1", strcmp(request->version, "1.1") == 0);
ASSERT("request->method is POST", strcmp(request->method, "POST") == 0);
ASSERT("request->path is /foobar", strcmp(request->path, "/foobar") == 0);
- ASSERT("request->body is \"Helo World\\r\\n\"", strcmp(request->body, "Hello World\r\n") == 0);
+ ASSERT("request->body is \"Hello World\\r\\n\"", strcmp(request->body->data, "Hello World\r\n") == 0);
http_parser_message_free(request);
request = http_parser_request_init();
- http_parser_request_data(request, optionsRequest, strlen(optionsRequest));
+ http_parser_request_data(request, &((struct buf){
+ .data = optionsRequest,
+ .len = strlen(optionsRequest),
+ .cap = strlen(optionsRequest)
+ }));
printf("# OPTIONS request\n");
ASSERT("request->version is 1.1", strcmp(request->version, "1.1") == 0);
@@ -159,32 +186,44 @@ int main() {
http_parser_message_free(response);
response = http_parser_response_init();
- http_parser_response_data(response, responseMessage, strlen(responseMessage));
+ http_parser_response_data(response, &((struct buf){
+ .data = responseMessage,
+ .len = strlen(responseMessage),
+ .cap = strlen(responseMessage)
+ }));
printf("# 200 OK response\n");
ASSERT("response->status = 200", response->status == 200);
ASSERT("response->statusmessage = \"OK\"", strcmp(response->statusMessage, "OK") == 0);
- ASSERT("response->body = \"Hello World\\r\\n\"", strcmp(response->body, "Hello World\r\n") == 0);
- ASSERT("response->toString matches", strcmp(responseMessage, http_parser_sprint_response(response)));
+ ASSERT("response->body = \"Hello World\\r\\n\"", strcmp(response->body->data, "Hello World\r\n") == 0);
+ ASSERT("response->toString matches", strcmp(responseMessage, http_parser_sprint_response(response)->data) == 0);
http_parser_message_free(response);
response = http_parser_response_init();
- http_parser_response_data(response, responseChunkedMessage, strlen(responseChunkedMessage));
+ http_parser_response_data(response, &((struct buf){
+ .data = responseChunkedMessage,
+ .len = strlen(responseChunkedMessage),
+ .cap = strlen(responseChunkedMessage)
+ }));
printf("# 200 OK response (chunked)\n");
ASSERT("response->status = 200", response->status == 200);
ASSERT("response->statusmessage = \"OK\"", strcmp(response->statusMessage, "OK") == 0);
- ASSERT("response->body = \"Hello World\\r\\n\"", strcmp(response->body, "Hello World\r\n") == 0);
+ ASSERT("response->body = \"Hello World\\r\\n\"", strcmp(response->body->data, "Hello World\r\n") == 0);
http_parser_message_free(response);
response = http_parser_response_init();
- http_parser_response_data(response, responseNotFoundMessage, strlen(responseNotFoundMessage));
+ http_parser_response_data(response, &((struct buf){
+ .data = responseNotFoundMessage,
+ .len = strlen(responseNotFoundMessage),
+ .cap = strlen(responseNotFoundMessage)
+ }));
printf("# 404 Not Found response\n");
ASSERT("response->status = 404", response->status == 404);
ASSERT("response->statusmessage = \"Not Found\"", strcmp(response->statusMessage, "Not Found") == 0);
- ASSERT("response->body = \"Not Found\\r\\n\"", strcmp(response->body, "Not Found\r\n") == 0);
- ASSERT("response->toString matches", strcmp(responseNotFoundMessage, http_parser_sprint_response(response)));
+ ASSERT("response->body = \"Not Found\\r\\n\"", strcmp(response->body->data, "Not Found\r\n") == 0);
+ ASSERT("response->toString matches", strcmp(responseNotFoundMessage, http_parser_sprint_response(response)->data) == 0);
return err;
}