/*
 * httpread - Manage reading file(s) from HTTP/TCP socket
 * Author: Ted Merrill
 * Copyright 2008 Atheros Communications
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 *
 * The files are buffered via internal callbacks from eloop, then presented to
 * an application callback routine when completely read into memory. May also
 * be used if no file is expected but just to get the header, including HTTP
 * replies (e.g. HTTP/1.1 200 OK etc.).
 *
 * This does not attempt to be an optimally efficient implementation, but does
 * attempt to be of reasonably small size and memory consumption; assuming that
 * only small files are to be read. A maximum file size is provided by
 * application and enforced.
 *
 * It is assumed that the application does not expect any of the following:
 * -- transfer encoding other than chunked
 * -- trailer fields
 * It is assumed that, even if the other side requested that the connection be
 * kept open, that we will close it (thus HTTP messages sent by application
 * should have the connection closed field); this is allowed by HTTP/1.1 and
 * simplifies things for us.
 *
 * Other limitations:
 * -- HTTP header may not exceed a hard-coded size.
 *
 * Notes:
 * This code would be massively simpler without some of the new features of
 * HTTP/1.1, especially chunked data.
 */

#include "includes.h"

#include "common.h"
#include "eloop.h"
#include "httpread.h"


/* Tunable parameters */
#define HTTPREAD_READBUF_SIZE 1024      /* read in chunks of this size */
#define HTTPREAD_HEADER_MAX_SIZE 4096   /* max allowed for headers */
#define HTTPREAD_BODYBUF_DELTA 4096     /* increase allocation by this */

#if 0
/* httpread_debug -- set this global variable > 0 e.g. from debugger
 * to enable debugs (larger numbers for more debugs)
 * Make this a #define of 0 to eliminate the debugging code.
 */
int httpread_debug = 99;
#else
#define httpread_debug 0        /* eliminates even the debugging code */
#endif


/* control instance -- actual definition (opaque to application)
 */
struct httpread {
	/* information from creation */
	int sd;         /* descriptor of TCP socket to read from */
	void (*cb)(struct httpread *handle, void *cookie,
		    enum httpread_event e);  /* call on event */
	void *cookie;   /* pass to callback */
	int max_bytes;          /* maximum file size else abort it */
	int timeout_seconds;            /* 0 or total duration timeout period */

	/* dynamically used information follows */
	int sd_registered;      /* nonzero if we need to unregister socket */
	int to_registered;      /* nonzero if we need to unregister timeout */

	int got_hdr;            /* nonzero when header is finalized */
	char hdr[HTTPREAD_HEADER_MAX_SIZE+1];   /* headers stored here */
	int hdr_nbytes;

	enum httpread_hdr_type hdr_type;
	int version;            /* 1 if we've seen 1.1 */
	int reply_code;         /* for type REPLY, e.g. 200 for HTTP/1.1 200 OK */
	int got_content_length; /* true if we know content length for sure */
	int content_length;     /* body length,  iff got_content_length */
	int chunked;            /* nonzero for chunked data */
	char *uri;

	int got_body;           /* nonzero when body is finalized */
	char *body;
	int body_nbytes;
	int body_alloc_nbytes;  /* amount allocated */

	int got_file;           /* here when we are done */

	/* The following apply if data is chunked: */
	int in_chunk_data;      /* 0=in/at header, 1=in the data or tail*/
	int chunk_start;        /* offset in body of chunk hdr or data */
	int chunk_size;         /* data of chunk (not hdr or ending CRLF)*/
	int in_trailer;         /* in header fields after data (chunked only)*/
	enum trailer_state {
		trailer_line_begin = 0,
		trailer_empty_cr,       /* empty line + CR */
		trailer_nonempty,
		trailer_nonempty_cr,
	} trailer_state;
};


/* Check words for equality, where words consist of graphical characters
 * delimited by whitespace
 * Returns nonzero if "equal" doing case insensitive comparison.
 */
