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::http {
25
26class Response;
27class Request;
28class StreamingBody;
29namespace request {
30class PendingRequest;
31std::pair<fastly::expected<fastly::http::Response>, std::vector<PendingRequest>>
32select(std::vector<PendingRequest> &reqs);
33} // namespace request
34
42class Body : public std::iostream, public std::streambuf {
43
44 friend StreamingBody;
45 friend Response;
46 friend Request;
49 friend kv_store::KVStore;
50
51protected:
52 int underflow();
53 int overflow(int_type val);
54 int sync();
55
56public:
59 : std::iostream(this), bod(fastly::sys::http::m_static_http_body_new()) {
60 this->setg(this->gbuf.data(), this->gbuf.data(), this->gbuf.data());
61 this->setp(this->pbuf.data(), this->pbuf.data() + this->pbuf.max_size());
62 };
63 Body(Body &&old)
64 : std::iostream(this), bod((old.sync(), std::move(old.bod))),
65 pbuf(std::move(old.pbuf)) {
66 auto gcurr{old.gptr() - old.eback()};
67 auto gend{old.egptr() - old.eback()};
68 this->gbuf = std::move(old.gbuf);
69 this->setg(this->gbuf.data(), this->gbuf.data() + gcurr,
70 this->gbuf.data() + gend);
71 this->setp(this->pbuf.data(), this->pbuf.data() + this->pbuf.max_size());
72 }
73 Body(std::vector<uint8_t> body_vec) : Body() {
74 if (!this->fill_from_vec(body_vec).map_error([](fastly::FastlyError err) {
75 std::cerr << err.error_msg() << std::endl;
76 })) {
77 std::abort();
78 }
79 };
80 Body(std::string body_str) : Body() { *this << body_str << std::flush; };
81 Body(const char *body_str) : Body() { *this << body_str << std::flush; };
82 Body(std::string_view body_str) : Body() { *this << body_str << std::flush; };
83
90 fastly::expected<size_t> read(uint8_t *buf, size_t bufsize);
91
98 fastly::expected<size_t> write(uint8_t *buf, size_t bufsize);
99
101 void append(Body other);
102
104 fastly::expected<void> append_trailer(std::string_view header_name,
105 std::string_view header_value);
106
108 std::string take_body_string() {
109 return std::string(std::istreambuf_iterator<char>(this->rdbuf()),
110 std::istreambuf_iterator<char>());
111 }
112
113 // TODO(@zkat): this needs a HeaderMap wrapper.
114 // HeaderMap get_trailers();
115
116 // TODO(@zkat)
117 // Prefix get_prefix(uint32_t prefix_len);
118 // PrefixString get_prefix_string(uint32_t prefix_len);
119 // class Prefix {
120 // private:
121 // rust::Box<fastly::sys::http::Prefix> pref;
122 // Prefix(rust::Box<fastly::sys::http::Prefix> prefix) :
123 // pref(std::move(prefix)) {};
124 // };
125
126 // class PrefixString {
127 // private:
128 // rust::Box<fastly::sys::http::PrefixString> pref;
129 // PrefixString(rust::Box<fastly::sys::http::PrefixString> prefix) :
130 // pref(std::move(prefix)) {};
131 // };
132private:
133 rust::Box<fastly::sys::http::Body> bod;
134 std::array<char, 512> pbuf;
135 std::array<char, 512> gbuf;
136 Body(rust::Box<fastly::sys::http::Body> body)
137 : std::iostream(this), bod(std::move(body)) {
138 this->setg(this->gbuf.data(), this->gbuf.data(), this->gbuf.data());
139 this->setp(this->pbuf.data(), this->pbuf.data() + this->pbuf.max_size());
140 };
141
142 fastly::expected<void> fill_from_vec(std::vector<uint8_t> vec) {
143 size_t pos{0};
144 fastly::expected<size_t> written{0};
145 while (*written) {
146 written = this->write(vec.data() + pos, vec.size() - pos);
147 if (written.has_value()) {
148 pos += *written;
149 } else {
150 return fastly::unexpected(std::move(written.error()));
151 }
152 }
153 return fastly::expected<void>();
154 }
155};
156
157class StreamingBody : public std::ostream, public std::streambuf {
158 friend Response;
159 friend Request;
160 friend std::pair<fastly::expected<Response>,
161 std::vector<request::PendingRequest>>
162 request::select(std::vector<request::PendingRequest> &reqs);
163
164protected:
165 int overflow(int_type val);
166 int sync();
167
168public:
170 : std::ostream(this), bod((other.sync(), std::move(other.bod))),
171 pbuf(std::move(other.pbuf)) {
172 this->setp(this->pbuf.data(), this->pbuf.data() + this->pbuf.max_size());
173 };
175 void append(Body other);
176 fastly::expected<size_t> write(uint8_t *buf, size_t bufsize);
177 fastly::expected<void> append_trailer(std::string_view header_name,
178 std::string_view header_value);
179 // TODO(@zkat): needs the HeaderMap type.
180 // fastly::expected<void> finish_with_trailers(&HeaderMap trailers);
181
182private:
183 StreamingBody(rust::Box<fastly::sys::http::StreamingBody> body)
184 : std::ostream(this), bod(std::move(body)) {
185 this->setp(this->pbuf.data(), this->pbuf.data() + this->pbuf.max_size());
186 };
187 rust::Box<fastly::sys::http::StreamingBody> bod;
188 std::array<char, 512> pbuf;
189};
190
191} // namespace fastly::http
192
193namespace fastly {
195}
196
197#endif
Body()
Get a new, empty HTTP body.
Definition body.h:58
Definition error.h:12
Definition body.h:42
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:82
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:73
std::string take_body_string()
Take the entire body as a string.
Definition body.h:108
Body()
Get a new, empty HTTP body.
Definition body.h:58
Body(Body &&old)
Definition body.h:63
Body(const char *body_str)
Definition body.h:81
fastly::expected< size_t > write(uint8_t *buf, size_t bufsize)
Body(std::string body_str)
Definition body.h:80
Definition request.h:149
Definition response.h:94
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:169
Definition kv_store.h:149
Definition kv_store.h:285
Definition kv_store.h:88
tl::unexpected< T > unexpected
Definition error.h:26
tl::expected< T, FastlyError > expected
Definition error.h:25
Definition body.h:29
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