summaryrefslogtreecommitdiffstats
path: root/tinyHTTP/test
diff options
context:
space:
mode:
authorMamadou DIOP <bossiel@yahoo.fr>2015-08-17 01:56:35 +0200
committerMamadou DIOP <bossiel@yahoo.fr>2015-08-17 01:56:35 +0200
commit631fffee8a28b1bec5ed1f1d26a20e0135967f99 (patch)
tree74afe3bf3efe15aa82bcd0272b2b0f4d48c2d837 /tinyHTTP/test
parent7908865936604036e6f200f1b5e069f8752f3a3a (diff)
downloaddoubango-631fffee8a28b1bec5ed1f1d26a20e0135967f99.zip
doubango-631fffee8a28b1bec5ed1f1d26a20e0135967f99.tar.gz
-
Diffstat (limited to 'tinyHTTP/test')
-rw-r--r--tinyHTTP/test/droid-makefile28
-rw-r--r--tinyHTTP/test/stdafx.c26
-rw-r--r--tinyHTTP/test/stdafx.h35
-rw-r--r--tinyHTTP/test/targetver.h18
-rw-r--r--tinyHTTP/test/test.c93
-rw-r--r--tinyHTTP/test/test.vcproj229
-rw-r--r--tinyHTTP/test/test_auth.h177
-rw-r--r--tinyHTTP/test/test_messages.h139
-rw-r--r--tinyHTTP/test/test_stack.h233
-rw-r--r--tinyHTTP/test/test_transport.h371
-rw-r--r--tinyHTTP/test/test_url.h93
11 files changed, 1442 insertions, 0 deletions
diff --git a/tinyHTTP/test/droid-makefile b/tinyHTTP/test/droid-makefile
new file mode 100644
index 0000000..7672f38
--- /dev/null
+++ b/tinyHTTP/test/droid-makefile
@@ -0,0 +1,28 @@
+APP := test
+
+CFLAGS := $(CFLAGS_COMMON) -I../include -I../../tinySAK/src -I../../tinyNET/src
+LDFLAGS := $(LDFLAGS_COMMON) -Wl,-Bsymbolic,--whole-archive -l$(PROJECT) -ltinySAK -ltinyNET -Wl,--entry=main
+
+all: $(APP)
+
+OBJS += $(APP).o
+
+$(APP): $(OBJS)
+ $(CC) $(LDFLAGS) -o $@ $^
+
+%.o: %.c
+ $(CC) -c $(INCLUDE) $(CFLAGS) $< -o $@
+
+install: $(APP)
+ $(ANDROID_SDK_ROOT)/tools/adb push $(APP) $(EXEC_DIR)/$(APP)
+ $(ANDROID_SDK_ROOT)/tools/adb shell chmod 777 $(EXEC_DIR)/$(APP)
+
+run:
+ $(ANDROID_SDK_ROOT)/tools/adb shell $(EXEC_DIR)/$(APP)
+
+#dbg:
+# $(MAKE) $(MAKEFILE) DEBUG="-g -DDEBUG"
+# $(MAKE) $(MAKEFILE) install
+
+clean:
+ @rm -f $(OBJS) $(APP) \ No newline at end of file
diff --git a/tinyHTTP/test/stdafx.c b/tinyHTTP/test/stdafx.c
new file mode 100644
index 0000000..e0ce978
--- /dev/null
+++ b/tinyHTTP/test/stdafx.c
@@ -0,0 +1,26 @@
+/*
+* Copyright (C) 2009 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/tinyHTTP/test/stdafx.h b/tinyHTTP/test/stdafx.h
new file mode 100644
index 0000000..6685bdc
--- /dev/null
+++ b/tinyHTTP/test/stdafx.h
@@ -0,0 +1,35 @@
+/*
+* Copyright (C) 2009 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+
+#ifndef TEST_TINYHTTP_STDAFX_H
+#define TEST_TINYHTTP_STDAFX_H
+
+#include "targetver.h"
+
+#include <stdio.h>
+
+#if (defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE)) && !defined(__SYMBIAN32__)
+#include <tchar.h>
+#endif
+
+// TODO: reference additional headers your program requires here
+#endif /* TEST_TINYHTTP_STDAFX_H */
diff --git a/tinyHTTP/test/targetver.h b/tinyHTTP/test/targetver.h
new file mode 100644
index 0000000..4d7bde0
--- /dev/null
+++ b/tinyHTTP/test/targetver.h
@@ -0,0 +1,18 @@
+#ifndef _TEST_TINYHTTP_VER
+#define _TEST_TINYHTTP_VER
+
+#if (defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE)) && !defined(__SYMBIAN32__)
+// The following macros define the minimum required platform. The minimum required platform
+// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run
+// your application. The macros work by enabling all features available on platform versions up to and
+// including the version specified.
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
+#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#endif
+
+#endif
diff --git a/tinyHTTP/test/test.c b/tinyHTTP/test/test.c
new file mode 100644
index 0000000..79ff388
--- /dev/null
+++ b/tinyHTTP/test/test.c
@@ -0,0 +1,93 @@
+/*
+* Copyright (C) 2009 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+#include "stdafx.h"
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+//#include "tsk.h"
+//#include "tnet.h"
+
+#include "tinyhttp.h"
+
+//#include "thttp.h"
+//#include "tinyHTTP/thttp_message.h"
+//#include "tinyHTTP/auth/thttp_auth.h"
+
+#define LOOP 0
+
+#define RUN_TEST_ALL 0
+#define RUN_TEST_AUTH 0
+#define RUN_TEST_STACK 1
+#define RUN_TEST_URL 0
+#define RUN_TEST_MSGS 0
+#define RUN_TEST_TRANSPORT 0
+
+#include "test_auth.h"
+#include "test_stack.h"
+#include "test_url.h"
+#include "test_messages.h"
+#include "test_transport.h"
+
+
+#ifdef _WIN32_WCE
+int _tmain(int argc, _TCHAR* argv[])
+#else
+int main()
+#endif
+{
+ tnet_startup();
+
+ do{
+ /* Print copyright information */
+ printf("Doubango Project\nCopyright (C) 2009-2013 Mamadou Diop \n\n");
+
+#if RUN_TEST_AUTH || RUN_TEST_ALL
+ test_ws_auth();
+ test_basic_auth();
+ test_digest_auth();
+#endif
+
+#if RUN_TEST_STACK || RUN_TEST_ALL
+ test_stack();
+#endif
+
+#if RUN_TEST_URL || RUN_TEST_ALL
+ test_url();
+#endif
+
+#if RUN_TEST_MSGS || RUN_TEST_ALL
+ test_messages();
+#endif
+
+#if RUN_TEST_TRANSPORT || RUN_TEST_ALL
+ test_transport();
+#endif
+
+ }
+ while(LOOP);
+
+ tnet_cleanup();
+
+ return 0;
+}
+
diff --git a/tinyHTTP/test/test.vcproj b/tinyHTTP/test/test.vcproj
new file mode 100644
index 0000000..79612cf
--- /dev/null
+++ b/tinyHTTP/test/test.vcproj
@@ -0,0 +1,229 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="test"
+ ProjectGUID="{BE242939-1E65-4875-A3E7-41D8B77D187F}"
+ RootNamespace="test"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\thirdparties\win32\include;..\..\tinyHTTP\include;..\..\tinySAK\src;..\..\tinyNET\src"
+ PreprocessorDefinitions="DEBUG_LEVEL=DEBUG_LEVEL_INFO;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT 0x0501"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$(OutDir)\tinySAK.lib $(OutDir)\tinyHTTP.lib $(OutDir)\tinyNET.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\stdafx.c"
+ >
+ </File>
+ <File
+ RelativePath=".\test.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\targetver.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="tests"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\test_auth.h"
+ >
+ </File>
+ <File
+ RelativePath=".\test_messages.h"
+ >
+ </File>
+ <File
+ RelativePath=".\test_stack.h"
+ >
+ </File>
+ <File
+ RelativePath=".\test_transport.h"
+ >
+ </File>
+ <File
+ RelativePath=".\test_url.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/tinyHTTP/test/test_auth.h b/tinyHTTP/test/test_auth.h
new file mode 100644
index 0000000..4a707f1
--- /dev/null
+++ b/tinyHTTP/test/test_auth.h
@@ -0,0 +1,177 @@
+/*
+* Copyright (C) 2009 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+#ifndef _TEST_AUTH_H_
+#define _TEST_AUTH_H_
+
+struct auth_basic_msg
+{
+ const char* userid;
+ const char* password;
+
+ const char* xres;
+};
+
+struct auth_basic_msg auth_basic_msgs[] =
+{
+ { "Aladdin"/*Ali baba*/, "open sesame", "QWxhZGRpbjpvcGVuIHNlc2FtZQ==" },
+};
+
+void test_basic_auth()
+{
+ char *response = tsk_null;
+ size_t i, size;
+
+ for(i=0; i<sizeof(auth_basic_msgs)/sizeof(struct auth_basic_msg); i++)
+ {
+ size = thttp_auth_basic_response(auth_basic_msgs[i].userid, auth_basic_msgs[i].password, &response);
+ if(tsk_striequals(auth_basic_msgs[i].xres, response)){
+ TSK_DEBUG_INFO("[HTTP_BASIC-%d] ==> OK", i);
+ }
+ else{
+ TSK_DEBUG_INFO("[HTTP_BASIC-%d] ==> NOK", i);
+ }
+
+ TSK_FREE(response);
+ }
+}
+
+
+//========================================================================
+
+struct auth_ws
+{
+ const char* key;
+ const char* xres;
+};
+
+struct auth_ws auth_ws_msgs[] =
+{
+ { "dGhlIHNhbXBsZSBub25jZQ==", "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=" },
+ { "x3JJHMbDL1EzLkh9GBhXDw==", "HSmrc0sMlYUkAGmm5OPpG2HaGWk=" },
+};
+
+void test_ws_auth()
+{
+ thttp_auth_ws_keystring_t response = {0};
+ size_t i, size;
+
+ for(i=0; i<sizeof(auth_ws_msgs)/sizeof(struct auth_ws); i++)
+ {
+ size = thttp_auth_ws_response(auth_ws_msgs[i].key, &response);
+ if(tsk_striequals(auth_ws_msgs[i].xres, response)){
+ TSK_DEBUG_INFO("[WS_AUTH-%d] ==> OK", i);
+ }
+ else{
+ TSK_DEBUG_INFO("[WS_AUTH-%d] ==> NOK", i);
+ }
+ }
+}
+
+
+
+//========================================================================
+
+
+struct auth_digest_msg
+{
+ const char* username;
+ const char* password;
+ const char* realm;
+ const char* nonce;
+ const char* method;
+ const char* uri;
+ const char* qop;
+ const char* nc;
+ const char* cnonce;
+ const char* opaque;
+ const char* entitybody;
+
+ const char* response;
+};
+
+struct auth_digest_msg auth_digest_msgs[] =
+{
+ {
+ "Mufasa",
+ "Circle Of Life",
+ "testrealm@host.com",
+ "dcd98b7102dd2f0e8b11d0f600bfb0c093",
+ "GET",
+ "/dir/index.html",
+ "auth",
+ "00000001",
+ "0a4f113b",
+ "5ccc069c403ebaf9f0171e9517f40e41",
+ 0,
+
+ "6629fae49393a05397450978507c4ef1"
+ }
+ ,
+
+
+};
+
+void test_digest_auth()
+{
+ tsk_md5string_t response, ha1, ha2;
+ size_t i;
+
+ for(i=0; i<sizeof(auth_digest_msgs)/sizeof(struct auth_digest_msg); i++)
+ {
+ tsk_buffer_t* entitybody;
+ /* HA1 */
+ thttp_auth_digest_HA1(auth_digest_msgs[i].username,
+ auth_digest_msgs[i].realm,
+ auth_digest_msgs[i].password,
+ &ha1);
+
+ /* HA2 */
+ entitybody = tsk_buffer_create(auth_digest_msgs[i].entitybody, strlen(auth_digest_msgs[i].entitybody));
+ thttp_auth_digest_HA2(auth_digest_msgs[i].method,
+ auth_digest_msgs[i].uri,
+ entitybody,
+ auth_digest_msgs[i].qop,
+ &ha2);
+ TSK_OBJECT_SAFE_FREE(entitybody);
+
+ /* RESPONSE */
+ thttp_auth_digest_response(&ha1,
+ auth_digest_msgs[i].nonce,
+ auth_digest_msgs[i].nc,
+ auth_digest_msgs[i].cnonce,
+ auth_digest_msgs[i].qop,
+ &ha2,
+ &response);
+
+ if(tsk_striequals(auth_digest_msgs[i].response, response)){
+ TSK_DEBUG_INFO("[HTTP_DIGEST-%d] ==> OK", i);
+ }
+ else{
+ TSK_DEBUG_INFO("[HTTP_DIGEST-%d] ==> NOK", i);
+ }
+ }
+}
+
+
+
+
+#endif /* _TEST_AUTH_H_ */
diff --git a/tinyHTTP/test/test_messages.h b/tinyHTTP/test/test_messages.h
new file mode 100644
index 0000000..2d2678c
--- /dev/null
+++ b/tinyHTTP/test/test_messages.h
@@ -0,0 +1,139 @@
+/*
+* Copyright (C) 2009 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+#ifndef _TEST_MESSAGES_H_
+#define _TEST_MESSAGES_H_
+
+#define TEST_MSG_200 \
+ "HTTP/1.1 200 OK\r\n" \
+ "Date: Wed, 10 Mar 2010 13:37:13 GMT\r\n" \
+ "Server: Apache\r\n" \
+ "Content-length: 3\r\n" \
+ "Expires: Sat, 07 Aug 2010 13:37:13 +0000\r\n" \
+ "Cache-Control: public\r\n" \
+ "X-Deezer-Cache: HIT\r\n" \
+ "Pragma: \r\n" \
+ "Keep-Alive: timeout=2, max=100\r\n" \
+ "Connection: Keep-Alive\r\n" \
+ "Content-Type: video/flv\r\n" \
+ "\r\n" \
+ "123"
+
+#define TEST_MSG_401 \
+ "HTTP/1.1 401 Unauthorized\r\n" \
+ "Server: Apache-Coyote/1.1\r\n" \
+ "WWW-Authenticate: Digest realm=\"example.com\", qop=\"auth\", nonce=\"f39d20a4dbfbd32d943de9b285d59a30\", opaque=\"c5ad02feb52eb050e464cec3740c0f2e\"\r\n" \
+ "WWW-Authenticate: Basic realm=\"WallyWorld\"\r\n" \
+ "Transfer-Encoding: chunked;test=21;tes7\r\n" \
+ "Date: Wed, 10 Mar 2010 14:20:47 GMT\r\n" \
+ "Etag: W/\"1231-3213213\"\r\n" \
+ "\r\n"
+
+#define TEST_MSG_WS \
+ "Upgrade: websocket\r\n" \
+ "Connection: Upgrade\r\n" \
+ "Host: 192.168.0.11:5060\r\n" \
+ "Origin: null\r\n" \
+ "Sec-WebSocket-Key: Z8DmZQ9jZqK7vJqXbsDlYw==\r\n" \
+ "Sec-WebSocket-Version: 13, 5, 6\r\n" \
+ "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" \
+ "\r\n"
+
+#define TEST_MSG_OPTIONS \
+ "OPTIONS /85 HTTP/1.1\r\n" \
+ "Host: 192.168.0.37:10063\r\n" \
+ "Connection: keep-alive\r\n" \
+ "Access-Control-Request-Method: POST\r\n" \
+ "Origin: null\r\n" \
+ "User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17\r\n" \
+ "Access-Control-Request-Headers: connection, origin, content-type\r\n" \
+ "Accept: */*\r\n" \
+ "Accept-Encoding: gzip,deflate,sdch\r\n" \
+ "Accept-Language: en-US,en;q=0.8\r\n" \
+ "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n" \
+ "\r\n"
+
+#define TEST_MSG TEST_MSG_OPTIONS
+
+
+static void test_messages()
+{
+ thttp_message_t *message = tsk_null;
+ tsk_ragel_state_t state;
+ int ret/*, idx*/;
+
+ const char* msg_start = TEST_MSG_WS;
+ const char* msg_end = msg_start + tsk_strlen(msg_start);
+ //const thttp_header_Sec_WebSocket_Key_t* ws_hdr_key;
+ //const thttp_header_Sec_WebSocket_Version_t* ws_hdr_version;
+ //const thttp_header_Sec_WebSocket_Accept_t* ws_hdr_accept;
+ message = thttp_message_create();
+
+ /*while(msg_start < msg_end){
+ if((idx = tsk_strindexOf(msg_start, (msg_end - msg_start), "\r\n")) <= 2){
+ break;
+ }
+ idx+= 2;
+ tsk_ragel_state_init(&state, msg_start, idx);
+ if((ret = thttp_header_parse(&state, message))){
+ break;
+ }
+ msg_start += idx;
+ }
+
+ if((ws_hdr_key = (const thttp_header_Sec_WebSocket_Key_t*)thttp_message_get_header(message, thttp_htype_Sec_WebSocket_Key))){
+ TSK_DEBUG_INFO("Sec-WebSocket-Key: %s", ws_hdr_key->value);
+ }
+
+ if((ws_hdr_accept = (const thttp_header_Sec_WebSocket_Accept_t*)thttp_message_get_header(message, thttp_htype_Sec_WebSocket_Accept))){
+ TSK_DEBUG_INFO("Sec-WebSocket-Accept: %s", ws_hdr_accept->value);
+ }
+
+ if((ws_hdr_version = (const thttp_header_Sec_WebSocket_Version_t*)thttp_message_get_header(message, thttp_htype_Sec_WebSocket_Version))){
+ const tsk_list_item_t* item;
+ tsk_list_foreach(item, ws_hdr_version->values){
+ TSK_DEBUG_INFO("Sec-WebSocket-Version: %s", TSK_STRING_STR(item->data));
+ }
+ }*/
+
+
+ /* deserialize the message */
+ tsk_ragel_state_init(&state, TEST_MSG, strlen(TEST_MSG));
+ if(!(ret = thttp_message_parse(&state, &message, tsk_true))){
+ tsk_buffer_t *buffer = tsk_buffer_create_null();
+
+ /* serialize the message */
+ thttp_message_serialize(message, buffer);
+ TSK_DEBUG_INFO("HTTP Message=\n%s", TSK_BUFFER_TO_STRING(buffer));
+
+ TSK_OBJECT_SAFE_FREE(buffer);
+ }
+ else{
+ TSK_DEBUG_ERROR("Failed to parse HTTP message.");
+ }
+
+ TSK_OBJECT_SAFE_FREE(message);
+
+ getchar();
+}
+
+#endif /* _TEST_MESSAGES_H_ */
+
diff --git a/tinyHTTP/test/test_stack.h b/tinyHTTP/test/test_stack.h
new file mode 100644
index 0000000..7ae015b
--- /dev/null
+++ b/tinyHTTP/test/test_stack.h
@@ -0,0 +1,233 @@
+/*
+* Copyright (C) 2009 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+#ifndef _TEST_STACK_H_
+#define _TEST_STACK_H_
+
+int test_stack_callback(const thttp_event_t *httpevent)
+{
+ thttp_session_id_t id = thttp_session_get_id(httpevent->session);
+ switch(httpevent->type){
+ case thttp_event_message: /* New HTTP message */
+ {
+ TSK_DEBUG_INFO("sid=%llu", id);
+ if(THTTP_MESSAGE_IS_RESPONSE(httpevent->message)){
+ const thttp_header_ETag_t* etag;
+ TSK_DEBUG_INFO("=== %d ==> %s", THTTP_RESPONSE_CODE(httpevent->message), THTTP_MESSAGE_CONTENT(httpevent->message));
+ // You can use
+ if((etag = (const thttp_header_ETag_t*)thttp_message_get_header(httpevent->message, thttp_htype_ETag))){
+ TSK_DEBUG_INFO("Etag=%s", etag->value);
+ }
+ }
+ else{
+ if(THTTP_MESSAGE_IS_RESPONSE(httpevent->message)){
+ TSK_DEBUG_INFO("=== code ==> %u", THTTP_RESPONSE_CODE(httpevent->message));
+ }
+ }
+ break;
+ }
+
+ case thttp_event_auth_failed:
+ {
+ TSK_DEBUG_INFO("auth failed sid=%llu", id);
+ break;
+ }
+
+ case thttp_event_closed: /* HTTP connection closed (informational) */
+ {
+ TSK_DEBUG_INFO("closed sid=%llu", id);
+ break;
+ }
+
+ case thttp_event_transport_error: /* HTTP connection closed (informational) */
+ {
+ TSK_DEBUG_INFO("Transport sid=%llu", id);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+#define PAYLOAD "<entry uri=\"sip:samba@micromethod.com\" xmlns=\"urn:ietf:params:xml:ns:resource-lists\">" \
+ "<display-name>samba</display-name>" \
+ "</entry>"
+
+void test_stack()
+{
+ thttp_session_handle_t *session = tsk_null;
+ int ret;
+
+ thttp_stack_handle_t* stack = thttp_stack_create(test_stack_callback,
+ THTTP_STACK_SET_TLS_ENABLED(tsk_true),
+ //THTTP_STACK_SET_TLS_CERTS_VERIFY(tsk_false),
+ //THTTP_STACK_SET_LOCAL_IP("0.0.0.0"),
+ //THTTP_STACK_SET_LOCAL_PORT(8080),
+ //THTTP_STACK_SET_PROXY("msp.f-secure.com", 443),
+
+ THTTP_STACK_SET_NULL());
+
+ if((ret = thttp_stack_start(stack))){
+ TSK_DEBUG_ERROR("Failed to start the HTTP/HTTPS stack.");
+ goto bail;
+ }
+
+
+ // http://ipv6.google.com/
+ //op = THTTP_OPERATION_CREATE(stack,
+ // THTTP_OPERATION_SET_PARAM("method", "GET"),
+ // THTTP_OPERATION_SET_PARAM("URL", "http://siptest.doubango.org:8080/services/resource-lists/users/sip:mercuro1@doubango.org/index"),
+ //
+ // THTTP_OPERATION_SET_HEADER("Content-Type", "application/resource-lists+xml"),
+ // THTTP_OPERATION_SET_HEADER("Pragma", "No-Cache"),
+ // THTTP_OPERATION_SET_HEADER("Connection", "Keep-Alive"),
+ // THTTP_OPERATION_SET_HEADER("User-Agent", "XDM-client/OMA1.1"),
+ // THTTP_OPERATION_SET_HEADER("X-3GPP-Intended-Identity", "sip:mercuro1@doubango.org"),
+ //
+ // THTTP_OPERATION_SET_NULL());
+ //thttp_operation_perform(op);
+
+ /* creates session */
+ session = thttp_session_create(stack,
+ // session-level options
+ THTTP_SESSION_SET_OPTION(THTTP_SESSION_OPTION_TIMEOUT, "6000"),
+
+ // session-level headers
+ THTTP_SESSION_SET_HEADER("Pragma", "No-Cache"),
+ THTTP_SESSION_SET_HEADER("Connection", "Keep-Alive"),
+ // THTTP_SESSION_SET_HEADER("Connection", "close"),
+ THTTP_SESSION_SET_HEADER("User-Agent", "doubango 1.0"),
+
+ THTTP_SESSION_SET_NULL()); /* MUST always be present */
+
+ //ret = thttp_action_GET(session, "http://siptest.doubango.org:8080/services/resource-lists/users/sip:mercuro1@doubango.org/index",
+ // THTTP_ACTION_SET_HEADER("Content-Type", "application/resource-lists+xml"),
+ //
+ // tsk_null);
+
+ //getchar();
+
+ //thttp_action_GET(session, "http://siptest.doubango.org:8080/services/resource-lists/users/sip:mercuro1@doubango.org/index",
+ // THTTP_ACTION_SET_HEADER("Content-Type", "application/resource-lists+xml"),
+ //
+ // tsk_null);
+
+ //getchar();
+
+ // HTTPS
+ thttp_action_GET(session, "https://msp.f-secure.com/web-test/common/test.html",
+ // action-level options
+ THTTP_ACTION_SET_OPTION(THTTP_ACTION_OPTION_TIMEOUT, "2500"),
+
+ // action-level headers
+ THTTP_ACTION_SET_HEADER("User-Agent", "Doubango"),
+ THTTP_ACTION_SET_HEADER("Connection", "Keep-Alive"),
+
+ THTTP_ACTION_SET_NULL());
+ getchar();
+
+
+ // IPv6
+ /*thttp_action_GET(session, "http://ipv6.google.com",
+ // action-level options
+ THTTP_ACTION_SET_OPTION(THTTP_ACTION_OPTION_TIMEOUT, "2500"),
+
+ // action-level headers
+ THTTP_ACTION_SET_HEADER("User-Agent", "XDM-client/OMA1.1"),
+ THTTP_ACTION_SET_HEADER("Connection", "Keep-Alive"),
+
+ THTTP_ACTION_SET_NULL());
+ getchar();*/
+
+ /*ret = thttp_action_GET(session, "http://doubango.org",
+ // action-level options
+ THTTP_ACTION_SET_OPTION(THTTP_ACTION_OPTION_TIMEOUT, "2500"),
+
+ THTTP_ACTION_SET_NULL());
+
+ getchar();*/
+
+ //thttp_action_GET(session, "http://www.google.com",
+ //THTTP_ACTION_SET_HEADER("Content-Type", "application/resource-lists+xml"),
+
+ // THTTP_ACTION_SET_NULL());
+
+ //thttp_action_GET(session, "http://www.doubango.org",
+
+ // THTTP_ACTION_SET_NULL());
+
+ /* Gets resource-lists document */
+ /*thttp_action_GET(session, "http://siptest.doubango.org:8080/services/resource-lists/users/sip:mercuro1@doubango.org/index",
+ THTTP_ACTION_SET_HEADER("Content-Type", "application/resource-lists+xml"),
+
+ tsk_null);
+
+ getchar();*/
+
+ //TSK_OBJECT_SAFE_FREE(session);
+
+ //getchar();
+
+ /* Gets xcap-caps document */
+ /*thttp_action_GET(session, "http://siptest.doubango.org:8080/services/xcap-caps/global/index",
+ THTTP_ACTION_SET_HEADER("Content-Type", "application/xcap-caps+xml"),
+
+ tsk_null);
+
+ getchar();*/
+
+ /*thttp_action_GET(session, "http://siptest.doubango.org:8080/services/resource-lists/users/sip:mercuro1@doubango.org/properties-resource-list.xml",
+ THTTP_ACTION_SET_HEADER("Content-Type", "application/resource-lists+xml"),
+
+ tsk_null);
+
+ getchar();*/
+
+ //thttp_operation_perform(op);
+
+/*
+ op = THTTP_OPERATION_CREATE(stack,
+ THTTP_OPERATION_SET_PARAM("method", "GET"),
+ //THTTP_OPERATION_SET_PARAM("URL", "https://msp.f-secure.com/web-test/common/test.html"),
+ THTTP_OPERATION_SET_PARAM("URL", "http://www.doubango.org"),
+
+ THTTP_OPERATION_SET_HEADER("Pragma", "No-Cache"),
+ THTTP_OPERATION_SET_HEADER("Connection", "Keep-Alive"),
+ THTTP_OPERATION_SET_HEADER("User-Agent", "XDM-client/OMA1.1"),
+
+ THTTP_OPERATION_SET_NULL());
+ thttp_operation_perform(op);
+*/
+ /*thttp_operation_set(op,
+ THTTP_OPERATION_SET_PARAM("method", "HEAD"),
+
+ THTTP_OPERATION_SET_NULL());
+ thttp_operation_perform(op);*/
+
+ getchar();
+bail:
+ TSK_OBJECT_SAFE_FREE(session);
+ TSK_OBJECT_SAFE_FREE(stack);
+}
+
+#endif /* _TEST_STACK_H_ */
+
+
diff --git a/tinyHTTP/test/test_transport.h b/tinyHTTP/test/test_transport.h
new file mode 100644
index 0000000..dec9920
--- /dev/null
+++ b/tinyHTTP/test/test_transport.h
@@ -0,0 +1,371 @@
+#ifndef _TEST_HTTP_TRANSPORT_H_
+#define _TEST_HTTP_TRANSPORT_H_
+
+#define TEST_HTTP_CAT_(A, B) A ## B
+#define TEST_HTTP_CAT(A, B) TEST_HTTP_CAT_(A, B)
+#define TEST_HTTP_STRING_(A) #A
+#define TEST_HTTP_STRING(A) TEST_HTTP_STRING_(A)
+
+#define TEST_HTTP_LOCAL_IP "0.0.0.0"
+#define TEST_HTTP_LOCAL_PORT 8080
+#define TEST_HTTP_REMOTE_IP "google.com"
+#define TEST_HTTP_REMOTE_PORT 80
+#define TEST_HTTP_MIN_STREAM_CHUNCK_SIZE 0x32
+#define TEST_HTTP_GET "GET / HTTP/1.1\r\n" \
+ "Host: " TEST_HTTP_REMOTE_IP ":" TEST_HTTP_STRING(TEST_HTTP_REMOTE_PORT) "\r\n" \
+ "Connection: keep-alive\r\n" \
+ "Cache-Control: max-age=0\r\n" \
+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" \
+ "User-Agent: Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko)\r\n" \
+ "Doubango 2.0\r\n" \
+ "Accept-Encoding: gzip,deflate,sdch\r\n" \
+ "Accept-Language: en-US,en;q=0.8\r\n" \
+ "\r\n" \
+
+static int test_http_transport_callback(const tnet_transport_event_t* e);
+
+/************************************************
+* test_http_peer_t
+************************************************/
+typedef struct test_http_peer_s
+{
+ TSK_DECLARE_OBJECT;
+ tnet_fd_t fd;
+ tsk_buffer_t* buff;
+}
+test_http_peer_t;
+typedef tsk_list_t test_http_peers_L_t;
+
+static tsk_object_t* test_http_peer_ctor(tsk_object_t * self, va_list * app) { return self; }
+static tsk_object_t* test_http_peer_dtor(tsk_object_t * self)
+{
+ test_http_peer_t *peer = self;
+ if (peer) {
+ TSK_OBJECT_SAFE_FREE(peer->buff);
+ }
+
+ return self;
+}
+static const tsk_object_def_t test_http_peer_def_s =
+{
+ sizeof(test_http_peer_t),
+ test_http_peer_ctor,
+ test_http_peer_dtor,
+ tsk_null,
+};
+
+static test_http_peer_t* test_http_peer_create(tnet_fd_t fd)
+{
+ test_http_peer_t* peer = tsk_object_new(&test_http_peer_def_s);
+ peer->fd = fd;
+ peer->buff = tsk_buffer_create_null();
+ return peer;
+}
+
+static int test_http_peer_pred_fd_cmp(const tsk_list_item_t* item, const void* data)
+{
+ return ((test_http_peer_t*)item->data)->fd - *((const tnet_fd_t*)data);
+}
+
+
+/************************************************
+* test_http_transport_t
+************************************************/
+typedef struct test_http_transport_s
+{
+ TSK_DECLARE_OBJECT;
+
+ test_http_peers_L_t* peers;
+ tnet_transport_handle_t* handle;
+}
+test_http_transport_t;
+
+static tsk_object_t* test_http_transport_ctor(tsk_object_t * self, va_list * app)
+{
+ test_http_transport_t *transport = self;
+ if (transport) {
+ }
+ return self;
+}
+static tsk_object_t* test_http_transport_dtor(tsk_object_t * self)
+{
+ test_http_transport_t *transport = self;
+ if(transport){
+ TSK_OBJECT_SAFE_FREE(transport->handle);
+ TSK_OBJECT_SAFE_FREE(transport->peers);
+ }
+
+ return self;
+}
+static const tsk_object_def_t test_http_transport_def_s =
+{
+ sizeof(test_http_transport_t),
+ test_http_transport_ctor,
+ test_http_transport_dtor,
+ tsk_null,
+};
+
+static test_http_transport_t* test_http_transport_create(const char* local_ip, tnet_port_t local_port, enum tnet_socket_type_e socket_type)
+{
+ test_http_transport_t *transport = tsk_object_new(&test_http_transport_def_s);
+ if (transport) {
+ transport->peers = tsk_list_create();
+ transport->handle = tnet_transport_create(local_ip, local_port, socket_type, "HTTP Transport");
+ if (!transport->handle) {
+ TSK_OBJECT_SAFE_FREE(transport);
+ return tsk_null;
+ }
+ tnet_transport_set_callback(transport->handle, test_http_transport_callback, transport);
+ }
+ return transport;
+}
+
+static int test_http_transport_start(test_http_transport_t* self)
+{
+ if (self) {
+ return tnet_transport_start(self->handle);
+ }
+ return -1;
+}
+
+// Up to the caller to free the returned object using TSK_OBJECT_SAFREE(peer)
+static test_http_peer_t* test_http_transport_connect_to(test_http_transport_t* self, const char* dst_host, tnet_port_t dst_port)
+{
+ tnet_fd_t fd = tnet_transport_connectto_2(self->handle, dst_host, dst_port);
+ if (fd > 0) {
+ return test_http_peer_create(fd);
+ }
+ return tsk_null;
+}
+
+static tsk_size_t test_http_transport_send_data(test_http_transport_t* self, tnet_fd_t fd, const void* data_ptr, tsk_size_t data_size)
+{
+ if (self && self->handle && data_ptr && data_size) {
+ return tnet_transport_send(self->handle, fd, data_ptr, data_size);
+ }
+ return 0;
+}
+
+static void test_http_transport_add_peer(test_http_transport_t* self, test_http_peer_t* peer)
+{
+ tsk_list_lock(self->peers);
+ tsk_list_push_back_data(self->peers, &peer);
+ tsk_list_unlock(self->peers);
+}
+
+static void test_http_transport_remove_peer_by_fd(test_http_transport_t* self, tnet_fd_t fd)
+{
+ tsk_list_lock(self->peers);
+ tsk_list_remove_item_by_pred(self->peers, test_http_peer_pred_fd_cmp, &fd);
+ tsk_list_unlock(self->peers);
+}
+
+static const test_http_peer_t* test_http_transport_find_peer_by_fd(test_http_transport_t* self, tnet_fd_t fd)
+{
+ const tsk_list_item_t* item;
+ tsk_list_lock(self->peers);
+ item = tsk_list_find_item_by_pred(self->peers, test_http_peer_pred_fd_cmp, &fd);
+ tsk_list_unlock(self->peers);
+ if (item) {
+ return (const test_http_peer_t*)item->data;
+ }
+ return tsk_null;
+}
+
+static void test_http_transport_process_incoming_msg(test_http_transport_t* self, const thttp_message_t* msg, tnet_fd_t fd)
+{
+ if (THTTP_MESSAGE_IS_REQUEST(msg)) {
+ if (tsk_striequals(msg->line.request.method, "GET")) {
+ char* result = tsk_null;
+ const char* content = "<html><body>Hello world!</body></html>";
+ int len = tsk_sprintf(
+ (char**)&result,
+ "HTTP/1.1 %u %s\r\n"
+ "Server: My test server \r\n"
+ "Access-Control-Allow-Origin: *\r\n"
+ "Content-Length: %u\r\n"
+ "Content-Type: text/html\r\n"
+ "Connection: Close\r\n"
+ "\r\n"
+ "%s", 200, "OK", tsk_strlen(content), content);
+ tnet_transport_send(self, fd, result, len);
+ TSK_FREE(result);
+ }
+ }
+}
+
+static int test_http_transport_callback(const tnet_transport_event_t* e)
+{
+ test_http_transport_t* transport = (test_http_transport_t*)e->callback_data;
+ const test_http_peer_t* _peer;
+ thttp_message_t *message = tsk_null;
+ int endOfheaders = -1;
+ tsk_ragel_state_t state;
+ tsk_bool_t have_all_content = tsk_false;
+ int ret;
+ switch (e->type)
+ {
+ case event_closed:
+ {
+ test_http_transport_remove_peer_by_fd(transport, e->local_fd);
+ return 0;
+ }
+
+ case event_connected:
+ case event_accepted:
+ {
+ _peer = test_http_transport_find_peer_by_fd(transport, e->local_fd);
+ if (!_peer) {
+ _peer = test_http_peer_create(e->local_fd);
+ test_http_transport_add_peer(transport, (test_http_peer_t*)_peer);
+ }
+ return 0;
+ }
+
+ case event_data:
+ {
+ TSK_DEBUG_INFO("\n\nRECV: %.*s\n\n", e->size, (const char*)e->data);
+ break;
+ }
+ default:
+ return 0;
+ }
+
+
+ _peer = test_http_transport_find_peer_by_fd(transport, e->local_fd);
+ if(!_peer) {
+ TSK_DEBUG_ERROR("Data event but no peer found!");
+ return -1;
+ }
+
+ /* Append new content. */
+ tsk_buffer_append(_peer->buff, e->data, e->size);
+
+ /* Check if we have all HTTP headers. */
+parse_buffer:
+ if ((endOfheaders = tsk_strindexOf(TSK_BUFFER_DATA(_peer->buff), TSK_BUFFER_SIZE(_peer->buff), "\r\n\r\n"/*2CRLF*/)) < 0) {
+ TSK_DEBUG_INFO("No all HTTP headers in the TCP buffer.");
+ goto bail;
+ }
+
+ /* If we are here this mean that we have all HTTP headers.
+ * ==> Parse the HTTP message without the content.
+ */
+ tsk_ragel_state_init(&state, TSK_BUFFER_DATA(_peer->buff), endOfheaders + 4/*2CRLF*/);
+ if (!(ret = thttp_message_parse(&state, &message, tsk_false/* do not extract the content */))) {
+ const thttp_header_Transfer_Encoding_t* transfer_Encoding;
+
+ /* chunked? */
+ if((transfer_Encoding = (const thttp_header_Transfer_Encoding_t*)thttp_message_get_header(message, thttp_htype_Transfer_Encoding)) && tsk_striequals(transfer_Encoding->encoding, "chunked")){
+ const char* start = (const char*)(TSK_BUFFER_TO_U8(_peer->buff) + (endOfheaders + 4/*2CRLF*/));
+ const char* end = (const char*)(TSK_BUFFER_TO_U8(_peer->buff) + TSK_BUFFER_SIZE(_peer->buff));
+ int index;
+
+ TSK_DEBUG_INFO("CHUNKED transfer.");
+ while(start < end){
+ /* RFC 2616 - 19.4.6 Introduction of Transfer-Encoding */
+ // read chunk-size, chunk-extension (if any) and CRLF
+ tsk_size_t chunk_size = (tsk_size_t)tsk_atox(start);
+ if((index = tsk_strindexOf(start, (end-start), "\r\n")) >=0){
+ start += index + 2/*CRLF*/;
+ }
+ else{
+ TSK_DEBUG_INFO("Parsing chunked data has failed.");
+ break;
+ }
+
+ if(chunk_size == 0 && ((start + 2) <= end) && *start == '\r' && *(start+ 1) == '\n'){
+ int parsed_len = (start - (const char*)(TSK_BUFFER_TO_U8(_peer->buff))) + 2/*CRLF*/;
+ tsk_buffer_remove(_peer->buff, 0, parsed_len);
+ have_all_content = tsk_true;
+ break;
+ }
+
+ thttp_message_append_content(message, start, chunk_size);
+ start += chunk_size + 2/*CRLF*/;
+ }
+ }
+ else{
+ tsk_size_t clen = THTTP_MESSAGE_CONTENT_LENGTH(message); /* MUST have content-length header. */
+ if(clen == 0){ /* No content */
+ tsk_buffer_remove(_peer->buff, 0, (endOfheaders + 4/*2CRLF*/)); /* Remove HTTP headers and CRLF ==> must never happen */
+ have_all_content = tsk_true;
+ }
+ else{ /* There is a content */
+ if((endOfheaders + 4/*2CRLF*/ + clen) > TSK_BUFFER_SIZE(_peer->buff)){ /* There is content but not all the content. */
+ TSK_DEBUG_INFO("No all HTTP content in the TCP buffer.");
+ goto bail;
+ }
+ else{
+ /* Add the content to the message. */
+ thttp_message_add_content(message, tsk_null, TSK_BUFFER_TO_U8(_peer->buff) + endOfheaders + 4/*2CRLF*/, clen);
+ /* Remove HTTP headers, CRLF and the content. */
+ tsk_buffer_remove(_peer->buff, 0, (endOfheaders + 4/*2CRLF*/ + clen));
+ have_all_content = tsk_true;
+ }
+ }
+ }
+ }
+
+ /* Alert the dialog (FSM) */
+ if(message){
+ if (have_all_content) { /* only if we have all data */
+ test_http_transport_process_incoming_msg(transport, message, e->local_fd);
+ /* Parse next chunck */
+ if (TSK_BUFFER_SIZE(_peer->buff) >= TEST_HTTP_MIN_STREAM_CHUNCK_SIZE) {
+ TSK_OBJECT_SAFE_FREE(message);
+ goto parse_buffer;
+ }
+ }
+ }
+
+bail:
+ TSK_OBJECT_SAFE_FREE(message);
+
+ return 0;
+}
+
+
+/************************************************
+* Main
+************************************************/
+static void test_transport()
+{
+ test_http_transport_t* p_transport = tsk_null;
+ test_http_peer_t* peer = tsk_null;
+ int ret;
+ static const char* __get_msg = TEST_HTTP_GET;
+
+ p_transport = test_http_transport_create(TEST_HTTP_LOCAL_IP, TEST_HTTP_LOCAL_PORT, tnet_socket_type_tcp_ipv4);
+ if (!p_transport) {
+ TSK_DEBUG_ERROR("Failed to HTTP transport");
+ goto bail;
+ }
+
+ ret = test_http_transport_start(p_transport);
+ if (ret) {
+ TSK_DEBUG_ERROR("Failed to start HTTP transport with error code = %d", ret);
+ goto bail;
+ }
+
+ getchar();
+
+ // Send data to google.com
+ peer = test_http_transport_connect_to(p_transport, TEST_HTTP_REMOTE_IP, TEST_HTTP_REMOTE_PORT);
+ ret = tnet_sockfd_waitUntilWritable(peer->fd, 1000); // you should use the callback function instead of blocking the process
+ if (ret) {
+ TSK_DEBUG_ERROR("Failed to connect to(%s,%d) with error code = %d", TEST_HTTP_REMOTE_IP, TEST_HTTP_REMOTE_PORT, ret);
+ goto bail;
+ }
+ ret = test_http_transport_send_data(p_transport, peer->fd, __get_msg, tsk_strlen(__get_msg));
+ TSK_DEBUG_INFO("Sent %d bytes", ret);
+
+ getchar();
+
+
+bail:
+ TSK_OBJECT_SAFE_FREE(p_transport); // stop server and free memory
+ TSK_OBJECT_SAFE_FREE(peer);
+}
+
+#endif /* _TEST_HTTP_TRANSPORT_H_ */
diff --git a/tinyHTTP/test/test_url.h b/tinyHTTP/test/test_url.h
new file mode 100644
index 0000000..c533c78
--- /dev/null
+++ b/tinyHTTP/test/test_url.h
@@ -0,0 +1,93 @@
+/*
+* Copyright (C) 2009 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+#ifndef _TEST_HTTPURL_H
+#define _TEST_HTTPURL_H
+
+#include "tinyhttp/parsers/thttp_parser_url.h"
+
+const char* urls[] =
+{
+
+ //== HTTP:
+ "http://www.doubango.org",
+ "http://www.doubango.org/?p=1",
+ "http://doubango.org:452/test",
+ "http://doubango.org:45/test?p=452",
+
+ //== HTTPS:
+ "https://www.doubango.org",
+ "https://www.doubango.org/?p=1",
+ "https://doubango.org:452/test",
+ "https://doubango.org:45/test?p=452",
+};
+#include "tsk_string.h"
+
+void test_url_tostring(const thttp_url_t *url)
+{
+ char* ret = thttp_url_tostring(url);
+ TSK_DEBUG_INFO("url_to_string=%s", ret);
+ TSK_FREE(ret);
+}
+
+void test_url_parser()
+{
+ int i;
+
+ for(i=0; i<sizeof(urls)/sizeof(const char*); i++)
+ {
+ thttp_url_t *url = thttp_url_parse(urls[i], strlen(urls[i]));
+
+ printf("\n== Parsing {{ %s }} ==\n\n", urls[i]);
+
+ if(url)
+ {
+ printf("scheme: %s\n", url->scheme);
+ printf("host: %s\n", url->host);
+ printf("port: %u\n", url->port);
+ printf("hpath: %s\n", url->hpath);
+ printf("search: %s\n", url->search);
+ printf("host-type: %s\n", url->host_type == thttp_host_ipv4 ? "IPv4" : (url->host_type == thttp_host_ipv6 ? "IPv6" : (url->host_type == thttp_host_hostname ? "HOSTNAME" : "UNKNOWN")) );
+
+ printf("---PARAMS---\n");
+
+ printf("Is-secure: %s\n", THTTP_URL_IS_SECURE(url) ? "YES" : "NO");
+
+ test_url_tostring(url);
+ }
+ else
+ {
+ printf("INVALID HTTP URL.\n");
+ }
+
+ printf("\n\n");
+ getchar();
+
+ TSK_OBJECT_SAFE_FREE(url);
+ }
+}
+
+void test_url()
+{
+ test_url_parser();
+}
+
+#endif /* _TEST_HTTPURL_H */
OpenPOWER on IntegriCloud