Subject: [PATCH] Add missing lib/header.c file
authorwonder-mice <wonder.mice@gmail.com>
Wed, 22 Apr 2015 18:35:37 +0000 (11:35 -0700)
committerAndy Green <andy.green@linaro.org>
Thu, 23 Apr 2015 23:22:52 +0000 (07:22 +0800)
File was lost during merge to upstream.

lib/header.c [new file with mode: 0644]

diff --git a/lib/header.c b/lib/header.c
new file mode 100644 (file)
index 0000000..8d83f5c
--- /dev/null
@@ -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;
+}