X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fm_httpd.cpp;h=f9e5bc0fdca282acb328208c51deef4780847e02;hb=09f35749aa7bf7dc20951d85bad60de3d219e4eb;hp=3a0d4f86102fffc121d29624c37344456b251ed3;hpb=77730fd5f09f8fc193205654c8bba84d34365670;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index 3a0d4f861..f9e5bc0fd 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -40,7 +40,9 @@ #endif // Fix warnings about shadowing in http_parser. -#pragma GCC diagnostic ignored "-Wshadow" +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wshadow" +#endif #include @@ -59,6 +61,7 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru friend ModuleHttpServer; http_parser parser; + http_parser_url url; std::string ip; std::string uri; HTTPHeaders headers; @@ -221,24 +224,12 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru AddToCull(); } - const char* Response(unsigned int response) - { - switch (response) - { -#define HTTP_STATUS_CASE(n, m, s) case n: return #s; - HTTP_STATUS_MAP(HTTP_STATUS_CASE) - default: - return "WTF"; - break; - } - } - void SendHTTPError(unsigned int response) { HTTPHeaders empty; std::string data = InspIRCd::Format( "Server error %u: %s
" - "Powered by InspIRCd", response, Response(response)); + "Powered by InspIRCd", response, http_status_str((http_status)response)); SendHeaders(data.length(), response, empty); WriteData(data); @@ -247,7 +238,7 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru void SendHeaders(unsigned long size, unsigned int response, HTTPHeaders &rheaders) { - WriteData(InspIRCd::Format("HTTP/%u.%u %u %s\r\n", parser.http_major ? parser.http_major : 1, parser.http_major ? parser.http_minor : 1, response, Response(response))); + WriteData(InspIRCd::Format("HTTP/%u.%u %u %s\r\n", parser.http_major ? parser.http_major : 1, parser.http_major ? parser.http_minor : 1, response, http_status_str((http_status)response))); rheaders.CreateHeader("Date", InspIRCd::TimeString(ServerInstance->Time(), "%a, %d %b %Y %H:%M:%S GMT", true)); rheaders.CreateHeader("Server", INSPIRCD_BRANCH); @@ -280,11 +271,13 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru { ModResult MOD_RESULT; std::string method = http_method_str(static_cast(parser.method)); - HTTPRequest acl(method, uri, &headers, this, ip, body); + HTTPRequestURI parsed; + ParseURI(uri, parsed); + HTTPRequest acl(method, parsed, &headers, this, ip, body); FIRST_MOD_RESULT_CUSTOM(*aclevprov, HTTPACLEventListener, OnHTTPACLCheck, MOD_RESULT, (acl)); if (MOD_RESULT != MOD_RES_DENY) { - HTTPRequest url(method, uri, &headers, this, ip, body); + HTTPRequest url(method, parsed, &headers, this, ip, body); FIRST_MOD_RESULT_CUSTOM(*reqevprov, HTTPRequestEventListener, OnHTTPRequest, MOD_RESULT, (url)); if (MOD_RESULT == MOD_RES_PASSTHRU) { @@ -309,6 +302,40 @@ class HttpServerSocket : public BufferedSocket, public Timer, public insp::intru Close(); ServerInstance->GlobalCulls.AddItem(this); } + + bool ParseURI(const std::string& uri, HTTPRequestURI& out) + { + http_parser_url_init(&url); + if (http_parser_parse_url(uri.c_str(), uri.size(), 0, &url) != 0) + return false; + + if (url.field_set & (1 << UF_PATH)) + out.path = uri.substr(url.field_data[UF_PATH].off, url.field_data[UF_PATH].len); + + if (url.field_set & (1 << UF_FRAGMENT)) + out.fragment = uri.substr(url.field_data[UF_FRAGMENT].off, url.field_data[UF_FRAGMENT].len); + + std::string param_str; + if (url.field_set & (1 << UF_QUERY)) + param_str = uri.substr(url.field_data[UF_QUERY].off, url.field_data[UF_QUERY].len); + + irc::sepstream param_stream(param_str, '&'); + std::string token; + std::string::size_type eq_pos; + while (param_stream.GetToken(token)) + { + eq_pos = token.find('='); + if (eq_pos == std::string::npos) + { + out.query_params.insert(std::make_pair(token, "")); + } + else + { + out.query_params.insert(std::make_pair(token.substr(0, eq_pos), token.substr(eq_pos + 1))); + } + } + return true; + } }; class HTTPdAPIImpl : public HTTPdAPIBase