Skip to content

Commit 92992ce

Browse files
committed
Initial release of the proxy-wasm C++ host implementation.
Signed-off-by: Piotr Sikora <[email protected]> Signed-off-by: John Plevyak <[email protected]>
1 parent 6bb50d0 commit 92992ce

30 files changed

+4159
-1314
lines changed

BUILD

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
licenses(["notice"]) # Apache 2
2+
3+
package(default_visibility = ["//visibility:public"])
4+
5+
cc_library(
6+
name = "include",
7+
hdrs = [
8+
"include/proxy-wasm/context.h",
9+
"include/proxy-wasm/compat.h",
10+
"include/proxy-wasm/exports.h",
11+
"include/proxy-wasm/null.h",
12+
"include/proxy-wasm/word.h",
13+
"include/proxy-wasm/v8.h",
14+
"include/proxy-wasm/wasm.h",
15+
"include/proxy-wasm/wasm_vm.h",
16+
],
17+
copts = ["-std=c++14"],
18+
deps = [
19+
"@proxy_wasm_cpp_sdk//:common_lib",
20+
],
21+
)
22+
23+
cc_library(
24+
name = "lib",
25+
srcs = [
26+
"src/exports.cc",
27+
"src/foreign.cc",
28+
"src/context.cc",
29+
"src/wasm.cc",
30+
"src/base64.cc",
31+
"src/base64.h",
32+
"src/v8/v8.cc",
33+
"src/null/null.cc",
34+
"src/null/null_plugin.cc",
35+
"src/null/null_plugin.h",
36+
"src/null/null_vm.cc",
37+
"src/null/null_vm.h",
38+
"src/null/null_vm_plugin.h",
39+
"src/null/wasm_api_impl.h",
40+
],
41+
copts = ["-std=c++14"],
42+
deps = [
43+
":include",
44+
"@proxy_wasm_cpp_sdk//:api_lib",
45+
"@proxy_wasm_cpp_sdk//:common_lib",
46+
"@envoy//external:abseil_strings",
47+
"@envoy//external:abseil_optional",
48+
"@envoy//external:zlib",
49+
"@boringssl//:ssl",
50+
"@envoy//external:wee8",
51+
"@envoy//external:protobuf",
52+
],
53+
)

WORKSPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
workspace(name = "proxy_wasm_cpp_host")

include/proxy-wasm/compat.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
// #ifdef PROXY_WASM_USE_ABSL
18+
#ifndef __cpp_lib_optional
19+
#include "absl/types/optional.h"
20+
#include "absl/strings/string_view.h"
21+
#else
22+
#include <optional>
23+
#include <string_view>
24+
#endif
25+
26+
namespace proxy_wasm {
27+
// #ifdef PROXY_WASM_USE_ABSL
28+
#ifndef __cpp_lib_optional
29+
using string_view = absl::string_view;
30+
template <typename T> using optional = absl::optional<T>;
31+
#else
32+
using string_view = std::string_view;
33+
template <typename T> using optional = std::optional<T>;
34+
#endif
35+
} // namespace proxy_wasm

