Fastly Compute C++ SDK
Loading...
Searching...
No Matches
body.h
Go to the documentation of this file.
1#ifndef FASTLY_HTTP_BODY_H
2#define FASTLY_HTTP_BODY_H
3
4#include <fastly/error.h>
7#include <fastly/sdk-sys.h>
8
9#include <array>
10#include <cstdint>
11#include <iostream>
12#include <memory>
13#include <streambuf>
14#include <string>
15#include <string_view>
16#include <vector>
17
19class InsertBuilder;
20class LookupResponse;
21class KVStore;
22} // namespace fastly::kv_store
23
24namespace fastly::cache::core {
25class TransactionInsertBuilder;
26class InsertBuilder;
27class Replace;
28class Found;
29} // namespace fastly::cache::core
30
31namespace fastly::http {
32
33class Response;
34class Request;
35class StreamingBody;
36namespace request {
37class PendingRequest;
38std::pair<fastly::expected<fastly::http::Response>, std::vector<PendingRequest>>
39select(std::vector<PendingRequest> &reqs);
40} // namespace request
41
49class Body : public std::iostream, public std::streambuf {
50
51 friend StreamingBody;
52 friend Response;
53 friend Request;
56 friend kv_store::KVStore;
57
58protected:
59 int underflow();
60 int overflow(int_type val);
61 int sync();
62
63public:
66 : std::iostream(this), bod(fastly::sys::http::m_static_http_body_new()) {
67 this->setg(this->gbuf.data(), this->gbuf.data(), this->gbuf.data());
68 this->setp(this->pbuf.data(), this->pbuf.data() + this->pbuf.max_size());
69 };
70 Body(Body &&old)
71 : std::iostream(this), bod((old.sync(), std::move(old.bod))),
72 pbuf(std::move(old.pbuf)) {
73 auto gcurr{old.gptr() - old.eback()};
74 auto gend{old.egptr() - old.eback()};
75 this->gbuf = std::move(old.gbuf);
76 this->setg(this->gbuf.data(), this->gbuf.data() + gcurr,
77 this->gbuf.data() + gend);
78 this->setp(this->pbuf.data(), this->pbuf.data() + this->pbuf.max_size());
79 }
80 Body(std::vector<uint8_t> body_vec) : Body() {
81 if (!this->fill_from_vec(body_vec).map_error([](fastly::FastlyError err) {
82 std::cerr << err.error_msg() << std::endl;
83 })) {
84 std::abort();
85 }
86 };
87 Body(std::string body_str) : Body() { *this << body_str << std::flush; };
88 Body(const char *body_str) : Body() { *this << body_str << std::flush; };
89 Body(std::string_view body_str) : Body() { *this << body_str << std::flush; };
90
97 fastly::expected<size_t> read(uint8_t *buf, size_t bufsize);
98
105 fastly::expected<size_t> write(uint8_t *buf, size_t bufsize);
106
108 void append(Body other);
109
111 fastly::expected<void> append_trailer(std::string_view header_name,
112 std::string_view header_value);
113
115 std::string take_body_string() {
116 return std::string(std::istreambuf_iterator<char>(this->rdbuf()),
117 std::istreambuf_iterator<char>());
118 }
119
120 // TODO(@zkat): this needs a HeaderMap wrapper.
121 // HeaderMap get_trailers();
122
123 // TODO(@zkat)
124 // Prefix get_prefix(uint32_t prefix_len);
125 // PrefixString get_prefix_string(uint32_t prefix_len);
126 // class Prefix {
127 // private:
128 // rust::Box<fastly::sys::http::Prefix> pref;
129 // Prefix(rust::Box<fastly::sys::http::Prefix> prefix) :
130 // pref(std::move(prefix)) {};
131 // };
132
133 // class PrefixString {
134 // private:
135 // rust::Box<fastly::sys::http::PrefixString> pref;
136 // PrefixString(rust::Box<fastly::sys::http::PrefixString> prefix) :
137 // pref(std::move(prefix)) {};
138 // };
139private:
140 friend cache::core::Found;
141 rust::Box<fastly::sys::http::Body> bod;
142 std::array<char, 512> pbuf;
143 std::array<char, 512> gbuf;
144 static Body from_handle(uint32_t body_handle) {
145 return Body(fastly::sys::http::m_static_http_body_from_handle(body_handle));
146 }
147 Body(rust::Box<fastly::sys::http::Body> body)
148 : std::iostream(this), bod(std::move(body)) {
149 this->setg(this->gbuf.data(), this->gbuf.data(), this->gbuf.data());
150 this->setp(this->pbuf.data(), this->pbuf.data() + this->pbuf.max_size());
151 };
152
153 fastly::expected<void> fill_from_vec(std::vector<uint8_t> vec) {
154 size_t pos{0};
155 fastly::expected<size_t> written{0};
156 while (*written) {
157 written = this->write(vec.data() + pos, vec.size() - pos);
158 if (written.has_value()) {
159 pos += *written;
160 } else {
161 return fastly::unexpected(std::move(written.error()));
162 }
163 }
164 return fastly::expected<void>();
165 }
166};
167
168class StreamingBody : public std::ostream, public std::streambuf {
169 friend Response;
170 friend Request;
174 friend std::pair<fastly::expected<Response>,
175 std::vector<request::PendingRequest>>
176 request::select(std::vector<request::PendingRequest> &reqs);
177
178protected:
179 int overflow(int_type val);
180 int sync();
181
182public:
184 : std::ostream(this), bod((other.sync(), std::move(other.bod))),
185 pbuf(std::move(other.pbuf)) {
186 this->setp(this->pbuf.data(), this->pbuf.data() + this->pbuf.max_size());
187 };
189 void append(Body other);
190 fastly::expected<size_t> write(uint8_t *buf, size_t bufsize);
191 fastly::expected<void> append_trailer(std::string_view header_name,
192 std::string_view header_value);
193 // TODO(@zkat): needs the HeaderMap type.
194 // fastly::expected<void> finish_with_trailers(&HeaderMap trailers);
195
196private:
197 StreamingBody(rust::Box<fastly::sys::http::StreamingBody> body)
198 : std::ostream(this), bod(std::move(body)) {
199 this->setp(this->pbuf.data(), this->pbuf.data() + this->pbuf.max_size());
200 };
201 static StreamingBody from_body_handle(uint32_t body_handle) {
202 return StreamingBody(
203 fastly::sys::http::m_static_http_streaming_body_from_body_handle(
204 body_handle));
205 }
206 rust::Box<fastly::sys::http::StreamingBody> bod;
207 std::array<char, 512> pbuf;
208};
209
210} // namespace fastly::http
211
212namespace fastly {
213using fastly::http::Body;
214}
215
216#endif
Body()
Get a new, empty HTTP body.
Definition body.h:65
Definition core.h:534
Definition core.h:1101
Definition error.h:12
Definition body.h:49
fastly::expected< void > append_trailer(std::string_view header_name, std::string_view header_value)
Appends request or response trailers to the body.
Body(std::string_view body_str)
Definition body.h:89
fastly::expected< size_t > read(uint8_t *buf, size_t bufsize)
int overflow(int_type val)
void append(Body other)
Append another body onto the end of this body.
Body(std::vector< uint8_t > body_vec)
Definition body.h:80
std::string take_body_string()
Take the entire body as a string.
Definition body.h:115
Body()
Get a new, empty HTTP body.
Definition body.h:65
Body(Body &&old)
Definition body.h:70
Body(const char *body_str)
Definition body.h:88
fastly::expected< size_t > write(uint8_t *buf, size_t bufsize)
Body(std::string body_str)
Definition body.h:87
Definition body.h:168
fastly::expected< size_t > write(uint8_t *buf, size_t bufsize)
fastly::expected< void > append_trailer(std::string_view header_name, std::string_view header_value)
int overflow(int_type val)
fastly::expected< void > finish()
StreamingBody(StreamingBody &&other)
Definition body.h:183
Definition kv_store.h:149
Definition kv_store.h:285
Definition kv_store.h:88
Definition core.h:17
tl::unexpected< T > unexpected
Definition error.h:26
tl::expected< T, FastlyError > expected
Definition error.h:25
Definition body.h:36
std::pair< fastly::expected< fastly::http::Response >, std::vector< PendingRequest > > select(std::vector< PendingRequest > &reqs)
Definition backend.h:13
Definition body.h:18
Definition backend.h:13