XRootD
Loading...
Searching...
No Matches
XrdHttpReq.hh
Go to the documentation of this file.
1//------------------------------------------------------------------------------
2// This file is part of XrdHTTP: A pragmatic implementation of the
3// HTTP/WebDAV protocol for the Xrootd framework
4//
5// Copyright (c) 2013 by European Organization for Nuclear Research (CERN)
6// Author: Fabrizio Furano <furano@cern.ch>
7// File Date: Nov 2012
8//------------------------------------------------------------------------------
9// XRootD is free software: you can redistribute it and/or modify
10// it under the terms of the GNU Lesser General Public License as published by
11// the Free Software Foundation, either version 3 of the License, or
12// (at your option) any later version.
13//
14// XRootD is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU Lesser General Public License
20// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
21//------------------------------------------------------------------------------
22
23
24
25
26
27
28
37
38#ifndef XRDHTTPREQ_HH
39#define XRDHTTPREQ_HH
40
41
43
48
49#include <vector>
50#include <string>
51#include <map>
52
53//#include <libxml/parser.h>
54//#include <libxml/tree.h>
55
56
57
58
60 std::string path;
61 long long size;
62 long id;
63 long flags;
64 long modtime;
65};
66
67
68class XrdHttpProtocol;
69class XrdOucEnv;
70
72private:
73 // HTTP response parameters to be sent back to the user
74 int httpStatusCode;
75 std::string httpStatusText;
76
77 // The value of the user agent, if specified
78 std::string m_user_agent;
79
80 // Whether transfer encoding was requested.
81 bool m_transfer_encoding_chunked;
82 long long m_current_chunk_offset;
83 long long m_current_chunk_size;
84
85 // Whether trailer headers were enabled
86 bool m_trailer_headers{false};
87
88 // Whether the client understands our special status trailer.
89 // The status trailer allows us to report when an IO error occurred
90 // after a response body has started
91 bool m_status_trailer{false};
92
93 int parseHost(char *);
94
95 void parseScitag(const std::string & val);
96
97 //xmlDocPtr xmlbody; /* the resulting document tree */
98 XrdHttpProtocol *prot;
99
100 void clientMarshallReadAheadList(int nitems);
101 void clientUnMarshallReadAheadList(int nitems);
102
103
104 void getfhandle();
105
106 // Process the checksum response and return a header that should
107 // be included in the response.
108 int PostProcessChecksum(std::string &digest_header);
109
110 // Process the listing request of a GET request against a directory
111 // - final_: True if this is the last entry in the listing.
112 int PostProcessListing(bool final_);
113
114 // Send the response for a GET request for a file read (i.e., not a directory)
115 // Invoked after the open is successful but before the first read is issued.
116 int ReturnGetHeaders();
117
123 int PostProcessHTTPReq(bool final = false);
124
125 // Parse a resource string, typically a filename, setting the resource field and the opaque data
126 void parseResource(char *url);
127 // Map an XRootD error code to an appropriate HTTP status code and message
128 void mapXrdErrorToHttpStatus();
129
130 // Sanitize the resource from http[s]://[host]/ questionable prefix
131 void sanitizeResourcePfx();
132
133 // parses the iovN data pointers elements as either a kXR_read or kXR_readv
134 // response and fills out a XrdHttpIOList with the corresponding length and
135 // buffer pointers. File offsets from kXR_readv responses are not recorded.
136 void getReadResponse(XrdHttpIOList &received);
137
138 // notifies the range handler of receipt of bytes and sends the client
139 // the data.
140 int sendReadResponseSingleRange(const XrdHttpIOList &received);
141
142 // notifies the range handler of receipt of bytes and sends the client
143 // the data and necessary headers, assuming multipart/byteranges content type.
144 int sendReadResponsesMultiRanges(const XrdHttpIOList &received);
145
146 // If requested by the client, sends any I/O errors that occur during the transfer
147 // into a footer.
148 void sendFooterError(const std::string &);
149
150 // Set the age header from the file modification time
151 void addAgeHeader(std::string & headers);
157 static void extractChecksumFromList(const std::string & checksumList, std::vector<std::string> & extractedChecksum);
158
165 static void determineXRootDChecksumFromUserDigest(const std::string & userDigest, std::vector<std::string> & xrootdChecksums);
166
167public:
169 readRangeHandler(rcfg), keepalive(true) {
170
171 prot = protinstance;
172 length = 0;
173 //xmlbody = 0;
174 depth = 0;
175 opaque = 0;
176 writtenbytes = 0;
177 fopened = false;
178 headerok = false;
179 mScitag = -1;
180 };
181
182 virtual ~XrdHttpReq();
183
184 virtual void reset();
185
187 int parseLine(char *line, int len);
188
190 int parseFirstLine(char *line, int len);
191
193 int parseBody(char *body, long long len);
194
196 int ReqReadV(const XrdHttpIOList &cl);
197 std::vector<readahead_list> ralist;
198
200 std::string buildPartialHdr(long long bytestart, long long byteend, long long filesize, char *token);
201
203 std::string buildPartialHdrEnd(char *token);
204
205 // Appends the opaque info that we have
206 // NOTE: this function assumes that the strings are unquoted, and will quote them
207 void appendOpaque(XrdOucString &s, XrdSecEntity *secent, char *hash, time_t tnow);
208
209 void addCgi(const std::string & key, const std::string & value);
210
211 // Return the current user agent; if none has been specified, returns an empty string
212 const std::string &userAgent() const {return m_user_agent;}
213
214 // ----------------
215 // Description of the request. The header/body parsing
216 // is supposed to populate these fields, for fast access while
217 // processing the request
218
220
236
239 std::string requestverb;
240
241 // We have to keep the headers for possible further processing
242 // by external plugins
243 std::map<std::string, std::string> allheaders;
244
251
252
255
259
261 long long length; // Total size from client for PUT; total length of response TO client for GET.
262 int depth;
264
266 std::string host;
268 std::string destination;
269
271 std::string m_req_digest;
272
275
281 std::string m_digest_header;
282
284 std::string hdr2cgistr;
287 bool m_appended_asize{false};
288
289 //
290 // Area for coordinating request and responses to/from the bridge
291 //
292
293
296
299
303 std::string etext;
305
307 const struct iovec *iovP;
308 int iovN;
309 int iovL;
310 bool final;
311
312 // The latest stat info got from the xrd layer
313 long long filesize;
317 char fhandle[4];
319
321 std::string stringresp;
322
325
327 long long writtenbytes;
328
330
331
332
333
334
340 int ProcessHTTPReq();
341
342
343 // ------------
344 // Items inherited from the Bridge class
345 //
346
347 //-----------------------------------------------------------------------------
373 //-----------------------------------------------------------------------------
374
375 virtual bool Data(XrdXrootd::Bridge::Context &info,
376 const
377 struct iovec *iovP,
378 int iovN,
379 int iovL,
380 bool final
381 );
382
383 //-----------------------------------------------------------------------------
393 //-----------------------------------------------------------------------------
394
395 virtual bool Done(XrdXrootd::Bridge::Context &info);
396
397
398 //-----------------------------------------------------------------------------
411 //-----------------------------------------------------------------------------
412
413 virtual bool Error(XrdXrootd::Bridge::Context &info,
414 int ecode,
415 const char *etext
416 );
417
418 //-----------------------------------------------------------------------------
431 //-----------------------------------------------------------------------------
432
433 virtual int File(XrdXrootd::Bridge::Context &info,
434 int dlen
435 );
436
437 //-----------------------------------------------------------------------------
450 //-----------------------------------------------------------------------------
451
452 virtual bool Redir(XrdXrootd::Bridge::Context &info,
453 int port,
454 const char *hname
455 );
456
457};
458
459
460
461void trim(std::string &str);
462
463#endif /* XRDHTTPREQ_HH */
464
XErrorCode
Definition XProtocol.hh:989
XResponseType
Definition XProtocol.hh:898
long long size
Definition XrdHttpReq.hh:61
void trim(std::string &str)
Definition XrdHttpReq.cc:76
std::string path
Definition XrdHttpReq.hh:60
std::vector< XrdOucIOVec2 > XrdHttpIOList
XrdOucString File
XrdHttpChecksumHandlerImpl::XrdHttpChecksumRawPtr XrdHttpChecksumRawPtr
int reqstate
State machine to talk to the bridge.
char fhandle[4]
int ReqReadV(const XrdHttpIOList &cl)
Prepare the buffers for sending a readv request.
unsigned int rwOpPartialDone
ReqType
These are the HTTP/DAV requests that we support.
int parseBody(char *body, long long len)
Parse the body of a request, assuming that it's XML and that it's entirely in memory.
Definition XrdHttpReq.cc:94
std::vector< readahead_list > ralist
long long length
std::string destination
The destination field specified in the req.
XrdOucString resource
The resource specified by the request, stripped of opaque data.
bool headerok
Tells if we have finished reading the header.
std::string m_digest_header
The computed digest for the HTTP response header.
std::string etext
std::string stringresp
If we want to give a string as a response, we compose it here.
const std::string & userAgent() const
XResponseType xrdresp
The last response data we got.
std::string requestverb
ReqType request
The request we got.
int ProcessHTTPReq()
long long writtenbytes
In a long write, we track where we have arrived.
XrdOucEnv * opaque
The opaque data, after parsing.
int iovL
byte count
const struct iovec * iovP
The latest data chunks got from the xrd layer. These are valid only inside the callbacks!
virtual ~XrdHttpReq()
std::string m_req_digest
The requested digest type.
XrdOucString resourceplusopaque
The resource specified by the request, including all the opaque data.
virtual bool Data(XrdXrootd::Bridge::Context &info, const struct iovec *iovP, int iovN, int iovL, bool final)
std::string hdr2cgistr
Additional opaque info that may come from the hdr2cgi directive.
virtual bool Done(XrdXrootd::Bridge::Context &info)
the result context
std::string host
The host field specified in the req.
long filemodtime
int parseFirstLine(char *line, int len)
Parse the first line of the header.
XrdOucString redirdest
int parseLine(char *line, int len)
Parse the header.
std::string buildPartialHdrEnd(char *token)
Build the closing part for a multipart response.
XrdHttpChecksumHandler::XrdHttpChecksumRawPtr m_req_cksum
The checksum that was ran for this request.
bool m_appended_hdr2cgistr
void appendOpaque(XrdOucString &s, XrdSecEntity *secent, char *hash, time_t tnow)
int iovN
array count
XrdHttpReq(XrdHttpProtocol *protinstance, const XrdHttpReadRangeHandler::Configuration &rcfg)
bool m_appended_asize
Track whether we already appended the oss.asize argument for PUTs.
XrdOucString m_resource_with_digest
long long filesize
bool readClosing
virtual bool Redir(XrdXrootd::Bridge::Context &info, int port, const char *hname)
XErrorCode xrderrcode
std::map< std::string, std::string > allheaders
unsigned int rwOpDone
To coordinate multipart responses across multiple calls.
void addCgi(const std::string &key, const std::string &value)
bool sendcontinue
ClientRequest xrdreq
The last issued xrd request, often pending.
std::string buildPartialHdr(long long bytestart, long long byteend, long long filesize, char *token)
Build a partial header for a multipart response.
XrdHttpReadRangeHandler readRangeHandler
Tracking the next ranges of data to read during GET.
virtual void reset()