fixes bug where priorities where lost when force-rechecking.
[libtorrent.git] / test / test_http_connection.cpp
blob3fbdf518990c1ac0c23eb25e5df679f6230990e8
1 /*
3 Copyright (c) 2008, Arvid Norberg
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #include "test.hpp"
34 #include "libtorrent/socket.hpp"
35 #include "libtorrent/connection_queue.hpp"
36 #include "libtorrent/http_connection.hpp"
37 #include "setup_transfer.hpp"
39 #include <fstream>
40 #include <boost/optional.hpp>
42 using namespace libtorrent;
44 io_service ios;
45 connection_queue cq(ios);
47 int connect_handler_called = 0;
48 int handler_called = 0;
49 int data_size = 0;
50 int http_status = 0;
51 error_code g_error_code;
52 char data_buffer[4000];
54 void print_http_header(http_parser const& p)
56 std::cerr << " < " << p.status_code() << " " << p.message() << std::endl;
58 for (std::map<std::string, std::string>::const_iterator i
59 = p.headers().begin(), end(p.headers().end()); i != end; ++i)
61 std::cerr << " < " << i->first << ": " << i->second << std::endl;
65 void http_connect_handler(http_connection& c)
67 ++connect_handler_called;
68 TEST_CHECK(c.socket().is_open());
69 std::cerr << "connected to: " << c.socket().remote_endpoint() << std::endl;
70 TEST_CHECK(c.socket().remote_endpoint().address() == address::from_string("127.0.0.1"));
73 void http_handler(error_code const& ec, http_parser const& parser
74 , char const* data, int size, http_connection& c)
76 ++handler_called;
77 data_size = size;
78 g_error_code = ec;
80 if (parser.header_finished())
82 http_status = parser.status_code();
83 if (http_status == 200)
85 TEST_CHECK(memcmp(data, data_buffer, size) == 0);
88 print_http_header(parser);
90 cq.close();
93 void reset_globals()
95 connect_handler_called = 0;
96 handler_called = 0;
97 data_size = 0;
98 http_status = 0;
99 g_error_code = error_code();
102 void run_test(std::string const& url, int size, int status, int connected
103 , boost::optional<error_code> ec, proxy_settings const& ps)
105 reset_globals();
107 std::cerr << " ===== TESTING: " << url << " =====" << std::endl;
109 boost::shared_ptr<http_connection> h(new http_connection(ios, cq
110 , &::http_handler, true, &::http_connect_handler));
111 h->get(url, seconds(5), 0, &ps);
112 ios.reset();
113 ios.run();
115 std::cerr << "connect_handler_called: " << connect_handler_called << std::endl;
116 std::cerr << "handler_called: " << handler_called << std::endl;
117 std::cerr << "status: " << http_status << std::endl;
118 std::cerr << "size: " << data_size << std::endl;
119 std::cerr << "error_code: " << g_error_code.message() << std::endl;
120 TEST_CHECK(connect_handler_called == connected);
121 TEST_CHECK(handler_called == 1);
122 TEST_CHECK(data_size == size || size == -1);
123 TEST_CHECK(!ec || g_error_code == *ec);
124 TEST_CHECK(http_status == status || status == -1);
127 void run_suite(std::string const& protocol, proxy_settings const& ps)
129 if (ps.type != proxy_settings::none)
131 start_proxy(ps.port, ps.type);
133 char const* test_name[] = {"no", "SOCKS4", "SOCKS5"
134 , "SOCKS5 password protected", "HTTP", "HTTP password protected"};
135 std::cout << "\n\n********************** using " << test_name[ps.type]
136 << " proxy **********************\n" << std::endl;
138 typedef boost::optional<error_code> err;
139 // this requires the hosts file to be modified
140 // run_test(protocol + "://test.dns.ts:8001/test_file", 3216, 200, 1, error_code(), ps);
142 run_test(protocol + "://127.0.0.1:8001/relative/redirect", 3216, 200, 2, error_code(), ps);
143 run_test(protocol + "://127.0.0.1:8001/redirect", 3216, 200, 2, error_code(), ps);
144 run_test(protocol + "://127.0.0.1:8001/infinite_redirect", 0, 301, 6, error_code(), ps);
145 run_test(protocol + "://127.0.0.1:8001/test_file", 3216, 200, 1, error_code(), ps);
146 run_test(protocol + "://127.0.0.1:8001/test_file.gz", 3216, 200, 1, error_code(), ps);
147 run_test(protocol + "://127.0.0.1:8001/non-existing-file", -1, 404, 1, err(), ps);
148 // if we're going through an http proxy, we won't get the same error as if the hostname
149 // resolution failed
150 if ((ps.type == proxy_settings::http || ps.type == proxy_settings::http_pw) && protocol != "https")
151 run_test(protocol + "://non-existent-domain.se/non-existing-file", -1, 502, 1, err(), ps);
152 else
153 run_test(protocol + "://non-existent-domain.se/non-existing-file", -1, -1, 0, err(), ps);
155 if (ps.type != proxy_settings::none)
156 stop_proxy(ps.port);
159 int test_main()
161 std::srand(std::time(0));
162 std::generate(data_buffer, data_buffer + sizeof(data_buffer), &std::rand);
163 std::ofstream("test_file").write(data_buffer, 3216);
164 std::system("gzip -9 -c test_file > test_file.gz");
166 proxy_settings ps;
167 ps.hostname = "127.0.0.1";
168 ps.port = 8034;
169 ps.username = "testuser";
170 ps.password = "testpass";
172 start_web_server(8001);
173 for (int i = 0; i < 5; ++i)
175 ps.type = (proxy_settings::proxy_type)i;
176 run_suite("http", ps);
178 stop_web_server(8001);
180 #ifdef TORRENT_USE_OPENSSL
181 start_web_server(8001, true);
182 for (int i = 0; i < 5; ++i)
184 ps.type = (proxy_settings::proxy_type)i;
185 run_suite("https", ps);
187 stop_web_server(8001);
188 #endif
190 std::remove("test_file");
191 return 0;