Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- Namespace List
- Namespace Members

Classes | Typedefs | Functions
Botan::HTTP Namespace Reference

## Classes
struct | HTTP_Error
struct | Response

## Typedefs
typedef std::function< std::string(const std::string &, const std::string &)> | http_exch_fn

## Functions
Response | GET_sync (const std::string &url, size_t allowable_redirects)
Response | http_sync (http_exch_fn http_transact, const std::string &verb, const std::string &url, const std::string &content_type, const std::vector< uint8_t > &body, size_t allowable_redirects)
Response | http_sync (const std::string &verb, const std::string &url, const std::string &content_type, const std::vector< uint8_t > &body, size_t allowable_redirects)
std::ostream & | operator<< (std::ostream &o, const Response &resp)
Response | POST_sync (const std::string &url, const std::string &content_type, const std::vector< uint8_t > &body, size_t allowable_redirects)
std::string | url_encode (const std::string &in)

## Typedef Documentation

typedef std::function<std::string (const std::string&, const std::string&)> Botan::HTTP::http_exch_fn

Definition at line 68 of file http_util.h.

## Function Documentation

BOTAN_DLL Response Botan::HTTP::GET_sync | ( | const std::string & | url,
|  | size_t | allowable_redirects
| ) |  |

Definition at line 289 of file http_util.cpp.

References http_sync().

Referenced by http_sync().

290 {
291 return http_sync("GET", url, "", std::vector<uint8_t>(), allowable_redirects);
292 }
Botan::HTTP::http_sync
Response http_sync(const std::string &verb, const std::string &url, const std::string &content_type, const std::vector< uint8_t > &body, size_t allowable_redirects)
Definition: http_util.cpp:274

BOTAN_DLL Response Botan::HTTP::http_sync | ( | http_exch_fn | http_transact,
|  | const std::string & | verb,
|  | const std::string & | url,
|  | const std::string & | content_type,
|  | const std::vector< uint8_t > & | body,
|  | size_t | allowable_redirects
| ) |  |

Definition at line 165 of file http_util.cpp.

References GET_sync(), Botan::search_map(), Botan::ASN1::to_string(), and Botan::to_u32bit().

Referenced by GET_sync(), http_sync(), and POST_sync().

171 {
172 if(url.empty())
173 throw HTTP_Error("URL empty");
174
175 const auto protocol_host_sep = url.find("://");
176 if(protocol_host_sep == std::string::npos)
177 throw HTTP_Error("Invalid URL '" + url + "'");
178
179 const auto host_loc_sep = url.find('/', protocol_host_sep + 3);
180
181 std::string hostname, loc;
182
183 if(host_loc_sep == std::string::npos)
184 {
185 hostname = url.substr(protocol_host_sep + 3, std::string::npos);
186 loc = "/";
187 }
188 else
189 {
190 hostname = url.substr(protocol_host_sep + 3, host_loc_sep-protocol_host_sep-3);
191 loc = url.substr(host_loc_sep, std::string::npos);
192 }
193
194 std::ostringstream outbuf;
195
196 outbuf << verb << " " << loc << " HTTP/1.0\r\n";
197 outbuf << "Host: " << hostname << "\r\n";
198
199 if(verb == "GET")
200 {
201 outbuf << "Accept: */*\r\n";
202 outbuf << "Cache-Control: no-cache\r\n";
203 }
204 else if(verb == "POST")
205 outbuf << "Content-Length: " << body.size() << "\r\n";
206
207 if(!content_type.empty())
208 outbuf << "Content-Type: " << content_type << "\r\n";
209 outbuf << "Connection: close\r\n\r\n";
210 outbuf.write(reinterpret_cast<const char*>(body.data()), body.size());
211
212 std::istringstream io(http_transact(hostname, outbuf.str()));
213
214 std::string line1;
215 std::getline(io, line1);
216 if(!io || line1.empty())
217 throw HTTP_Error("No response");
218
219 std::stringstream response_stream(line1);
220 std::string http_version;
221 unsigned int status_code;
222 std::string status_message;
223
224 response_stream >> http_version >> status_code;
225
226 std::getline(response_stream, status_message);
227
228 if(!response_stream || http_version.substr(0,5) != "HTTP/")
229 throw HTTP_Error("Not an HTTP response");
230
231 std::map<std::string, std::string> headers;
232 std::string header_line;
233 while (std::getline(io, header_line) && header_line != "\r")
234 {
235 auto sep = header_line.find(": ");
236 if(sep == std::string::npos || sep > header_line.size() - 2)
237 throw HTTP_Error("Invalid HTTP header " + header_line);
238 const std::string key = header_line.substr(0, sep);
239
240 if(sep + 2 < header_line.size() - 1)
241 {
242 const std::string val = header_line.substr(sep + 2, (header_line.size() - 1) - (sep + 2));
243 headers[key] = val;
244 }
245 }
246
247 if(status_code == 301 && headers.count("Location"))
248 {
249 if(allowable_redirects == 0)
250 throw HTTP_Error("HTTP redirection count exceeded");
251 return GET_sync(headers["Location"], allowable_redirects - 1);
252 }
253
254 std::vector<uint8_t> resp_body;
255 std::vector<uint8_t> buf(4096);
256 while(io.good())
257 {
258 io.read(reinterpret_cast<char*>(buf.data()), buf.size());
259 resp_body.insert(resp_body.end(), buf.data(), &buf[io.gcount()]);
260 }
261
262 const std::string header_size = search_map(headers, std::string("Content-Length"));
263
264 if(!header_size.empty())
265 {
266 if(resp_body.size() != to_u32bit(header_size))
267 throw HTTP_Error("Content-Length disagreement, header says " +
268 header_size + " got " + std::to_string(resp_body.size()));
269 }
270
271 return Response(status_code, status_message, resp_body, headers);
272 }
Botan::to_u32bit
uint32_t to_u32bit(const std::string &str)
Definition: parsing.cpp:18
Botan::search_map
V search_map(const std::map< K, V > &mapping, const K &key, const V &null_result=V())
Definition: stl_util.h:52
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
Botan::HTTP::GET_sync
Response GET_sync(const std::string &url, size_t allowable_redirects)
Definition: http_util.cpp:289

