XRootD
Loading...
Searching...
No Matches
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
13class XrdSfsFile;
14class XrdHttpExtReq;
15typedef void CURL;
16struct curl_slist;
17
18namespace TPC {
19class Stream;
20
21class State {
22public:
23
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
146private:
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
State(off_t start_offset, Stream &stream, CURL *curl, bool push, bool tpcForwardCreds)
State * Duplicate()
void Move(State &other)
int GetStatusCode() const
CURL * GetHandle() const
void DumpBuffers() const
off_t BytesTransferred() const
bool BodyTransferInProgress() const
void SetErrorMessage(const std::string &error_msg)
void ResetAfterRequest()
int GetErrorCode() const
void SetTransferParameters(off_t offset, size_t size)
std::string GetErrorMessage() const
std::string GetConnectionDescription()
void SetupHeaders(XrdHttpExtReq &req)
void SetContentLength(const off_t content_length)
off_t GetContentLength() const
void SetErrorCode(int error_code)
bool Finalize()
State(CURL *curl, bool tpcForwardCreds)
int AvailableBuffers() const