xrootd
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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"
47 
48 #include <vector>
49 #include <string>
50 #include <map>
51 
52 //#include <libxml/parser.h>
53 //#include <libxml/tree.h>
54 
55 
56 
57 #define READV_MAXCHUNKS 512
58 #define READV_MAXCHUNKSIZE (1024*128)
59 
60 struct ReadWriteOp {
61  // < 0 means "not specified"
62  long long bytestart;
63  long long byteend;
64 };
65 
66 struct DirListInfo {
67  std::string path;
68  long long size;
69  long id;
70  long flags;
71  long modtime;
72 };
73 
74 
75 class XrdHttpProtocol;
76 class XrdOucEnv;
77 
79 private:
80  // HTTP response parameters to be sent back to the user
82  std::string httpStatusText;
83 
84  // Whether transfer encoding was requested.
88 
89  int parseContentRange(char *);
90  int parseHost(char *);
91  int parseRWOp(char *);
92 
93  //xmlDocPtr xmlbody; /* the resulting document tree */
95 
96  void clientMarshallReadAheadList(int nitems);
97  void clientUnMarshallReadAheadList(int nitems);
98 
99 
100  void getfhandle();
101 
102  // Process the checksum response and return a header that should
103  // be included in the response.
104  int PostProcessChecksum(std::string &digest_header);
105 
111  int PostProcessHTTPReq(bool final = false);
112 
113  // Parse a resource string, typically a filename, setting the resource field and the opaque data
114  void parseResource(char *url);
115  // Map an XRootD error code to an appropriate HTTP status code and message
117 
118  // Sanitize the resource from http[s]://[host]/ questionable prefix
119  void sanitizeResourcePfx();
120 
126  static void extractChecksumFromList(const std::string & checksumList, std::vector<std::string> & extractedChecksum);
127 
134  static void determineXRootDChecksumFromUserDigest(const std::string & userDigest, std::vector<std::string> & xrootdChecksums);
135 
136 public:
137  XrdHttpReq(XrdHttpProtocol *protinstance) : keepalive(true) {
138 
139  prot = protinstance;
140  length = 0;
141  //xmlbody = 0;
142  depth = 0;
143  ralist = 0;
144  opaque = 0;
145  writtenbytes = 0;
146  fopened = false;
147  headerok = false;
148  };
149 
150  virtual ~XrdHttpReq();
151 
152  virtual void reset();
153 
155  int parseLine(char *line, int len);
156 
158  int parseFirstLine(char *line, int len);
159 
161  int parseBody(char *body, long long len);
162 
164  int ReqReadV();
166 
168  std::string buildPartialHdr(long long bytestart, long long byteend, long long filesize, char *token);
169 
171  std::string buildPartialHdrEnd(char *token);
172 
173  // Appends the opaque info that we have
174  // NOTE: this function assumes that the strings are unquoted, and will quote them
175  void appendOpaque(XrdOucString &s, XrdSecEntity *secent, char *hash, time_t tnow);
176 
177  // ----------------
178  // Description of the request. The header/body parsing
179  // is supposed to populate these fields, for fast access while
180  // processing the request
181 
183 
184  enum ReqType {
185  rtUnset = -1,
198  };
199 
202  std::string requestverb;
203 
204  // We have to keep the headers for possible further processing
205  // by external plugins
206  std::map<std::string, std::string> allheaders;
207 
214 
215 
217  bool headerok;
218 
219 
220  // This can be largely optimized...
222  std::vector<ReadWriteOp> rwOps;
225  std::vector<ReadWriteOp> rwOps_split;
226 
227  bool keepalive;
228  long long length; // Total size from client for PUT; total length of response TO client for GET.
229  int depth;
231 
233  std::string host;
235  std::string destination;
236 
238  std::string m_req_digest;
239 
242 
248  std::string m_digest_header;
249 
251  std::string hdr2cgistr;
253 
254  //
255  // Area for coordinating request and responses to/from the bridge
256  //
257 
258 
260  unsigned int rwOpDone, rwOpPartialDone;
261 
264 
268  std::string etext;
270 
272  const struct iovec *iovP;
273  int iovN;
274  int iovL;
275  bool final;
276 
277  // The latest stat info got from the xrd layer
278  long long filesize;
279  long fileflags;
281  char fhandle[4];
282  bool fopened;
283 
285  std::string stringresp;
286 
288  int reqstate;
289 
291  long long writtenbytes;
292 
293 
294 
295 
296 
302  int ProcessHTTPReq();
303 
304 
305  // ------------
306  // Items inherited from the Bridge class
307  //
308 
309  //-----------------------------------------------------------------------------
335  //-----------------------------------------------------------------------------
336 
337  virtual bool Data(XrdXrootd::Bridge::Context &info,
338  const
339  struct iovec *iovP,
340  int iovN,
341  int iovL,
342  bool final
343  );
344 
345  //-----------------------------------------------------------------------------
355  //-----------------------------------------------------------------------------
356 
357  virtual bool Done(XrdXrootd::Bridge::Context &info);
358 
359 
360  //-----------------------------------------------------------------------------
373  //-----------------------------------------------------------------------------
374 
375  virtual bool Error(XrdXrootd::Bridge::Context &info,
376  int ecode,
377  const char *etext
378  );
379 
380  //-----------------------------------------------------------------------------
393  //-----------------------------------------------------------------------------
394 
395  virtual int File(XrdXrootd::Bridge::Context &info,
396  int dlen
397  );
398 
399  //-----------------------------------------------------------------------------
412  //-----------------------------------------------------------------------------
413 
414  virtual bool Redir(XrdXrootd::Bridge::Context &info,
415  int port,
416  const char *hname
417  );
418 
419 };
420 
421 
422 
423 void trim(std::string &str);
424 
425 #endif /* XRDHTTPREQ_HH */
426 
long filemodtime
Definition: XrdHttpReq.hh:280
virtual bool Data(XrdXrootd::Bridge::Context &info, const struct iovec *iovP, int iovN, int iovL, bool final)
int depth
Definition: XrdHttpReq.hh:229
XResponseType xrdresp
The last response data we got.
Definition: XrdHttpReq.hh:266
void clientMarshallReadAheadList(int nitems)
Definition: XrdHttpReq.hh:193
std::string requestverb
Definition: XrdHttpReq.hh:202
Definition: XrdHttpReq.hh:189
long modtime
Definition: XrdHttpReq.hh:71
long fileflags
Definition: XrdHttpReq.hh:279
std::string buildPartialHdr(long long bytestart, long long byteend, long long filesize, char *token)
Build a partial header for a multipart response.
int parseFirstLine(char *line, int len)
Parse the first line of the header.
long long writtenbytes
In a long write, we track where we have arrived.
Definition: XrdHttpReq.hh:291
Definition: XProtocol.hh:658
bool sendcontinue
Definition: XrdHttpReq.hh:230
XrdHttpProtocol * prot
Definition: XrdHttpReq.hh:94
std::string destination
The destination field specified in the req.
Definition: XrdHttpReq.hh:235
Definition: XrdXrootdBridge.hh:225
XrdOucString resourceplusopaque
The resource specified by the request, including all the opaque data.
Definition: XrdHttpReq.hh:213
XrdOucString m_resource_with_digest
Definition: XrdHttpReq.hh:246
Definition: XrdHttpReq.hh:78
void parseResource(char *url)
static void determineXRootDChecksumFromUserDigest(const std::string &userDigest, std::vector< std::string > &xrootdChecksums)
void trim(std::string &str)
int ProcessHTTPReq()
virtual bool Redir(XrdXrootd::Bridge::Context &info, int port, const char *hname)
Definition: XrdHttpReq.hh:196
ReqType
These are the HTTP/DAV requests that we support.
Definition: XrdHttpReq.hh:184
bool fopened
Definition: XrdHttpReq.hh:282
long long size
Definition: XrdHttpReq.hh:68
static void extractChecksumFromList(const std::string &checksumList, std::vector< std::string > &extractedChecksum)
Definition: XrdHttpReq.hh:60
XrdOucEnv * opaque
The opaque data, after parsing.
Definition: XrdHttpReq.hh:211
XResponseType
Definition: XProtocol.hh:896
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: XrdOucJson.hh:5221
int parseLine(char *line, int len)
Parse the header.
int iovL
byte count
Definition: XrdHttpReq.hh:274
XrdHttpChecksumHandler::XrdHttpChecksumRawPtr m_req_cksum
The checksum that was ran for this request.
Definition: XrdHttpReq.hh:241
std::string etext
Definition: XrdHttpReq.hh:268
long long bytestart
Definition: XrdHttpReq.hh:62
virtual bool Error(XrdXrootd::Bridge::Context &info, int ecode, const char *etext)
Definition: XrdHttpReq.hh:197
bool headerok
Tells if we have finished reading the header.
Definition: XrdHttpReq.hh:217
bool keepalive
Definition: XrdHttpReq.hh:227
std::vector< ReadWriteOp > rwOps
The original list of multiple reads to perform.
Definition: XrdHttpReq.hh:222
char fhandle[4]
Definition: XrdHttpReq.hh:281
virtual int File(XrdXrootd::Bridge::Context &info, int dlen)
Definition: XrdHttpReq.hh:185
int httpStatusCode
Definition: XrdHttpReq.hh:81
int parseHost(char *)
virtual ~XrdHttpReq()
Definition: XrdHttpReq.hh:66
virtual bool Done(XrdXrootd::Bridge::Context &info)
the result context
Definition: XrdHttpReq.hh:195
long long m_current_chunk_size
Definition: XrdHttpReq.hh:87
std::string buildPartialHdrEnd(char *token)
Build the closing part for a multipart response.
std::string hdr2cgistr
Additional opaque info that may come from the hdr2cgi directive.
Definition: XrdHttpReq.hh:251
int PostProcessHTTPReq(bool final=false)
XErrorCode
Definition: XProtocol.hh:987
readahead_list * ralist
Definition: XrdHttpReq.hh:165
Definition: XrdOucEnv.hh:41
std::string host
The host field specified in the req.
Definition: XrdHttpReq.hh:233
std::string httpStatusText
Definition: XrdHttpReq.hh:82
std::vector< ReadWriteOp > rwOps_split
Definition: XrdHttpReq.hh:225
int parseBody(char *body, long long len)
Parse the body of a request, assuming that it&#39;s XML and that it&#39;s entirely in memory.
std::string m_req_digest
The requested digest type.
Definition: XrdHttpReq.hh:238
void getfhandle()
unsigned int rwOpDone
To coordinate multipart responses across multiple calls.
Definition: XrdHttpReq.hh:260
bool m_transfer_encoding_chunked
Definition: XrdHttpReq.hh:85
std::string m_digest_header
The computed digest for the HTTP response header.
Definition: XrdHttpReq.hh:248
int PostProcessChecksum(std::string &digest_header)
int ReqReadV()
Prepare the buffers for sending a readv request.
void mapXrdErrorToHttpStatus()
Definition: XrdHttpProtocol.hh:77
long id
Definition: XrdHttpReq.hh:69
Definition: XrdXrootdBridge.hh:293
Definition: XrdHttpReq.hh:187
void clientUnMarshallReadAheadList(int nitems)
ClientRequest xrdreq
The last issued xrd request, often pending.
Definition: XrdHttpReq.hh:263
std::string stringresp
If we want to give a string as a response, we compose it here.
Definition: XrdHttpReq.hh:285
long long length
Definition: XrdHttpReq.hh:228
Definition: XrdHttpChecksum.hh:32
int iovN
array count
Definition: XrdHttpReq.hh:273
Definition: XrdHttpReq.hh:194
long long m_current_chunk_offset
Definition: XrdHttpReq.hh:86
int reqstate
State machine to talk to the bridge.
Definition: XrdHttpReq.hh:288
long long filesize
Definition: XrdHttpReq.hh:278
XrdHttpReq(XrdHttpProtocol *protinstance)
Definition: XrdHttpReq.hh:137
int parseRWOp(char *)
bool m_appended_hdr2cgistr
Definition: XrdHttpReq.hh:252
Definition: XrdHttpReq.hh:186
long long byteend
Definition: XrdHttpReq.hh:63
void appendOpaque(XrdOucString &s, XrdSecEntity *secent, char *hash, time_t tnow)
XErrorCode xrderrcode
Definition: XrdHttpReq.hh:267
Definition: XrdSecEntity.hh:63
Definition: XProtocol.hh:843
XrdOucString redirdest
Definition: XrdHttpReq.hh:269
virtual void reset()
ReqType request
The request we got.
Definition: XrdHttpReq.hh:201
XrdOucString resource
The resource specified by the request, stripped of opaque data.
Definition: XrdHttpReq.hh:209
Definition: XrdHttpReq.hh:190
Definition: XrdHttpReq.hh:188
struct iovec * iovP
The latest data chunks got from the xrd layer. These are valid only inside the callbacks! ...
Definition: XrdHttpReq.hh:272
std::map< std::string, std::string > allheaders
Definition: XrdHttpReq.hh:206
Definition: XrdHttpReq.hh:192
void sanitizeResourcePfx()
Definition: XrdOucString.hh:254
unsigned int rwOpPartialDone
Definition: XrdHttpReq.hh:260
long flags
Definition: XrdHttpReq.hh:70
Definition: XrdHttpReq.hh:191
std::string path
Definition: XrdHttpReq.hh:67
int parseContentRange(char *)