static int word_eq(char *s1, char *s2)
{
	int c1;
	int c2;
	int end1 = 0;
	int end2 = 0;
	for (;;) {
		c1 = *s1++;
		c2 = *s2++;
		if (isalpha(c1) && isupper(c1))
			c1 = tolower(c1);
		if (isalpha(c2) && isupper(c2))
			c2 = tolower(c2);
		end1 = !isgraph(c1);
		end2 = !isgraph(c2);
		if (end1 || end2 || c1 != c2)
			break;
	}
	return end1 && end2;  /* reached end of both words? */
}


/* convert hex to binary
 * Requires that c have been previously tested true with isxdigit().
 */
static int hex_value(int c)
{
	if (isdigit(c))
		return c - '0';
	if (islower(c))
		return 10 + c - 'a';
	return 10 + c - 'A';
}


static void httpread_timeout_handler(void *eloop_data, void *user_ctx);

/* httpread_destroy -- if h is non-NULL, clean up
 * This must eventually be called by the application following
 * call of the application's callback and may be called
 * earlier if desired.
 */
void httpread_destroy(struct httpread *h)
{
	if (httpread_debug >= 10)
		wpa_printf(MSG_DEBUG, "ENTER httpread_destroy(%p)", h);
	if (!h)
		return;

	if (h->to_registered)
		eloop_cancel_timeout(httpread_timeout_handler, NULL, h);
	h->to_registered = 0;
	if (h->sd_registered)
		eloop_unregister_sock(h->sd, EVENT_TYPE_READ);
	h->sd_registered = 0;
	os_free(h->body);
	os_free(h->uri);
	os_memset(h, 0, sizeof(*h));  /* aid debugging */
	h->sd = -1;     /* aid debugging */
	os_free(h);
}


/* httpread_timeout_handler -- called on excessive total duration
 */
static void httpread_timeout_handler(void *eloop_data, void *user_ctx)
{
	struct httpread *h = user_ctx;
	wpa_printf(MSG_DEBUG, "httpread timeout (%p)", h);
	h->to_registered = 0;   /* is self-cancelling */
	(*h->cb)(h, h->cookie, HTTPREAD_EVENT_TIMEOUT);
}


/* Analyze options only so far as is needed to correctly obtain the file.
 * The application can look at the raw header to find other options.
 */
static int httpread_hdr_option_analyze(
	struct httpread *h,
	char *hbp       /* pointer to current line in header buffer */
	)
{
	if (word_eq(hbp, "CONTENT-LENGTH:")) {
		while (isgraph(*hbp))
			hbp++;
		while (*hbp == ' ' || *hbp == '\t')
			hbp++;
		if (!isdigit(*hbp))
			return -1;
		h->content_length = atol(hbp);
		h->got_content_length = 1;
		return 0;
	}
	if (word_eq(hbp, "TRANSFER_ENCODING:") ||
	    word_eq(hbp, "TRANSFER-ENCODING:")) {
		while (isgraph(*hbp))
			hbp++;
		while (*hbp == ' ' || *hbp == '\t')
			hbp++;
		/* There should (?) be no encodings of interest
		 * other than chunked...
		 */
		if (word_eq(hbp, "CHUNKED")) {
			h->chunked = 1;
			h->in_chunk_data = 0;
			/* ignore possible ;<parameters> */
		}
		return 0;
	}
	/* skip anything we don't know, which is a lot */
	return 0;
}


