Skip to content
File

Blob: src/workerd/api/util.h

cpp93 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5#pragma once
6 
7#include <workerd/jsg/jsg.h>
8 
9#include <v8.h>
10 
11#include <kj/async-io.h>
12#include <kj/compat/url.h>
13#include <kj/string.h>
14 
15namespace workerd::api {
16 
17// =======================================================================================
18 
19#if _MSC_VER
20#define strcasecmp _stricmp
21#endif
22 
23// Case-insensitive comparator for use with std::set/map.
24struct CiLess {
25 bool operator()(kj::StringPtr lhs, kj::StringPtr rhs) const {
26 return strcasecmp(lhs.begin(), rhs.begin()) < 0;
27 }
28};
29 
30// Parse `rawText` as application/x-www-form-urlencoded name/value pairs and store in `query`. If
31// `skipLeadingQuestionMark` is true, any initial '?' will be ignored. Otherwise, it will be
32// interpreted as part of the first URL-encoded field.
33void parseQueryString(kj::Vector<kj::Url::QueryParam>& query,
34 kj::ArrayPtr<const char> rawText,
35 bool skipLeadingQuestionMark = false);
36// TODO(cleanup): Would be really nice to move this to kj-url.
37 
38// Given the value of a Content-Type header, returns the value of a single expected parameter.
39// For example:
40//
41// readContentTypeParameter("application/x-www-form-urlencoded; charset=\"foobar\"", "charset")
42//
43// would return "foobar" (without the quotes).
44//
45// Assumptions:
46// - `contentType` has a semi-colon followed by OWS before the parameters.
47// - If the wanted parameter uses quoted-string values, the correct
48// value may not be returned.
49kj::Maybe<kj::String> readContentTypeParameter(kj::StringPtr contentType, kj::StringPtr param);
50// TODO(cleanup): Replace this function with a full kj::MimeType parser.
51 
52// =======================================================================================
53 
54struct ErrorTranslation {
55 // A snippet of a KJ API exception description to be searched for.
56 kj::StringPtr kjDescription;
57 
58 // A cleaned up exception description suitable for exposing to JavaScript. There is no need to
59 // prefix it with jsg.TypeError.
60 kj::StringPtr jsDescription;
61};
62 
63// HACK: In some cases, KJ APIs throw exceptions with essential details that we want to expose to
64// the user, but also sensitive details or poor formatting which we'd prefer not to expose to the
65// user. While crude, we can string match to provide cleaned up exception messages. This O(n)
66// function helps you do that.
67kj::Maybe<kj::Exception> translateKjException(
68 const kj::Exception& exception, std::initializer_list<ErrorTranslation> translations);
69 
70// =======================================================================================
71 
72// Wrap the given stream in an adapter which translates kj::newTee()-specific exceptions into
73// JS-visible exceptions.
74kj::Own<kj::AsyncInputStream> newTeeErrorAdapter(kj::Own<kj::AsyncInputStream> inner);
75 
76// Redacts potential secret keys from a given URL using a couple heuristics:
77// - Any run of hex characters of 32 or more digits, ignoring potential "+-_" separators
78// - Any run of base64 characters of 21 or more digits, including at least
79// two each of digits, capital letters, and lowercase letters.
80// Such ids are replaced with the text "REDACTED".
81kj::String redactUrl(kj::StringPtr url);
82 
83// =======================================================================================
84 
85void maybeWarnIfNotText(jsg::Lock& js, kj::StringPtr str);
86 
87kj::String fastEncodeBase64Url(kj::ArrayPtr<const byte> bytes);
88kj::Array<char16_t> fastEncodeUtf16(kj::ArrayPtr<const char> bytes);
89 
90kj::String uriEncodeControlChars(kj::ArrayPtr<const byte> bytes);
91 
92} // namespace workerd::api