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[] = {