See libevent http.c evhttp_parse_query_impl() and https://www.rfc-editor.org/rfc/rfc3986#section-3.4
| 640 | // See libevent http.c evhttp_parse_query_impl() |
| 641 | // and https://www.rfc-editor.org/rfc/rfc3986#section-3.4 |
| 642 | std::optional<std::string> GetQueryParameterFromUri(const std::string_view uri, const std::string_view key) |
| 643 | { |
| 644 | // find query in URI |
| 645 | size_t start = uri.find('?'); |
| 646 | if (start == std::string::npos) return std::nullopt; |
| 647 | size_t end = uri.find('#', start); |
| 648 | if (end == std::string::npos) { |
| 649 | end = uri.length(); |
| 650 | } |
| 651 | const std::string_view query{uri.data() + start + 1, end - start - 1}; |
| 652 | // find requested parameter in query |
| 653 | const std::vector<std::string_view> params{Split<std::string_view>(query, "&")}; |
| 654 | for (const std::string_view& param : params) { |
| 655 | size_t delim = param.find('='); |
| 656 | if (key == UrlDecode(param.substr(0, delim))) { |
| 657 | if (delim == std::string::npos) { |
| 658 | return ""; |
| 659 | } else { |
| 660 | return std::string(UrlDecode(param.substr(delim + 1))); |
| 661 | } |
| 662 | } |
| 663 | } |
| 664 | return std::nullopt; |
| 665 | } |
| 666 | |
| 667 | std::pair<bool, std::string> HTTPRequest::GetHeader(const std::string_view hdr) const |
| 668 | { |