From: asterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Date: Tue, 11 Oct 2011 14:53:23 +0000 (+0000)
Subject: Make server reply content type message configurable. Add related tests.
X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=ebdb6199fdf3a09932ea6da7b147ee9e19834078;p=bertos.git

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
---

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 <stdlib.h>
 #include <string.h>
 
-
-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: