|
| 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 <kj-rs/convert.h> |
| 8 | +#include <rust/cxx.h> |
| 9 | + |
| 10 | +#include <kj/compat/http.h> |
| 11 | + |
| 12 | +namespace kj::rust { |
| 13 | + |
| 14 | +struct HttpConnectSettings; |
| 15 | + |
| 16 | +// --- Async IO |
| 17 | + |
| 18 | +using AsyncInputStream = kj::AsyncInputStream; |
| 19 | +using AsyncOutputStream = kj::AsyncOutputStream; |
| 20 | +using AsyncIoStream = kj::AsyncIoStream; |
| 21 | + |
| 22 | +// --- kj::HttpHeaders ffi |
| 23 | + |
| 24 | +using BuiltinIndicesEnum = kj::HttpHeaders::BuiltinIndicesEnum; |
| 25 | +using HttpHeaders = kj::HttpHeaders; |
| 26 | + |
| 27 | +inline kj::Own<kj::HttpHeaders> clone_shallow(const HttpHeaders& headers) { |
| 28 | + // there is no c++ stack frame to hold the new instance, |
| 29 | + // so sadly we have to heap allocate it. |
| 30 | + return kj::heap(headers.cloneShallow()); |
| 31 | +} |
| 32 | + |
| 33 | +inline kj::HttpHeaderId toHeaderId(BuiltinIndicesEnum id) { |
| 34 | + switch (id) { |
| 35 | + case kj::HttpHeaders::BuiltinIndicesEnum::CONNECTION: |
| 36 | + return kj::HttpHeaderId::CONNECTION; |
| 37 | + case kj::HttpHeaders::BuiltinIndicesEnum::KEEP_ALIVE: |
| 38 | + return kj::HttpHeaderId::KEEP_ALIVE; |
| 39 | + case kj::HttpHeaders::BuiltinIndicesEnum::TE: |
| 40 | + return kj::HttpHeaderId::TE; |
| 41 | + case kj::HttpHeaders::BuiltinIndicesEnum::TRAILER: |
| 42 | + return kj::HttpHeaderId::TRAILER; |
| 43 | + case kj::HttpHeaders::BuiltinIndicesEnum::UPGRADE: |
| 44 | + return kj::HttpHeaderId::UPGRADE; |
| 45 | + case kj::HttpHeaders::BuiltinIndicesEnum::CONTENT_LENGTH: |
| 46 | + return kj::HttpHeaderId::CONTENT_LENGTH; |
| 47 | + case kj::HttpHeaders::BuiltinIndicesEnum::TRANSFER_ENCODING: |
| 48 | + return kj::HttpHeaderId::TRANSFER_ENCODING; |
| 49 | + case kj::HttpHeaders::BuiltinIndicesEnum::SEC_WEBSOCKET_KEY: |
| 50 | + return kj::HttpHeaderId::SEC_WEBSOCKET_KEY; |
| 51 | + case kj::HttpHeaders::BuiltinIndicesEnum::SEC_WEBSOCKET_VERSION: |
| 52 | + return kj::HttpHeaderId::SEC_WEBSOCKET_VERSION; |
| 53 | + case kj::HttpHeaders::BuiltinIndicesEnum::SEC_WEBSOCKET_ACCEPT: |
| 54 | + return kj::HttpHeaderId::SEC_WEBSOCKET_ACCEPT; |
| 55 | + case kj::HttpHeaders::BuiltinIndicesEnum::SEC_WEBSOCKET_EXTENSIONS: |
| 56 | + return kj::HttpHeaderId::SEC_WEBSOCKET_EXTENSIONS; |
| 57 | + case kj::HttpHeaders::BuiltinIndicesEnum::HOST: |
| 58 | + return kj::HttpHeaderId::HOST; |
| 59 | + case kj::HttpHeaders::BuiltinIndicesEnum::DATE: |
| 60 | + return kj::HttpHeaderId::DATE; |
| 61 | + case kj::HttpHeaders::BuiltinIndicesEnum::LOCATION: |
| 62 | + return kj::HttpHeaderId::LOCATION; |
| 63 | + case kj::HttpHeaders::BuiltinIndicesEnum::CONTENT_TYPE: |
| 64 | + return kj::HttpHeaderId::CONTENT_TYPE; |
| 65 | + case kj::HttpHeaders::BuiltinIndicesEnum::RANGE: |
| 66 | + return kj::HttpHeaderId::RANGE; |
| 67 | + case kj::HttpHeaders::BuiltinIndicesEnum::CONTENT_RANGE: |
| 68 | + return kj::HttpHeaderId::CONTENT_RANGE; |
| 69 | + break; |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +inline void set_header(HttpHeaders& headers, BuiltinIndicesEnum id, ::rust::Str value) { |
| 74 | + headers.set(toHeaderId(id), kj::str(value)); |
| 75 | +} |
| 76 | + |
| 77 | +inline kj::Maybe<::rust::Slice<const kj::byte>> get_header( |
| 78 | + const HttpHeaders& headers, BuiltinIndicesEnum id) { |
| 79 | + auto header = headers.get(toHeaderId(id)); |
| 80 | + return header.map([](auto header) { return header.asBytes().template as<kj_rs::Rust>(); }); |
| 81 | +} |
| 82 | + |
| 83 | +// --- kj::HttpService ffi |
| 84 | +using AsyncInputStream = kj::AsyncInputStream; |
| 85 | +using AsyncIoStream = kj::AsyncIoStream; |
| 86 | +using ConnectResponse = kj::HttpService::ConnectResponse; |
| 87 | +using HttpMethod = kj::HttpMethod; |
| 88 | +using HttpService = kj::HttpService; |
| 89 | +using HttpServiceResponse = kj::HttpService::Response; |
| 90 | +using TlsStarterCallback = kj::TlsStarterCallback; |
| 91 | + |
| 92 | +inline kj::Promise<void> request(HttpService& service, |
| 93 | + HttpMethod method, |
| 94 | + ::rust::Slice<const kj::byte> url, |
| 95 | + const HttpHeaders& headers, |
| 96 | + AsyncInputStream& request_body, |
| 97 | + HttpServiceResponse& response) { |
| 98 | + auto strUrl = kj::str(kj_rs::from<kj_rs::Rust>(url).asChars()); |
| 99 | + co_await service.request(method, strUrl, headers, request_body, response); |
| 100 | +} |
| 101 | + |
| 102 | +kj::Promise<void> connect(HttpService& service, |
| 103 | + ::rust::Slice<const kj::byte> host, |
| 104 | + const HttpHeaders& headers, |
| 105 | + AsyncIoStream& connection, |
| 106 | + ConnectResponse& response, |
| 107 | + HttpConnectSettings settings); |
| 108 | + |
| 109 | +} // namespace kj::rust |
0 commit comments