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