+ if (!messagecomplete)
+ {
+ AddToCull();
+ return false;
+ }
+
+ return true;
+ }
+
+ template<int (HttpServerSocket::*f)()>
+ static int Callback(http_parser* p)
+ {
+ HttpServerSocket* sock = static_cast<HttpServerSocket*>(p->data);
+ return (sock->*f)();
+ }
+
+ template<int (HttpServerSocket::*f)(const char*, size_t)>
+ static int DataCallback(http_parser* p, const char* buf, size_t len)
+ {
+ HttpServerSocket* sock = static_cast<HttpServerSocket*>(p->data);
+ return (sock->*f)(buf, len);
+ }
+
+ static void ConfigureParser()
+ {
+ http_parser_settings_init(&parser_settings);
+ parser_settings.on_message_begin = Callback<&HttpServerSocket::OnMessageBegin>;
+ parser_settings.on_url = DataCallback<&HttpServerSocket::OnUrl>;
+ parser_settings.on_header_field = DataCallback<&HttpServerSocket::OnHeaderField>;
+ parser_settings.on_body = DataCallback<&HttpServerSocket::OnBody>;
+ parser_settings.on_message_complete = Callback<&HttpServerSocket::OnMessageComplete>;
+ }
+
+ int OnMessageBegin()
+ {
+ uri.clear();
+ header_state = HEADER_NONE;
+ body.clear();
+ total_buffers = 0;
+ return 0;
+ }
+
+ bool AcceptData(size_t len)
+ {
+ total_buffers += len;
+ return total_buffers < 8192;
+ }
+
+ int OnUrl(const char* buf, size_t len)
+ {
+ if (!AcceptData(len))
+ {
+ status_code = HTTP_STATUS_URI_TOO_LONG;
+ return -1;
+ }
+ uri.append(buf, len);
+ return 0;
+ }
+
+ enum { HEADER_NONE, HEADER_FIELD, HEADER_VALUE } header_state;
+ std::string header_field;
+ std::string header_value;
+
+ void OnHeaderComplete()
+ {
+ headers.SetHeader(header_field, header_value);
+ header_field.clear();
+ header_value.clear();
+ }
+
+ int OnHeaderField(const char* buf, size_t len)
+ {
+ if (header_state == HEADER_VALUE)
+ OnHeaderComplete();
+ header_state = HEADER_FIELD;
+ if (!AcceptData(len))
+ {
+ status_code = HTTP_STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE;
+ return -1;
+ }
+ header_field.append(buf, len);
+ return 0;
+ }
+
+ 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()
+ {
+ messagecomplete = true;
+ ServeData();
+ return 0;