tinywebd
diff src/http.c @ 5:def49a046566
serialization of responses
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 17 Apr 2015 01:57:00 +0300 |
parents | 9e054c002489 |
children | 5ec50ca0d071 |
line diff
1.1 --- a/src/http.c Thu Apr 16 17:34:15 2015 +0300 1.2 +++ b/src/http.c Fri Apr 17 01:57:00 2015 +0300 1.3 @@ -1,6 +1,7 @@ 1.4 #include <stdio.h> 1.5 #include <stdlib.h> 1.6 #include <string.h> 1.7 +#include <stdarg.h> 1.8 #include <ctype.h> 1.9 #include <alloca.h> 1.10 #include "http.h" 1.11 @@ -195,6 +196,91 @@ 1.12 free(hdr->uri); 1.13 } 1.14 1.15 +int http_init_resp(struct http_resp_header *resp) 1.16 +{ 1.17 + memset(resp, 0, sizeof *resp); 1.18 + resp->status = 200; 1.19 + resp->ver_major = resp->ver_minor = 1; 1.20 + resp->fields = 0; 1.21 + resp->num_fields = 0; 1.22 + 1.23 + return 0; 1.24 +} 1.25 + 1.26 +int http_add_resp_field(struct http_resp_header *resp, const char *fmt, ...) 1.27 +{ 1.28 + int sz; 1.29 + va_list ap; 1.30 + char *field, *newarr, tmp; 1.31 + 1.32 + va_start(ap, fmt); 1.33 + sz = vsnprintf(&tmp, 0, fmt, ap); 1.34 + va_end(ap); 1.35 + 1.36 + if(sz <= 0) sz = 1023; 1.37 + if(!(field = malloc(sz + 1))) { 1.38 + return -1; 1.39 + } 1.40 + va_start(ap, fmt); 1.41 + vsnprintf(field, sz + 1, fmt, ap); 1.42 + va_end(ap); 1.43 + 1.44 + if(!(newarr = realloc(resp->fields, (resp->num_fields + 1) * sizeof *resp->fields))) { 1.45 + free(field); 1.46 + return -1; 1.47 + } 1.48 + resp->fields[resp->num_fields++] = newarr; 1.49 + return 0; 1.50 +} 1.51 + 1.52 +void http_destroy_resp(struct http_resp_header *resp) 1.53 +{ 1.54 + int i; 1.55 + if(resp->fields) { 1.56 + for(i=0; i<resp->num_fields; i++) { 1.57 + free(resp->fields[i]); 1.58 + } 1.59 + free(resp->fields); 1.60 + resp->fields = 0; 1.61 + } 1.62 + resp->num_fields = 0; 1.63 +} 1.64 + 1.65 +int http_serialize_resp(struct http_resp_header *resp, char *buf) 1.66 +{ 1.67 + int i, stsize, size, *fsize; 1.68 + char *ptr, tmp; 1.69 + 1.70 + stsize = snprintf(&tmp, 0, "HTTP/%d.%d %d %s\r\n", resp->ver_major, resp->ver_minor, 1.71 + resp->status, http_strmsg(resp->status)); 1.72 + 1.73 + fsize = alloca(resp->num_fields * sizeof *fsize); 1.74 + 1.75 + size = stsize; 1.76 + for(i=0; i<resp->num_fields; i++) { 1.77 + int len = strlen(resp->fields[i]) + 2; 1.78 + fsize[i] = len; 1.79 + size += len; 1.80 + } 1.81 + size += 2; /* CRLF and null */ 1.82 + 1.83 + if(buf) { 1.84 + sprintf(buf, "HTTP/%d.%d %d %s\r\n", resp->ver_major, resp->ver_minor, 1.85 + resp->status, http_strmsg(resp->status)); 1.86 + 1.87 + ptr = buf + stsize; 1.88 + for(i=0; i<resp->num_fields; i++) { 1.89 + sprintf(ptr, "%s\r\n", resp->fields[i]); 1.90 + ptr += fsize[i]; 1.91 + } 1.92 + *ptr++ = '\r'; 1.93 + *ptr++ = '\n'; 1.94 + *ptr++ = 0; 1.95 + } 1.96 + 1.97 + return size; 1.98 +} 1.99 + 1.100 const char *http_strmsg(int code) 1.101 { 1.102 static const char **msgxxx[] = {