From ebdb6199fdf3a09932ea6da7b147ee9e19834078 Mon Sep 17 00:00:00 2001 From: asterix Date: Tue, 11 Oct 2011 14:53:23 +0000 Subject: [PATCH] Make server reply content type message configurable. Add related tests. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@5151 38d2e660-2303-0410-9eaa-f027e97ec537 --- bertos/net/http.c | 85 ++++++++++++++++++++++++++++++++++-------- bertos/net/http.h | 21 +++++++++-- bertos/net/http_test.c | 40 ++++++++++++++++++++ 3 files changed, 128 insertions(+), 18 deletions(-) diff --git a/bertos/net/http.c b/bertos/net/http.c index f15af4d7..9098da51 100644 --- a/bertos/net/http.c +++ b/bertos/net/http.c @@ -58,10 +58,21 @@ #include #include - -static const char http_html_hdr_200[] = "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"; -static const char http_html_hdr_404[] = "HTTP/1.0 404 Not Found\r\nContent-type: text/html\r\n\r\n"; -static const char http_html_hdr_500[] = "HTTP/1.0 500 Internal Server Error\r\nContent-type: text/html\r\n\r\n"; +static struct { const char *key; const char *content; } http_content_type[] = +{ + {"", "Content-type: application/json\r\n\r\n"}, + {"htm", "Content-type: text/html\r\n\r\n"}, + {"css", "Content-type: text/css\r\n\r\n"}, + {"js", "Content-type: text/javascript\r\n\r\n"}, + {"png", "Content-type: image/png\r\n\r\n"}, + {"jpg", "Content-type: image/jpeg\r\n\r\n"}, + {"gif", "Content-type: image/gif\r\n\r\n"}, + {"txt", "Content-type: text/plain\r\n\r\n"}, +}; + +static const char http_html_hdr_200[] = "HTTP/1.0 200 OK\r\n"; +static const char http_html_hdr_404[] = "HTTP/1.0 404 Not Found\r\n"; +static const char http_html_hdr_500[] = "HTTP/1.0 500 Internal Server Error\r\n"; static HttpCGI *cgi_table; static http_handler_t http_callback; @@ -214,14 +225,41 @@ INLINE const char *get_ext(const char *name) return NULL; } +int http_searchContentType(const char *name) +{ + if (!name) + return 0; + + const char *ext = get_ext(name); + LOG_INFO("Ext: %s\n", !ext ? "none" : ext); + + if (!ext) + return 0; + + if (!strcmp(ext, "ico")) + return HTTP_CONTENT_JPEG; + + for (int i = 0; i < HTTP_CONTENT_CNT; i++) + { + if (!strcmp(ext, http_content_type[i].key)) + return i; + } + + return 0; +} + /** * Send on \param client socket * the 200 Ok http header */ -void http_sendOk(struct netconn *client) +void http_sendOk(struct netconn *client, int content_type) { - netconn_write(client, http_html_hdr_200, sizeof(http_html_hdr_200) - 1, NETCONN_NOCOPY); + ASSERT(content_type < HTTP_CONTENT_CNT); + + netconn_write(client, http_html_hdr_200, sizeof(http_html_hdr_200) - 1, NETCONN_COPY); + netconn_write(client, http_content_type[content_type].content, + strlen(http_content_type[content_type].content), NETCONN_COPY); } @@ -229,18 +267,26 @@ void http_sendOk(struct netconn *client) * Send on \param client socket * the 404 File not found http header */ -void http_sendFileNotFound(struct netconn *client) +void http_sendFileNotFound(struct netconn *client, int content_type) { - netconn_write(client, http_html_hdr_404, sizeof(http_html_hdr_404) - 1, NETCONN_NOCOPY); + ASSERT(content_type < HTTP_CONTENT_CNT); + + netconn_write(client, http_html_hdr_404, sizeof(http_html_hdr_404) - 1, NETCONN_COPY); + netconn_write(client, http_content_type[content_type].content, + strlen(http_content_type[content_type].content), NETCONN_COPY); } /** * Send on \param client socket * the 500 internal server error http header */ -void http_sendInternalErr(struct netconn *client) +void http_sendInternalErr(struct netconn *client, int content_type) { - netconn_write(client, http_html_hdr_500, sizeof(http_html_hdr_500) - 1, NETCONN_NOCOPY); + ASSERT(content_type < HTTP_CONTENT_CNT); + + netconn_write(client, http_html_hdr_500, sizeof(http_html_hdr_500) - 1, NETCONN_COPY); + netconn_write(client, http_content_type[content_type].content, + strlen(http_content_type[content_type].content), NETCONN_COPY); } static http_handler_t cgi_search(const char *name, HttpCGI *table) @@ -250,26 +296,35 @@ static http_handler_t cgi_search(const char *name, HttpCGI *table) int i = 0; const char *ext = get_ext(name); - LOG_INFO("EXT %s\n", ext ? "none" : ext); + while(table[i].name) { if (ext && table[i].type == CGI_MATCH_EXT) { - LOG_INFO("Match all ext %s\n", ext); + if (!strcmp(table[i].name, ext)) + { + LOG_INFO("Match all ext %s\n", ext); break; + } } else if (table[i].type == CGI_MATCH_NAME) { - LOG_INFO("Match all name %s\n", name); + if (strstr(name, table[i].name) != NULL) + { + LOG_INFO("Match all name %s\n", name); break; + } } else /* (table[i].type == CGI_MATCH_WORD) */ { - LOG_INFO("Match all word %s\n", name); + if (!strcmp(table[i].name, name)) + { + LOG_INFO("Match all word %s\n", name); break; + } } i++; @@ -316,7 +371,7 @@ void http_poll(struct netconn *server) if (cgi(client, req_string, rx_buf, len) < 0) { LOG_ERR("Internal server error\n"); - http_sendInternalErr(client); + http_sendInternalErr(client, HTTP_CONTENT_HTML); netconn_write(client, http_server_error, http_server_error_len - 1, NETCONN_NOCOPY); } } diff --git a/bertos/net/http.h b/bertos/net/http.h index fe368c0b..29fa27d6 100644 --- a/bertos/net/http.h +++ b/bertos/net/http.h @@ -55,6 +55,20 @@ typedef struct HttpCGI http_handler_t handler; ///< Callback to process the special request } HttpCGI; +enum +{ + HTTP_CONTENT_JSON = 0, + HTTP_CONTENT_HTML, + HTTP_CONTENT_CSS, + HTTP_CONTENT_JS, + HTTP_CONTENT_PNG, + HTTP_CONTENT_JPEG, + HTTP_CONTENT_GIF, + HTTP_CONTENT_PLAIN, + + HTTP_CONTENT_CNT +}; + #define CGI_MATCH_NONE 0 #define CGI_MATCH_WORD 1 ///< Select item in table only if string match #define CGI_MATCH_EXT 2 ///< Select item in table if the extention match @@ -64,10 +78,11 @@ int http_getValue(char *tolenized_buf, size_t tolenized_buf_len, const char *key int http_tokenizeGetRequest(char *raw_buf, size_t raw_len); void http_getPageName(const char *recv_buf, size_t recv_len, char *page_name, size_t len); void http_decodeUrl(const char *raw_buf, size_t raw_len, char *decodec_buf, size_t len); +int http_searchContentType(const char *name); -void http_sendOk(struct netconn *client); -void http_sendFileNotFound(struct netconn *client); -void http_sendInternalErr(struct netconn *client); +void http_sendOk(struct netconn *client, int content_type); +void http_sendFileNotFound(struct netconn *client, int content_type); +void http_sendInternalErr(struct netconn *client, int content_type); void http_poll(struct netconn *server); void http_init(http_handler_t default_callback, struct HttpCGI *table); diff --git a/bertos/net/http_test.c b/bertos/net/http_test.c index 28828277..f0dbbf49 100644 --- a/bertos/net/http_test.c +++ b/bertos/net/http_test.c @@ -82,6 +82,34 @@ static char token_str[] = "var1=1&var2=2&var3=3&var4=4"; static char token_str1[] = "var1=1&var2=2&=3&var4="; static char token_str2[] = "var1=test+test&var2=2&var3=test%5B%5D!@;'%22%5C.%20&var4=4"; +static struct {const char *content;} contents[] = +{ + {"one/two/three/test"}, + {"one/two/three.htm"}, + {"one/test.css"}, + {"one/two/test.js"}, + {"one/two/test.png"}, + {"one/two/test.ico"}, + {"one/two/test.jpg"}, + {"one/two/test.gif"}, +}; + + +static int contents_check_type[] = +{ + HTTP_CONTENT_JSON, + HTTP_CONTENT_HTML, + HTTP_CONTENT_CSS, + HTTP_CONTENT_JS, + HTTP_CONTENT_PNG, + HTTP_CONTENT_JPEG, + HTTP_CONTENT_JPEG, + HTTP_CONTENT_GIF, +}; + +#define CONTENT_TEST_CNT 8 + + int http_testSetup(void) { kdbg_init(); @@ -243,6 +271,18 @@ int http_testRun(void) } + + for (int i = 0; i < CONTENT_TEST_CNT; i++) + { + int type = http_searchContentType(contents[i].content); + if (type != contents_check_type[i]) + { + kprintf("error 8-%d return type %d expect %d\n", i, type, contents_check_type[i]); + kprintf("error 8-%d ext %s\n", i, contents[i].content); + goto error; + } + } + return 0; error: -- 2.25.1