plugins/wasm-cpp/common/http_util.h (76 lines of code) (raw):

/* * Copyright (c) 2022 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <array> #include <chrono> #include <map> #include <unordered_set> #include "absl/strings/string_view.h" #include "absl/time/time.h" #ifndef NULL_PLUGIN #include "proxy_wasm_intrinsics.h" #else #include "include/proxy-wasm/null_plugin.h" using namespace proxy_wasm::null_plugin; using proxy_wasm::FilterDataStatus; using proxy_wasm::FilterHeadersStatus; #endif namespace Wasm::Common::Http { using QueryParams = std::map<std::string, std::string>; using SystemTime = std::chrono::time_point<std::chrono::system_clock>; namespace Status { constexpr int OK = 200; constexpr int InternalServerError = 500; constexpr int Unauthorized = 401; } // namespace Status namespace Header { constexpr std::string_view Scheme(":scheme"); constexpr std::string_view Method(":method"); constexpr std::string_view Host(":authority"); constexpr std::string_view Path(":path"); constexpr std::string_view EnvoyOriginalPath("x-envoy-original-path"); constexpr std::string_view Accept("accept"); constexpr std::string_view ContentDisposition("content-disposition"); constexpr std::string_view ContentMD5("content-md5"); constexpr std::string_view ContentType("content-type"); constexpr std::string_view ContentLength("content-length"); constexpr std::string_view TransferEncoding("transfer-encoding"); constexpr std::string_view UserAgent("user-agent"); constexpr std::string_view Date("date"); constexpr std::string_view Cookie("cookie"); constexpr std::string_view StrictTransportSecurity("strict-transport-security"); } // namespace Header namespace ContentTypeValues { constexpr std::string_view Grpc{"application/grpc"}; constexpr std::string_view Json{"application/json"}; constexpr std::string_view MultipartFormData{"multipart/form-data"}; } // namespace ContentTypeValues class PercentEncoding { public: /** * Encodes string view to its percent encoded representation. Non-visible * ASCII is always escaped, in addition to a given list of reserved chars. * * @param value supplies string to be encoded. * @param reserved_chars list of reserved chars to escape. By default the * escaped chars in * https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#responses * are used. * @return std::string percent-encoded string. */ static std::string encode(absl::string_view value, absl::string_view reserved_chars = "%"); /** * Decodes string view from its percent encoded representation. * @param encoded supplies string to be decoded. * @return std::string decoded string * https://tools.ietf.org/html/rfc3986#section-2.1. */ static std::string decode(absl::string_view value); private: // Encodes string view to its percent encoded representation, with start // index. static std::string encode(absl::string_view value, size_t index, const std::unordered_set<char>& reserved_char_set); }; SystemTime httpTime(std::string_view date); inline bool timePointValid(SystemTime time_point) { return std::chrono::duration_cast<std::chrono::milliseconds>( time_point.time_since_epoch()) .count() != 0; } std::string_view stripPortFromHost(std::string_view request_host); /** * Parse a URL into query parameters. * @param url supplies the url to parse. * @return QueryParams the parsed parameters, if any. */ QueryParams parseQueryString(absl::string_view url); /** * Parse a URL into query parameters. * @param url supplies the url to parse. * @return QueryParams the parsed and percent-decoded parameters, if any. */ QueryParams parseAndDecodeQueryString(absl::string_view url); /** * Parse a a request body into query parameters. * @param body supplies the body to parse. * @return QueryParams the parsed parameters, if any. */ QueryParams parseFromBody(absl::string_view body); /** * Parse query parameters from a URL or body. * @param data supplies the data to parse. * @param start supplies the offset within the data. * @param decode_params supplies the flag whether to percent-decode the parsed * parameters (both name and value). Set to false to keep the parameters * encoded. * @return QueryParams the parsed parameters, if any. */ QueryParams parseParameters(absl::string_view data, size_t start, bool decode_params); std::vector<std::string> getAllOfHeader(std::string_view key); std::unordered_map<std::string, std::string> parseCookies( const std::function<bool(std::string_view)>& key_filter); std::string buildOriginalUri(std::optional<uint32_t> max_path_length); void extractHostPathFromUri(const absl::string_view& uri, absl::string_view& host, absl::string_view& path); void extractPathWithoutArgsFromUri(const std::string_view& uri, std::string_view& path_without_args); bool hasRequestBody(); } // namespace Wasm::Common::Http