Decode percent-encoding in url. Add test. Reorder code.
authorasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 3 Oct 2011 14:32:33 +0000 (14:32 +0000)
committerasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Mon, 3 Oct 2011 14:32:33 +0000 (14:32 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@5133 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/net/http.c
bertos/net/http.h
bertos/net/http_test.c

index 8941105232539e0afcebfab0cdef99d9b0f7aaab..891c462bbd13356c0920d0803e38c070e43c9785 100644 (file)
@@ -55,6 +55,7 @@
 #include <cfg/log.h>
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 
@@ -65,47 +66,54 @@ static const char http_html_hdr_500[] = "HTTP/1.1 500 Internal Server Error\r\nC
 static HttpCGI *cgi_table;
 static http_handler_t http_callback;
 
-/**
- * Send on \param client socket
- * the 200 Ok http header
- */
-void http_sendOk(struct netconn *client)
-{
-       netconn_write(client, http_html_hdr_200, sizeof(http_html_hdr_200) - 1, NETCONN_NOCOPY);
-}
 
-
-/**
- * Send on \param client socket
- * the 404 File not found http header
- */
-void http_sendFileNotFound(struct netconn *client)
+static char http_hexToAscii(char first, char second)
 {
-       netconn_write(client, http_html_hdr_404, sizeof(http_html_hdr_404) - 1, NETCONN_NOCOPY);
+       char hex[5], *stop;
+       hex[0] = '0';
+       hex[1] = 'x';
+       hex[2] = first;
+       hex[3] = second;
+       hex[4] = 0;
+       return strtol(hex, &stop, 16);
 }
 
-/**
- * Send on \param client socket
- * the 500 internal server error http header
- */
-void http_sendInternalErr(struct netconn *client)
+void http_decodeUri(const char *raw_buf, size_t raw_len, char *decodec_buf, size_t len)
 {
-       netconn_write(client, http_html_hdr_500, sizeof(http_html_hdr_500) - 1, NETCONN_NOCOPY);
+       char value;
+       for (size_t i = 0; i < raw_len; i++)
+       {
+               if (raw_buf[i] == '%')
+               {
+                       if (i + 2 < raw_len)
+                       {
+                               /* convert hex value after % */
+                               value = http_hexToAscii(raw_buf[i + 1], raw_buf[i + 2]);
+                               if (value)
+                               {
+                                       *decodec_buf++ = value;
+                                       i += 2;
+                                       continue;
+                               }
+                       }
+               }
+               *decodec_buf++ = raw_buf[i];
+       }
 }
 
-void http_getPageName(const char *revc_buf, size_t recv_len, char *page_name, size_t len)
+void http_getPageName(const char *recv_buf, size_t recv_len, char *page_name, size_t len)
 {
        int i = 0;
        bool str_ok = false;
 
-       if (revc_buf && (recv_len > sizeof("GET /")))
+       if (recv_buf && (recv_len > sizeof("GET /")))
        {
-               if (*revc_buf++ == 'G' &&
-                       *revc_buf++ == 'E' && *revc_buf++ == 'T')
+               if (*recv_buf++ == 'G' &&
+                       *recv_buf++ == 'E' && *recv_buf++ == 'T')
                        {
                                str_ok = true;
                                /* skip the space and "/" */
-                               revc_buf += 2;
+                               recv_buf += 2;
                        }
        }
 
@@ -113,7 +121,7 @@ void http_getPageName(const char *revc_buf, size_t recv_len, char *page_name, si
        {
                while ((size_t)i < recv_len)
                {
-                       char ch = *(revc_buf++);
+                       char ch = *(recv_buf++);
                        if (ch == ' ' || ch == '\t' || ch == '\n')
                                break;
                        if((size_t)i == len - 1)
@@ -134,6 +142,35 @@ INLINE const char *get_ext(const char *name)
        return NULL;
 }
 
+
+/**
+ * Send on \param client socket
+ * the 200 Ok http header
+ */
+void http_sendOk(struct netconn *client)
+{
+       netconn_write(client, http_html_hdr_200, sizeof(http_html_hdr_200) - 1, NETCONN_NOCOPY);
+}
+
+
+/**
+ * Send on \param client socket
+ * the 404 File not found http header
+ */
+void http_sendFileNotFound(struct netconn *client)
+{
+       netconn_write(client, http_html_hdr_404, sizeof(http_html_hdr_404) - 1, NETCONN_NOCOPY);
+}
+
+/**
+ * Send on \param client socket
+ * the 500 internal server error http header
+ */
+void http_sendInternalErr(struct netconn *client)
+{
+       netconn_write(client, http_html_hdr_500, sizeof(http_html_hdr_500) - 1, NETCONN_NOCOPY);
+}
+
 static http_handler_t cgi_search(const char *name,  HttpCGI *table)
 {
        if (!table)
index 2b49c7f0b7dd7abbb084711842187df394f943ae..4cbdaac08443b3c499ec45fbd23f475300843eb9 100644 (file)
@@ -60,7 +60,8 @@ typedef struct HttpCGI
 #define CGI_MATCH_EXT    2  ///< Select item in table if the extention match
 #define CGI_MATCH_NAME   3  ///< Select item in table if the string is content
 
-void http_getPageName(const char *revc_buf, size_t recv_len, char *page_name, size_t len);
+void http_getPageName(const char *recv_buf, size_t recv_len, char *page_name, size_t len);
+void http_decodeUri(const char *raw_buf, size_t raw_len, char *decodec_buf, size_t len);
 
 void http_sendOk(struct netconn *client);
 void http_sendFileNotFound(struct netconn *client);
index e57ced9aa4310a8e8d181863c76db620a542bc99..1636cf904d4d5ecdb3d5d84783d9874d9e7d44b3 100644 (file)
@@ -66,6 +66,14 @@ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 \
 Accept-Encoding: gzip,deflate,sdch Accept-Language: it-IT,it;q=0.8,en-US;\
 q=0.6,en;q=0.4 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3";
 
+
+static const char uri[] = "test%5B%5D!@;'%22%5C.%20";
+static const char uri_check[] = "test[]!@;'\"\\. ";
+
+static const char uri1[] = "!*'();:@&=%2B%24%2C/?#%5B%5D%3C%3E%7E.%22%7B%7D%7C%5C-%60_%5E%25";
+static const char uri_check1[] = "!*'();:@&=+$,/?#[]<>~.\"{}|\\-`_^%";
+
+
 int http_testSetup(void)
 {
        kdbg_init();
@@ -78,26 +86,56 @@ int http_testRun(void)
        memset(name, 0, sizeof(name));
        http_getPageName(get_str, sizeof(get_str), name, sizeof(name));
 
-       if (!strcmp("/test/page1", name))
+       if (strcmp("test/page1", name))
+       {
+               kprintf("error 0 %s\n", name);
                goto error;
+       }
 
        http_getPageName(get_str1, sizeof(get_str1), name, sizeof(name));
 
-       kprintf("1 name %s\n", name);
-       if (!strcmp("/test/page1", name))
+       if (strcmp("test/page1", name))
+       {
+               kprintf("error 1 %s\n", name);
                goto error;
+       }
+
 
        http_getPageName(get_str2, sizeof(get_str2), name, sizeof(name));
 
-       kprintf("2 name %s\n", name);
        if (name[0] != '\0')
+       {
+               kprintf("error 2 %s\n", name);
                goto error;
+       }
+
 
        http_getPageName(get_str2, sizeof(get_str2), name, sizeof(name));
 
-       kprintf("3 name %s\n", name);
        if (name[0] != '\0')
+       {
+               kprintf("error 3 %s\n", name);
+               goto error;
+       }
+
+
+       char decoded[sizeof(uri)];
+       http_decodeUri(uri,sizeof(uri), decoded, sizeof(uri));
+
+       if (strcmp(decoded, uri_check))
+       {
+               kprintf("error 4 %s\n", decoded);
+               goto error;
+       }
+
+       char decoded1[sizeof(uri1)];
+       http_decodeUri(uri1,sizeof(uri1), decoded1, sizeof(uri1));
+
+       if (strcmp(decoded1, uri_check1))
+       {
+               kprintf("error 5 %s\n", decoded1);
                goto error;
+       }
 
        return 0;