Subject: [PATCH] Add missing lib/header.c file

File was lost during merge to upstream.
diff --git a/lib/header.c b/lib/header.c
new file mode 100644
index 0000000..8d83f5c
--- /dev/null
+++ b/lib/header.c
@@ -0,0 +1,209 @@
+/*
+ * libwebsockets - small server side websockets and web server implementation
+ *
+ * Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation:
+ *  version 2.1 of the License.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "private-libwebsockets.h"
+#include "lextable-strings.h"
+
+const unsigned char *lws_token_to_string(enum lws_token_indexes token)
+{
+	if ((unsigned int)token >= ARRAY_SIZE(set))
+		return NULL;
+	return (unsigned char *)set[token];
+}
+
+int lws_add_http_header_by_name(struct libwebsocket_context *context,
+			    struct libwebsocket *wsi,
+			    const unsigned char *name,
+			    const unsigned char *value,
+			    int length,
+			    unsigned char **p,
+			    unsigned char *end)
+{
+#ifdef LWS_USE_HTTP2
+	if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
+		return lws_add_http2_header_by_name(context, wsi, name, value, length, p, end);
+#endif
+	if (name) {
+		while (*p < end && *name)
+			*((*p)++) = *name++;
+		if (*p == end)
+			return 1;
+		*((*p)++) = ' ';
+	}
+	if (*p + length + 3 >= end)
+		return 1;
+
+	memcpy(*p, value, length);
+	*p += length;
+	*((*p)++) = '\x0d';
+	*((*p)++) = '\x0a';
+	return 0;
+}
+
+int lws_finalize_http_header(struct libwebsocket_context *context,
+			    struct libwebsocket *wsi,
+			    unsigned char **p,
+			    unsigned char *end)
+{
+#ifdef LWS_USE_HTTP2
+	if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
+		return 0;
+#endif
+	if ((long)(end - *p) < 3)
+		return 1;
+	*((*p)++) = '\x0d';
+	*((*p)++) = '\x0a';
+	return 0;
+}
+
+int lws_add_http_header_by_token(struct libwebsocket_context *context,
+			    struct libwebsocket *wsi,
+			    enum lws_token_indexes token,
+			    const unsigned char *value,
+			    int length,
+			    unsigned char **p,
+			    unsigned char *end)
+{
+	const unsigned char *name;
+#ifdef LWS_USE_HTTP2
+	if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
+		return lws_add_http2_header_by_token(context, wsi, token, value, length, p, end);
+#endif
+	name = lws_token_to_string(token);
+	if (!name)
+		return 1;
+	return lws_add_http_header_by_name(context, wsi, name, value, length, p, end);
+}
+
+int lws_add_http_header_content_length(struct libwebsocket_context *context,
+			    struct libwebsocket *wsi,
+			    unsigned long content_length,
+			    unsigned char **p,
+			    unsigned char *end)
+{
+	char b[24];
+	int n;
+
+	n = sprintf(b, "%lu", content_length);
+	if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH, (unsigned char *)b, n, p, end))
+		return 1;
+	wsi->u.http.content_length = content_length;
+	wsi->u.http.content_remain = content_length;
+
+	return 0;
+}
+
+static const char *err400[] = {
+	"Bad Request",
+	"Unauthorized",
+	"Payment Required",
+	"Forbidden",
+	"Not Found",
+	"Method Not Allowed",
+	"Not Acceptable",
+	"Proxy Auth Required",
+	"Request Timeout",
+	"Conflict",
+	"Gone",
+	"Length Required",
+	"Precondition Failed",
+	"Request Entity Too Large",
+	"Request URI too Long",
+	"Unsupported Media Type",
+	"Requested Range Not Satisfiable",
+	"Expectation Failed"
+};
+
+static const char *err500[] = {
+	"Internal Server Error",
+	"Not Implemented",
+	"Bad Gateway",
+	"Service Unavailable",
+	"Gateway Timeout",
+	"HTTP Version Not Supported"
+};
+
+int lws_add_http_header_status(struct libwebsocket_context *context,
+			    struct libwebsocket *wsi,
+			    unsigned int code,
+			    unsigned char **p,
+			    unsigned char *end)
+{
+	unsigned char code_and_desc[60];
+	const char *description = "";
+	int n;
+
+#ifdef LWS_USE_HTTP2
+	if (wsi->mode == LWS_CONNMODE_HTTP2_SERVING)
+		return lws_add_http2_header_status(context, wsi, code, p, end);
+#endif
+	if (code >= 400 && code < (400 + ARRAY_SIZE(err400)))
+		description = err400[code - 400];
+	if (code >= 500 && code < (500 + ARRAY_SIZE(err500)))
+		description = err500[code - 500];
+
+	n = sprintf((char *)code_and_desc, "HTTP/1.0 %u %s", code, description);
+
+	return lws_add_http_header_by_name(context, wsi, NULL, code_and_desc, n, p, end);
+}
+
+/**
+ * libwebsockets_return_http_status() - Return simple http status
+ * @context:		libwebsockets context
+ * @wsi:		Websocket instance (available from user callback)
+ * @code:		Status index, eg, 404
+ * @html_body:		User-readable HTML description < 1KB, or NULL
+ *
+ *	Helper to report HTTP errors back to the client cleanly and
+ *	consistently
+ */
+LWS_VISIBLE int libwebsockets_return_http_status(
+		struct libwebsocket_context *context, struct libwebsocket *wsi,
+				       unsigned int code, const char *html_body)
+{
+	int n, m;
+
+	unsigned char *p = context->service_buffer + LWS_SEND_BUFFER_PRE_PADDING;
+	unsigned char *start = p;
+	unsigned char *end = p + sizeof(context->service_buffer) -
+					LWS_SEND_BUFFER_PRE_PADDING;
+
+	if (!html_body)
+		html_body = "";
+
+	if (lws_add_http_header_status(context, wsi, code, &p, end))
+		return 1;
+	if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_SERVER, (unsigned char *)"libwebsockets", 13, &p, end))
+		return 1;
+	if (lws_add_http_header_by_token(context, wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *)"text/html", 9, &p, end))
+		return 1;
+	if (lws_finalize_http_header(context, wsi, &p, end))
+		return 1;
+
+	m = libwebsocket_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS);
+	if (m != (int)(p - start))
+		return 1;
+
+	n = sprintf((char *)start, "<html><body><h1>%u</h1>%s</body></html>", code, html_body);
+	m = libwebsocket_write(wsi, start, n, LWS_WRITE_HTTP);
+
+	return m != n;
+}