static int httpread_hdr_analyze(struct httpread *h)
{
	char *hbp = h->hdr;      /* pointer into h->hdr */
	int standard_first_line = 1;

	/* First line is special */
	h->hdr_type = HTTPREAD_HDR_TYPE_UNKNOWN;
	if (!isgraph(*hbp))
		goto bad;
	if (os_strncmp(hbp, "HTTP/", 5) == 0) {
		h->hdr_type = HTTPREAD_HDR_TYPE_REPLY;
		standard_first_line = 0;
		hbp += 5;
		if (hbp[0] == '1' && hbp[1] == '.' &&
		    isdigit(hbp[2]) && hbp[2] != '0')
			h->version = 1;
		while (isgraph(*hbp))
			hbp++;
		while (*hbp == ' ' || *hbp == '\t')
			hbp++;
		if (!isdigit(*hbp))
			goto bad;
		h->reply_code = atol(hbp);
	} else if (word_eq(hbp, "GET"))
		h->hdr_type = HTTPREAD_HDR_TYPE_GET;
	else if (word_eq(hbp, "HEAD"))
		h->hdr_type = HTTPREAD_HDR_TYPE_HEAD;
	else if (word_eq(hbp, "POST"))
		h->hdr_type = HTTPREAD_HDR_TYPE_POST;
	else if (word_eq(hbp, "PUT"))
		h->hdr_type = HTTPREAD_HDR_TYPE_PUT;
	else if (word_eq(hbp, "DELETE"))
		h->hdr_type = HTTPREAD_HDR_TYPE_DELETE;
	else if (word_eq(hbp, "TRACE"))
		h->hdr_type = HTTPREAD_HDR_TYPE_TRACE;
	else if (word_eq(hbp, "CONNECT"))
		h->hdr_type = HTTPREAD_HDR_TYPE_CONNECT;
	else if (word_eq(hbp, "NOTIFY"))
		h->hdr_type = HTTPREAD_HDR_TYPE_NOTIFY;
	else if (word_eq(hbp, "M-SEARCH"))
		h->hdr_type = HTTPREAD_HDR_TYPE_M_SEARCH;
	else if (word_eq(hbp, "M-POST"))
		h->hdr_type = HTTPREAD_HDR_TYPE_M_POST;
	else if (word_eq(hbp, "SUBSCRIBE"))
		h->hdr_type = HTTPREAD_HDR_TYPE_SUBSCRIBE;
	else if (word_eq(hbp, "UNSUBSCRIBE"))
		h->hdr_type = HTTPREAD_HDR_TYPE_UNSUBSCRIBE;
	else {
	}

	if (standard_first_line) {
		char *rawuri;
		char *uri;
		/* skip type */
		while (isgraph(*hbp))
			hbp++;
		while (*hbp == ' ' || *hbp == '\t')
			hbp++;
		/* parse uri.
		 * Find length, allocate memory for translated
		 * copy, then translate by changing %<hex><hex>
		 * into represented value.
		 */
		rawuri = hbp;
		while (isgraph(*hbp))
			hbp++;
		h->uri = os_malloc((hbp - rawuri) + 1);
		if (h->uri == NULL)
			goto bad;
		uri = h->uri;
		while (rawuri < hbp) {
			int c = *rawuri;
			if (c == '%' &&
			    isxdigit(rawuri[1]) && isxdigit(rawuri[2])) {
				*uri++ = (hex_value(rawuri[1]) << 4) |
					hex_value(rawuri[2]);
				rawuri += 3;
			} else {
				*uri++ = c;
				rawuri++;
			}
		}
		*uri = 0;       /* null terminate */
		while (isgraph(*hbp))
			hbp++;
		while (*hbp == ' ' || *hbp == '\t')
			hbp++;
		/* get version */
		if (0 == strncmp(hbp, "HTTP/", 5)) {
			hbp += 5;
			if (hbp[0] == '1' && hbp[1] == '.' &&
			    isdigit(hbp[2]) && hbp[2] != '0')
				h->version = 1;
		}
	}
	/* skip rest of line */
	while (*hbp)
		if (*hbp++ == '\n')
			break;

	/* Remainder of lines are options, in any order;
	 * or empty line to terminate
	 */
	for (;;) {
		/* Empty line to terminate */
		if (hbp[0] == '\n' ||
		    (hbp[0] == '\r' && hbp[1] == '\n'))
			break;
		if (!isgraph(*hbp))
			goto bad;
		if (httpread_hdr_option_analyze(h, hbp))
			goto bad;
		/* skip line */
		while (*hbp)
			if (*hbp++ == '\n')
				break;
	}

	/* chunked overrides content-length always */
	if (h->chunked)
		h->got_content_length = 0;

	/* For some types, we should not try to read a body
	 * This is in addition to the application determining
	 * that we should not read a body.
	 */
	switch (h->hdr_type) {
	case HTTPREAD_HDR_TYPE_REPLY:
		/* Some codes can have a body and some not.
		 * For now, just assume that any other than 200
		 * do not...
		 */
		if (h->reply_code != 200)
			h->max_bytes = 0;
		break;
	case HTTPREAD_HDR_TYPE_GET:
	case HTTPREAD_HDR_TYPE_HEAD:
		/* in practice it appears that it is assumed
		 * that GETs have a body length of 0... ?
		 */
		if (h->chunked == 0 && h->got_content_length == 0)
			h->max_bytes = 0;
		break;
	case HTTPREAD_HDR_TYPE_POST:
	case HTTPREAD_HDR_TYPE_PUT:
	case HTTPREAD_HDR_TYPE_DELETE:
	case HTTPREAD_HDR_TYPE_TRACE:
	case HTTPREAD_HDR_TYPE_CONNECT:
	case HTTPREAD_HDR_TYPE_NOTIFY:
	case HTTPREAD_HDR_TYPE_M_SEARCH:
	case HTTPREAD_HDR_TYPE_M_POST:
	case HTTPREAD_HDR_TYPE_SUBSCRIBE:
	case HTTPREAD_HDR_TYPE_UNSUBSCRIBE:
	default:
		break;
	}

	return 0;

bad:
	/* Error */
	return -1;
}


