-
Notifications
You must be signed in to change notification settings - Fork 34
/
BackendRequest.hpp
277 lines (230 loc) · 12.1 KB
/
BackendRequest.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*
* This File is part of Davix, The IO library for HTTP based protocols
* Copyright (C) CERN 2019
* Author: Georgios Bitzes <georgios.bitzes@cern.ch>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef BACKEND_REQUEST_HPP
#define BACKEND_REQUEST_HPP
#include <davix_internal.hpp>
#include <request/httprequest.hpp>
#include <utils/davix_uri.hpp>
#include <memory>
#define DEFAULT_REQUEST_SIGNING_DURATION 3600
namespace Davix{
//------------------------------------------------------------------------------
// Describe current request status.
//------------------------------------------------------------------------------
enum class RequestStatus {
kNotStarted = 0, // request is not active
kStarted, // request has been started
kCompletedOneShot, // request completed through 'executeRequest', not begin/end
};
//------------------------------------------------------------------------------
// Abstract HTTP request type towards a backend.
//------------------------------------------------------------------------------
class BackendRequest {
public:
//----------------------------------------------------------------------------
// Default constructor
//----------------------------------------------------------------------------
BackendRequest(Context &c, const Uri &uri);
//----------------------------------------------------------------------------
// Virtual destructor
//----------------------------------------------------------------------------
virtual ~BackendRequest();
//----------------------------------------------------------------------------
// No evil constructors, no move semantics.
//----------------------------------------------------------------------------
BackendRequest(const BackendRequest& other) = delete;
BackendRequest(BackendRequest&& other) = delete;
BackendRequest& operator=(BackendRequest&& other) = delete;
BackendRequest& operator=(const BackendRequest& other) = delete;
//----------------------------------------------------------------------------
// Major read member - implementations need to override.
// Read a block of max_size bytes (at max) into buffer.
//----------------------------------------------------------------------------
virtual dav_ssize_t readBlock(char* buffer, dav_size_t max_size, DavixError** err) = 0;
//----------------------------------------------------------------------------
// Get a specific response header
//----------------------------------------------------------------------------
virtual bool getAnswerHeader(const std::string &header_name, std::string &value) const = 0;
//----------------------------------------------------------------------------
// Get all response headers
//----------------------------------------------------------------------------
virtual size_t getAnswerHeaders(std::vector<std::pair<std::string, std::string > > & vec_headers) const = 0;
//----------------------------------------------------------------------------
// Start request.
//----------------------------------------------------------------------------
virtual int beginRequest(DavixError** err) = 0;
//----------------------------------------------------------------------------
// Finish an already started request.
//----------------------------------------------------------------------------
virtual int endRequest(DavixError** err) = 0;
//----------------------------------------------------------------------------
// Execute request synchronously, and store result in internal buffer.
//----------------------------------------------------------------------------
virtual int executeRequest(DavixError** err) = 0;
//----------------------------------------------------------------------------
// Get response status.
//----------------------------------------------------------------------------
virtual int getRequestCode() = 0;
//----------------------------------------------------------------------------
// Helper read members - implemented in terms of readBlock, and an internal
// buffer.
//----------------------------------------------------------------------------
dav_ssize_t readSegment(char* buffer, dav_size_t size_read, bool stop_at_line_boundary, DavixError** err);
dav_ssize_t readLine(char* buffer, dav_size_t max_size, DavixError** err);
dav_ssize_t readToFd(int fd, dav_size_t read_size, DavixError** err);
//----------------------------------------------------------------------------
// Add custom header to the request, replace an existing one if already
// exists. If value is empty, the entire header line is removed.
//----------------------------------------------------------------------------
void addHeaderField(const std::string & field, const std::string & value){
_headers_field.emplace_back(field, value);
}
//----------------------------------------------------------------------------
// Set the request verb. (such as GET, POST, PUT, PROPFIND, etc)
//----------------------------------------------------------------------------
void setRequestMethod(const std::string &val){
_request_type = val;
}
//----------------------------------------------------------------------------
// Get the request verb. (such as GET, POST, PUT, PROPFIND, etc)
//----------------------------------------------------------------------------
std::string getRequestMethod() {
return _request_type;
}
//----------------------------------------------------------------------------
// Set the value of a request flag
//----------------------------------------------------------------------------
void setFlag(const RequestFlag::RequestFlag flag, bool value) {
if(value) {
_req_flag |= flag;
}
else {
_req_flag &= ~(flag);
}
}
//----------------------------------------------------------------------------
// Get the value of a request flag
//----------------------------------------------------------------------------
bool getFlag(const RequestFlag::RequestFlag flag) const {
return _req_flag & ((int) flag);
}
//----------------------------------------------------------------------------
// Several different ways to provide the request body.
//----------------------------------------------------------------------------
void setRequestBody(const std::string & body);
void setRequestBody(const void * buffer, dav_size_t len);
void setRequestBody(int fd, dav_off_t offset, dav_size_t len);
void setRequestBody(HttpBodyProvider provider, dav_size_t len, void* udata);
void setRequestBody(ContentProvider &provider);
//----------------------------------------------------------------------------
// Set request parameters.
//----------------------------------------------------------------------------
void setParameters(const RequestParams &p);
//----------------------------------------------------------------------------
// Get request parameters.
//----------------------------------------------------------------------------
RequestParams& getParameters();
//----------------------------------------------------------------------------
// Get this requests' context.
//----------------------------------------------------------------------------
Context& getContext() const;
//----------------------------------------------------------------------------
// Get original URL, before any redirections
//----------------------------------------------------------------------------
std::shared_ptr<Uri> getOriginalUri() const;
//----------------------------------------------------------------------------
// Access response buffer.
//----------------------------------------------------------------------------
const char* getAnswerContent();
std::vector<char> & getAnswerContentVec();
//----------------------------------------------------------------------------
// Clear response buffer.
//----------------------------------------------------------------------------
void clearAnswerContent();
//----------------------------------------------------------------------------
// Parse "Last-Modified" response header, return as time_t.
//----------------------------------------------------------------------------
time_t getLastModified() const;
//----------------------------------------------------------------------------
// Get answer size
//----------------------------------------------------------------------------
dav_ssize_t getAnswerSize() const;
protected:
//----------------------------------------------------------------------------
// Configure request for S3.
//----------------------------------------------------------------------------
void configureS3params();
//----------------------------------------------------------------------------
// Configure request for Azure.
//----------------------------------------------------------------------------
void configureAzureParams();
//----------------------------------------------------------------------------
// Configure request for Gcloud.
//----------------------------------------------------------------------------
void configureGcloudParams();
//----------------------------------------------------------------------------
// Configure request for Swift.
//----------------------------------------------------------------------------
void configureSwiftParams();
//----------------------------------------------------------------------------
// Set-up deadline, but only if uninitialized
//----------------------------------------------------------------------------
void setupDeadlineIfUnset();
//----------------------------------------------------------------------------
// Check if deadline has already passed
//----------------------------------------------------------------------------
bool checkTimeout(DavixError **err);
//----------------------------------------------------------------------------
// Get answer size from headers.
//----------------------------------------------------------------------------
dav_ssize_t getAnswerSizeFromHeaders() const;
//----------------------------------------------------------------------------
// Member variables common to all implementations.
//----------------------------------------------------------------------------
Context& _context;
std::shared_ptr<Uri> _current, _orig;
RequestParams _params;
std::vector<std::pair<std::string, std::string>> _headers_field;
std::string _request_type;
int _req_flag;
Chrono::TimePoint _deadline;
//----------------------------------------------------------------------------
// Request content.
//----------------------------------------------------------------------------
std::unique_ptr<ContentProvider> _owned_content_provider;
ContentProvider *_content_provider;
//----------------------------------------------------------------------------
// Answer length.
//----------------------------------------------------------------------------
mutable dav_ssize_t _ans_size;
//----------------------------------------------------------------------------
// Answer buffers.
//----------------------------------------------------------------------------
std::vector<char> _vec;
std::vector<char> _vec_line;
//----------------------------------------------------------------------------
// Early termination flag and status.
//----------------------------------------------------------------------------
bool _early_termination;
DavixError* _early_termination_error;
};
}
#endif