Bredbandskollen CLI  1.2
Asynchronous network task engine
httpserverconnection.h
1 // Copyright (c) 2018 IIS (The Internet Foundation in Sweden)
2 // Written by Göran Andersson <initgoran@gmail.com>
3 
4 #pragma once
5 
6 #include <map>
7 
8 #include "httpconnection.h"
9 
10 class WebServerTask;
11 
12 enum class HttpState {
13  CLOSE,
14  WAITING_FOR_REQUEST, SENDING_RESPONSE,
15  READING_POST_DATA, WEBSOCKET
16 };
17 
29 public:
30  HttpServerConnection(const std::string &label, WebServerTask *task, int fd,
31  const char *ip, uint16_t port);
32  virtual ~HttpServerConnection() override;
33  PollState connected() final {
34  return PollState::READ;
35  }
36  PollState readData(char *buf, size_t len) final;
37  //PollState unexpectedData(char *, size_t ) override;
38  PollState writeData() override;
39 
41  bool hasQueryPar(const std::string &name) const;
42 
43  void eraseQueryPar(const std::string &name) {
44  current_query_pars.erase(name);
45  }
46 
50  std::string getQueryVal(const std::string &name) const;
51 
52  const std::multimap<std::string, std::string> &currentQueryPars() const {
53  return current_query_pars;
54  }
55 
56  std::map<std::string, std::string> currentRequestCookies() const;
57 
59  std::string cookieVal(const std::string &name) const;
60 
65  std::string getHeaderVal(const std::string &name) const;
66 
67  typedef std::multimap<std::string, std::string>::const_iterator Hit;
68  std::pair<Hit, Hit> getHeaderVals(const std::string &name) const {
69  return http_request_headers.equal_range(name);
70  }
71 
73  size_t sendHttpResponse(const std::string &headers,
74  const std::string &mime,
75  const std::string &contents);
76 
78  size_t sendHttpResponseHeader(const std::string &headers,
79  const std::string &mime,
80  size_t content_length);
81 
84  size_t sendChunkedResponseHeader(const std::string &headers,
85  const std::string &mime);
86 
88  size_t sendChunk(const std::string &content);
89 
91  size_t chunkedResponseComplete();
92 
93  bool sendingChunkedResponse() const {
94  return sending_chunked_response;
95  }
96 
97 #ifdef USE_WEBROOT
103  bool prepareFileResponse(const std::string &url);
104 
105  HttpState sendHttpFileResponse(const std::string &headers,
106  const std::string &mime);
107 
108 #endif
109 
110  const std::string &currentUri() const {
111  return current_uri;
112  }
113 
114  const std::string currentFullUrl() const {
115  if (current_query_string.empty())
116  return current_uri;
117  return current_uri + '?' + current_query_string;
118  }
119 
120  const std::string &currentQueryString() const {
121  return current_query_string;
122  }
123 
125  size_t remainingPostData() const {
126  return remaining_post_data;
127  }
128 
135  void bufferPostData() {
136  buffer_post_data = true;
137  }
138 
141  notify_after_ws_handshake = true;
142  }
143 
146  void setOwner(Task *new_owner) override;
147 
149  std::string currentRequest() const {
150  return current_request;
151  }
152 private:
153  // A weak pointer to the owner task. Dangerous. However, the EventLoop will
154  // kill all connections (i.e. us) before killing the owner task.
155  WebServerTask *owner_task;
156  HttpState state = HttpState::WAITING_FOR_REQUEST;
157  std::string current_request;
158  std::multimap<std::string, std::string> http_request_headers;
159  std::string current_method, current_uri;
160  std::string current_query_string;
161  std::multimap<std::string, std::string> current_query_pars;
162  static void get_all_parameters(const char *qpos,
163  std::multimap<std::string, std::string> &pars);
164 
165  // Will be set when sending a response with known Content-Length:
166  size_t remaining_bytes;
167 
168 #ifdef USE_WEBROOT
169  // Will be set if sending_static_file is true:
170  int static_file_fd;
171 
172  // Will be true when sending a static file:
173  bool sending_static_file = false;
174 #endif
175 
176  // Will be true when sending chunked response:
177  bool sending_chunked_response = false;
178 
179  // If set to true, the owner will be notified after handshake:
180  bool notify_after_ws_handshake = false;
181 
182  // Will be set in state READING_POST_DATA:
183  bool buffer_post_data;
184  size_t remaining_post_data;
185 
186  bool parse_request();
187  PollState got_post_data(const char *buf, size_t len);
188  PollState check_buffer();
189 };
Definition: httpconnection.h:11
HTTP/1.1 server protocol.
Definition: httpserverconnection.h:28
size_t remainingPostData() const
Number of bytes left of the current HTTP POST.
Definition: httpserverconnection.h:125
void notifyWsHandshake()
Call this if the owner is to be notified after handshake:
Definition: httpserverconnection.h:140
bool hasQueryPar(const std::string &name) const
Return true if query string in current request has parameter name:
Definition: httpserverconnection.cpp:407
size_t sendChunkedResponseHeader(const std::string &headers, const std::string &mime)
Definition: httpserverconnection.cpp:374
PollState readData(char *buf, size_t len) final
Callback, called when data has arrived; len > 0.
Definition: httpserverconnection.cpp:155
std::string getHeaderVal(const std::string &name) const
Definition: httpserverconnection.cpp:418
void setOwner(Task *new_owner) override
Definition: httpserverconnection.cpp:47
std::string getQueryVal(const std::string &name) const
Definition: httpserverconnection.cpp:411
size_t sendHttpResponse(const std::string &headers, const std::string &mime, const std::string &contents)
Async send response. Return length of what's to be sent.
Definition: httpserverconnection.cpp:349
PollState connected() final
Will be called when the connection is established.
Definition: httpserverconnection.h:33
size_t chunkedResponseComplete()
To notify that all chunks have been sent.
Definition: httpserverconnection.cpp:396
size_t sendChunk(const std::string &content)
Send chunk. May only be used if we sent chunked headers.
Definition: httpserverconnection.cpp:385
size_t sendHttpResponseHeader(const std::string &headers, const std::string &mime, size_t content_length)
Async send response headers. Return length of what's to be sent:
Definition: httpserverconnection.cpp:361
std::string cookieVal(const std::string &name) const
Return value of cookie if it exists, otherwise empty string.
Definition: httpserverconnection.cpp:445
std::string currentRequest() const
Current request (first line and headers) in raw form.
Definition: httpserverconnection.h:149
PollState writeData() override
Callback, called when socket is writable.
Definition: httpserverconnection.cpp:125
void bufferPostData()
Definition: httpserverconnection.h:135
std::string label() const
Return the object's log label.
Definition: logger.h:251
uint16_t port() const
Return port number to which the socket is supposed to connect.
Definition: socket.h:37
The purpose of a task is to manage socket connections, and/or to execute timers.
Definition: task.h:39
API for HTTP servers.
Definition: webservertask.h:16
PollState
Definition: pollstate.h:11