Skip to content
File

Blob: src/workerd/api/r2-rpc.h

cpp114 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/api/blob.h>
8#include <workerd/jsg/jsg.h>
9 
10namespace kj {
11class HttpClient;
12}
13 
14namespace workerd::api {
15 
16class ReadableStreamSource;
17class ReadableStream;
18 
19// NOTE: We don't currently actually use this as a structured object (hence the `kj::Own<R2Error>`
20// that we see pop up).
21// TODO(soon): Switch to structured objects and use jsg::Ref<R2Error> instead of kj::Own<R2Error>
22// to maintain ownership.
23class R2Error: public jsg::Object {
24 public:
25 R2Error(uint v4Code, kj::String message): v4Code(v4Code), message(kj::mv(message)) {}
26 
27 constexpr kj::StringPtr getName() const {
28 return "R2Error"_kj;
29 }
30 uint getV4Code() const {
31 return v4Code;
32 }
33 kj::StringPtr getMessage() const {
34 return message;
35 }
36 kj::StringPtr getAction() const {
37 return KJ_ASSERT_NONNULL(action);
38 }
39 jsg::JsValue getStack(jsg::Lock& js);
40 
41 JSG_RESOURCE_TYPE(R2Error) {
42 JSG_INHERIT_INTRINSIC(v8::kErrorPrototype);
43 
44 JSG_READONLY_INSTANCE_PROPERTY(name, getName);
45 JSG_READONLY_INSTANCE_PROPERTY(code, getV4Code);
46 JSG_READONLY_INSTANCE_PROPERTY(message, getMessage);
47 JSG_READONLY_INSTANCE_PROPERTY(action, getAction);
48 
49 JSG_READONLY_INSTANCE_PROPERTY(stack, getStack);
50 // See getStack in dom-exception.h
51 
52 JSG_TS_ROOT();
53 }
54 
55 private:
56 uint v4Code;
57 kj::String message;
58 kj::Maybe<kj::String> action;
59 // Initialized when thrown.
60 
61 kj::Maybe<v8::Global<v8::Object>> errorForStack;
62 // See dom-exception.h.
63 
64 friend struct R2Result;
65};
66 
67using R2PutValue = kj::OneOf<jsg::Ref<ReadableStream>,
68 kj::Array<kj::byte>,
69 jsg::NonCoercible<kj::String>,
70 jsg::Ref<Blob>>;
71 
72struct R2Result {
73 uint httpStatus;
74 
75 // Non-null if httpStatus >= 400.
76 kj::Maybe<kj::Own<R2Error>> toThrow;
77 
78 kj::Maybe<kj::Array<char>> metadataPayload;
79 
80 kj::Maybe<kj::Own<workerd::api::ReadableStreamSource>> stream;
81 
82 bool objectNotFound() {
83 return httpStatus == 404 && v4ErrorCode() == 10007;
84 }
85 
86 bool preconditionFailed() {
87 return httpStatus == 412 && (v4ErrorCode() == 10031 || v4ErrorCode() == 10032);
88 }
89 
90 bool success() {
91 return httpStatus >= 200 && httpStatus < 400;
92 }
93 
94 kj::Maybe<uint> v4ErrorCode();
95 kj::Maybe<kj::String> getR2ErrorMessage();
96 void throwIfError(kj::StringPtr action, const jsg::TypeHandler<jsg::Ref<R2Error>>& errorType);
97};
98 
99kj::Promise<R2Result> doR2HTTPGetRequest(kj::Own<kj::HttpClient> client,
100 kj::String metadataPayload,
101 kj::ArrayPtr<kj::StringPtr> path,
102 kj::Maybe<kj::StringPtr> jwt,
103 CompatibilityFlags::Reader flags);
104 
105kj::Promise<R2Result> doR2HTTPPutRequest(kj::Own<kj::HttpClient> client,
106 kj::Maybe<R2PutValue> value,
107 kj::Maybe<uint64_t> streamSize,
108 // Deprecated. For internal beta API only.
109 kj::String metadataPayload,
110 kj::ArrayPtr<kj::StringPtr> path,
111 kj::Maybe<kj::StringPtr> jwt);
112 
113} // namespace workerd::api