Skip to content

Commit 56c68fa

Browse files
authored
Introduce use_dual_stack to allow support for both ipv4 and ipv6
* Introduce use_dual_stack to allow support for both ipv4 and ipv6. See: etr#202 * Remove explicit DNS resolve for IPV6 * IPV6 tests run if IPV6_TESTS_ENABLED specified * Enable IPV6 tests only on osx Travis linux doesn't currently support IPV6
1 parent 6ede3c9 commit 56c68fa

File tree

6 files changed

+62
-0
lines changed

6 files changed

+62
-0
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ before_install:
3333
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo pip install gcovr; fi
3434
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get install cppcheck; fi
3535
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then export CFLAGS='-mtune=generic'; fi
36+
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then export IPV6_TESTS_ENABLED="true"; fi
3637
- |-
3738
case $TRAVIS_OS_NAME in
3839
windows)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ For example, if your connection limit is “1”, a browser may open a first con
188188
* _.bind_socket(**int** socket_fd):_ Listen socket to use. Pass a listen socket for the daemon to use (systemd-style). If this option is used, the daemon will not open its own listen socket(s). The argument passed must be of type "int" and refer to an existing socket that has been bound to a port and is listening.
189189
* _.max_thread_stack_size(**int** stack_size):_ Maximum stack size for threads created by the library. Not specifying this option or using a value of zero means using the system default (which is likely to differ based on your platform). Default is `0 (system default)`.
190190
* _.use_ipv6() and .no_ipv6():_ Enable or disable the IPv6 protocol support (by default, libhttpserver will just support IPv4). If you specify this and the local platform does not support it, starting up the server will throw an exception. `off` by default.
191+
* _.use_dual_stack() and .no_dual_stack():_ Enable or disable the support for both IPv6 and IPv4 protocols at the same time (by default, libhttpserver will just support IPv4). If you specify this and the local platform does not support it, starting up the server will throw an exception. Note that this will mean that IPv4 addresses are returned in the IPv6-mapped format (the ’structsockaddrin6’ format will be used for IPv4 and IPv6). `off` by default.
191192
* _.pedantic() and .no_pedantic():_ Enables pedantic checks about the protocol (as opposed to as tolerant as possible). Specifically, at the moment, this flag causes the library to reject HTTP 1.1 connections without a `Host` header. This is required by the standard, but of course in violation of the “be as liberal as possible in what you accept” norm. It is recommended to turn this **off** if you are testing clients against the library, and **on** in production. `off` by default.
192193
* _.debug() and .no_debug():_ Enables debug messages from the library. `off` by default.
193194
* _.regex_checking() and .no_regex_checking():_ Enables pattern matching for endpoints. Read more [here](#registering-resources). `on` by default.

src/httpserver/create_webserver.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ class create_webserver
120120
create_webserver& no_ssl() { _use_ssl = false; return *this; }
121121
create_webserver& use_ipv6() { _use_ipv6 = true; return *this; }
122122
create_webserver& no_ipv6() { _use_ipv6 = false; return *this; }
123+
create_webserver& use_dual_stack() { _use_dual_stack = true; return *this; }
124+
create_webserver& no_dual_stack() { _use_dual_stack = false; return *this; }
123125
create_webserver& debug() { _debug = true; return *this; }
124126
create_webserver& no_debug() { _debug = false; return *this; }
125127
create_webserver& pedantic() { _pedantic = true; return *this; }
@@ -273,6 +275,7 @@ class create_webserver
273275
int _max_thread_stack_size = 0;
274276
bool _use_ssl = false;
275277
bool _use_ipv6 = false;
278+
bool _use_dual_stack = false;
276279
bool _debug = false;
277280
bool _pedantic = false;
278281
std::string _https_mem_key = "";

src/httpserver/webserver.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class webserver
154154
const int max_thread_stack_size;
155155
const bool use_ssl;
156156
const bool use_ipv6;
157+
const bool use_dual_stack;
157158
const bool debug;
158159
const bool pedantic;
159160
const std::string https_mem_key;

src/webserver.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ webserver::webserver(const create_webserver& params):
149149
max_thread_stack_size(params._max_thread_stack_size),
150150
use_ssl(params._use_ssl),
151151
use_ipv6(params._use_ipv6),
152+
use_dual_stack(params._use_dual_stack),
152153
debug(params._debug),
153154
pedantic(params._pedantic),
154155
https_mem_key(params._https_mem_key),
@@ -311,6 +312,8 @@ bool webserver::start(bool blocking)
311312
start_conf |= MHD_USE_SSL;
312313
if(use_ipv6)
313314
start_conf |= MHD_USE_IPv6;
315+
if(use_dual_stack)
316+
start_conf |= MHD_USE_DUAL_STACK;
314317
if(debug)
315318
start_conf |= MHD_USE_DEBUG;
316319
if(pedantic)

test/integ/ws_start_stop.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,59 @@ LT_BEGIN_AUTO_TEST(ws_start_stop_suite, start_stop)
143143
}
144144
LT_END_AUTO_TEST(start_stop)
145145

146+
#if defined(IPV6_TESTS_ENABLED)
147+
148+
LT_BEGIN_AUTO_TEST(ws_start_stop_suite, ipv6)
149+
{
150+
webserver ws = create_webserver(8080).use_ipv6();
151+
ok_resource ok;
152+
ws.register_resource("base", &ok);
153+
ws.start(false);
154+
155+
curl_global_init(CURL_GLOBAL_ALL);
156+
std::string s;
157+
CURL *curl = curl_easy_init();
158+
CURLcode res;
159+
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8080/base");
160+
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
161+
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
162+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
163+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
164+
res = curl_easy_perform(curl);
165+
LT_ASSERT_EQ(res, 0);
166+
LT_CHECK_EQ(s, "OK");
167+
curl_easy_cleanup(curl);
168+
169+
ws.stop();
170+
}
171+
LT_END_AUTO_TEST(ipv6)
172+
173+
LT_BEGIN_AUTO_TEST(ws_start_stop_suite, dual_stack)
174+
{
175+
webserver ws = create_webserver(8080).use_dual_stack();
176+
ok_resource ok;
177+
ws.register_resource("base", &ok);
178+
ws.start(false);
179+
180+
curl_global_init(CURL_GLOBAL_ALL);
181+
std::string s;
182+
CURL *curl = curl_easy_init();
183+
CURLcode res;
184+
curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:8080/base");
185+
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
186+
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
187+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
188+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
189+
res = curl_easy_perform(curl);
190+
LT_ASSERT_EQ(res, 0);
191+
LT_CHECK_EQ(s, "OK");
192+
curl_easy_cleanup(curl);
193+
194+
ws.stop();
195+
}
196+
LT_END_AUTO_TEST(dual_stack)
197+
198+
#endif
146199

147200
LT_BEGIN_AUTO_TEST(ws_start_stop_suite, sweet_kill)
148201
webserver ws = create_webserver(8080);

0 commit comments

Comments
 (0)