XRootD
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 
38 #ifndef XRDHTTPREQ_HH
39 #define XRDHTTPREQ_HH
40 
41 
42 #include "XrdOuc/XrdOucString.hh"
43 
44 #include "XProtocol/XProtocol.hh"
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 
59 struct DirListInfo {
60  std::string path;
61  long long size;
62  long id;
63  long flags;
64  long modtime;
65 };
66 
67 
68 class XrdHttpProtocol;
69 class XrdOucEnv;
70 
72 private:
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 
155  static void extractChecksumFromList(const std::string & checksumList, std::vector<std::string> & extractedChecksum);
156 
163  static void determineXRootDChecksumFromUserDigest(const std::string & userDigest, std::vector<std::string> & xrootdChecksums);
164 
165 public:
167  readRangeHandler(rcfg), keepalive(true) {
168 
169  prot = protinstance;
170  length = 0;
171  //xmlbody = 0;
172  depth = 0;
173  opaque = 0;
174  writtenbytes = 0;
175  fopened = false;
176  headerok = false;
177  mScitag = -1;
178  };
179 
180  virtual ~XrdHttpReq();
181 
182  virtual void reset();
183 
185  int parseLine(char *line, int len);
186 
188  int parseFirstLine(char *line, int len);
189 
191  int parseBody(char *body, long long len);
192 
194  int ReqReadV(const XrdHttpIOList &cl);
195  std::vector<readahead_list> ralist;
196 
198  std::string buildPartialHdr(long long bytestart, long long byteend, long long filesize, char *token);
199 
201  std::string buildPartialHdrEnd(char *token);
202 
203  // Appends the opaque info that we have
204  // NOTE: this function assumes that the strings are unquoted, and will quote them
205  void appendOpaque(XrdOucString &s, XrdSecEntity *secent, char *hash, time_t tnow);
206 
207  void addCgi(const std::string & key, const std::string & value);
208 
209  // Return the current user agent; if none has been specified, returns an empty string
210  const std::string &userAgent() const {return m_user_agent;}
211 
212  // ----------------
213  // Description of the request. The header/body parsing
214  // is supposed to populate these fields, for fast access while
215  // processing the request
216 
218 
219  enum ReqType {
220  rtUnset = -1,
232  rtPOST
233  };
234 
237  std::string requestverb;
238 
239  // We have to keep the headers for possible further processing
240  // by external plugins
241  std::map<std::string, std::string> allheaders;
242 
249 
250 
252  bool headerok;
253 
257 
258  bool keepalive;
259  long long length; // Total size from client for PUT; total length of response TO client for GET.
260  int depth;
262 
264  std::string host;
266  std::string destination;
267 
269  std::string m_req_digest;
270 
273 
279  std::string m_digest_header;
280 
282  std::string hdr2cgistr;
285  bool m_appended_asize{false};
286 
287  //
288  // Area for coordinating request and responses to/from the bridge
289  //
290 
291 
293  unsigned int rwOpDone, rwOpPartialDone;
294 
297 
301  std::string etext;
303 
305  const struct iovec *iovP;
306  int iovN;
307  int iovL;
308  bool final;
309 
310  // The latest stat info got from the xrd layer
311  long long filesize;
312  long fileflags;
314  long filectime;
315  char fhandle[4];
316  bool fopened;
317 
319  std::string stringresp;
320 
322  int reqstate;
323 
325  long long writtenbytes;
326 
327  int mScitag;
328 
329 
330 
331 
332 
338  int ProcessHTTPReq();
339 
340 
341  // ------------
342  // Items inherited from the Bridge class
343  //
344 
345  //-----------------------------------------------------------------------------
371  //-----------------------------------------------------------------------------
372 
373  virtual bool Data(XrdXrootd::Bridge::Context &info,
374  const
375  struct iovec *iovP,
376  int iovN,
377  int iovL,
378  bool final
379  );
380 
381  //-----------------------------------------------------------------------------
391  //-----------------------------------------------------------------------------
392 
393  virtual bool Done(XrdXrootd::Bridge::Context &info);
394 
395 
396  //-----------------------------------------------------------------------------
409  //-----------------------------------------------------------------------------
410 
411  virtual bool Error(XrdXrootd::Bridge::Context &info,
412  int ecode,
413  const char *etext
414  );
415 
416  //-----------------------------------------------------------------------------
429  //-----------------------------------------------------------------------------
430 
431  virtual int File(XrdXrootd::Bridge::Context &info,
432  int dlen
433  );
434 
435  //-----------------------------------------------------------------------------
448  //-----------------------------------------------------------------------------
449 
450  virtual bool Redir(XrdXrootd::Bridge::Context &info,
451  int port,
452  const char *hname
453  );
454 
455 };
456 
457 
458 
459 void trim(std::string &str);
460 
461 #endif /* XRDHTTPREQ_HH */
462 
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
long modtime
Definition: XrdHttpReq.hh:64
std::vector< XrdOucIOVec2 > XrdHttpIOList
Definition: XrdHttpUtils.hh:95
int reqstate
State machine to talk to the bridge.
Definition: XrdHttpReq.hh:322
char fhandle[4]
Definition: XrdHttpReq.hh:315
int ReqReadV(const XrdHttpIOList &cl)
Prepare the buffers for sending a readv request.
Definition: XrdHttpReq.cc:388
bool keepalive
Definition: XrdHttpReq.hh:258
unsigned int rwOpPartialDone
Definition: XrdHttpReq.hh:293
ReqType
These are the HTTP/DAV requests that we support.
Definition: XrdHttpReq.hh:219
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
Definition: XrdHttpReq.hh:195
long long length
Definition: XrdHttpReq.hh:259
std::string destination
The destination field specified in the req.
Definition: XrdHttpReq.hh:266
XrdOucString resource
The resource specified by the request, stripped of opaque data.
Definition: XrdHttpReq.hh:244
bool headerok
Tells if we have finished reading the header.
Definition: XrdHttpReq.hh:252
std::string m_digest_header
The computed digest for the HTTP response header.
Definition: XrdHttpReq.hh:279
std::string etext
Definition: XrdHttpReq.hh:301
std::string stringresp
If we want to give a string as a response, we compose it here.
Definition: XrdHttpReq.hh:319
XResponseType xrdresp
The last response data we got.
Definition: XrdHttpReq.hh:299
std::string requestverb
Definition: XrdHttpReq.hh:237
ReqType request
The request we got.
Definition: XrdHttpReq.hh:236
int ProcessHTTPReq()
Definition: XrdHttpReq.cc:928
long long writtenbytes
In a long write, we track where we have arrived.
Definition: XrdHttpReq.hh:325
XrdOucEnv * opaque
The opaque data, after parsing.
Definition: XrdHttpReq.hh:246
long fileflags
Definition: XrdHttpReq.hh:312
int iovL
byte count
Definition: XrdHttpReq.hh:307
bool fopened
Definition: XrdHttpReq.hh:316
const struct iovec * iovP
The latest data chunks got from the xrd layer. These are valid only inside the callbacks!
Definition: XrdHttpReq.hh:305
virtual ~XrdHttpReq()
Definition: XrdHttpReq.cc:110
std::string m_req_digest
The requested digest type.
Definition: XrdHttpReq.hh:269
XrdOucString resourceplusopaque
The resource specified by the request, including all the opaque data.
Definition: XrdHttpReq.hh:248
virtual bool Data(XrdXrootd::Bridge::Context &info, const struct iovec *iovP, int iovN, int iovL, bool final)
Definition: XrdHttpReq.cc:443
long filectime
Definition: XrdHttpReq.hh:314
std::string hdr2cgistr
Additional opaque info that may come from the hdr2cgi directive.
Definition: XrdHttpReq.hh:282
virtual bool Done(XrdXrootd::Bridge::Context &info)
the result context
Definition: XrdHttpReq.cc:489
std::string host
The host field specified in the req.
Definition: XrdHttpReq.hh:264
long filemodtime
Definition: XrdHttpReq.hh:313
int parseFirstLine(char *line, int len)
Parse the first line of the header.
Definition: XrdHttpReq.cc:256
XrdOucString redirdest
Definition: XrdHttpReq.hh:302
int parseLine(char *line, int len)
Parse the header.
Definition: XrdHttpReq.cc:116
std::string buildPartialHdrEnd(char *token)
Build the closing part for a multipart response.
Definition: XrdHttpReq.cc:435
XrdHttpChecksumHandler::XrdHttpChecksumRawPtr m_req_cksum
The checksum that was ran for this request.
Definition: XrdHttpReq.hh:272
bool m_appended_hdr2cgistr
Definition: XrdHttpReq.hh:283
void appendOpaque(XrdOucString &s, XrdSecEntity *secent, char *hash, time_t tnow)
Definition: XrdHttpReq.cc:629
int iovN
array count
Definition: XrdHttpReq.hh:306
XrdHttpReq(XrdHttpProtocol *protinstance, const XrdHttpReadRangeHandler::Configuration &rcfg)
Definition: XrdHttpReq.hh:166
bool m_appended_asize
Track whether we already appended the oss.asize argument for PUTs.
Definition: XrdHttpReq.hh:285
XrdOucString m_resource_with_digest
Definition: XrdHttpReq.hh:277
long long filesize
Definition: XrdHttpReq.hh:311
bool readClosing
Definition: XrdHttpReq.hh:256
virtual bool Redir(XrdXrootd::Bridge::Context &info, int port, const char *hname)
Definition: XrdHttpReq.cc:533
XErrorCode xrderrcode
Definition: XrdHttpReq.hh:300
virtual int File(XrdXrootd::Bridge::Context &info, int dlen)
Definition: XrdHttpReq.cc:465
std::map< std::string, std::string > allheaders
Definition: XrdHttpReq.hh:241
unsigned int rwOpDone
To coordinate multipart responses across multiple calls.
Definition: XrdHttpReq.hh:293
void addCgi(const std::string &key, const std::string &value)
Definition: XrdHttpReq.cc:786
bool sendcontinue
Definition: XrdHttpReq.hh:261
ClientRequest xrdreq
The last issued xrd request, often pending.
Definition: XrdHttpReq.hh:296
const std::string & userAgent() const
Definition: XrdHttpReq.hh:210
std::string buildPartialHdr(long long bytestart, long long byteend, long long filesize, char *token)
Build a partial header for a multipart response.
Definition: XrdHttpReq.cc:425
XrdHttpReadRangeHandler readRangeHandler
Tracking the next ranges of data to read during GET.
Definition: XrdHttpReq.hh:255
virtual void reset()
Definition: XrdHttpReq.cc:2757
virtual bool Error(XrdXrootd::Bridge::Context &info, int ecode, const char *etext)
Definition: XrdHttpReq.cc:506