test.c (8112B)
1 #include <stdio.h> 2 #include <string.h> 3 4 #include "http-parser.h" 5 6 #ifndef NULL 7 #define NULL ((void*)0) 8 #endif 9 10 #define T_RED "\e[31m" 11 #define T_LIME "\e[32m" 12 #define T_MAGENTA "\e[35m" 13 #define T_NORMAL "\e[00m" 14 #define T_BOLD "\e[01m" 15 16 #define ASSERT(M,c) (printf(((err|=!(c),(c)) ? (T_LIME " PASS " T_NORMAL " %s\n") : (T_RED " FAIL " T_NORMAL " %s\n")),M)) 17 18 #ifndef MIN 19 #define MIN(a,b) ((a)<(b)?(a):(b)) 20 #endif 21 #ifndef MAX 22 #define MAX(a,b) ((a)>(b)?(a):(b)) 23 #endif 24 25 /* static void onRequest(struct http_parser_event *ev) { */ 26 /* // The request has been received */ 27 /* // Answer the request directly or pass it to a route handler of sorts */ 28 29 /* // Fetching the request */ 30 /* // Has been wrapped in http_parser_event to support more features in the future */ 31 /* struct http_parser_request *request = ev->request; */ 32 33 /* // Basic http request data */ 34 /* printf("Method: %s\n", request->method); */ 35 36 /* // Reading headers are case-insensitive due to non-compliant clients/servers */ 37 /* printf("Host: %s\n", http_parser_header_get(request, "host")); */ 38 39 /* // Once you're done with the request, you'll have to free it */ 40 /* http_parser_request_free(request); */ 41 /* } */ 42 43 /* // Initialize a request */ 44 /* struct http_parser_request *request = http_parser_init(); */ 45 46 /* // Assign userdata into the request */ 47 /* // Use it to track whatever you need */ 48 /* request->udata = (void*)...; */ 49 50 /* // Attach a function */ 51 52 // Stored http messages 53 char *getMessage = 54 "GET /foobar HTTP/1.1\r\n" 55 "Host: localhost\r\n" 56 "\r\n" 57 ; 58 59 char *postMessage = 60 "POST /foobar HTTP/1.1\r\n" 61 "Host: localhost\r\n" 62 "Content-Length: 13\r\n" 63 "\r\n" 64 "Hello World\r\n" 65 ; 66 67 char *postOrderedMessage = 68 "POST /foobar HTTP/1.1\r\n" 69 "Content-Length: 13\r\n" 70 "Host: localhost\r\n" 71 "\r\n" 72 "Hello World\r\n" 73 ; 74 75 char *postChunkedMessage = 76 "POST /foobar?token=pizza HTTP/1.1\r\n" 77 "Host: localhost\r\n" 78 "Transfer-Encoding: chunked\r\n" 79 "\r\n" 80 "2\r\n" 81 "He\r\n" 82 "B\r\n" 83 "llo World\r\n" 84 "0\r\n" 85 ; 86 87 char *optionsRequest = 88 "OPTIONS /hello/world HTTP/1.1\r\n" 89 "Host: localhost\r\n" 90 "\r\n" 91 ; 92 93 char *responseMessage = 94 "HTTP/1.0 200 OK\r\n" 95 "Content-Length: 13\r\n" 96 "\r\n" 97 "Hello World\r\n" 98 ; 99 100 char *responseChunkedMessage = 101 "HTTP/1.0 200 OK\r\n" 102 "Transfer-Encoding: chunked\r\n" 103 "\r\n" 104 "2\r\n" 105 "He\r\n" 106 "B\r\n" 107 "llo World\r\n" 108 "0\r\n" 109 ; 110 111 char *responseNotFoundMessage = 112 "HTTP/1.0 404 Not Found\r\n" 113 "Content-Length: 11\r\n" 114 "\r\n" 115 "Not Found\r\n" 116 ; 117 118 char *responseNotFoundExtendedMessage = 119 "HTTP/1.0 404 Not Found\r\n" 120 "Content-Length: 11\r\n" 121 "Content-Type: text/plain\r\n" 122 "\r\n" 123 "Not Found\r\n" 124 ; 125 126 127 /* // Passing network data into it */ 128 /* http_parser_request_data(request, message, strlen(message)); */ 129 130 int main() { 131 struct http_parser_message *request = http_parser_request_init(); 132 struct http_parser_message *response = http_parser_response_init(); 133 struct buf *msgbuf; 134 135 int err = 0; 136 137 printf("# Pre-loaded request\n"); 138 ASSERT("request->method is null", request->method == NULL); 139 ASSERT("request->body is null", request->body == NULL); 140 ASSERT("request->chunksize is -1", request->chunksize == -1); 141 ASSERT("request->header->host is NULL", http_parser_header_get(request, "host") == NULL); 142 143 http_parser_message_free(request); 144 request = http_parser_request_init(); 145 http_parser_request_data(request, &((struct buf){ 146 .data = getMessage, 147 .len = strlen(getMessage), 148 .cap = strlen(getMessage) 149 })); 150 151 printf("# GET request\n"); 152 ASSERT("request->version is 1.1", strcmp(request->version, "1.1") == 0); 153 ASSERT("request->method is GET", strcmp(request->method, "GET") == 0); 154 ASSERT("request->path is /foobar", strcmp(request->path, "/foobar") == 0); 155 msgbuf = http_parser_sprint_request(request); 156 ASSERT("request->toString matches", strcmp(getMessage, msgbuf->data) == 0); 157 ASSERT("request->header->host is localhost", strcmp(http_parser_header_get(request, "host"), "localhost") == 0); 158 159 http_parser_message_free(request); 160 request = http_parser_request_init(); 161 http_parser_request_data(request, &((struct buf){ 162 .data = postMessage, 163 .len = strlen(postMessage), 164 .cap = strlen(postMessage) 165 })); 166 167 printf("# POST request\n"); 168 ASSERT("request->version is 1.1", strcmp(request->version, "1.1") == 0); 169 ASSERT("request->method is POST", strcmp(request->method, "POST") == 0); 170 ASSERT("request->path is /foobar", strcmp(request->path, "/foobar") == 0); 171 ASSERT("request->body is \"Hello World\\r\\n\"", strcmp(request->body->data, "Hello World\r\n") == 0); 172 msgbuf = http_parser_sprint_request(request); 173 ASSERT("request->toString matches", strcmp(postOrderedMessage, msgbuf->data) == 0); 174 175 http_parser_message_free(request); 176 request = http_parser_request_init(); 177 http_parser_request_data(request, &((struct buf){ 178 .data = postChunkedMessage, 179 .len = strlen(postChunkedMessage), 180 .cap = strlen(postChunkedMessage) 181 })); 182 183 printf("# POST request (chunked)\n"); 184 ASSERT("request->version is 1.1", strcmp(request->version, "1.1") == 0); 185 ASSERT("request->method is POST", strcmp(request->method, "POST") == 0); 186 ASSERT("request->path is /foobar", strcmp(request->path, "/foobar") == 0); 187 ASSERT("request->body is \"Hello World\\r\\n\"", strcmp(request->body->data, "Hello World\r\n") == 0); 188 189 http_parser_message_free(request); 190 request = http_parser_request_init(); 191 http_parser_request_data(request, &((struct buf){ 192 .data = optionsRequest, 193 .len = strlen(optionsRequest), 194 .cap = strlen(optionsRequest) 195 })); 196 197 printf("# OPTIONS request\n"); 198 ASSERT("request->version is 1.1", strcmp(request->version, "1.1") == 0); 199 ASSERT("request->method is OPTIONS", strcmp(request->method, "OPTIONS") == 0); 200 ASSERT("request->path is /hello/world", strcmp(request->path, "/hello/world") == 0); 201 202 printf("# Pre-loaded response\n"); 203 ASSERT("response->status = 200", response->status == 200); 204 205 http_parser_message_free(response); 206 response = http_parser_response_init(); 207 http_parser_response_data(response, &((struct buf){ 208 .data = responseMessage, 209 .len = strlen(responseMessage), 210 .cap = strlen(responseMessage) 211 })); 212 213 printf("# 200 OK response\n"); 214 ASSERT("response->status = 200", response->status == 200); 215 ASSERT("response->statusmessage = \"OK\"", strcmp(response->statusMessage, "OK") == 0); 216 ASSERT("response->body = \"Hello World\\r\\n\"", strcmp(response->body->data, "Hello World\r\n") == 0); 217 ASSERT("response->toString matches", strcmp(responseMessage, http_parser_sprint_response(response)->data) == 0); 218 219 http_parser_message_free(response); 220 response = http_parser_response_init(); 221 http_parser_response_data(response, &((struct buf){ 222 .data = responseChunkedMessage, 223 .len = strlen(responseChunkedMessage), 224 .cap = strlen(responseChunkedMessage) 225 })); 226 227 printf("# 200 OK response (chunked)\n"); 228 ASSERT("response->status = 200", response->status == 200); 229 ASSERT("response->statusmessage = \"OK\"", strcmp(response->statusMessage, "OK") == 0); 230 ASSERT("response->body = \"Hello World\\r\\n\"", strcmp(response->body->data, "Hello World\r\n") == 0); 231 232 http_parser_message_free(response); 233 response = http_parser_response_init(); 234 http_parser_response_data(response, &((struct buf){ 235 .data = responseNotFoundMessage, 236 .len = strlen(responseNotFoundMessage), 237 .cap = strlen(responseNotFoundMessage) 238 })); 239 240 printf("# 404 Not Found response\n"); 241 ASSERT("response->status = 404", response->status == 404); 242 ASSERT("response->statusmessage = \"Not Found\"", strcmp(response->statusMessage, "Not Found") == 0); 243 ASSERT("response->body = \"Not Found\\r\\n\"", strcmp(response->body->data, "Not Found\r\n") == 0); 244 ASSERT("response->toString matches", strcmp(responseNotFoundMessage, http_parser_sprint_response(response)->data) == 0); 245 246 http_parser_header_set(response, "Content-Type", "text/plain"); 247 248 ASSERT("response->toString matches after header modification", strcmp(responseNotFoundExtendedMessage, http_parser_sprint_response(response)->data) == 0); 249 250 return err; 251 }