--- /dev/null
+/*
+ * http_defaultheaderparser.c
+ *
+ * Copyright (c) 2012 project bchan
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+#include "http_defaultheaderparser.h"
+
+#include <basic.h>
+#include <bstdio.h>
+#include <bctype.h>
+
+#include "http_typedef.h"
+#include "http_headerlexer.h"
+#include <parse/tokenchecker.h>
+
+#ifdef BCHAN_CONFIG_DEBUG
+# define DP(arg) printf arg
+# define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
+#else
+# define DP(arg) /**/
+# define DP_ER(msg, err) /**/
+#endif
+
+#if 0
+# define DP_STATE(state) printf("%s\n", state)
+#else
+# define DP_STATE(state) /**/
+#endif
+
+enum {
+ HTTP_DHP_FIELDNAME_CONTENT_ENCODING = 1,
+ HTTP_DHP_FIELDNAME_CONTENT_LENGTH,
+ HTTP_DHP_FIELDNAME_TRANSER_ENCODING,
+ HTTP_DHP_FIELDNAME_CONNECTION,
+};
+
+LOCAL VOID http_defaultheaderparser_inputhlex(http_defaultheaderparser_t *parser, http_headerlexer_result *cmd, HTTP_DEFAULTHEADERPARSER_RESULT *result)
+{
+ TOKENCHECKER_RESULT tchk;
+ W val;
+
+ switch (parser->state) {
+ case HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME:
+ DP_STATE("FIELDNAME");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDNAME) {
+ tchk = tokenchecker_inputchar(&parser->checker.fieldname, cmd->ch, &val);
+ if (tchk == TOKENCHECKER_RESULT_CONTINUE_NOMATCH) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDNAME;
+ } else if (tchk != TOKENCHECKER_RESULT_CONTINUE) {
+ /* format error */
+ DP(("format error 0\n"));
+ }
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDNAME_END) {
+ tchk = tokenchecker_endinput(&parser->checker.fieldname, &val);
+ if (tchk == TOKENCHECKER_RESULT_DETERMINE) {
+ switch (val) {
+ case HTTP_DHP_FIELDNAME_CONTENT_ENCODING:
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_ENCODING_LWS;
+ break;
+ case HTTP_DHP_FIELDNAME_CONTENT_LENGTH:
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_LENGTH_LWS;
+ break;
+ case HTTP_DHP_FIELDNAME_TRANSER_ENCODING:
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_TRANSFER_ENCODING_LWS;
+ break;
+ case HTTP_DHP_FIELDNAME_CONNECTION:
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_CONNECTION_LWS;
+ break;
+ default:
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDVALUE;
+ break;
+ }
+ } else if (tchk == TOKENCHECKER_RESULT_NOMATCH) {
+ } else {
+ /* format error */
+ DP(("format error 1\n"));
+ }
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_MESSAGEHEADER_END) {
+ *result = HTTP_DEFAULTHEADERPARSER_RESULT_MESSAGE_HEADER_END;
+ } else {
+ /* format error */
+ DP(("format error 2\n"));
+ }
+ break;
+ case HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDNAME:
+ DP_STATE("SKIP_FIELDNAME");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDNAME_END) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDVALUE;
+ } else if (cmd->type != HTTP_HEADERLEXER_RESULT_FIELDNAME) {
+ /* format error */
+ DP(("format error 3\n"));
+ }
+ break;
+ case HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDVALUE:
+ DP_STATE("SKIP_FIELDVALUE");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDVALUE_END) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME;
+ tokenchecker_clear(&parser->checker.fieldname);
+ } else if ((cmd->type != HTTP_HEADERLEXER_RESULT_FIELDCONTENT)&&(cmd->type != HTTP_HEADERLEXER_RESULT_LWS)) {
+ /* format error */
+ DP(("format error 4\n"));
+ }
+ break;
+ case HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_ENCODING_LWS:
+ DP_STATE("CONTENT_ENCODING_LWS");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_LWS) {
+ break;
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDVALUE_END) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME;
+ tokenchecker_clear(&parser->checker.fieldname);
+ } else if (cmd->type != HTTP_HEADERLEXER_RESULT_FIELDCONTENT) {
+ /* format error */
+ DP(("format error 5\n"));
+ }
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_ENCODING;
+ tokenchecker_clear(&parser->checker.contentcoding);
+ case HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_ENCODING:
+ DP_STATE("CONTENT_ENCODING");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDCONTENT) {
+ tchk = tokenchecker_inputchar(&parser->checker.contentcoding, cmd->ch, &val);
+ if (tchk == TOKENCHECKER_RESULT_CONTINUE_NOMATCH) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDVALUE;
+ } else if (tchk != TOKENCHECKER_RESULT_CONTINUE) {
+ /* format error */
+ DP(("format error 6\n"));
+ }
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDVALUE_END) {
+ tchk = tokenchecker_endinput(&parser->checker.contentcoding, &val);
+ if (tchk == TOKENCHECKER_RESULT_DETERMINE) {
+ parser->result.contentcoding = val;
+ } else if (tchk == TOKENCHECKER_RESULT_NOMATCH) {
+ } else {
+ /* format error */
+ DP(("format error 7\n"));
+ }
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME;
+ tokenchecker_clear(&parser->checker.fieldname);
+ } else {
+ /* format error */
+ DP(("format error 8\n"));
+ }
+ break;
+ case HTTP_DEFAULTHEADERPARSER_STATE_TRANSFER_ENCODING_LWS:
+ DP_STATE("TRANSFER_ENCODING_LWS");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_LWS) {
+ break;
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDVALUE_END) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME;
+ tokenchecker_clear(&parser->checker.fieldname);
+ } else if (cmd->type != HTTP_HEADERLEXER_RESULT_FIELDCONTENT) {
+ /* format error */
+ DP(("format error 9\n"));
+ }
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_TRANSFER_ENCODING;
+ tokenchecker_clear(&parser->checker.transfercoding);
+ case HTTP_DEFAULTHEADERPARSER_STATE_TRANSFER_ENCODING:
+ DP_STATE("TRANSFER_ENCODING");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDCONTENT) {
+ tchk = tokenchecker_inputchar(&parser->checker.transfercoding, cmd->ch, &val);
+ if (tchk == TOKENCHECKER_RESULT_CONTINUE_NOMATCH) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDVALUE;
+ } else if (tchk != TOKENCHECKER_RESULT_CONTINUE) {
+ /* format error */
+ DP(("format error 10\n"));
+ }
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDVALUE_END) {
+ tchk = tokenchecker_endinput(&parser->checker.transfercoding, &val);
+ if (tchk == TOKENCHECKER_RESULT_DETERMINE) {
+ parser->result.transfercoding = val;
+ } else if (tchk == TOKENCHECKER_RESULT_NOMATCH) {
+ } else {
+ /* format error */
+ DP(("format error 11\n"));
+ }
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME;
+ tokenchecker_clear(&parser->checker.fieldname);
+ } else {
+ /* format error */
+ DP(("format error 12\n"));
+ }
+ break;
+ case HTTP_DEFAULTHEADERPARSER_STATE_CONNECTION_LWS:
+ DP_STATE("CONNECTION_LWS");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_LWS) {
+ break;
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDVALUE_END) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME;
+ tokenchecker_clear(&parser->checker.fieldname);
+ } else if (cmd->type != HTTP_HEADERLEXER_RESULT_FIELDCONTENT){
+ /* format error */
+ DP(("format error 13\n"));
+ }
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_CONNECTION;
+ tokenchecker_clear(&parser->checker.connection);
+ case HTTP_DEFAULTHEADERPARSER_STATE_CONNECTION:
+ DP_STATE("CONNECTION");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDCONTENT) {
+ tchk = tokenchecker_inputchar(&parser->checker.connection, cmd->ch, &val);
+ if (tchk == TOKENCHECKER_RESULT_CONTINUE_NOMATCH) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDVALUE;
+ } else if (tchk != TOKENCHECKER_RESULT_CONTINUE) {
+ /* format error */
+ DP(("format error 14\n"));
+ }
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDVALUE_END) {
+ tchk = tokenchecker_endinput(&parser->checker.connection, &val);
+ if (tchk == TOKENCHECKER_RESULT_DETERMINE) {
+ if (val == 1) {
+ parser->result.connectionclosed = True;
+ } else {
+ /* unexpected token */
+ DP(("unexpected token\n"));
+ }
+ } else if (tchk == TOKENCHECKER_RESULT_NOMATCH) {
+ } else {
+ /* format error */
+ DP(("format error 15\n"));
+ }
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME;
+ tokenchecker_clear(&parser->checker.fieldname);
+ } else {
+ /* format error */
+ DP(("format error 16\n"));
+ }
+ break;
+ case HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_LENGTH_LWS:
+ DP_STATE("CONTENT_LENGTH_LWS");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_LWS) {
+ break;
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDVALUE_END) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME;
+ tokenchecker_clear(&parser->checker.fieldname);
+ } else if (cmd->type != HTTP_HEADERLEXER_RESULT_FIELDCONTENT){
+ /* format error */
+ DP(("format error 17\n"));
+ }
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_LENGTH;
+ parser->result.contentlength = 0;
+ case HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_LENGTH:
+ DP_STATE("CONTENT_LENGTH");
+ if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDCONTENT) {
+ if (isdigit(cmd->ch) != 0) {
+ parser->result.contentlength = parser->result.contentlength * 10 + (cmd->ch - '0');
+ } else {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDVALUE;
+ }
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_LWS) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDVALUE;
+ } else if (cmd->type == HTTP_HEADERLEXER_RESULT_FIELDVALUE_END) {
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME;
+ tokenchecker_clear(&parser->checker.fieldname);
+ } else {
+ /* format error */
+ DP(("format error 18\n"));
+ }
+ break;
+ }
+}
+
+EXPORT VOID http_defaultheaderparser_inputchar(http_defaultheaderparser_t *parser, UB ch, HTTP_DEFAULTHEADERPARSER_RESULT *result)
+{
+ http_headerlexer_result *hlex;
+ W i, result_len;
+
+ http_headerlexer_inputchar(&parser->header, ch, &hlex, &result_len);
+
+ for (i = 0; i < result_len; i++) {
+ *result = HTTP_DEFAULTHEADERPARSER_RESULT_NONE;
+ if (hlex[i].type == HTTP_HEADERLEXER_RESULT_NONE) {
+ continue;
+ }
+ http_defaultheaderparser_inputhlex(parser, hlex+i, result);
+ }
+}
+
+EXPORT W http_defaultheaderparsr_contentlength(http_defaultheaderparser_t *parser)
+{
+ return parser->result.contentlength;
+}
+
+EXPORT HTTP_TRANSFERCODING_TYPE http_defaultheaderparsr_transferencoding(http_defaultheaderparser_t *parser)
+{
+ return parser->result.transfercoding;
+}
+
+EXPORT HTTP_CONTENTCODING_VALUE http_defaultheaderparsr_contentencoding(http_defaultheaderparser_t *parser)
+{
+ return parser->result.contentcoding;
+}
+
+EXPORT Bool http_defaultheaderparser_connectionclosed(http_defaultheaderparser_t *parser)
+{
+ return parser->result.connectionclosed;
+}
+
+LOCAL tokenchecker_valuetuple_t nList_fieldname[] = {
+ {"Connection", HTTP_DHP_FIELDNAME_CONNECTION},
+ {"Content-Encoding", HTTP_DHP_FIELDNAME_CONTENT_ENCODING},
+ {"Content-Length", HTTP_DHP_FIELDNAME_CONTENT_LENGTH},
+ {"Transfer-Encoding", HTTP_DHP_FIELDNAME_TRANSER_ENCODING},
+};
+LOCAL B eToken_fieldname[] = ":";
+
+LOCAL tokenchecker_valuetuple_t nList_transfercoding[] = {
+ {"chunked", HTTP_TRANSFERCODING_TYPE_CHUNKED},
+ {"identity", HTTP_TRANSFERCODING_TYPE_IDENTITY},
+};
+LOCAL B eToken_transfercoding[] = "\r";
+
+LOCAL tokenchecker_valuetuple_t nList_contentcoding[] = {
+ {"compress", HTTP_CONTENTCODING_VALUE_COMPRESS},
+ {"deflate", HTTP_CONTENTCODING_VALUE_DEFLATE},
+ {"gzip", HTTP_CONTENTCODING_VALUE_GZIP},
+ {"identity", HTTP_CONTENTCODING_VALUE_IDENTITY},
+};
+LOCAL B eToken_contentcoding[] = "\r";
+
+LOCAL tokenchecker_valuetuple_t nList_connection[] = {
+ {"close", 1},
+};
+LOCAL B eToken_connection[] = "\r";
+
+EXPORT VOID http_defaultheaderparser_initialize(http_defaultheaderparser_t *parser)
+{
+ parser->state = HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME;
+ http_headerlexer_initialize(&parser->header);
+ tokenchecker_initialize(&(parser->checker.fieldname), nList_fieldname, 4, eToken_fieldname);
+ tokenchecker_initialize(&(parser->checker.transfercoding), nList_transfercoding, 2, eToken_transfercoding);
+ tokenchecker_initialize(&(parser->checker.contentcoding), nList_contentcoding, 4, eToken_contentcoding);
+ tokenchecker_initialize(&(parser->checker.connection), nList_connection, 1, eToken_connection);
+ parser->result.contentlength = 0;
+ parser->result.transfercoding = HTTP_TRANSFERCODING_TYPE_IDENTITY;
+ parser->result.contentcoding = HTTP_CONTENTCODING_VALUE_IDENTITY;
+ parser->result.connectionclosed = False;
+}
+
+EXPORT VOID http_defaultheaderparser_finalize(http_defaultheaderparser_t *parser)
+{
+ tokenchecker_finalize(&(parser->checker.connection));
+ tokenchecker_finalize(&(parser->checker.contentcoding));
+ tokenchecker_finalize(&(parser->checker.transfercoding));
+ tokenchecker_finalize(&(parser->checker.fieldname));
+ http_headerlexer_finalize(&parser->header);
+}
--- /dev/null
+/*
+ * http_defaultheaderparser.h
+ *
+ * Copyright (c) 2012 project bchan
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+/* Vendor name: */
+/* Functionality name: http */
+/* Detail name: defaultheaderparser */
+
+#include <basic.h>
+
+#include "http_typedef.h"
+#include "http_headerlexer.h"
+#include <parse/tokenchecker.h>
+
+/* HTTP header parser for using in http_connector_t. */
+/* Content-Encoding, Content-Length, Transfer-Encoding, Connection */
+
+#ifndef __HTTP_DEFAULTHEADERPARSER_H__
+#define __HTTP_DEFAULTHEADERPARSER_H__
+
+/* Functionality name: http */
+/* Detail name: defaultheaderparser */
+struct http_defaultheaderparser_t_ {
+ enum {
+ HTTP_DEFAULTHEADERPARSER_STATE_FIELDNAME,
+ HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDNAME,
+ HTTP_DEFAULTHEADERPARSER_STATE_SKIP_FIELDVALUE,
+ HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_ENCODING_LWS,
+ HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_ENCODING,
+ HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_LENGTH_LWS,
+ HTTP_DEFAULTHEADERPARSER_STATE_CONTENT_LENGTH,
+ HTTP_DEFAULTHEADERPARSER_STATE_TRANSFER_ENCODING_LWS,
+ HTTP_DEFAULTHEADERPARSER_STATE_TRANSFER_ENCODING,
+ HTTP_DEFAULTHEADERPARSER_STATE_CONNECTION_LWS,
+ HTTP_DEFAULTHEADERPARSER_STATE_CONNECTION,
+ } state;
+ http_headerlexer_t header;
+ struct {
+ tokenchecker_t fieldname;
+ tokenchecker_t transfercoding;
+ tokenchecker_t contentcoding;
+ tokenchecker_t connection;
+ } checker;
+ struct {
+ W contentlength;
+ HTTP_TRANSFERCODING_TYPE transfercoding;
+ HTTP_CONTENTCODING_VALUE contentcoding;
+ Bool connectionclosed;
+ } result;
+};
+typedef struct http_defaultheaderparser_t_ http_defaultheaderparser_t;
+
+/* Functionality name: http */
+/* Detail name: defaultheaderparser */
+/* Data structure identifier: RESULT */
+enum HTTP_DEFAULTHEADERPARSER_RESULT_ {
+ HTTP_DEFAULTHEADERPARSER_RESULT_NONE,
+ /*HTTP_DEFAULTHEADERPARSER_RESULT_FIELD_VALUE_END,*/
+ HTTP_DEFAULTHEADERPARSER_RESULT_MESSAGE_HEADER_END
+};
+typedef enum HTTP_DEFAULTHEADERPARSER_RESULT_ HTTP_DEFAULTHEADERPARSER_RESULT;
+
+IMPORT VOID http_defaultheaderparser_initialize(http_defaultheaderparser_t *parser);
+IMPORT VOID http_defaultheaderparser_finalize(http_defaultheaderparser_t *parser);
+IMPORT VOID http_defaultheaderparser_inputchar(http_defaultheaderparser_t *parser, UB ch, HTTP_DEFAULTHEADERPARSER_RESULT *result);
+IMPORT W http_defaultheaderparsr_contentlength(http_defaultheaderparser_t *parser);
+IMPORT HTTP_TRANSFERCODING_TYPE http_defaultheaderparsr_transferencoding(http_defaultheaderparser_t *parser);
+IMPORT HTTP_CONTENTCODING_VALUE http_defaultheaderparsr_contentencoding(http_defaultheaderparser_t *parser);
+IMPORT Bool http_defaultheaderparser_connectionclosed(http_defaultheaderparser_t *parser);
+
+#endif
--- /dev/null
+/*
+ * test_http_defaultheaderparser.c
+ *
+ * Copyright (c) 2012 project bchan
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+#include "test_http.h"
+
+#include "http_defaultheaderparser.h"
+
+#include <basic.h>
+#include <bstdio.h>
+#include <bstdlib.h>
+#include <bstring.h>
+
+#include <unittest_driver.h>
+
+#include "http_typedef.h"
+
+LOCAL UNITTEST_RESULT test_http_defaultheaderparser_common(UB *testdata, W testdata_len, W expected_cl, HTTP_TRANSFERCODING_TYPE expected_tc, HTTP_CONTENTCODING_VALUE expected_cc, Bool expected_connectionclose)
+{
+ http_defaultheaderparser_t parser;
+ HTTP_DEFAULTHEADERPARSER_RESULT result;
+ W i;
+ UNITTEST_RESULT ret = UNITTEST_RESULT_PASS;
+ W cl;
+ HTTP_TRANSFERCODING_TYPE tc;
+ HTTP_CONTENTCODING_VALUE cc;
+ Bool connectionclosed;
+
+ http_defaultheaderparser_initialize(&parser);
+
+ for (i = 0; i < testdata_len; i++) {
+ http_defaultheaderparser_inputchar(&parser, testdata[i], &result);
+ if (result == HTTP_DEFAULTHEADERPARSER_RESULT_MESSAGE_HEADER_END) {
+ i++;
+ break;
+ }
+ }
+ if (i != testdata_len) {
+ printf("end before header end\n");
+ ret = UNITTEST_RESULT_FAIL;
+ }
+ if (result != HTTP_DEFAULTHEADERPARSER_RESULT_MESSAGE_HEADER_END) {
+ printf("not return MESSAGE_HEADER_END\n");
+ ret = UNITTEST_RESULT_FAIL;
+ }
+
+ cl = http_defaultheaderparsr_contentlength(&parser);
+ if (expected_cl != cl) {
+ printf("Content-Length is not expected. expected = %d, result = %d\n", expected_cl, cl);
+ ret = UNITTEST_RESULT_FAIL;
+ }
+ tc = http_defaultheaderparsr_transferencoding(&parser);
+ if (expected_tc != tc) {
+ printf("Transfer-Encoding is not expected. expected = %d, result = %d\n", expected_tc, tc);
+ ret = UNITTEST_RESULT_FAIL;
+ }
+ cc = http_defaultheaderparsr_contentencoding(&parser);
+ if (expected_cc != cc) {
+ printf("Content-Encoding is not expected. expected = %d, result = %d\n", expected_cc, cc);
+ ret = UNITTEST_RESULT_FAIL;
+ }
+ connectionclosed = http_defaultheaderparser_connectionclosed(&parser);
+ if (expected_connectionclose != connectionclosed) {
+ printf("Connection is not expected. expected = %d, result = %d\n", expected_connectionclose, connectionclosed);
+ ret = UNITTEST_RESULT_FAIL;
+ }
+
+ http_defaultheaderparser_finalize(&parser);
+
+ return ret;
+}
+
+LOCAL UB testdata_header_01[] = {
+ "Date: Wed, 10 Dec 2008 21:33:30 GMT\r\n"
+ "Server: Apache/2.2.9\r\n"
+ "Vary: User-Agent,Accept-Encoding\r\n"
+ "Last-Modified: Wed, 24 Dec 2008 21:14:12 GMT\r\n"
+ "ETag: \"1a2dd38-446e-45ed15f9ad100\"-gzip\r\n"
+ "Accept-Ranges: bytes\r\n"
+ "Content-Encoding: gzip\r\n"
+ "Content-Length: 3511\r\n"
+ "Connection: close\r\n"
+ "Content-Type: text/plain; charset=Shift_JIS\r\n"
+ "\r\n"
+};
+
+LOCAL UNITTEST_RESULT test_http_defaultheaderparser_1()
+{
+ UB *testdata = testdata_header_01;
+ W testdata_len = strlen(testdata_header_01);
+ W expected_contentlength = 3511;
+ HTTP_TRANSFERCODING_TYPE expected_transfercoding = HTTP_TRANSFERCODING_TYPE_IDENTITY;
+ HTTP_CONTENTCODING_VALUE expected_contentcoding = HTTP_CONTENTCODING_VALUE_GZIP;
+ Bool expected_connectionclose = True;
+ return test_http_defaultheaderparser_common(testdata, testdata_len, expected_contentlength, expected_transfercoding, expected_contentcoding, expected_connectionclose);
+}
+
+LOCAL UB testdata_header_02[] = {
+ "Date: Wed, 10 Dec 2008 21:40:53 GMT\r\n"
+ "Server: Apache/2.2.9\r\n"
+ "Vary: User-Agent,Accept-Encoding\r\n"
+ "Last-Modified: Wed, 24 Dec 2008 21:39:58 GMT\r\n"
+ "ETag: \"1a2dd38-44a7-45ed1bbc0e780\"\r\n"
+ "Accept-Ranges: bytes\r\n"
+ "Content-Range: bytes 17517-17574/17575\r\n"
+ "Content-Length: 58\r\n"
+ "Connection: close\r\n"
+ "Content-Type: text/plain; charset=Shift_JIS\r\n"
+ "\r\n"
+};
+
+LOCAL UNITTEST_RESULT test_http_defaultheaderparser_2()
+{
+ UB *testdata = testdata_header_02;
+ W testdata_len = strlen(testdata_header_02);
+ W expected_contentlength = 58;
+ HTTP_TRANSFERCODING_TYPE expected_transfercoding = HTTP_TRANSFERCODING_TYPE_IDENTITY;
+ HTTP_CONTENTCODING_VALUE expected_contentcoding = HTTP_CONTENTCODING_VALUE_IDENTITY;
+ Bool expected_connectionclose = True;
+ return test_http_defaultheaderparser_common(testdata, testdata_len, expected_contentlength, expected_transfercoding, expected_contentcoding, expected_connectionclose);
+}
+
+LOCAL UB testdata_header_03[] = {
+ "Date: Wed, 10 Dec 2008 21:33:30 GMT\r\n"
+ "Server: Apache/2.2.9\r\n"
+ "Vary: User-Agent,Accept-Encoding\r\n"
+ "Last-Modified: Wed, 24 Dec 2008 21:14:12 GMT\r\n"
+ "ETag: \"1a2dd38-446e-45ed15f9ad100\"-gzip\r\n"
+ "Accept-Ranges: bytes\r\n"
+ "Content-Encoding: compress\r\n"
+ "Content-Length: 0\r\n"
+ "Content-Type: text/plain; charset=Shift_JIS\r\n"
+ "\r\n"
+};
+
+LOCAL UNITTEST_RESULT test_http_defaultheaderparser_3()
+{
+ UB *testdata = testdata_header_03;
+ W testdata_len = strlen(testdata_header_03);
+ W expected_contentlength = 0;
+ HTTP_TRANSFERCODING_TYPE expected_transfercoding = HTTP_TRANSFERCODING_TYPE_IDENTITY;
+ HTTP_CONTENTCODING_VALUE expected_contentcoding = HTTP_CONTENTCODING_VALUE_COMPRESS;
+ Bool expected_connectionclose = False;
+ return test_http_defaultheaderparser_common(testdata, testdata_len, expected_contentlength, expected_transfercoding, expected_contentcoding, expected_connectionclose);
+}
+
+LOCAL UB testdata_header_04[] = {
+ "Date: Wed, 10 Dec 2008 21:33:30 GMT\r\n"
+ "Server: Apache/2.2.9\r\n"
+ "Vary: User-Agent,Accept-Encoding\r\n"
+ "Last-Modified: Wed, 24 Dec 2008 21:14:12 GMT\r\n"
+ "ETag: \"1a2dd38-446e-45ed15f9ad100\"-gzip\r\n"
+ "Accept-Ranges: bytes\r\n"
+ "Content-Encoding: deflate\r\n"
+ "Content-Length: 12340\r\n"
+ "Content-Type: text/plain; charset=Shift_JIS\r\n"
+ "\r\n"
+};
+
+LOCAL UNITTEST_RESULT test_http_defaultheaderparser_4()
+{
+ UB *testdata = testdata_header_04;
+ W testdata_len = strlen(testdata_header_04);
+ W expected_contentlength = 12340;
+ HTTP_TRANSFERCODING_TYPE expected_transfercoding = HTTP_TRANSFERCODING_TYPE_IDENTITY;
+ HTTP_CONTENTCODING_VALUE expected_contentcoding = HTTP_CONTENTCODING_VALUE_DEFLATE;
+ Bool expected_connectionclose = False;
+ return test_http_defaultheaderparser_common(testdata, testdata_len, expected_contentlength, expected_transfercoding, expected_contentcoding, expected_connectionclose);
+}
+
+LOCAL UB testdata_header_05[] = {
+ "Date: Wed, 10 Dec 2008 21:33:30 GMT\r\n"
+ "Server: Apache/2.2.9\r\n"
+ "Vary: User-Agent,Accept-Encoding\r\n"
+ "Last-Modified: Wed, 24 Dec 2008 21:14:12 GMT\r\n"
+ "ETag: \"1a2dd38-446e-45ed15f9ad100\"-gzip\r\n"
+ "Accept-Ranges: bytes\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "Connection: close"
+ "Content-Type: text/plain; charset=Shift_JIS\r\n"
+ "\r\n"
+};
+
+LOCAL UNITTEST_RESULT test_http_defaultheaderparser_5()
+{
+ UB *testdata = testdata_header_05;
+ W testdata_len = strlen(testdata_header_05);
+ W expected_contentlength = 0;
+ HTTP_TRANSFERCODING_TYPE expected_transfercoding = HTTP_TRANSFERCODING_TYPE_CHUNKED;
+ HTTP_CONTENTCODING_VALUE expected_contentcoding = HTTP_CONTENTCODING_VALUE_IDENTITY;
+ Bool expected_connectionclose = False;
+ return test_http_defaultheaderparser_common(testdata, testdata_len, expected_contentlength, expected_transfercoding, expected_contentcoding, expected_connectionclose);
+}
+
+EXPORT VOID test_http_defaultheaderparser_main(unittest_driver_t *driver)
+{
+ UNITTEST_DRIVER_REGIST(driver, test_http_defaultheaderparser_1);
+ UNITTEST_DRIVER_REGIST(driver, test_http_defaultheaderparser_2);
+ UNITTEST_DRIVER_REGIST(driver, test_http_defaultheaderparser_3);
+ UNITTEST_DRIVER_REGIST(driver, test_http_defaultheaderparser_4);
+ UNITTEST_DRIVER_REGIST(driver, test_http_defaultheaderparser_5);
+}