/* httpread_read_handler -- called when socket ready to read
 *
 * Note: any extra data we read past end of transmitted file is ignored;
 * if we were to support keeping connections open for multiple files then
 * this would have to be addressed.
 */
static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx)
{
	struct httpread *h = sock_ctx;
	int nread;
	char *rbp;      /* pointer into read buffer */
	char *hbp;      /* pointer into header buffer */
	char *bbp;      /* pointer into body buffer */
	char readbuf[HTTPREAD_READBUF_SIZE];  /* temp use to read into */

	if (httpread_debug >= 20)
		wpa_printf(MSG_DEBUG, "ENTER httpread_read_handler(%p)", h);

	/* read some at a time, then search for the interal
	 * boundaries between header and data and etc.
	 */
	nread = read(h->sd, readbuf, sizeof(readbuf));
	if (nread < 0)
		goto bad;
	if (nread == 0) {
		/* end of transmission... this may be normal
		 * or may be an error... in some cases we can't
		 * tell which so we must assume it is normal then.
		 */
		if (!h->got_hdr) {
			/* Must at least have completed header */
			wpa_printf(MSG_DEBUG, "httpread premature eof(%p)", h);
			goto bad;
		}
		if (h->chunked || h->got_content_length) {
			/* Premature EOF; e.g. dropped connection */
			wpa_printf(MSG_DEBUG,
				   "httpread premature eof(%p) %d/%d",
				   h, h->body_nbytes,
				   h->content_length);
			goto bad;
		}
		/* No explicit length, hopefully we have all the data
		 * although dropped connections can cause false
		 * end
		 */
		if (httpread_debug >= 10)
			wpa_printf(MSG_DEBUG, "httpread ok eof(%p)", h);
			h->got_body = 1;
			goto got_file;
	}
	rbp = readbuf;

	/* Header consists of text lines (terminated by both CR and LF)
	 * and an empty line (CR LF only).
	 */
	if (!h->got_hdr) {
		hbp = h->hdr + h->hdr_nbytes;
		/* add to headers until:
		 *      -- we run out of data in read buffer
		 *      -- or, we run out of header buffer room
		 *      -- or, we get double CRLF in headers
		 */
		for (;;) {
			if (nread == 0)
				goto get_more;
			if (h->hdr_nbytes == HTTPREAD_HEADER_MAX_SIZE) {
				goto bad;
			}
			*hbp++ = *rbp++;
			nread--;
			h->hdr_nbytes++;
			if (h->hdr_nbytes >= 4 &&
			    hbp[-1] == '\n' &&
			    hbp[-2] == '\r' &&
			    hbp[-3] == '\n' &&
			    hbp[-4] == '\r' ) {
				h->got_hdr = 1;
				*hbp = 0;       /* null terminate */
				break;
			}
		}
		/* here we've just finished reading the header */
		if (httpread_hdr_analyze(h)) {
			wpa_printf(MSG_DEBUG, "httpread bad hdr(%p)", h);
			goto bad;
		}
		if (h->max_bytes == 0) {
			if (httpread_debug >= 10)
				wpa_printf(MSG_DEBUG,
					   "httpread no body hdr end(%p)", h);
			goto got_file;
		}
		if (h->got_content_length && h->content_length == 0) {
			if (httpread_debug >= 10)
				wpa_printf(MSG_DEBUG,
					   "httpread zero content length(%p)",
					   h);
			goto got_file;
		}
	}

	/* Certain types of requests never have data and so
	 * must be specially recognized.
	 */
	if (!os_strncasecmp(h->hdr, "SUBSCRIBE", 9) ||
	    !os_strncasecmp(h->hdr, "UNSUBSCRIBE", 11) ||
	    !os_strncasecmp(h->hdr, "HEAD", 4) ||
	    !os_strncasecmp(h->hdr, "GET", 3)) {
		if (!h->got_body) {
			if (httpread_debug >= 10)
				wpa_printf(MSG_DEBUG,
					   "httpread NO BODY for sp. type");
		}
		h->got_body = 1;
		goto got_file;
	}

	/* Data can be just plain binary data, or if "chunked"
	 * consists of chunks each with a header, ending with
	 * an ending header.
	 */
	if (nread == 0)
		goto get_more;
	if (!h->got_body) {
		/* Here to get (more of) body */
		/* ensure we have enough room for worst case for body
		 * plus a null termination character
		 */
		if (h->body_alloc_nbytes < (h->body_nbytes + nread + 1)) {
			char *new_body;
			int new_alloc_nbytes;

			if (h->body_nbytes >= h->max_bytes)
				goto bad;
			new_alloc_nbytes = h->body_alloc_nbytes +
				HTTPREAD_BODYBUF_DELTA;
			/* For content-length case, the first time
			 * through we allocate the whole amount
			 * we need.
			 */
			if (h->got_content_length &&
			    new_alloc_nbytes < (h->content_length + 1))
				new_alloc_nbytes = h->content_length + 1;
			if ((new_body = os_realloc(h->body, new_alloc_nbytes))
			    == NULL)
				goto bad;

			h->body = new_body;
			h->body_alloc_nbytes = new_alloc_nbytes;
		}
		/* add bytes */
		bbp = h->body + h->body_nbytes;
		for (;;) {
			int ncopy;
			/* See if we need to stop */
			if (h->chunked && h->in_chunk_data == 0) {
				/* in chunk header */
				char *cbp = h->body + h->chunk_start;
				if (bbp-cbp >= 2 && bbp[-2] == '\r' &&
				    bbp[-1] == '\n') {
					/* end of chunk hdr line */
					/* hdr line consists solely
					 * of a hex numeral and CFLF
					 */
					if (!isxdigit(*cbp))
						goto bad;
					h->chunk_size = strtoul(cbp, NULL, 16);
					/* throw away chunk header
					 * so we have only real data
					 */
					h->body_nbytes = h->chunk_start;
					bbp = cbp;
					if (h->chunk_size == 0) {
						/* end of chunking */
						/* trailer follows */
						h->in_trailer = 1;
						if (httpread_debug >= 20)
							wpa_printf(
								MSG_DEBUG,
								"httpread end chunks(%p)", h);
						break;
					}
					h->in_chunk_data = 1;
					/* leave chunk_start alone */
				}
			} else if (h->chunked) {
				/* in chunk data */
				if ((h->body_nbytes - h->chunk_start) ==
				    (h->chunk_size + 2)) {
					/* end of chunk reached,
					 * new chunk starts
					 */
					/* check chunk ended w/ CRLF
					 * which we'll throw away
					 */
					if (bbp[-1] == '\n' &&
					    bbp[-2] == '\r') {
					} else
						goto bad;
					h->body_nbytes -= 2;
					bbp -= 2;
					h->chunk_start = h->body_nbytes;
					h->in_chunk_data = 0;
					h->chunk_size = 0; /* just in case */
				}
			} else if (h->got_content_length &&
				   h->body_nbytes >= h->content_length) {
				h->got_body = 1;
				if (httpread_debug >= 10)
					wpa_printf(
						MSG_DEBUG,
						"httpread got content(%p)", h);
				goto got_file;
			}
			if (nread <= 0)
				break;
			/* Now transfer. Optimize using memcpy where we can. */
			if (h->chunked && h->in_chunk_data) {
				/* copy up to remainder of chunk data
				 * plus the required CR+LF at end
				 */
				ncopy = (h->chunk_start + h->chunk_size + 2) -
					h->body_nbytes;
			} else if (h->chunked) {
				/*in chunk header -- don't optimize */
				*bbp++ = *rbp++;
				nread--;
				h->body_nbytes++;
				continue;
			} else if (h->got_content_length) {
				ncopy = h->content_length - h->body_nbytes;
			} else {
				ncopy = nread;
			}
			/* Note: should never be 0 */
			if (ncopy > nread)
				ncopy = nread;
			os_memcpy(bbp, rbp, ncopy);
			bbp += ncopy;
			h->body_nbytes += ncopy;
			rbp += ncopy;
			nread -= ncopy;
		}       /* body copy loop */
	}       /* !got_body */
	if (h->chunked && h->in_trailer) {
		/* If "chunked" then there is always a trailer,
		 * consisting of zero or more non-empty lines
		 * ending with CR LF and then an empty line w/ CR LF.
		 * We do NOT support trailers except to skip them --
		 * this is supported (generally) by the http spec.
		 */
		bbp = h->body + h->body_nbytes;
		for (;;) {
			int c;
			if (nread <= 0)
				break;
			c = *rbp++;
			nread--;
			switch (h->trailer_state) {
			case trailer_line_begin:
				if (c == '\r')
					h->trailer_state = trailer_empty_cr;
				else
					h->trailer_state = trailer_nonempty;
				break;
			case trailer_empty_cr:
				/* end empty line */
				if (c == '\n') {
					h->trailer_state = trailer_line_begin;
					h->in_trailer = 0;
					if (httpread_debug >= 10)
						wpa_printf(
							MSG_DEBUG,
							"httpread got content(%p)", h);
					h->got_body = 1;
					goto got_file;
				}
				h->trailer_state = trailer_nonempty;
				break;
			case trailer_nonempty:
				if (c == '\r')
					h->trailer_state = trailer_nonempty_cr;
				break;
			case trailer_nonempty_cr:
				if (c == '\n')
					h->trailer_state = trailer_line_begin;
				else
					h->trailer_state = trailer_nonempty;
				break;
			}
		}
	}
	goto get_more;

bad:
	/* Error */
	wpa_printf(MSG_DEBUG, "httpread read/parse failure (%p)", h);
	(*h->cb)(h, h->cookie, HTTPREAD_EVENT_ERROR);
	return;

get_more:
	return;

got_file:
	if (httpread_debug >= 10)
		wpa_printf(MSG_DEBUG,
			   "httpread got file %d bytes type %d",
			   h->body_nbytes, h->hdr_type);
	/* Null terminate for convenience of some applications */
	if (h->body)
		h->body[h->body_nbytes] = 0; /* null terminate */
	h->got_file = 1;
	/* Assume that we do NOT support keeping connection alive,
	 * and just in case somehow we don't get destroyed right away,
	 * unregister now.
	 */
	if (h->sd_registered)
		eloop_unregister_sock(h->sd, EVENT_TYPE_READ);
	h->sd_registered = 0;
	/* The application can destroy us whenever they feel like...
	 * cancel timeout.
	 */
	if (h->to_registered)
		eloop_cancel_timeout(httpread_timeout_handler, NULL, h);
	h->to_registered = 0;
	(*h->cb)(h, h->cookie, HTTPREAD_EVENT_FILE_READY);
}


