]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // sync_client.cpp | |
3 | // ~~~~~~~~~~~~~~~ | |
4 | // | |
b32b8144 | 5 | // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
7c673cae FG |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
9 | // | |
10 | ||
11 | #include <iostream> | |
12 | #include <iomanip> | |
13 | #include <ostream> | |
14 | #include <string> | |
15 | #include <boost/asio.hpp> | |
16 | #include <boost/array.hpp> | |
17 | #include "socks4.hpp" | |
18 | ||
19 | using boost::asio::ip::tcp; | |
20 | ||
21 | int main(int argc, char* argv[]) | |
22 | { | |
23 | try | |
24 | { | |
25 | if (argc != 4) | |
26 | { | |
27 | std::cout << "Usage: sync_client <socks4server> <socks4port> <user>\n"; | |
28 | std::cout << "Examples:\n"; | |
29 | std::cout << " sync_client 127.0.0.1 1080 chris\n"; | |
30 | std::cout << " sync_client localhost socks chris\n"; | |
31 | return 1; | |
32 | } | |
33 | ||
b32b8144 | 34 | boost::asio::io_context io_context; |
7c673cae FG |
35 | |
36 | // Get a list of endpoints corresponding to the SOCKS 4 server name. | |
b32b8144 FG |
37 | tcp::resolver resolver(io_context); |
38 | tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]); | |
7c673cae FG |
39 | |
40 | // Try each endpoint until we successfully establish a connection to the | |
41 | // SOCKS 4 server. | |
b32b8144 FG |
42 | tcp::socket socket(io_context); |
43 | boost::asio::connect(socket, endpoints); | |
7c673cae FG |
44 | |
45 | // Get an endpoint for the Boost website. This will be passed to the SOCKS | |
46 | // 4 server. Explicitly specify IPv4 since SOCKS 4 does not support IPv6. | |
b32b8144 FG |
47 | tcp::endpoint http_endpoint = |
48 | *resolver.resolve(tcp::v4(), "www.boost.org", "http").begin(); | |
7c673cae FG |
49 | |
50 | // Send the request to the SOCKS 4 server. | |
51 | socks4::request socks_request( | |
52 | socks4::request::connect, http_endpoint, argv[3]); | |
53 | boost::asio::write(socket, socks_request.buffers()); | |
54 | ||
55 | // Receive a response from the SOCKS 4 server. | |
56 | socks4::reply socks_reply; | |
57 | boost::asio::read(socket, socks_reply.buffers()); | |
58 | ||
59 | // Check whether we successfully negotiated with the SOCKS 4 server. | |
60 | if (!socks_reply.success()) | |
61 | { | |
62 | std::cout << "Connection failed.\n"; | |
63 | std::cout << "status = 0x" << std::hex << socks_reply.status(); | |
64 | return 1; | |
65 | } | |
66 | ||
67 | // Form the HTTP request. We specify the "Connection: close" header so that | |
68 | // the server will close the socket after transmitting the response. This | |
69 | // will allow us to treat all data up until the EOF as the response. | |
70 | std::string request = | |
71 | "GET / HTTP/1.0\r\n" | |
72 | "Host: www.boost.org\r\n" | |
73 | "Accept: */*\r\n" | |
74 | "Connection: close\r\n\r\n"; | |
75 | ||
76 | // Send the HTTP request. | |
77 | boost::asio::write(socket, boost::asio::buffer(request)); | |
78 | ||
79 | // Read until EOF, writing data to output as we go. | |
80 | boost::array<char, 512> response; | |
81 | boost::system::error_code error; | |
82 | while (std::size_t s = socket.read_some( | |
83 | boost::asio::buffer(response), error)) | |
84 | std::cout.write(response.data(), s); | |
85 | if (error != boost::asio::error::eof) | |
86 | throw boost::system::system_error(error); | |
87 | } | |
88 | catch (std::exception& e) | |
89 | { | |
90 | std::cout << "Exception: " << e.what() << "\n"; | |
91 | } | |
92 | ||
93 | return 0; | |
94 | } |