Loading...
Searching...
No Matches
XrdHttpReq.hh
Go to the documentation of this file.
//------------------------------------------------------------------------------
// This file is part of XrdHTTP: A pragmatic implementation of the
// HTTP/WebDAV protocol for the Xrootd framework
//
// Copyright (c) 2013 by European Organization for Nuclear Research (CERN)
// Author: Fabrizio Furano <furano@cern.ch>
// File Date: Nov 2012
//------------------------------------------------------------------------------
// XRootD 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 3 of the License, or
// (at your option) any later version.
//
// XRootD 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 General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with XRootD. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------
#ifndef XRDHTTPREQ_HH
#define XRDHTTPREQ_HH
#include "XrdOuc/XrdOucString.hh"
#include "XProtocol/XProtocol.hh"
#include "XrdXrootd/XrdXrootdBridge.hh"
#include "XrdHttpChecksumHandler.hh"
#include "XrdHttpReadRangeHandler.hh"
#include <vector>
#include <string>
#include <map>
//#include <libxml/parser.h>
//#include <libxml/tree.h>
struct DirListInfo {
std::string path;
long long size;
long id;
long flags;
long modtime;
};
class XrdHttpProtocol;
class XrdOucEnv;
class XrdHttpReq : public XrdXrootd::Bridge::Result {
public:
// ----------------
// Description of the request. The header/body parsing
// is supposed to populate these fields, for fast access while
// processing the request
enum ReqType: int {
rtUnset = -1,
rtUnknown = 0,
rtMalformed,
rtGET,
rtHEAD,
rtPUT,
rtOPTIONS,
rtPATCH,
rtDELETE,
rtPROPFIND,
rtMKCOL,
rtMOVE,
rtPOST
};
private:
// HTTP response parameters to be sent back to the user
int httpStatusCode;
// HTTP Error code for the response
// e.g. 8.1, 8.3.1, etc.
// https://twiki.cern.ch/twiki/bin/view/LCG/WebdavErrorImprovement
std::string httpErrorCode;
// HTTP response text with following format:
// Severity: ErrorCode: free-style text message
// Severity being OK, WARNING, or ERROR
// ErrorCode being a decimal numeric plus dot string, i.e. n or n.m or n.m.l,
// etc. free-style text message any UTF-8 string
// Optionally, it also contains the trailer headers whereever applicable
// e.g. X-Transfer-Status: 200: OK
// or X-Transfer-Status: 500: ERROR: <error message>: <additional text>
std::string httpErrorBody;
// The value of the user agent, if specified
std::string m_user_agent;
// Whether transfer encoding was requested.
bool m_transfer_encoding_chunked;
long long m_current_chunk_offset;
long long m_current_chunk_size;
// Whether trailer headers were enabled
bool m_trailer_headers{false};
// Whether the client understands our special status trailer.
// The status trailer allows us to report when an IO error occurred
// after a response body has started
bool m_status_trailer{false};
int parseHost(char *);
void parseScitag(const std::string & val);
//xmlDocPtr xmlbody; /* the resulting document tree */
XrdHttpProtocol *prot;
void clientMarshallReadAheadList(int nitems);
void clientUnMarshallReadAheadList(int nitems);
void getfhandle();
// Process the checksum response and return a header that should
// be included in the response.
int PostProcessChecksum(std::string &digest_header);
// Process the listing request of a GET request against a directory
// - final_: True if this is the last entry in the listing.
int PostProcessListing(bool final_);
// Send the response for a GET request for a file read (i.e., not a directory)
// Invoked after the open is successful but before the first read is issued.
int ReturnGetHeaders();
int PostProcessHTTPReq(bool final = false);
// Parse a resource string, typically a filename, setting the resource field and the opaque data
void parseResource(char *url);
// Set Webdav Error messages
void generateWebdavErrMsg();
// Sanitize the resource from http[s]://[host]/ questionable prefix
void sanitizeResourcePfx();
// parses the iovN data pointers elements as either a kXR_read or kXR_readv
// response and fills out a XrdHttpIOList with the corresponding length and
// buffer pointers. File offsets from kXR_readv responses are not recorded.
void getReadResponse(XrdHttpIOList &received);
// notifies the range handler of receipt of bytes and sends the client
// the data.
int sendReadResponseSingleRange(const XrdHttpIOList &received);
// notifies the range handler of receipt of bytes and sends the client
// the data and necessary headers, assuming multipart/byteranges content type.
int sendReadResponsesMultiRanges(const XrdHttpIOList &received);
// If requested by the client, sends any I/O errors that occur during the transfer
// into a footer.
int sendFooterError(const std::string &);
// Set the age header from the file modification time
void addAgeHeader(std::string & headers);
static void extractChecksumFromList(const std::string & checksumList, std::vector<std::string> & extractedChecksum);
static void determineXRootDChecksumFromUserDigest(const std::string & userDigest, std::vector<std::string> & xrootdChecksums);
public:
XrdHttpReq(XrdHttpProtocol *protinstance, const XrdHttpReadRangeHandler::Configuration &rcfg) :
readRangeHandler(rcfg), closeAfterError(false), keepalive(true) {
prot = protinstance;
length = 0;
//xmlbody = 0;
depth = 0;
opaque = 0;
writtenbytes = 0;
fopened = false;
headerok = false;
mScitag = -1;
};
virtual ~XrdHttpReq();
virtual void reset();
int parseLine(char *line, int len);
int parseFirstLine(char *line, int len);
int parseBody(char *body, long long len);
int ReqReadV(const XrdHttpIOList &cl);
std::vector<readahead_list> ralist;
std::string buildPartialHdr(long long bytestart, long long byteend, long long filesize, char *token);
std::string buildPartialHdrEnd(char *token);
// Appends the opaque info that we have
// NOTE: this function assumes that the strings are unquoted, and will quote them
void appendOpaque(XrdOucString &s, XrdSecEntity *secent, char *hash, time_t tnow);
void addCgi(const std::string & key, const std::string & value);
// Set the transfer status header, if requested by the client
void setTransferStatusHeader(std::string &header);
// Return the current user agent; if none has been specified, returns an empty string
const std::string &userAgent() const {return m_user_agent;}
ReqType request;
std::string requestverb;
// We have to keep the headers for possible further processing
// by external plugins
std::map<std::string, std::string> allheaders;
XrdOucString resource;
XrdOucEnv *opaque;
XrdOucString resourceplusopaque;
bool headerok;
XrdHttpReadRangeHandler readRangeHandler;
bool readClosing;
// Indication that there was a read error and the next
// request processing state should cleanly close the file.
bool closeAfterError;
bool keepalive;
long long length; // Total size from client for PUT; total length of response TO client for GET.
int depth;
bool sendcontinue;
std::string host;
std::string destination;
std::string m_req_digest;
XrdHttpChecksumHandler::XrdHttpChecksumRawPtr m_req_cksum = nullptr;
XrdOucString m_resource_with_digest;
std::string m_digest_header;
std::string hdr2cgistr;
bool m_appended_hdr2cgistr;
bool m_appended_asize{false};
//
// Area for coordinating request and responses to/from the bridge
//
unsigned int rwOpDone, rwOpPartialDone;
ClientRequest xrdreq;
XResponseType xrdresp;
XErrorCode xrderrcode;
std::string etext;
XrdOucString redirdest;
const struct iovec *iovP;
int iovN;
int iovL;
bool final;
// The latest stat info got from the xrd layer
long long filesize;
long fileflags;
long filemodtime;
long filectime;
char fhandle[4];
bool fopened;
std::string stringresp;
int reqstate;
long long writtenbytes;
int mScitag;
std::string m_origin;
int ProcessHTTPReq();
// ------------
// Items inherited from the Bridge class
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
virtual bool Data(XrdXrootd::Bridge::Context &info,
const
struct iovec *iovP,
int iovN,
int iovL,
bool final
);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
virtual bool Done(XrdXrootd::Bridge::Context &info);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
virtual bool Error(XrdXrootd::Bridge::Context &info,
int ecode,
const char *etext
);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
virtual int File(XrdXrootd::Bridge::Context &info,
int dlen
);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
virtual bool Redir(XrdXrootd::Bridge::Context &info,
int port,
const char *hname
);
};
void trim(std::string &str);
#endif /* XRDHTTPREQ_HH */
XProtocol.hh
XErrorCode
XErrorCode
Definition XProtocol.hh:989
XResponseType
XResponseType
Definition XProtocol.hh:898
ClientRequest
Definition XProtocol.hh:845
XrdHttpChecksumHandler.hh
XrdHttpReadRangeHandler.hh
DirListInfo::size
long long size
Definition XrdHttpReq.hh:61
DirListInfo::flags
long flags
Definition XrdHttpReq.hh:63
trim
void trim(std::string &str)
Definition XrdHttpReq.cc:77
DirListInfo::id
long id
Definition XrdHttpReq.hh:62
DirListInfo::path
std::string path
Definition XrdHttpReq.hh:60
DirListInfo::modtime
long modtime
Definition XrdHttpReq.hh:64
DirListInfo
Definition XrdHttpReq.hh:59
XrdHttpIOList
std::vector< XrdOucIOVec2 > XrdHttpIOList
Definition XrdHttpUtils.hh:252
XrdOucString.hh
File
XrdOucString File
Definition XrdSecpwdSrvAdmin.cc:159
Error
@ Error
Definition XrdTlsNotaryUtils.hh:42
XrdXrootdBridge.hh
XrdHttpChecksumHandler::XrdHttpChecksumRawPtr
XrdHttpChecksumHandlerImpl::XrdHttpChecksumRawPtr XrdHttpChecksumRawPtr
Definition XrdHttpChecksumHandler.hh:87
XrdHttpProtocol
Definition XrdHttpProtocol.hh:81
XrdHttpReadRangeHandler
Definition XrdHttpReadRangeHandler.hh:36
XrdHttpReq::reqstate
int reqstate
State machine to talk to the bridge.
Definition XrdHttpReq.hh:348
XrdHttpReq::fhandle
char fhandle[4]
Definition XrdHttpReq.hh:341
XrdHttpReq::ReqReadV
int ReqReadV(const XrdHttpIOList &cl)
Prepare the buffers for sending a readv request.
Definition XrdHttpReq.cc:397
XrdHttpReq::keepalive
bool keepalive
Definition XrdHttpReq.hh:284
XrdHttpReq::rwOpPartialDone
unsigned int rwOpPartialDone
Definition XrdHttpReq.hh:319
XrdHttpReq::parseBody
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:95
XrdHttpReq::ralist
std::vector< readahead_list > ralist
Definition XrdHttpReq.hh:236
XrdHttpReq::length
long long length
Definition XrdHttpReq.hh:285
XrdHttpReq::destination
std::string destination
The destination field specified in the req.
Definition XrdHttpReq.hh:292
XrdHttpReq::resource
XrdOucString resource
The resource specified by the request, stripped of opaque data.
Definition XrdHttpReq.hh:266
XrdHttpReq::headerok
bool headerok
Tells if we have finished reading the header.
Definition XrdHttpReq.hh:274
XrdHttpReq::m_digest_header
std::string m_digest_header
The computed digest for the HTTP response header.
Definition XrdHttpReq.hh:305
XrdHttpReq::etext
std::string etext
Definition XrdHttpReq.hh:327
XrdHttpReq::stringresp
std::string stringresp
If we want to give a string as a response, we compose it here.
Definition XrdHttpReq.hh:345
XrdHttpReq::userAgent
const std::string & userAgent() const
Definition XrdHttpReq.hh:254
XrdHttpReq::xrdresp
XResponseType xrdresp
The last response data we got.
Definition XrdHttpReq.hh:325
XrdHttpReq::requestverb
std::string requestverb
Definition XrdHttpReq.hh:259
XrdHttpReq::request
ReqType request
The request we got.
Definition XrdHttpReq.hh:258
XrdHttpReq::ProcessHTTPReq
int ProcessHTTPReq()
Definition XrdHttpReq.cc:839
XrdHttpReq::closeAfterError
bool closeAfterError
Definition XrdHttpReq.hh:282
XrdHttpReq::writtenbytes
long long writtenbytes
In a long write, we track where we have arrived.
Definition XrdHttpReq.hh:351
XrdHttpReq::opaque
XrdOucEnv * opaque
The opaque data, after parsing.
Definition XrdHttpReq.hh:268
XrdHttpReq::fileflags
long fileflags
Definition XrdHttpReq.hh:338
XrdHttpReq::iovL
int iovL
byte count
Definition XrdHttpReq.hh:333
XrdHttpReq::depth
int depth
Definition XrdHttpReq.hh:286
XrdHttpReq::fopened
bool fopened
Definition XrdHttpReq.hh:342
XrdHttpReq::iovP
const struct iovec * iovP
The latest data chunks got from the xrd layer. These are valid only inside the callbacks!
Definition XrdHttpReq.hh:331
XrdHttpReq::mScitag
int mScitag
Definition XrdHttpReq.hh:353
XrdHttpReq::~XrdHttpReq
virtual ~XrdHttpReq()
Definition XrdHttpReq.cc:111
XrdHttpReq::m_req_digest
std::string m_req_digest
The requested digest type.
Definition XrdHttpReq.hh:295
XrdHttpReq::resourceplusopaque
XrdOucString resourceplusopaque
The resource specified by the request, including all the opaque data.
Definition XrdHttpReq.hh:270
XrdHttpReq::Data
virtual bool Data(XrdXrootd::Bridge::Context &info, const struct iovec *iovP, int iovN, int iovL, bool final)
Definition XrdHttpReq.cc:452
XrdHttpReq::filectime
long filectime
Definition XrdHttpReq.hh:340
XrdHttpReq::hdr2cgistr
std::string hdr2cgistr
Additional opaque info that may come from the hdr2cgi directive.
Definition XrdHttpReq.hh:308
XrdHttpReq::Done
virtual bool Done(XrdXrootd::Bridge::Context &info)
the result context
Definition XrdHttpReq.cc:498
XrdHttpReq::host
std::string host
The host field specified in the req.
Definition XrdHttpReq.hh:290
XrdHttpReq::filemodtime
long filemodtime
Definition XrdHttpReq.hh:339
XrdHttpReq::parseFirstLine
int parseFirstLine(char *line, int len)
Parse the first line of the header.
Definition XrdHttpReq.cc:265
XrdHttpReq::redirdest
XrdOucString redirdest
Definition XrdHttpReq.hh:328
XrdHttpReq::m_origin
std::string m_origin
Definition XrdHttpReq.hh:355
XrdHttpReq::ReqType
ReqType
These are the HTTP/DAV requests that we support.
Definition XrdHttpReq.hh:81
XrdHttpReq::rtUnset
@ rtUnset
Definition XrdHttpReq.hh:82
XrdHttpReq::rtMalformed
@ rtMalformed
Definition XrdHttpReq.hh:84
XrdHttpReq::rtDELETE
@ rtDELETE
Definition XrdHttpReq.hh:90
XrdHttpReq::rtOPTIONS
@ rtOPTIONS
Definition XrdHttpReq.hh:88
XrdHttpReq::rtMOVE
@ rtMOVE
Definition XrdHttpReq.hh:93
XrdHttpReq::rtHEAD
@ rtHEAD
Definition XrdHttpReq.hh:86
XrdHttpReq::rtGET
@ rtGET
Definition XrdHttpReq.hh:85
XrdHttpReq::rtPATCH
@ rtPATCH
Definition XrdHttpReq.hh:89
XrdHttpReq::rtPROPFIND
@ rtPROPFIND
Definition XrdHttpReq.hh:91
XrdHttpReq::rtPUT
@ rtPUT
Definition XrdHttpReq.hh:87
XrdHttpReq::rtUnknown
@ rtUnknown
Definition XrdHttpReq.hh:83
XrdHttpReq::rtPOST
@ rtPOST
Definition XrdHttpReq.hh:94
XrdHttpReq::rtMKCOL
@ rtMKCOL
Definition XrdHttpReq.hh:92
XrdHttpReq::parseLine
int parseLine(char *line, int len)
Parse the header.
Definition XrdHttpReq.cc:117
XrdHttpReq::buildPartialHdrEnd
std::string buildPartialHdrEnd(char *token)
Build the closing part for a multipart response.
Definition XrdHttpReq.cc:444
XrdHttpReq::m_req_cksum
XrdHttpChecksumHandler::XrdHttpChecksumRawPtr m_req_cksum
The checksum that was ran for this request.
Definition XrdHttpReq.hh:298
XrdHttpReq::setTransferStatusHeader
void setTransferStatusHeader(std::string &header)
Definition XrdHttpReq.cc:2017
XrdHttpReq::m_appended_hdr2cgistr
bool m_appended_hdr2cgistr
Definition XrdHttpReq.hh:309
XrdHttpReq::appendOpaque
void appendOpaque(XrdOucString &s, XrdSecEntity *secent, char *hash, time_t tnow)
Definition XrdHttpReq.cc:639
XrdHttpReq::iovN
int iovN
array count
Definition XrdHttpReq.hh:332
XrdHttpReq::XrdHttpReq
XrdHttpReq(XrdHttpProtocol *protinstance, const XrdHttpReadRangeHandler::Configuration &rcfg)
Definition XrdHttpReq.hh:207
XrdHttpReq::m_appended_asize
bool m_appended_asize
Track whether we already appended the oss.asize argument for PUTs.
Definition XrdHttpReq.hh:311
XrdHttpReq::m_resource_with_digest
XrdOucString m_resource_with_digest
Definition XrdHttpReq.hh:303
XrdHttpReq::filesize
long long filesize
Definition XrdHttpReq.hh:337
XrdHttpReq::readClosing
bool readClosing
Definition XrdHttpReq.hh:278
XrdHttpReq::Redir
virtual bool Redir(XrdXrootd::Bridge::Context &info, int port, const char *hname)
Definition XrdHttpReq.cc:545
XrdHttpReq::xrderrcode
XErrorCode xrderrcode
Definition XrdHttpReq.hh:326
XrdHttpReq::allheaders
std::map< std::string, std::string > allheaders
Definition XrdHttpReq.hh:263
XrdHttpReq::rwOpDone
unsigned int rwOpDone
To coordinate multipart responses across multiple calls.
Definition XrdHttpReq.hh:319
XrdHttpReq::addCgi
void addCgi(const std::string &key, const std::string &value)
Definition XrdHttpReq.cc:747
XrdHttpReq::sendcontinue
bool sendcontinue
Definition XrdHttpReq.hh:287
XrdHttpReq::xrdreq
ClientRequest xrdreq
The last issued xrd request, often pending.
Definition XrdHttpReq.hh:322
XrdHttpReq::buildPartialHdr
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:434
XrdHttpReq::readRangeHandler
XrdHttpReadRangeHandler readRangeHandler
Tracking the next ranges of data to read during GET.
Definition XrdHttpReq.hh:277
XrdHttpReq::reset
virtual void reset()
Definition XrdHttpReq.cc:2715
XrdOucEnv
Definition XrdOucEnv.hh:42
XrdOucString
Definition XrdOucString.hh:252
XrdSecEntity
Definition XrdSecEntity.hh:65
XrdXrootd::Bridge::Context
Definition XrdXrootdBridge.hh:226
XrdXrootd::Bridge::Result
Definition XrdXrootdBridge.hh:294
XrdHttpReadRangeHandler::Configuration
Definition XrdHttpReadRangeHandler.hh:54