Line data Source code
1 : // HTTP Client & Server -- classes to ease handling HTTP protocol
2 : // Copyright (c) 2012-2019 Made to Order Software Corp. All Rights Reserved
3 : //
4 : // This program is free software; you can redistribute it and/or modify
5 : // it under the terms of the GNU General Public License as published by
6 : // the Free Software Foundation; either version 2 of the License, or
7 : // (at your option) any later version.
8 : //
9 : // This program is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : // GNU General Public License for more details.
13 : //
14 : // You should have received a copy of the GNU General Public License
15 : // along with this program; if not, write to the Free Software
16 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 : #pragma once
18 :
19 : #include "snapwebsites/tcp_client_server.h"
20 :
21 : #include <map>
22 : #include <vector>
23 :
24 :
25 : namespace http_client_server
26 : {
27 :
28 :
29 :
30 0 : class http_client_server_logic_error : public std::logic_error
31 : {
32 : public:
33 0 : http_client_server_logic_error(std::string const& errmsg) : logic_error(errmsg) {}
34 : };
35 :
36 0 : class http_client_server_runtime_error : public std::runtime_error
37 : {
38 : public:
39 0 : http_client_server_runtime_error(std::string const& errmsg) : runtime_error(errmsg) {}
40 : };
41 :
42 0 : class http_client_exception_io_error : public http_client_server_runtime_error
43 : {
44 : public:
45 0 : http_client_exception_io_error(std::string const& errmsg) : http_client_server_runtime_error(errmsg) {}
46 : };
47 :
48 :
49 :
50 :
51 : // name / value pairs
52 : typedef std::map<std::string, std::string> header_t;
53 :
54 : // attachment buffer
55 : typedef std::vector<char> attachment_t;
56 :
57 :
58 : class http_request
59 : {
60 : public:
61 : typedef std::shared_ptr<http_request> pointer_t;
62 :
63 : std::string get_host() const;
64 : int get_port() const;
65 : std::string get_command() const;
66 : std::string get_path() const;
67 : std::string get_header(std::string const& name) const;
68 : std::string get_post(std::string const& name) const;
69 : std::string get_body() const; // also returns data
70 : std::string get_request(bool keep_alive) const;
71 :
72 : void set_uri(std::string const& uri);
73 : void set_host(std::string const& host);
74 : void set_port(int port);
75 : void set_command(std::string const& command);
76 : void set_path(std::string const& path);
77 : void set_header(std::string const& name, std::string const& value);
78 : void set_post(std::string const& name, std::string const& value);
79 : void set_basic_auth(std::string const& username, std::string const& secret);
80 : void set_data(std::string const& data);
81 : void set_body(std::string const& body);
82 :
83 : private:
84 : std::string f_host = std::string();
85 : std::string f_command = std::string();
86 : std::string f_path = std::string();
87 : int32_t f_port = -1;
88 : header_t f_headers = header_t();
89 : header_t f_post = header_t();
90 : std::string f_body = std::string();
91 : std::vector<attachment_t> f_attachments = std::vector<attachment_t>(); // not used yet (Also look in a way that allows us to avoid an extra copy)
92 : bool f_has_body = false;
93 : bool f_has_data = false;
94 : bool f_has_post = false;
95 : bool f_has_attachment = false; // not used yet
96 : };
97 :
98 :
99 : class http_client;
100 :
101 :
102 0 : class http_response
103 : {
104 : public:
105 : typedef std::shared_ptr<http_response> pointer_t;
106 :
107 : enum class protocol_t
108 : {
109 : UNKNOWN,
110 : HTTP_1_0,
111 : HTTP_1_1
112 : };
113 :
114 : std::string get_original_header() const;
115 : protocol_t get_protocol() const;
116 : int get_response_code() const;
117 : std::string get_http_message() const;
118 : bool has_header(std::string const & name) const;
119 : std::string get_header(std::string const & name) const;
120 : std::string get_response() const;
121 :
122 : void append_original_header(std::string const & header);
123 : void set_protocol(protocol_t protocol);
124 : void set_response_code(int code);
125 : void set_http_message(std::string const& message);
126 : void set_header(std::string const & name, std::string const & value);
127 : void set_response(std::string const & response);
128 :
129 : private:
130 : friend http_client;
131 :
132 : void read_response(tcp_client_server::bio_client::pointer_t connection);
133 :
134 : std::string f_original_header = std::string();
135 : protocol_t f_protocol = protocol_t::UNKNOWN;
136 : int32_t f_response_code = 0;
137 : std::string f_http_message = std::string();
138 : header_t f_header = header_t();
139 : std::string f_response = std::string();
140 : };
141 :
142 :
143 : class http_client
144 : {
145 : public:
146 : http_client() {}
147 :
148 : http_client(http_client const &) = delete;
149 : http_client & operator = (http_client const &) = delete;
150 :
151 : bool get_keep_alive() const;
152 :
153 : void set_keep_alive(bool keep_alive);
154 :
155 : http_response::pointer_t send_request(http_request const & request);
156 :
157 : private:
158 : bool f_keep_alive = true;
159 : tcp_client_server::bio_client::pointer_t f_connection = tcp_client_server::bio_client::pointer_t();
160 : std::string f_host = std::string();
161 : int32_t f_port = -1;
162 : };
163 :
164 :
165 : } // namespace http_client_server
166 : // vim: ts=4 sw=4 et
|