11#include <promeki/config.h>
12#if PROMEKI_ENABLE_HTTP
25PROMEKI_NAMESPACE_BEGIN
72class HttpConnection :
public ObjectBase {
73 PROMEKI_OBJECT(HttpConnection, ObjectBase)
76 using List = ::promeki::List<HttpConnection *>;
79 static constexpr unsigned int DefaultIdleTimeoutMs = 60'000;
82 static constexpr int64_t DefaultMaxBodyBytes = 64 * 1024 * 1024;
93 using RequestHandler = Function<void(HttpRequest &request, HttpResponse &response)>;
106 HttpConnection(TcpSocket *socket, ObjectBase *parent =
nullptr);
122 void setNeedsServerHandshake();
125 ~HttpConnection()
override;
136 void setRequestHandler(RequestHandler handler);
156 bool isOpen()
const {
return _state != State::Closed; }
159 String peerAddress()
const;
166 void setIdleTimeoutMs(
unsigned int ms) { _idleTimeoutMs = ms; }
174 void setMaxBodyBytes(int64_t bytes) { _maxBodyBytes = bytes; }
187 Error postResponse(HttpResponse response);
190 PROMEKI_SIGNAL(requestReceived, HttpRequest);
193 PROMEKI_SIGNAL(responseSent, HttpRequest, HttpResponse);
196 PROMEKI_SIGNAL(closed);
199 PROMEKI_SIGNAL(errorOccurred, Error);
216 UniquePtr<Impl> _impl;
218 TcpSocket *_socket =
nullptr;
219 EventLoop *_loop =
nullptr;
222 State _state = State::Reading;
224 RequestHandler _handler;
227 size_t _writeOffset = 0;
229 HttpRequest _pendingRequest;
230 HttpRequest _lastRequest;
231 IODevice::Shared _streamSource;
232 int64_t _streamRemaining = -1;
233 bool _streamChunked =
false;
234 bool _keepAlive =
true;
241 size_t _streamReadyReadSlotId = 0;
242 bool _streamReadyReadConnected =
false;
243 bool _streamParked =
false;
249 HttpResponse::UpgradeHook _pendingUpgradeHook;
251 unsigned int _idleTimeoutMs = DefaultIdleTimeoutMs;
252 int64_t _maxBodyBytes = DefaultMaxBodyBytes;
253 int64_t _bodyBytesSoFar = 0;
254 bool _needsServerHandshake =
false;
263 bool _hdrFieldComplete =
false;
264 bool _hdrValueComplete =
false;
267 void onIoReady(
int fd, uint32_t events);
268 void onIdleTimeout();
271 void deliverRequest();
272 void enqueueResponse(HttpResponse response);
273 void scheduleStreamPump();
274 void completeProtocolUpgrade();
281 void attachStreamReadyRead();
282 void detachStreamReadyRead();
283 void onStreamReadyRead();
285 void flushPendingHeaderPair();
286 void resetForNextRequest();
289 static int cbMessageBegin(
void *parser);
290 static int cbUrl(
void *parser,
const char *at,
size_t len);
291 static int cbHeaderField(
void *parser,
const char *at,
size_t len);
292 static int cbHeaderValue(
void *parser,
const char *at,
size_t len);
293 static int cbHeadersComplete(
void *parser);
294 static int cbBody(
void *parser,
const char *at,
size_t len);
295 static int cbMessageComplete(
void *parser);