BOTAN_DLL Response Botan::HTTP::http_sync | ( | const std::string & | verb,
|  | const std::string & | url,
|  | const std::string & | content_type,
|  | const std::vector< uint8_t > & | body,
|  | size_t | allowable_redirects
| ) |  |

Definition at line 274 of file http_util.cpp.

References http_sync().

279 {
280 return http_sync(
281 http_transact,
282 verb,
283 url,
284 content_type,
285 body,
286 allowable_redirects);
287 }
Botan::HTTP::http_sync
Response http_sync(const std::string &verb, const std::string &url, const std::string &content_type, const std::vector< uint8_t > &body, size_t allowable_redirects)
Definition: http_util.cpp:274

BOTAN_DLL std::ostream & Botan::HTTP::operator<< | ( | std::ostream & | o,
|  | const Response & | resp
| ) |  |

Definition at line 155 of file http_util.cpp.

References Botan::HTTP::Response::body(), Botan::HTTP::Response::headers(), Botan::HTTP::Response::status_code(), Botan::HTTP::Response::status_message(), and Botan::ASN1::to_string().

156 {
157 o << "HTTP " << resp.status_code() << " " << resp.status_message() << "\n";
158 for(auto h : resp.headers())
159 o << "Header '" << h.first << "' = '" << h.second << "'\n";
160 o << "Body " << std::to_string(resp.body().size()) << " bytes:\n";
161 o.write(reinterpret_cast<const char*>(&resp.body()[0]), resp.body().size());
162 return o;
163 }
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47

BOTAN_DLL Response Botan::HTTP::POST_sync | ( | const std::string & | url,
|  | const std::string & | content_type,
|  | const std::vector< uint8_t > & | body,
|  | size_t | allowable_redirects
| ) |  |

Definition at line 294 of file http_util.cpp.

References http_sync().

298 {
299 return http_sync("POST", url, content_type, body, allowable_redirects);
300 }
Botan::HTTP::http_sync
Response http_sync(const std::string &verb, const std::string &url, const std::string &content_type, const std::vector< uint8_t > &body, size_t allowable_redirects)
Definition: http_util.cpp:274

BOTAN_DLL std::string Botan::HTTP::url_encode | ( | const std::string & | in | ) |

Definition at line 134 of file http_util.cpp.

135 {
136 std::ostringstream out;
137
138 for(auto c : in)
139 {
140 if(c >= 'A' && c <= 'Z')
141 out << c;
142 else if(c >= 'a' && c <= 'z')
143 out << c;
144 else if(c >= '0' && c <= '9')
145 out << c;
146 else if(c == '-' || c == '_' || c == '.' || c == '~')
147 out << c;
148 else
149 out << '%' << hex_encode(reinterpret_cast<uint8_t*>(&c), 1);
150 }
151
152 return out.str();
153 }