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
72
73public:
74 // ----------------
75 // Description of the request. The header/body parsing
76 // is supposed to populate these fields, for fast access while
77 // processing the request
78
80
96
97private:
98 // HTTP response parameters to be sent back to the user
99 int httpStatusCode;
100 // HTTP Error code for the response
101 // e.g. 8.1, 8.3.1, etc.
102 // https://twiki.cern.ch/twiki/bin/view/LCG/WebdavErrorImprovement
103 std::string httpErrorCode;
104 // HTTP response text with following format:
105 // Severity: ErrorCode: free-style text message
106 // Severity being OK, WARNING, or ERROR
107 // ErrorCode being a decimal numeric plus dot string, i.e. n or n.m or n.m.l,
108 // etc. free-style text message any UTF-8 string
109 // Optionally, it also contains the trailer headers whereever applicable
110 // e.g. X-Transfer-Status: 200: OK
111 // or X-Transfer-Status: 500: ERROR: <error message>: <additional text>
112 std::string httpErrorBody;
113
114
115 // The value of the user agent, if specified
116 std::string m_user_agent;
117
118 // Whether transfer encoding was requested.
119 bool m_transfer_encoding_chunked;
120 long long m_current_chunk_offset;
121 long long m_current_chunk_size;
122
123 // Whether trailer headers were enabled
124 bool m_trailer_headers{false};
125
126 // Whether the client understands our special status trailer.
127 // The status trailer allows us to report when an IO error occurred
128 // after a response body has started
129 bool m_status_trailer{false};
130
131 int parseHost(char *);
132
133 void parseScitag(const std::string & val);
134
135 //xmlDocPtr xmlbody; /* the resulting document tree */
136 XrdHttpProtocol *prot;
137
138 void clientMarshallReadAheadList(int nitems);
139 void clientUnMarshallReadAheadList(int nitems);
140
141
142 void getfhandle();
143
144 // Process the checksum response and return a header that should
145 // be included in the response.
146 int PostProcessChecksum(std::string &digest_header);
147
148 // Process the listing request of a GET request against a directory
149 // - final_: True if this is the last entry in the listing.
150 int PostProcessListing(bool final_);
151
152 // Send the response for a GET request for a file read (i.e., not a directory)
153 // Invoked after the open is successful but before the first read is issued.
154 int ReturnGetHeaders();
155
161 int PostProcessHTTPReq(bool final = false);
162
163 // Parse a resource string, typically a filename, setting the resource field and the opaque data
164 void parseResource(char *url);
165 // Map an XRootD error code to an appropriate HTTP status code and message
166 void mapXrdErrorToHttpStatus();
167
168 // Set Webdav Error messages
169 void sendWebdavErrorMessage(XResponseType xrdresp, XErrorCode xrderrcode,
170 ReqType httpVerb, XRequestTypes xrdOperation,
171 std::string etext, const char *desc,
172 const char *header_to_add, bool keepalive);
173
174 // Sanitize the resource from http[s]://[host]/ questionable prefix
175 void sanitizeResourcePfx();
176
177 // parses the iovN data pointers elements as either a kXR_read or kXR_readv
178 // response and fills out a XrdHttpIOList with the corresponding length and
179 // buffer pointers. File offsets from kXR_readv responses are not recorded.
180 void getReadResponse(XrdHttpIOList &received);
181
182 // notifies the range handler of receipt of bytes and sends the client
183 // the data.
184 int sendReadResponseSingleRange(const XrdHttpIOList &received);
185
186 // notifies the range handler of receipt of bytes and sends the client
187 // the data and necessary headers, assuming multipart/byteranges content type.
188 int sendReadResponsesMultiRanges(const XrdHttpIOList &received);
189
190 // If requested by the client, sends any I/O errors that occur during the transfer
191 // into a footer.
192 int sendFooterError(const std::string &);
193
194 // Set the age header from the file modification time
195 void addAgeHeader(std::string & headers);
201 static void extractChecksumFromList(const std::string & checksumList, std::vector<std::string> & extractedChecksum);
202
209 static void determineXRootDChecksumFromUserDigest(const std::string & userDigest, std::vector<std::string> & xrootdChecksums);
210
211public:
213 readRangeHandler(rcfg), closeAfterError(false), keepalive(true) {
214
215 prot = protinstance;
216 length = 0;
217 //xmlbody = 0;
218 depth = 0;
219 opaque = 0;
220 writtenbytes = 0;
221 fopened = false;
222 headerok = false;
223 mScitag = -1;
224 };
225
226 virtual ~XrdHttpReq();
227
228 virtual void reset();
229
231 int parseLine(char *line, int len);
232
234 int parseFirstLine(char *line, int len);
235
237 int parseBody(char *body, long long len);
238
240 int ReqReadV(const XrdHttpIOList &cl);
241 std::vector<readahead_list> ralist;
242
244 std::string buildPartialHdr(long long bytestart, long long byteend, long long filesize, char *token);
245
247 std::string buildPartialHdrEnd(char *token);
248
249 // Appends the opaque info that we have
250 // NOTE: this function assumes that the strings are unquoted, and will quote them
251 void appendOpaque(XrdOucString &s, XrdSecEntity *secent, char *hash, time_t tnow);
252
253 void addCgi(const std::string & key, const std::string & value);
254
255 // Set the transfer status header, if requested by the client
256 void setTransferStatusHeader(std::string &header);
257
258 // Return the current user agent; if none has been specified, returns an empty string
259 const std::string &userAgent() const {return m_user_agent;}
260
261
264 std::string requestverb;
265
266 // We have to keep the headers for possible further processing
267 // by external plugins
268 std::map<std::string, std::string> allheaders;
269
276
277
280
284
285 // Indication that there was a read error and the next
286 // request processing state should cleanly close the file.
288
290 long long length; // Total size from client for PUT; total length of response TO client for GET.
291 int depth;
293
295 std::string host;
297 std::string destination;
298
300 std::string m_req_digest;
301
304
310 std::string m_digest_header;
311
313 std::string hdr2cgistr;
316 bool m_appended_asize{false};
317
318 //
319 // Area for coordinating request and responses to/from the bridge
320 //
321
322
325
328
332 std::string etext;
334
336 const struct iovec *iovP;
337 int iovN;
338 int iovL;
339 bool final;
340
341 // The latest stat info got from the xrd layer
342 long long filesize;
346 char fhandle[4];
348
350 std::string stringresp;
351
354
356 long long writtenbytes;
357
359
360
361
362
363
369 int ProcessHTTPReq();
370
371
372 // ------------
373 // Items inherited from the Bridge class
374 //
375
376 //-----------------------------------------------------------------------------
402 //-----------------------------------------------------------------------------
403
404 virtual bool Data(XrdXrootd::Bridge::Context &info,
405 const
406 struct iovec *iovP,
407 int iovN,
408 int iovL,
409 bool final
410 );
411
412 //-----------------------------------------------------------------------------
422 //-----------------------------------------------------------------------------
423
424 virtual bool Done(XrdXrootd::Bridge::Context &info);
425
426
427 //-----------------------------------------------------------------------------
440 //-----------------------------------------------------------------------------
441
442 virtual bool Error(XrdXrootd::Bridge::Context &info,
443 int ecode,
444 const char *etext
445 );
446
447 //-----------------------------------------------------------------------------
460 //-----------------------------------------------------------------------------
461
462 virtual int File(XrdXrootd::Bridge::Context &info,
463 int dlen
464 );
465
466 //-----------------------------------------------------------------------------
479 //-----------------------------------------------------------------------------
480
481 virtual bool Redir(XrdXrootd::Bridge::Context &info,
482 int port,
483 const char *hname
484 );
485
486};
487
488
489
490void trim(std::string &str);
491
492#endif /* XRDHTTPREQ_HH */
493
XErrorCode
Definition XProtocol.hh:989
XResponseType
Definition XProtocol.hh:898
XRequestTypes
Definition XProtocol.hh:110
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
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()
bool closeAfterError
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
ReqType
These are the HTTP/DAV requests that we support.
Definition XrdHttpReq.hh:81
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.
void setTransferStatusHeader(std::string &header)
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()