/* httpread_create -- start a new reading session making use of eloop.
 * The new instance will use the socket descriptor for reading (until
 * it gets a file and not after) but will not close the socket, even
 * when the instance is destroyed (the application must do that).
 * Return NULL on error.
 *
 * Provided that httpread_create successfully returns a handle,
 * the callback fnc is called to handle httpread_event events.
 * The caller should do destroy on any errors or unknown events.
 *
 * Pass max_bytes == 0 to not read body at all (required for e.g.
 * reply to HEAD request).
 */
struct httpread * httpread_create(
	int sd,	 /* descriptor of TCP socket to read from */
	void (*cb)(struct httpread *handle, void *cookie,
		   enum httpread_event e),  /* call on event */
	void *cookie,    /* pass to callback */
	int max_bytes,	  /* maximum body size else abort it */
	int timeout_seconds     /* 0; or total duration timeout period */
	)
{
	struct httpread *h = NULL;

	h = os_zalloc(sizeof(*h));
	if (h == NULL)
		goto fail;
	h->sd = sd;
	h->cb = cb;
	h->cookie = cookie;
	h->max_bytes = max_bytes;
	h->timeout_seconds = timeout_seconds;

	if (timeout_seconds > 0) {
		if (eloop_register_timeout(timeout_seconds, 0,
					   httpread_timeout_handler,
					   NULL, h)) {
			/* No way to recover (from malloc failure) */
			goto fail;
		}
		h->to_registered = 1;
	}
	if (eloop_register_sock(sd, EVENT_TYPE_READ, httpread_read_handler,
				NULL, h)) {
		/* No way to recover (from malloc failure) */
		goto fail;
	}
	h->sd_registered = 1;
	return h;

fail:

	/* Error */
	httpread_destroy(h);
	return NULL;
}


