http_request_handler.cpp
Go to the documentation of this file.
2 
5 
6 #include <boost/bind.hpp>
7 #include <boost/enable_shared_from_this.hpp>
8 #include <boost/noncopyable.hpp>
9 #include <boost/regex.hpp>
10 #include <boost/shared_ptr.hpp>
11 
12 #if defined(_MSC_VER)
13 # include <BaseTsd.h>
14 using ssize_t = SSIZE_T;
15 #endif
16 
17 namespace async_web_server_cpp
18 {
19 
21  HttpServerRequestHandler default_handler)
22  : default_handler_(default_handler)
23 {
24 }
25 
27 {
28 public:
29  explicit PathMatcher(const std::string& path_regex_string)
30  : path_regex_(boost::regex(path_regex_string))
31  {
32  }
33 
34  bool operator()(const HttpRequest& request)
35  {
36  return regex_match(request.path, path_regex_);
37  }
38 
39 private:
40  const boost::regex path_regex_;
41 };
42 
44  const std::string& path_regex, HttpServerRequestHandler handler)
45 {
46  addHandler(PathMatcher(path_regex), handler);
47 }
48 
51 {
52  handlers_.push_back(std::make_pair(predicate, handler));
53 }
54 
56  const HttpRequest& request, boost::shared_ptr<HttpConnection> connection,
57  const char* begin, const char* end)
58 {
59  for (auto& handler : handlers_)
60  {
61  if (handler.first(request))
62  {
63  if (handler.second(request, connection, begin, end))
64  return true;
65  }
66  }
67  return default_handler_(request, connection, begin, end);
68 }
69 
71 typedef boost::shared_ptr<BodyCollectingConnection> BodyCollectingConnectionPtr;
72 typedef boost::weak_ptr<BodyCollectingConnection>
75  : public boost::enable_shared_from_this<BodyCollectingConnection>,
76  private boost::noncopyable
77 {
78 public:
80  const HttpRequest& request,
81  boost::shared_ptr<HttpConnection> connection)
82  : handler_(handler), request_(request), connection_(connection),
83  received_length_(0)
84  {
85  std::string length_str =
86  request_.get_header_value_or_default("Content-Length", "");
87  try
88  {
89  length_ = boost::lexical_cast<ssize_t>(length_str);
90  }
91  catch (const boost::bad_lexical_cast&)
92  {
93  length_ = -1; // indicate error
94  }
95  }
96 
97  static void static_handle_read(BodyCollectingConnectionPtr _this,
98  const char* begin, const char* end)
99  {
100  _this->handle_read(begin, end);
101  }
102  void handle_read(const char* begin, const char* end)
103  {
104  if (length_ < 0)
105  {
107  connection_->write("No Content-Length header");
108  return;
109  }
110  std::string chunk(begin, end - begin);
111  body_stream_ << chunk;
112  received_length_ += chunk.length();
113  if (received_length_ >= static_cast<size_t>(length_))
114  {
115  handler_(request_, connection_,
116  body_stream_.str().substr(0, length_));
117  }
118  else
119  {
120  connection_->async_read(
122  shared_from_this(), _1, _2));
123  }
124  }
125 
126 private:
129  boost::shared_ptr<HttpConnection> connection_;
130  std::stringstream body_stream_;
131  ssize_t length_;
133 };
134 
136  : handler_(handler)
137 {
138 }
139 
141  const HttpRequest& request, boost::shared_ptr<HttpConnection> connection,
142  const char* begin, const char* end)
143 {
144  BodyCollectingConnectionPtr collecting_connection(
145  new BodyCollectingConnection(handler_, request, connection));
146  collecting_connection->handle_read(begin, end);
147  return true;
148 }
149 
150 } // namespace async_web_server_cpp
void addHandler(HandlerPredicate predicate, HttpServerRequestHandler handler)
void handle_read(const char *begin, const char *end)
boost::function< bool(const HttpRequest &)> HandlerPredicate
bool operator()(const HttpRequest &request, boost::shared_ptr< HttpConnection > connection, const char *begin, const char *end)
static ReplyBuilder builder(status_type status)
Definition: http_reply.cpp:447
boost::shared_ptr< BodyCollectingConnection > BodyCollectingConnectionPtr
boost::function< void(const HttpRequest &, boost::shared_ptr< HttpConnection >, const std::string &body)> Handler
boost::weak_ptr< BodyCollectingConnection > BodyCollectingConnectionWeakPtr
bool operator()(const HttpRequest &request, boost::shared_ptr< HttpConnection > connection, const char *begin, const char *end)
static void static_handle_read(BodyCollectingConnectionPtr _this, const char *begin, const char *end)
void write(HttpConnectionPtr connection)
Definition: http_reply.cpp:475
std::vector< std::pair< HandlerPredicate, HttpServerRequestHandler > > handlers_
HttpRequestHandlerGroup(HttpServerRequestHandler default_handler)
boost::function< bool(const HttpRequest &, boost::shared_ptr< HttpConnection >, const char *begin, const char *end)> HttpServerRequestHandler
boost::shared_ptr< HttpConnection > connection_
bool operator()(const HttpRequest &request)
PathMatcher(const std::string &path_regex_string)
BodyCollectingConnection(HttpRequestBodyCollector::Handler handler, const HttpRequest &request, boost::shared_ptr< HttpConnection > connection)
void addHandlerForPath(const std::string &path_regex, HttpServerRequestHandler handler)


async_web_server_cpp
Author(s): Mitchell Wills , Russel Toris
autogenerated on Mon Feb 28 2022 21:54:08