staticlib_pion  2.0.2
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros
http_request.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015, alex at staticlibs.net
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // ---------------------------------------------------------------------
18 // pion: a Boost C++ framework for building lightweight HTTP interfaces
19 // ---------------------------------------------------------------------
20 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)
21 //
22 // Distributed under the Boost Software License, Version 1.0.
23 // See http://www.boost.org/LICENSE_1_0.txt
24 //
25 
26 #ifndef STATICLIB_PION_HTTP_REQUEST_HPP
27 #define STATICLIB_PION_HTTP_REQUEST_HPP
28 
29 #include <functional>
30 #include <string>
31 
32 #include "staticlib/config.hpp"
33 
36 
37 namespace staticlib {
38 namespace pion {
39 
43 class http_request : public http_message {
44 
48  std::string m_method;
49 
53  std::string m_resource;
54 
58  std::string m_original_resource;
59 
63  std::string m_query_string;
64 
68  std::unordered_multimap<std::string, std::string, algorithm::ihash, algorithm::iequal_to> m_query_params;
69 
73  http_parser::payload_handler_type m_payload_handler;
74 
78  http_parser* m_request_reader;
79 
80 public:
81 
86  m_method(REQUEST_METHOD_GET) { }
87 
91  http_request(const http_request&) = delete;
92 
96  http_request& operator=(const http_request&) = delete;
97 
101  virtual ~http_request() STATICLIB_NOEXCEPT { }
102 
106  virtual void clear() {
108  m_method.erase();
109  m_resource.erase();
110  m_original_resource.erase();
111  m_query_string.erase();
112  m_query_params.clear();
113  }
114 
120  virtual bool is_content_length_implied() const {
121  return false;
122  }
123 
129  const std::string& get_method() const {
130  return m_method;
131  }
132 
138  const std::string& get_resource() const {
139  return m_resource;
140  }
141 
147  const std::string& get_original_resource() const {
148  return m_original_resource;
149  }
150 
156  const std::string& get_query_string() const {
157  return m_query_string;
158  }
159 
166  const std::string& get_query(const std::string& key) const {
167  return get_value(m_query_params, key);
168  }
169 
175  std::unordered_multimap<std::string, std::string, algorithm::ihash, algorithm::iequal_to>& get_queries() {
176  return m_query_params;
177  }
178 
185  bool has_query(const std::string& key) const {
186  return (m_query_params.find(key) != m_query_params.end());
187  }
188 
194  void set_method(const std::string& str) {
195  m_method = str;
197  }
198 
202  void set_resource(const std::string& str) {
203  m_resource = m_original_resource = str;
205  }
206 
212  void change_resource(const std::string& str) {
213  m_resource = str;
214  }
215 
221  void set_query_string(const std::string& str) {
222  m_query_string = str;
224  }
225 
232  void add_query(const std::string& key, const std::string& value) {
233  m_query_params.insert(std::make_pair(key, value));
234  }
235 
242  void change_query(const std::string& key, const std::string& value) {
243  change_value(m_query_params, key, value);
244  }
245 
251  void delete_query(const std::string& key) {
252  delete_value(m_query_params, key);
253  }
254 
259  set_query_string(make_query_string(m_query_params));
260  }
261 
266  std::string post_content(make_query_string(m_query_params));
267  set_content_length(post_content.size());
268  char *ptr = create_content_buffer(); // null-terminates buffer
269  if (!post_content.empty()) {
270  memcpy(ptr, post_content.c_str(), post_content.size());
271  }
274  }
275 
281  void set_content(const std::string &value) {
282  set_content_length(value.size());
283  char *ptr = create_content_buffer();
284  if (!value.empty()) {
285  memcpy(ptr, value.c_str(), value.size());
286  }
287  }
288 
293  void set_content(const char* value, size_t size){
294  if (nullptr == value || 0 == size) return;
295  set_content_length(size);
296  char *ptr = create_content_buffer();
297  std::memcpy(ptr, value, size);
298  }
299 
306  void set_payload_handler(http_parser::payload_handler_type ph) {
307  m_payload_handler = std::move(ph);
308  // this should be done only once during request processing
309  // and we won't restrict request_reader lifecycle after
310  // payload is processed, so we drop the pointer to it
311  if (m_request_reader) {
312  // request will always outlive reader
313  m_request_reader->set_payload_handler(m_payload_handler);
314  m_request_reader = nullptr;
315  }
316  }
317 
323  template<typename T>
325  return m_payload_handler.target<T>();
326  }
327 
333  http_parser::payload_handler_type& get_payload_handler_wrapper() {
334  return m_payload_handler;
335  }
336 
341  m_request_reader = rr;
342  }
343 
344 protected:
345 
349  virtual void update_first_line() const {
350  // start out with the request method
351  m_first_line = m_method;
352  m_first_line += ' ';
353  // append the resource requested
354  m_first_line += m_resource;
355  if (!m_query_string.empty()) {
356  // append query string if not empty
357  m_first_line += '?';
358  m_first_line += m_query_string;
359  }
360  m_first_line += ' ';
361  // append HTTP version
363  }
364 
368  virtual void append_cookie_headers() {
369  for (std::unordered_multimap<std::string, std::string, algorithm::ihash, algorithm::iequal_to>::const_iterator i = get_cookies().begin(); i != get_cookies().end(); ++i) {
370  std::string cookie_header;
371  cookie_header = i->first;
372  cookie_header += COOKIE_NAME_VALUE_DELIMITER;
373  cookie_header += i->second;
374  add_header(HEADER_COOKIE, cookie_header);
375  }
376  }
377 
378 };
379 
383 using http_request_ptr = std::unique_ptr<http_request>;
384 
385 
386 } // namespace
387 }
388 
389 #endif // STATICLIB_PION_HTTP_REQUEST_HPP