/* httpread_hdr_type_get -- When file is ready, returns header type. */
enum httpread_hdr_type httpread_hdr_type_get(struct httpread *h)
{
	return h->hdr_type;
}


/* httpread_uri_get -- When file is ready, uri_get returns (translated) URI
 * or possibly NULL (which would be an error).
 */
char * httpread_uri_get(struct httpread *h)
{
	return h->uri;
}


/* httpread_reply_code_get -- When reply is ready, returns reply code */
int httpread_reply_code_get(struct httpread *h)
{
	return h->reply_code;
}


/* httpread_length_get -- When file is ready, returns file length. */
int httpread_length_get(struct httpread *h)
{
	return h->body_nbytes;
}


/* httpread_data_get -- When file is ready, returns file content
 * with null byte appened.
 * Might return NULL in some error condition.
 */
void * httpread_data_get(struct httpread *h)
{
	return h->body ? h->body : "";
}


/* httpread_hdr_get -- When file is ready, returns header content
 * with null byte appended.
 * Might return NULL in some error condition.
 */
char * httpread_hdr_get(struct httpread *h)
{
	return h->hdr;
}


/* httpread_hdr_line_get -- When file is ready, returns pointer
 * to line within header content matching the given tag
 * (after the tag itself and any spaces/tabs).
 *
 * The tag should end with a colon for reliable matching.
 *
 * If not found, returns NULL;
 */
char * httpread_hdr_line_get(struct httpread *h, const char *tag)
{
	int tag_len = os_strlen(tag);
	char *hdr = h->hdr;
	hdr = os_strchr(hdr, '\n');
	if (hdr == NULL)
		return NULL;
	hdr++;
	for (;;) {
		if (!os_strncasecmp(hdr, tag, tag_len)) {
			hdr += tag_len;
			while (*hdr == ' ' || *hdr == '\t')
				hdr++;
			return hdr;
		}
		hdr = os_strchr(hdr, '\n');
		if (hdr == NULL)
			return NULL;
		hdr++;
	}
}
