XRootD
XrdTpcState.hh
Go to the documentation of this file.
1 
6 #ifndef __XRD_TPC_STATE_HH__
7 #define __XRD_TPC_STATE_HH__
8 
9 #include <memory>
10 #include <vector>
11 
12 // Forward dec'ls
13 class XrdSfsFile;
14 class XrdHttpExtReq;
15 typedef void CURL;
16 struct curl_slist;
17 
18 namespace TPC {
19 class Stream;
20 
21 class State {
22 public:
23 
24  State() :
25  m_push(true),
26  m_recv_status_line(false),
27  m_recv_all_headers(false),
28  m_offset(0),
29  m_start_offset(0),
30  m_status_code(-1),
31  m_error_code(0),
32  m_content_length(-1),
33  m_stream(NULL),
34  m_curl(NULL),
35  m_headers(NULL),
36  m_is_transfer_state(true)
37  {}
38 
43  State(CURL * curl, bool tpcForwardCreds):
44  m_push(true),
45  m_recv_status_line(false),
46  m_recv_all_headers(false),
47  m_offset(0),
48  m_start_offset(0),
49  m_status_code(-1),
50  m_error_code(0),
51  m_content_length(-1),
52  m_push_length(-1),
53  m_stream(NULL),
54  m_curl(curl),
55  m_headers(NULL),
56  m_is_transfer_state(false),
57  tpcForwardCreds(tpcForwardCreds)
58  {
59  InstallHandlers(curl);
60  }
61 
62  // Note that we are "borrowing" a reference to the curl handle;
63  // it is not owned / freed by the State object. However, we use it
64  // as if there's only one handle per State.
65  State (off_t start_offset, Stream &stream, CURL *curl, bool push, bool tpcForwardCreds) :
66  m_push(push),
67  m_recv_status_line(false),
68  m_recv_all_headers(false),
69  m_offset(0),
70  m_start_offset(start_offset),
71  m_status_code(-1),
72  m_error_code(0),
73  m_content_length(-1),
74  m_push_length(-1),
75  m_stream(&stream),
76  m_curl(curl),
77  m_headers(NULL),
78  m_is_transfer_state(true),
79  tpcForwardCreds(tpcForwardCreds)
80  {
81  InstallHandlers(curl);
82  }
83 
84  ~State();
85 
86  void SetTransferParameters(off_t offset, size_t size);
87 
88  void SetupHeaders(XrdHttpExtReq &req);
89 
90  off_t BytesTransferred() const {return m_offset;}
91 
92  void SetContentLength(const off_t content_length) { m_content_length = content_length; }
93 
94  off_t GetContentLength() const {return m_content_length;}
95 
96  int GetErrorCode() const {return m_error_code;}
97 
98  void SetErrorCode(int error_code) {m_error_code = error_code;}
99 
100  int GetStatusCode() const {return m_status_code;}
101 
102  std::string GetErrorMessage() const {return m_error_buf;}
103 
104  void SetErrorMessage(const std::string &error_msg) {m_error_buf = error_msg;}
105 
106  void ResetAfterRequest();
107 
108  CURL *GetHandle() const {return m_curl;}
109 
110  int AvailableBuffers() const;
111 
112  void DumpBuffers() const;
113 
114  // Returns true if at least one byte of the response has been received,
115  // but not the entire contents of the response.
116  bool BodyTransferInProgress() const {return m_offset && (m_offset != m_content_length);}
117 
118  // Duplicate the current state; all settings are copied over, but those
119  // related to the transient state are reset as if from a constructor.
120  State *Duplicate();
121 
122  // Move the contents of a State object. To be replaced by a move
123  // constructor once C++11 is allowed in XRootD.
124  void Move (State &other);
125 
126  // Flush and finalize a transfer state. Eventually calls close() on the underlying
127  // file handle, which should hopefully synchronize the file metadata across
128  // all readers (even other load-balanced servers on the same distributed file
129  // system).
130  //
131  // Returns true on success; false otherwise. Failures can happen, for example, if
132  // not all buffers have been reordered by the underlying stream.
133  bool Finalize();
134 
135  // Flush the data in memory to disk, even if it may cause unaligned or short
136  // writes. Typically, only done while shutting down the transfer (note some
137  // backends may be unable to handle unaligned writes unless it's the last write).
138  int Flush();
139 
140  // Retrieve the description of the remote connection; is of the form:
141  // tcp:129.93.3.4:1234
142  // tcp:[2600:900:6:1301:268a:7ff:fef6:a590]:2345
143  // This is meant to facilitate the monitoring via the performance markers.
144  std::string GetConnectionDescription();
145 
146 private:
147  bool InstallHandlers(CURL *curl);
148 
149  State(const State&);
150  // Add back once C++11 is available
151  //State(State &&) noexcept;
152 
153  // libcurl callback functions, along with the corresponding class methods.
154  static size_t HeaderCB(char *buffer, size_t size, size_t nitems,
155  void *userdata);
156  int Header(const std::string &header);
157  static size_t WriteCB(void *buffer, size_t size, size_t nitems, void *userdata);
158  ssize_t Write(char *buffer, size_t size);
159  static size_t ReadCB(void *buffer, size_t size, size_t nitems, void *userdata);
160  int Read(char *buffer, size_t size);
161 
162  bool m_push; // whether we are transferring in "push-mode"
163  bool m_recv_status_line; // whether we have received a status line in the response from the remote host.
164  bool m_recv_all_headers; // true if we have seen the end of headers.
165  off_t m_offset; // number of bytes we have received.
166  off_t m_start_offset; // offset where we started in the file.
167  int m_status_code; // status code from HTTP response.
168  int m_error_code; // error code from underlying stream operations.
169  off_t m_content_length; // value of Content-Length header, if we received one.
170  off_t m_push_length; // For push transfers, the size of the file on our server.
171  Stream *m_stream; // stream corresponding to this transfer.
172  CURL *m_curl; // libcurl handle
173  struct curl_slist *m_headers; // any headers we set as part of the libcurl request.
174  std::vector<std::string> m_headers_copy; // Copies of custom headers.
175  std::string m_resp_protocol; // Response protocol in the HTTP status line.
176  std::string m_error_buf; // Any error associated with a response.
177  bool m_is_transfer_state; // If set to true, this state will be used to perform some transfers
178  bool tpcForwardCreds = false; // if set to true, the redirection will send user credentials to the redirection host
179 };
180 
181 };
182 
183 #endif
void CURL
Definition: XrdTpcState.hh:14
State(off_t start_offset, Stream &stream, CURL *curl, bool push, bool tpcForwardCreds)
Definition: XrdTpcState.hh:65
State * Duplicate()
Definition: XrdTpcState.cc:260
void Move(State &other)
Definition: XrdTpcState.cc:27
int GetStatusCode() const
Definition: XrdTpcState.hh:100
CURL * GetHandle() const
Definition: XrdTpcState.hh:108
void DumpBuffers() const
Definition: XrdTpcState.cc:297
off_t BytesTransferred() const
Definition: XrdTpcState.hh:90
bool BodyTransferInProgress() const
Definition: XrdTpcState.hh:116
void SetErrorMessage(const std::string &error_msg)
Definition: XrdTpcState.hh:104
void ResetAfterRequest()
Definition: XrdTpcState.cc:135
int GetErrorCode() const
Definition: XrdTpcState.hh:96
void SetTransferParameters(off_t offset, size_t size)
Definition: XrdTpcState.cc:283
std::string GetErrorMessage() const
Definition: XrdTpcState.hh:102
std::string GetConnectionDescription()
Definition: XrdTpcState.cc:312
void SetupHeaders(XrdHttpExtReq &req)
Definition: XrdTpcState.cc:101
void SetContentLength(const off_t content_length)
Definition: XrdTpcState.hh:92
off_t GetContentLength() const
Definition: XrdTpcState.hh:94
void SetErrorCode(int error_code)
Definition: XrdTpcState.hh:98
bool Finalize()
Definition: XrdTpcState.cc:302
State(CURL *curl, bool tpcForwardCreds)
Definition: XrdTpcState.hh:43
int AvailableBuffers() const
Definition: XrdTpcState.cc:292