From 04145828dccb10843ca8fdc3b9d1951933362c92 Mon Sep 17 00:00:00 2001 From: asterix Date: Mon, 3 Oct 2011 14:32:33 +0000 Subject: [PATCH] Decode percent-encoding in url. Add test. Reorder code. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@5133 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/net/http.c | 91 +++++++++++++++++++++++++++++------------- bertos/net/http.h | 3 +- bertos/net/http_test.c | 48 +++++++++++++++++++--- 3 files changed, 109 insertions(+), 33 deletions(-) diff --git a/bertos/net/http.c b/bertos/net/http.c index 89411052..891c462b 100644 --- a/bertos/net/http.c +++ b/bertos/net/http.c @@ -55,6 +55,7 @@ #include #include +#include #include @@ -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) diff --git a/bertos/net/http.h b/bertos/net/http.h index 2b49c7f0..4cbdaac0 100644 --- a/bertos/net/http.h +++ b/bertos/net/http.h @@ -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); diff --git a/bertos/net/http_test.c b/bertos/net/http_test.c index e57ced9a..1636cf90 100644 --- a/bertos/net/http_test.c +++ b/bertos/net/http_test.c @@ -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; -- 2.25.1