1 /*
2 * Copyright (C) 2011 Emweb bv, Herent, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6
7 #include <Wt/WConfig.h>
8
9 #ifdef WT_THREADED
10
11 #include <boost/test/unit_test.hpp>
12 #include <thread>
13 #include <condition_variable>
14 #include <mutex>
15
16 #include <Wt/WApplication.h>
17 #include <Wt/WIOService.h>
18 #include <Wt/Http/Client.h>
19 #include <Wt/Test/WTestEnvironment.h>
20
21 using namespace Wt;
22 using namespace Wt::Http;
23
24 namespace {
25
26 class TestFixture : public WApplication
27 {
28 public:
TestFixture(const WEnvironment & env)29 TestFixture(const WEnvironment& env)
30 : WApplication(env),
31 done_(false)
32 { }
33
waitDone()34 void waitDone()
35 {
36 std::unique_lock<std::mutex> guard(doneMutex_);
37
38 while (!done_)
39 doneCondition_.wait(guard);
40 }
41
reset()42 void reset()
43 {
44 done_ = false;
45 }
46
onDone(Wt::AsioWrapper::error_code err,const Message & m)47 void onDone(Wt::AsioWrapper::error_code err, const Message& m)
48 {
49 assert (WApplication::instance() == this);
50
51 std::unique_lock<std::mutex> guard(doneMutex_);
52
53 err_ = err;
54 message_ = m;
55
56 if (err_)
57 std::cerr << "Http client error: " << err_.message() << std::endl;
58 else {
59 std::cerr << "Http client result status: " << m.status() << std::endl;
60 for (unsigned i = 0; i < m.headers().size(); ++i) {
61 const Message::Header& h = m.headers()[i];
62 std::cerr << " " << h.name() << ": " << h.value() << std::endl;
63 }
64 std::cerr << " Body: -----" << std::endl;
65 std::cerr << m.body();
66 std::cerr << "-----" << std::endl;
67 }
68
69 done_ = true;
70 doneCondition_.notify_one();
71 }
72
73 private:
74 bool done_;
75 std::condition_variable doneCondition_;
76 std::mutex doneMutex_;
77
78 Wt::AsioWrapper::error_code err_;
79 Message message_;
80 };
81 }
82
BOOST_AUTO_TEST_CASE(http_client_test1)83 BOOST_AUTO_TEST_CASE( http_client_test1 )
84 {
85 Wt::Test::WTestEnvironment environment;
86 TestFixture app(environment);
87
88 std::unique_ptr<Client> c(new Client());
89 c->done().connect(std::bind(&TestFixture::onDone, &app,
90 std::placeholders::_1,
91 std::placeholders::_2));
92
93 std::string ok = "www.google.com/";
94
95 if (c->get("https://" + ok)) {
96 environment.endRequest();
97 app.waitDone();
98 environment.startRequest();
99 }
100 }
101
BOOST_AUTO_TEST_CASE(http_client_test2)102 BOOST_AUTO_TEST_CASE( http_client_test2 )
103 {
104 Wt::Test::WTestEnvironment environment;
105 TestFixture app(environment);
106
107 std::unique_ptr<Client> c(new Client());
108 c->done().connect(std::bind(&TestFixture::onDone, &app,
109 std::placeholders::_1,
110 std::placeholders::_2));
111
112 std::string verifyFail = "pause.perl.org/";
113
114 /* Does no longer fail! Too bad */
115 if (c->get("https://" + verifyFail)) {
116 environment.endRequest();
117 app.waitDone();
118 environment.startRequest();
119 }
120 }
121
BOOST_AUTO_TEST_CASE(http_client_test3)122 BOOST_AUTO_TEST_CASE( http_client_test3 )
123 {
124 Wt::Test::WTestEnvironment environment;
125 TestFixture app(environment);
126
127 std::unique_ptr<Client> c(new Client());
128 c->done().connect(std::bind(&TestFixture::onDone, &app,
129 std::placeholders::_1,
130 std::placeholders::_2));
131
132 std::string asioFail = "www.google.be/";
133
134 /* Asio no longer fails. Good! */
135 if (c->get("https://" + asioFail)) {
136 environment.endRequest();
137 app.waitDone();
138 environment.startRequest();
139 }
140 }
141
BOOST_AUTO_TEST_CASE(http_client_test4)142 BOOST_AUTO_TEST_CASE( http_client_test4 )
143 {
144 Wt::Test::WTestEnvironment environment;
145 TestFixture app(environment);
146
147 environment.server()->ioService().start();
148
149 std::unique_ptr<Client> c(new Client());
150 c->done().connect(std::bind(&TestFixture::onDone, &app,
151 std::placeholders::_1,
152 std::placeholders::_2));
153
154 std::string ok = "www.google.com/";
155
156 if (c->get("https://" + ok)) {
157 environment.endRequest();
158 app.waitDone();
159 environment.startRequest();
160 }
161
162 environment.server()->ioService().stop();
163 environment.server()->ioService().start();
164
165 app.reset();
166
167 if (c->get("https://" + ok)) {
168 environment.endRequest();
169 app.waitDone();
170 environment.startRequest();
171 }
172 }
173
BOOST_AUTO_TEST_CASE(http_client_test5)174 BOOST_AUTO_TEST_CASE( http_client_test5 )
175 {
176 // Test parseUrl
177 Wt::Http::Client::URL url;
178 bool result = Wt::Http::Client::parseUrl(
179 "https://www.googleapis.com/calendar/v3/calendars/abcdefgh112233344444@group.calendar.google.com",
180 url);
181
182 BOOST_REQUIRE(result);
183 BOOST_CHECK_EQUAL(url.auth, "");
184 BOOST_CHECK_EQUAL(url.protocol, "https");
185 BOOST_CHECK_EQUAL(url.host, "www.googleapis.com");
186 BOOST_CHECK_EQUAL(url.port, 443);
187 BOOST_CHECK_EQUAL(url.path, "/calendar/v3/calendars/abcdefgh112233344444@group.calendar.google.com");
188 }
189
BOOST_AUTO_TEST_CASE(http_client_test6)190 BOOST_AUTO_TEST_CASE( http_client_test6 )
191 {
192 // Test parseUrl with auth
193 Wt::Http::Client::URL url;
194 bool result = Wt::Http::Client::parseUrl(
195 "http://foo:bar@example.com/a/b/c",
196 url);
197
198 BOOST_REQUIRE(result);
199 BOOST_CHECK_EQUAL(url.auth, "foo:bar");
200 BOOST_CHECK_EQUAL(url.protocol, "http");
201 BOOST_CHECK_EQUAL(url.host, "example.com");
202 BOOST_CHECK_EQUAL(url.port, 80);
203 BOOST_CHECK_EQUAL(url.path, "/a/b/c");
204 }
205
206 #endif // WT_THREADED
207