proc: expose HTTP Origin header in process environment
[project/uhttpd.git] / utils.c
diff --git a/utils.c b/utils.c
index b1d7d37..d990d7d 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -25,10 +25,14 @@ bool uh_use_chunked(struct client *cl)
        if (cl->request.version != UH_HTTP_VER_1_1)
                return false;
 
-       if (cl->request.method == UH_HTTP_MSG_HEAD)
+       if (cl->request.method == UH_HTTP_MSG_HEAD || cl->request.method == UH_HTTP_MSG_OPTIONS)
                return false;
 
-       return true;
+       /* RFC2616 10.2.5, 10.3.5 */
+       if (cl->http_code == 204 || cl->http_code == 304)
+               return false;
+
+       return !cl->request.disable_chunked;
 }
 
 void uh_chunk_write(struct client *cl, const void *data, int len)
@@ -204,6 +208,10 @@ bool uh_path_match(const char *prefix, const char *url)
 {
        int len = strlen(prefix);
 
+       /* A prefix of "/" will - by definition - match any url */
+       if (prefix[0] == '/' && len == 1)
+               return true;
+
        if (strncmp(url, prefix, len) != 0)
                return false;
 
@@ -241,3 +249,45 @@ bool uh_addr_rfc1918(struct uh_addr *addr)
 
        return 0;
 }
+
+
+static bool is_html_special_char(char c)
+{
+       switch (c)
+       {
+       case 0x22:
+       case 0x26:
+       case 0x27:
+       case 0x3C:
+       case 0x3E:
+               return true;
+
+       default:
+               return false;
+       }
+}
+
+char *uh_htmlescape(const char *str)
+{
+       size_t i, len;
+       char *p, *copy;
+
+       for (i = 0, len = 1; str[i]; i++)
+               if (is_html_special_char(str[i]))
+                       len += 6; /* &#x??; */
+               else
+                       len++;
+
+       copy = calloc(1, len);
+
+       if (!copy)
+               return NULL;
+
+       for (i = 0, p = copy; str[i]; i++)
+               if (is_html_special_char(str[i]))
+                       p += sprintf(p, "&#x%02x;", (unsigned int)str[i]);
+               else
+                       *p++ = str[i];
+
+       return copy;
+}