+ int OnHeaderValue(const char* buf, size_t len)
+ {
+ header_state = HEADER_VALUE;
+ if (!AcceptData(len))
+ {
+ status_code = HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE;
+ return -1;
+ }
+ header_value.append(buf, len);
+ return 0;
+ }
+
+ int OnHeadersComplete()
+ {
+ if (header_state != HEADER_NONE)
+ OnHeaderComplete();
+ return 0;
+ }
+
+ int OnBody(const char* buf, size_t len)
+ {
+ if (!AcceptData(len))
+ {
+ status_code = HTTP_STATUS_PAYLOAD_TOO_LARGE;
+ return -1;
+ }
+ body.append(buf, len);
+ return 0;
+ }
+
+ int OnMessageComplete()
+ {
+ ServeData();
+ return 0;
+ }
+
+ public:
+ HttpServerSocket(int newfd, const std::string& IP, ListenSocket* via, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server, unsigned int timeoutsec)
+ : BufferedSocket(newfd)
+ , Timer(timeoutsec)
+ , ip(IP)
+ , status_code(0)
+ , waitingcull(false)
+ {
+ if ((!via->iohookprovs.empty()) && (via->iohookprovs.back()))
+ {
+ via->iohookprovs.back()->OnAccept(this, client, server);
+ // IOHook may have errored
+ if (!getError().empty())
+ {
+ AddToCull();
+ return;
+ }
+ }
+
+ parser.data = this;
+ http_parser_init(&parser, HTTP_REQUEST);
+ ServerInstance->Timers.AddTimer(this);
+ }
+
+ ~HttpServerSocket()
+ {
+ sockets.erase(this);
+ }
+
+ void OnError(BufferedSocketError) CXX11_OVERRIDE
+ {
+ AddToCull();
+ }
+
+ void SendHTTPError(unsigned int response)