include/proxy-wasm/context.h

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
// Copyright 2016-2019 Envoy Project Authors
2+
// Copyright 2020 Google LLC
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
#pragma once
17+
18+
#include "include/proxy-wasm/compat.h"
19+
20+
#include <time.h>
21+
#include <atomic>
22+
#include <iostream>
23+
#include <map>
24+
#include <memory>
25+
#include <vector>
26+
27+
namespace proxy_wasm {
28+
29+
#include "proxy_wasm_common.h"
30+
#include "proxy_wasm_enums.h"
31+
32+
class WasmBase;
33+
class WasmVm;
34+
35+
using Pairs = std::vector<std::pair<string_view, string_view>>;
36+
using PairsWithStringValues = std::vector<std::pair<string_view, std::string>>;
37+
using CallOnThreadFunction = std::function<void(std::function<void()>)>;
38+
39+
struct BufferInterface {
40+
virtual ~BufferInterface() {}
41+
virtual size_t size() const = 0;
42+
// Returns true on success.
43+
virtual bool copyTo(WasmBase *wasm, size_t start, size_t length, uint64_t ptr_ptr,
44+
uint64_t size_ptr) const = 0;
45+
};
46+
47+
// Opaque context object.
48+
class StorageObject {
49+
public:
50+
virtual ~StorageObject() = default;
51+
};
52+
53+
struct PluginBase {
54+
PluginBase(string_view name, string_view root_id, string_view vm_id,
55+
string_view plugin_configuration)
56+
: name_(std::string(name)), root_id_(std::string(root_id)), vm_id_(std::string(vm_id)),
57+
plugin_configuration_(plugin_configuration) {}
58+
59+
const std::string name_;
60+
const std::string root_id_;
61+
const std::string vm_id_;
62+
std::string plugin_configuration_;
63+
const std::string &log_prefix() const { return log_prefix_; }
64+
65+
private:
66+
std::string makeLogPrefix() const;
67+
68+
std::string log_prefix_;
69+
};
70+
71+
// A context which will be the target of callbacks for a particular session
72+
// e.g. a handler of a stream.
73+
class ContextBase {
74+
public:
75+
ContextBase(); // Testing.
76+
ContextBase(WasmBase *wasm); // Vm Context.
77+
ContextBase(WasmBase *wasm, std::shared_ptr<PluginBase> plugin); // Root Context.
78+
ContextBase(WasmBase *wasm, uint32_t root_context_id,
79+
std::shared_ptr<PluginBase> plugin); // Stream context.
80+
virtual ~ContextBase();
81+
82+
WasmBase *wasm() const { return wasm_; }
83+
uint32_t id() const { return id_; }
84+
bool isVmContext() { return id_ == 0; }
85+
bool isRootContext() { return root_context_id_ == 0; }
86+
ContextBase *root_context() { return root_context_; }
87+
string_view root_id() const { return plugin_->root_id_; }
88+
string_view log_prefix() const { return plugin_->log_prefix(); }
89+
WasmVm *wasmVm() const;
90+
91+
// Called before deleting the context.
92+
virtual void destroy();
93+
94+
//
95+
// VM level downcalls into the WASM code on Context(id == 0).
96+
//
97+
virtual bool onStart(std::shared_ptr<PluginBase> plugin);
98+
virtual bool onConfigure(std::shared_ptr<PluginBase> plugin);
99+
100+
//
101+
// Stream downcalls on Context(id > 0).
102+
//
103+
// General stream downcall on a new stream.
104+
virtual void onCreate(uint32_t root_context_id);
105+
// Network
106+
virtual FilterStatus onNetworkNewConnection();
107+
virtual FilterStatus onDownstreamData(int data_length, bool end_of_stream);
108+
virtual FilterStatus onUpstreamData(int data_length, bool end_of_stream);
109+
enum class PeerType : uint32_t {
110+
Unknown = 0,
111+
Local = 1,
112+
Remote = 2,
113+
};
114+
virtual void onDownstreamConnectionClose(PeerType);
115+
virtual void onUpstreamConnectionClose(PeerType);
116+
// HTTP Filter Stream Request Downcalls.
117+
virtual FilterHeadersStatus onRequestHeaders();
118+
virtual FilterDataStatus onRequestBody(int body_buffer_length, bool end_of_stream);
119+
virtual FilterTrailersStatus onRequestTrailers();
120+
virtual FilterMetadataStatus onRequestMetadata();
121+
// HTTP Filter Stream Response Downcalls.
122+
virtual FilterHeadersStatus onResponseHeaders();
123+
virtual FilterDataStatus onResponseBody(int body_buffer_length, bool end_of_stream);
124+
virtual FilterTrailersStatus onResponseTrailers();
125+
virtual FilterMetadataStatus onResponseMetadata();
126+
// Async call response.
127+
virtual void onHttpCallResponse(uint32_t token, uint32_t headers, uint32_t body_size,
128+
uint32_t trailers);
129+
// Inter-VM shared queue message arrival.
130+
virtual void onQueueReady(uint32_t token);
131+
// General stream downcall when the stream/vm has ended.
132+
virtual bool onDone();
133+
// General stream downcall for logging. Occurs after onDone().
134+
virtual void onLog();
135+
// General stream downcall when no further stream calls will occur.
136+
virtual void onDelete();
137+
138+
virtual void error(string_view message) {
139+
std::cerr << message << "\n";
140+
abort();
141+
}
142+
virtual void unimplemented() { error("unimplemented proxy-wasm API"); }
143+
144+
//
145+
// General Callbacks.
146+
//
147+
virtual WasmResult log(uint64_t /* level */, string_view /* message */) {
148+
return WasmResult::Unimplemented;
149+
}
150+
virtual WasmResult setTimerPeriod(std::chrono::milliseconds period);
151+
virtual uint64_t getCurrentTimeNanoseconds() {
152+
struct timespec tpe;
153+
clock_gettime(CLOCK_REALTIME, &tpe);
154+
uint64_t t = tpe.tv_sec;
155+
t *= 1000000000;
156+
t += tpe.tv_nsec;
157+
return t;
158+
}
159+
virtual std::pair<uint32_t, string_view> getStatus();
160+
161+
// Buffer
162+
virtual const BufferInterface *getBuffer(WasmBufferType type);
163+
virtual bool end_of_stream();
164+
165+
// HTTP
166+
// Returns a token which will be used with the corresponding onHttpCallResponse.
167+
virtual WasmResult httpCall(string_view /* target */, const Pairs & /*request_headers */,
168+
string_view /* request_body */, const Pairs & /* request_trailers */,
169+
int /* timeout_millisconds */, uint32_t * /* token_ptr */) {
170+
unimplemented();
171+
return WasmResult::Unimplemented;
172+
}
173+
174+
// gRPC
175+
// Returns a token which will be used with the corresponding onGrpc and grpc calls.
176+
virtual WasmResult grpcCall(string_view /* grpc_service */, string_view /* service_name */,
177+
string_view /* method_name */, string_view /* request */,
178+
const optional<std::chrono::milliseconds> & /* timeout */,
179+
uint32_t * /* token_ptr */) {
180+
unimplemented();
181+
return WasmResult::Unimplemented;
182+
}
183+
virtual WasmResult grpcStream(string_view /* grpc_service */, string_view /* service_name */,
184+
string_view /* method_name */, uint32_t * /* token_ptr */) {
185+
unimplemented();
186+
return WasmResult::Unimplemented;
187+
}
188+
virtual WasmResult grpcClose(uint32_t /* token */) { // cancel on call, close on stream.
189+
unimplemented();
190+
return WasmResult::Unimplemented;
191+
}
192+
virtual WasmResult grpcCancel(uint32_t /* token */) { // cancel on call, reset on stream.
193+
unimplemented();
194+
return WasmResult::Unimplemented;
195+
}
196+
virtual WasmResult grpcSend(uint32_t /* token */, string_view /* message */,
197+
bool /* end_stream */) { // stream only
198+
unimplemented();
199+
return WasmResult::Unimplemented;
200+
}
201+
202+
// Metrics
203+
virtual WasmResult defineMetric(MetricType type, string_view name, uint32_t *metric_id_ptr);
204+
virtual WasmResult incrementMetric(uint32_t metric_id, int64_t offset);
205+
virtual WasmResult recordMetric(uint32_t metric_id, uint64_t value);
206+
virtual WasmResult getMetric(uint32_t metric_id, uint64_t *value_ptr);
207+
208+
// State accessors
209+
virtual WasmResult getProperty(string_view path, std::string *result);
210+
virtual WasmResult setProperty(string_view key, string_view serialized_value);
211+
212+
// Continue
213+
virtual void continueRequest() { unimplemented(); }
214+
virtual void continueResponse() { unimplemented(); }
215+
virtual void sendLocalResponse(uint64_t /* response_code */, string_view /* body_text */,
216+
Pairs /* additional_headers */, uint64_t /* grpc_status */,
217+
string_view /* details */) {
218+
unimplemented();
219+
}
220+
221+
// Shared Data
222+
virtual WasmResult getSharedData(string_view /* key */,
223+
std::pair<std::string, uint32_t /* cas */> * /* data */);
224+
virtual WasmResult setSharedData(string_view /* key */, string_view /* value */,
225+
uint32_t /* cas */);
226+
227+
// Shared Queue
228+
virtual uint32_t registerSharedQueue(string_view /* queue_name */);
229+
virtual WasmResult resolveSharedQueue(string_view /* vm_id */, string_view /* queue_name */,
230+
uint32_t * /* token */);
231+
virtual WasmResult dequeueSharedQueue(uint32_t /* token */, std::string * /* data */);
232+
virtual WasmResult enqueueSharedQueue(uint32_t /* token */, string_view /* value */);
233+
234+
// Header/Trailer/Metadata Maps
235+
virtual void addHeaderMapValue(WasmHeaderMapType /* type */, string_view /* key */,
236+
string_view /* value */) {
237+
unimplemented();
238+
}
239+
virtual string_view getHeaderMapValue(WasmHeaderMapType /* type */, string_view /* key */) {
240+
unimplemented();
241+
return "";
242+
}
243+
virtual Pairs getHeaderMapPairs(WasmHeaderMapType /* type */) {
244+
unimplemented();
245+
return {};
246+
}
247+
virtual void setHeaderMapPairs(WasmHeaderMapType /* type */, const Pairs & /* pairs */) {
248+
unimplemented();
249+
}
250+
251+
virtual void removeHeaderMapValue(WasmHeaderMapType /* type */, string_view /* key */) {
252+
unimplemented();
253+
}
254+
virtual void replaceHeaderMapValue(WasmHeaderMapType /* type */, string_view /* key */,
255+
string_view /* value */) {
256+
unimplemented();
257+
}
258+
259+
virtual uint32_t getHeaderMapSize(WasmHeaderMapType /* type */) {
260+
unimplemented();
261+
return 0;
262+
}
263+
264+
protected:
265+
friend class WasmBase;
266+
267+
virtual void initializeRoot(WasmBase *wasm, std::shared_ptr<PluginBase> plugin);
268+
std::string makeRootLogPrefix(string_view vm_id) const;
269+
270+
WasmBase *wasm_{nullptr};
271+
uint32_t id_{0};
272+
uint32_t root_context_id_{0}; // 0 for roots and the general context.
273+
ContextBase *root_context_{nullptr}; // set in all contexts.
274+
std::string root_id_; // set only in root context.
275+
std::string root_log_prefix_; // set only in root context.
276+
std::shared_ptr<PluginBase> plugin_;
277+
bool in_vm_context_created_ = false;
278+
bool destroyed_ = false;
279+
};
280+
281+
uint32_t resolveQueueForTest(string_view vm_id, string_view queue_name);
282+
283+
} // namespace proxy_wasm

0 commit comments

Comments
 (0)