src/examples/cpp03/iostreams/http_client.cpp | src/examples/cpp11/iostreams/http_client.cpp |
⋮ | ⋮ |
1 | // | 1 | // |
2 | //·http_client.cpp | 2 | //·http_client.cpp |
3 | //·~~~~~~~~~~~~~~~ | 3 | //·~~~~~~~~~~~~~~~ |
4 | // | 4 | // |
5 | //·Copyright·(c)·2003-2023·Christopher·M.·Kohlhoff·(chris·at·kohlhoff·dot·com) | 5 | //·Copyright·(c)·2003-2023·Christopher·M.·Kohlhoff·(chris·at·kohlhoff·dot·com) |
6 | // | 6 | // |
7 | //·Distributed·under·the·Boost·Software·License,·Version·1.0.·(See·accompanying | 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) | 8 | //·file·LICENSE_1_0.txt·or·copy·at·http://www.boost.org/LICENSE_1_0.txt) |
9 | // | 9 | // |
10 | | 10 | |
11 | #include·<iostream> | 11 | #include·<iostream> |
12 | #include·<istream> | 12 | #include·<istream> |
13 | #include·<ostream> | 13 | #include·<ostream> |
14 | #include·<string> | 14 | #include·<string> |
15 | #include·<asio/ip/tcp.hpp> | 15 | #include·<asio/ip/tcp.hpp> |
16 | | 16 | |
17 | using·asio::ip::tcp; | 17 | using·asio::ip::tcp; |
18 | | 18 | |
19 | int·main(int·argc,·char*·argv[]) | 19 | int·main(int·argc,·char*·argv[]) |
20 | { | 20 | { |
21 | ··try | 21 | ··try |
22 | ··{ | 22 | ··{ |
23 | ····if·(argc·!=·3) | 23 | ····if·(argc·!=·3) |
24 | ····{ | 24 | ····{ |
25 | ······std::cout·<<·"Usage:·http_client·<server>·<path>\n"; | 25 | ······std::cout·<<·"Usage:·http_client·<server>·<path>\n"; |
26 | ······std::cout·<<·"Example:\n"; | 26 | ······std::cout·<<·"Example:\n"; |
27 | ······std::cout·<<·"··http_client·www.boost.org·/LICENSE_1_0.txt\n"; | 27 | ······std::cout·<<·"··http_client·www.boost.org·/LICENSE_1_0.txt\n"; |
28 | ······return·1; | 28 | ······return·1; |
29 | ····} | 29 | ····} |
30 | | 30 | |
31 | ····asio::ip::tcp::iostream·s; | 31 | ····asio::ip::tcp::iostream·s; |
32 | | 32 | |
33 | ····//·The·entire·sequence·of·I/O·operations·must·complete·within·60·seconds. | 33 | ····//·The·entire·sequence·of·I/O·operations·must·complete·within·60·seconds. |
34 | ····//·If·an·expiry·occurs,·the·socket·is·automatically·closed·and·the·stream | 34 | ····//·If·an·expiry·occurs,·the·socket·is·automatically·closed·and·the·stream |
35 | ····//·becomes·bad. | 35 | ····//·becomes·bad. |
36 | ····s.expires_after(asio::chrono::seconds(60)); | 36 | ····s.expires_after(std::chrono::seconds(60)); |
37 | | 37 | |
38 | ····//·Establish·a·connection·to·the·server. | 38 | ····//·Establish·a·connection·to·the·server. |
39 | ····s.connect(argv[1],·"http"); | 39 | ····s.connect(argv[1],·"http"); |
40 | ····if·(!s) | 40 | ····if·(!s) |
41 | ····{ | 41 | ····{ |
42 | ······std::cout·<<·"Unable·to·connect:·"·<<·s.error().message()·<<·"\n"; | 42 | ······std::cout·<<·"Unable·to·connect:·"·<<·s.error().message()·<<·"\n"; |
43 | ······return·1; | 43 | ······return·1; |
44 | ····} | 44 | ····} |
45 | | 45 | |
46 | ····//·Send·the·request.·We·specify·the·"Connection:·close"·header·so·that·the | 46 | ····//·Send·the·request.·We·specify·the·"Connection:·close"·header·so·that·the |
47 | ····//·server·will·close·the·socket·after·transmitting·the·response.·This·will | 47 | ····//·server·will·close·the·socket·after·transmitting·the·response.·This·will |
48 | ····//·allow·us·to·treat·all·data·up·until·the·EOF·as·the·content. | 48 | ····//·allow·us·to·treat·all·data·up·until·the·EOF·as·the·content. |
49 | ····s·<<·"GET·"·<<·argv[2]·<<·"·HTTP/1.0\r\n"; | 49 | ····s·<<·"GET·"·<<·argv[2]·<<·"·HTTP/1.0\r\n"; |
50 | ····s·<<·"Host:·"·<<·argv[1]·<<·"\r\n"; | 50 | ····s·<<·"Host:·"·<<·argv[1]·<<·"\r\n"; |
51 | ····s·<<·"Accept:·*/*\r\n"; | 51 | ····s·<<·"Accept:·*/*\r\n"; |
52 | ····s·<<·"Connection:·close\r\n\r\n"; | 52 | ····s·<<·"Connection:·close\r\n\r\n"; |
53 | | 53 | |
54 | ····//·By·default,·the·stream·is·tied·with·itself.·This·means·that·the·stream | 54 | ····//·By·default,·the·stream·is·tied·with·itself.·This·means·that·the·stream |
55 | ····//·automatically·flush·the·buffered·output·before·attempting·a·read.·It·is | 55 | ····//·automatically·flush·the·buffered·output·before·attempting·a·read.·It·is |
56 | ····//·not·necessary·not·explicitly·flush·the·stream·at·this·point. | 56 | ····//·not·necessary·not·explicitly·flush·the·stream·at·this·point. |
57 | | 57 | |
58 | ····//·Check·that·response·is·OK. | 58 | ····//·Check·that·response·is·OK. |
59 | ····std::string·http_version; | 59 | ····std::string·http_version; |
60 | ····s·>>·http_version; | 60 | ····s·>>·http_version; |
61 | ····unsigned·int·status_code; | 61 | ····unsigned·int·status_code; |
62 | ····s·>>·status_code; | 62 | ····s·>>·status_code; |
63 | ····std::string·status_message; | 63 | ····std::string·status_message; |
64 | ····std::getline(s,·status_message); | 64 | ····std::getline(s,·status_message); |
65 | ····if·(!s·||·http_version.substr(0,·5)·!=·"HTTP/") | 65 | ····if·(!s·||·http_version.substr(0,·5)·!=·"HTTP/") |
66 | ····{ | 66 | ····{ |
67 | ······std::cout·<<·"Invalid·response\n"; | 67 | ······std::cout·<<·"Invalid·response\n"; |
68 | ······return·1; | 68 | ······return·1; |
69 | ····} | 69 | ····} |
70 | ····if·(status_code·!=·200) | 70 | ····if·(status_code·!=·200) |
71 | ····{ | 71 | ····{ |
72 | ······std::cout·<<·"Response·returned·with·status·code·"·<<·status_code·<<·"\n"; | 72 | ······std::cout·<<·"Response·returned·with·status·code·"·<<·status_code·<<·"\n"; |
73 | ······return·1; | 73 | ······return·1; |
74 | ····} | 74 | ····} |
75 | | 75 | |
76 | ····//·Process·the·response·headers,·which·are·terminated·by·a·blank·line. | 76 | ····//·Process·the·response·headers,·which·are·terminated·by·a·blank·line. |
77 | ····std::string·header; | 77 | ····std::string·header; |
78 | ····while·(std::getline(s,·header)·&&·header·!=·"\r") | 78 | ····while·(std::getline(s,·header)·&&·header·!=·"\r") |
79 | ······std::cout·<<·header·<<·"\n"; | 79 | ······std::cout·<<·header·<<·"\n"; |
80 | ····std::cout·<<·"\n"; | 80 | ····std::cout·<<·"\n"; |
81 | | 81 | |
82 | ····//·Write·the·remaining·data·to·output. | 82 | ····//·Write·the·remaining·data·to·output. |
83 | ····std::cout·<<·s.rdbuf(); | 83 | ····std::cout·<<·s.rdbuf(); |
84 | ··} | 84 | ··} |
85 | ··catch·(std::exception&·e) | 85 | ··catch·(std::exception&·e) |
86 | ··{ | 86 | ··{ |
87 | ····std::cout·<<·"Exception:·"·<<·e.what()·<<·"\n"; | 87 | ····std::cout·<<·"Exception:·"·<<·e.what()·<<·"\n"; |
88 | ··} | 88 | ··} |
89 | | 89 | |
90 | ··return·0; | 90 | ··return·0; |
91 | } | 91 | } |