XRootD
Loading...
Searching...
No Matches
XrdClHttp::CurlVectorReadOp Class Reference

#include <XrdClHttpOps.hh>

Inheritance diagram for XrdClHttp::CurlVectorReadOp:
Collaboration diagram for XrdClHttp::CurlVectorReadOp:

Public Member Functions

 CurlVectorReadOp (XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, const XrdCl::ChunkList &op_list, XrdCl::Log *logger, CreateConnCalloutType callout, HeaderCallout *header_callout)
virtual ~CurlVectorReadOp ()
void Fail (uint16_t errCode, uint32_t errNum, const std::string &msg) override
virtual HttpVerb GetVerb () const override
void ReleaseHandle () override
void SetSeparator (const std::string &sep)
void SetStatusCode (int sc)
bool Setup (CURL *curl, CurlWorker &) override
void Success () override
size_t Write (char *buffer, size_t size)
Public Member Functions inherited from XrdClHttp::CurlOperation
 CurlOperation (const CurlOperation &)=delete
 CurlOperation (XrdCl::ResponseHandler *handler, const std::string &url, std::chrono::steady_clock::time_point expiry, XrdCl::Log *log, CreateConnCalloutType, HeaderCallout *header_callout)
 CurlOperation (XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, CreateConnCalloutType, HeaderCallout *header_callout)
virtual ~CurlOperation ()
virtual bool ContinueHandle ()
bool FinishSetup (CURL *curl)
std::pair< XErrorCode, std::string > GetCallbackError () const
CreateConnCalloutType GetConnCalloutFunc () const
std::string GetCurlErrorMessage () const
CURLGetCurlHandle () const
OpError GetError () const
std::chrono::steady_clock::time_point GetHeaderExpiry () const
std::chrono::steady_clock::time_point GetOperationExpiry ()
std::unique_ptr< ResponseInfoGetResponseInfo ()
int GetStatusCode () const
std::string GetStatusMessage () const
bool GetTriedBoker () const
const std::string & GetUrl () const
bool HasFailed () const
bool HeaderTimeoutExpired (const std::chrono::steady_clock::time_point &now)
bool IsDone () const
bool IsPaused () const
bool IsRedirect () const
std::unique_ptr< ResponseInfoMoveResponseInfo ()
bool OperationTimeoutExpired (const std::chrono::steady_clock::time_point &now)
virtual void OptionsDone ()
virtual RedirectAction Redirect (std::string &target)
virtual bool RequiresOptions () const
virtual void SetContinueQueue (std::shared_ptr< XrdClHttp::HandlerQueue > queue)
void SetTriedBoker ()
bool StartConnectionCallout (std::string &err)
std::tuple< uint64_t, std::chrono::steady_clock::duration, std::chrono::steady_clock::duration, std::chrono::steady_clock::duration > StatisticsReset ()
bool TransferStalled (uint64_t xfer_bytes, const std::chrono::steady_clock::time_point &now)
bool UseConnectionCallout ()
virtual int WaitSocket ()
virtual int WaitSocketCallback (std::string &err)

Protected Attributes

off_t m_bytes_consumed {0}
off_t m_chunk_buffer_idx {0}
XrdCl::ChunkList m_chunk_list
std::pair< off_t, off_t > m_current_op {-1, -1}
std::string m_header_line
std::string m_response_headers
size_t m_response_idx {0}
uint64_t m_skip_bytes {0}
std::unique_ptr< XrdCl::VectorReadInfom_vr
Protected Attributes inherited from XrdClHttp::CurlOperation
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
XrdCl::ResponseHandlerm_handler {nullptr}
HeaderCalloutm_header_callout
std::chrono::steady_clock::time_point m_header_expiry
HeaderParser m_headers
std::vector< std::pair< std::string, std::string > > m_headers_list
XrdCl::Logm_logger
int m_minimum_rate {m_minimum_transfer_rate}
std::chrono::steady_clock::time_point m_operation_expiry
const std::string m_url

Additional Inherited Members

Public Types inherited from XrdClHttp::CurlOperation
using HeaderList = std::vector<std::pair<std::string, std::string>>
enum class  HttpVerb {
  COPY ,
  DELETE ,
  HEAD ,
  GET ,
  MKCOL ,
  OPTIONS ,
  PROPFIND ,
  PUT ,
  Count
}
enum  OpError {
  ErrNone ,
  ErrHeaderTimeout ,
  ErrCallback ,
  ErrOperationTimeout ,
  ErrTransferClientStall ,
  ErrTransferStall ,
  ErrTransferSlow
}
enum class  RedirectAction {
  Fail ,
  Reinvoke ,
  ReinvokeAfterAllow
}
Static Public Member Functions inherited from XrdClHttp::CurlOperation
static void CleanupDnsCache ()
static int GetDefaultSlowRateBytesSec ()
static int GetDefaultStallTimeout ()
static const std::string GetVerbString (HttpVerb)
static void SetSlowRateBytesSec (int rate)
static void SetStallTimeout (const std::chrono::steady_clock::duration &stall_interval)
static void SetStallTimeout (int stall_interval)
Protected Member Functions inherited from XrdClHttp::CurlOperation
int FailCallback (XErrorCode ecode, const std::string &emsg)
void SetDone (bool has_failed)
void SetPaused (bool paused)
void UpdateBytes (uint64_t bytes)
Static Protected Attributes inherited from XrdClHttp::CurlOperation
static constexpr int m_default_minimum_rate {1024 * 256}
static int m_minimum_transfer_rate {CurlOperation::m_default_minimum_rate}

Detailed Description

Definition at line 698 of file XrdClHttpOps.hh.

Constructor & Destructor Documentation

◆ CurlVectorReadOp()

CurlVectorReadOp::CurlVectorReadOp ( XrdCl::ResponseHandler * handler,
const std::string & url,
struct timespec timeout,
const XrdCl::ChunkList & op_list,
XrdCl::Log * logger,
CreateConnCalloutType callout,
HeaderCallout * header_callout )

Definition at line 30 of file XrdClHttpOpReadV.cc.

32 :
33 CurlOperation(handler, url, timeout, logger, callout, header_callout),
34 m_vr(new XrdCl::VectorReadInfo()),
35 m_chunk_list(op_list)
36 {}
CurlOperation(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, CreateConnCalloutType, HeaderCallout *header_callout)
XrdCl::ChunkList m_chunk_list
std::unique_ptr< XrdCl::VectorReadInfo > m_vr

References XrdClHttp::CurlOperation::CurlOperation(), m_chunk_list, and m_vr.

Here is the call graph for this function:

◆ ~CurlVectorReadOp()

virtual XrdClHttp::CurlVectorReadOp::~CurlVectorReadOp ( )
inlinevirtual

Definition at line 704 of file XrdClHttpOps.hh.

704{}

Member Function Documentation

◆ Fail()

void CurlVectorReadOp::Fail ( uint16_t errCode,
uint32_t errNum,
const std::string & msg )
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 61 of file XrdClHttpOpReadV.cc.

62{
63 std::string custom_msg = msg;
64 SetDone(true);
65 if (m_handler == nullptr) {return;}
66 std::string offset = "(unknown)";
67 std::string length = "(unknown)";
68 if (!m_chunk_list.empty()) {
69 offset = std::to_string(m_chunk_list[0].GetOffset());
70 length = std::to_string(m_chunk_list[0].GetLength());
71 }
72 if (!custom_msg.empty()) {
73 m_logger->Debug(kLogXrdClHttp, "curl operation with vector starting offset %s / length %s failed with message: %s", offset.c_str(), length.c_str(), custom_msg.c_str());
74 custom_msg += " (vector read operation starting at offset " + offset + " / length " + length + ")";
75 } else {
76 m_logger->Debug(kLogXrdClHttp, "curl vector operation starting at offset %s / length %s failed with status code %d", offset.c_str(), length.c_str(), errNum);
77 }
78 auto status = new XrdCl::XRootDStatus(XrdCl::stError, errCode, errNum, custom_msg);
79 auto handle = m_handler;
80 m_handler = nullptr;
81 handle->HandleResponse(status, nullptr);
82}
void SetDone(bool has_failed)
XrdCl::ResponseHandler * m_handler
const uint64_t kLogXrdClHttp
const uint16_t stError
An error occurred that could potentially be retried.

References XrdClHttp::kLogXrdClHttp, m_chunk_list, XrdClHttp::CurlOperation::m_handler, XrdClHttp::CurlOperation::m_logger, XrdClHttp::CurlOperation::SetDone(), and XrdCl::stError.

Here is the call graph for this function:

◆ GetVerb()

virtual HttpVerb XrdClHttp::CurlVectorReadOp::GetVerb ( ) const
inlineoverridevirtual

◆ ReleaseHandle()

void CurlVectorReadOp::ReleaseHandle ( )
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 107 of file XrdClHttpOpReadV.cc.

108{
109 if (m_curl == nullptr) return;
110 curl_easy_setopt(m_curl.get(), CURLOPT_WRITEFUNCTION, nullptr);
111 curl_easy_setopt(m_curl.get(), CURLOPT_WRITEDATA, nullptr);
112 curl_easy_setopt(m_curl.get(), CURLOPT_HTTPHEADER, nullptr);
113 curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETFUNCTION, nullptr);
114 curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETDATA, nullptr);
115 curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTFUNCTION, nullptr);
116 curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTDATA, nullptr);
118}
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
virtual void ReleaseHandle()

References XrdClHttp::CurlOperation::m_curl, and XrdClHttp::CurlOperation::ReleaseHandle().

Here is the call graph for this function:

◆ SetSeparator()

void XrdClHttp::CurlVectorReadOp::SetSeparator ( const std::string & sep)
inline

Definition at line 713 of file XrdClHttpOps.hh.

713 {
714 m_headers.SetMultipartSeparator(sep);
715 }

References XrdClHttp::CurlOperation::m_headers.

◆ SetStatusCode()

void XrdClHttp::CurlVectorReadOp::SetStatusCode ( int sc)
inline

Definition at line 718 of file XrdClHttpOps.hh.

718{m_headers.SetStatusCode(sc);}

References XrdClHttp::CurlOperation::m_headers.

◆ Setup()

bool CurlVectorReadOp::Setup ( CURL * curl,
CurlWorker & worker )
overridevirtual

Reimplemented from XrdClHttp::CurlOperation.

Definition at line 39 of file XrdClHttpOpReadV.cc.

40{
41 if (!CurlOperation::Setup(curl, worker)) return false;
42 curl_easy_setopt(m_curl.get(), CURLOPT_WRITEFUNCTION, CurlVectorReadOp::WriteCallback);
43 curl_easy_setopt(m_curl.get(), CURLOPT_WRITEDATA, this);
44
45 std::stringstream ss;
46 auto multiple = false;
47 for (const auto &chunk : m_chunk_list) {
48 if (!chunk.GetLength()) continue;
49 if (multiple) {ss << ",";}
50 ss << chunk.GetOffset() << "-" << chunk.GetOffset() + chunk.GetLength() - 1;
51 multiple = true;
52 }
53 auto byte_range_val = ss.str();
54 if (byte_range_val.size()) {
55 m_headers_list.emplace_back("Range", "bytes=" + byte_range_val);
56 }
57 return true;
58}
std::vector< std::pair< std::string, std::string > > m_headers_list
virtual bool Setup(CURL *curl, CurlWorker &)

References m_chunk_list, XrdClHttp::CurlOperation::m_curl, XrdClHttp::CurlOperation::m_headers_list, and XrdClHttp::CurlOperation::Setup().

Here is the call graph for this function:

◆ Success()

void CurlVectorReadOp::Success ( )
overridevirtual

Implements XrdClHttp::CurlOperation.

Definition at line 85 of file XrdClHttpOpReadV.cc.

86{
87 SetDone(false);
88 if (m_handler == nullptr) {return;}
89
90 // If there's a partial last response, give it to the client.
92 auto &chunk = m_chunk_list[m_response_idx];
93 m_vr->GetChunks().emplace_back(chunk.GetOffset(), m_chunk_buffer_idx, chunk.GetBuffer());
95 }
96
97 auto status = new XrdCl::XRootDStatus();
98 m_vr->SetSize(m_bytes_consumed);
99 auto obj = new XrdCl::AnyObject();
100 obj->Set(m_vr.release());
101 auto handle = m_handler;
102 m_handler = nullptr;
103 handle->HandleResponse(status, obj);
104}

References m_bytes_consumed, m_chunk_buffer_idx, m_chunk_list, XrdClHttp::CurlOperation::m_handler, m_response_idx, m_vr, and XrdClHttp::CurlOperation::SetDone().

Here is the call graph for this function:

◆ Write()

size_t CurlVectorReadOp::Write ( char * buffer,
size_t size )

Definition at line 128 of file XrdClHttpOpReadV.cc.

129{
130 UpdateBytes(orig_length);
131 //m_logger->Debug(kLogXrdClHttp, "Received a write of size %ld with contents:\n%s", static_cast<long>(orig_length), std::string(orig_buffer, orig_length).c_str());
132
133 // Handle the (hopefully uncommon) cases where the server responds to a vector read op
134 // with a single response. We set the length of the response to the max as we
135 // don't care how many bytes the server actually sends.
136 if (GetStatusCode() == 200) {
137 m_current_op.first = 0;
138 m_current_op.second = std::numeric_limits<off_t>::max();
139 } else if (HTTPStatusIsError(GetStatusCode())) {
140 return orig_length;
141 } else if (!m_headers.IsMultipartByterange()) {
142 m_current_op.first = m_headers.GetOffset();
143 m_current_op.second = std::numeric_limits<off_t>::max();
144 }
145
146 auto buffer = orig_buffer;
147 auto length = orig_length;
148
149 while (length) {
150 // If we're in the middle of a response chunk, copy as much data as possible.
151 if (m_current_op.first != -1 && m_current_op.second != -1) {
152 //m_logger->Debug(kLogXrdClHttp, "Processing response buffer of (%lld, %lld)", static_cast<long long>(m_current_op.first), static_cast<long long>(m_current_op.second));
153 if (m_skip_bytes) {
154 //m_logger->Debug(kLogXrdClHttp, "Skipping %lld bytes", static_cast<long long>(m_skip_bytes));
155 auto to_skip = (m_skip_bytes < length) ? m_skip_bytes : length;
156 buffer += to_skip;
157 length -= to_skip;
158 m_skip_bytes -= to_skip;
159 continue;
160 } else {
161 auto &chunk = m_chunk_list[m_response_idx];
162 auto remaining = static_cast<off_t>(chunk.GetLength()) - m_chunk_buffer_idx;
163 if (remaining < 0) {
164 return FailCallback(kXR_ServerError, "Invalid chunk framing");
165 }
166 auto to_copy = (static_cast<size_t>(remaining) < length) ? static_cast<size_t>(remaining) : length;
167 //m_logger->Debug(kLogXrdClHttp, "Copying %lld bytes to request buffer %ld at offset %lld", static_cast<long long>(to_copy), m_response_idx, static_cast<long long>(m_chunk_buffer_idx));
168 memcpy(static_cast<char *>(chunk.GetBuffer()) + m_chunk_buffer_idx, buffer, to_copy);
169 m_chunk_buffer_idx += to_copy;
170 buffer += to_copy;
171 length -= to_copy;
172 // Handle cases where the requested or response chunk is complete
173 if (chunk.GetLength() == m_chunk_buffer_idx) {
174 m_vr->GetChunks().emplace_back(chunk.GetOffset(), m_chunk_buffer_idx, chunk.GetBuffer());
178 if (m_current_op.second == chunk.GetLength()) {
179 m_current_op.first = m_current_op.second = -1;
180 m_multipart_boundary = true;
181 } else {
182 // We may need to skip the remaining bytes or, potentially, the server
183 // coalesced two adjacent requests into one larger response.
184 m_current_op.first += chunk.GetLength();
185 m_current_op.second -= chunk.GetLength();
186 CalculateNextBuffer();
187 continue;
188 }
189 } else if (m_current_op.second == m_chunk_buffer_idx) {
190 // There are no more bytes in the response but the requested chunk hasn't finished.
191 // Add what we have to the results and create a new chunk on the request list from the remainder; perhaps
192 // the server will send it in the future.
193 m_chunk_list.emplace_back(chunk.GetOffset() + m_chunk_buffer_idx, chunk.GetLength() - m_chunk_buffer_idx, static_cast<char*>(chunk.GetBuffer()) + m_chunk_buffer_idx);
194 m_vr->GetChunks().emplace_back(chunk.GetOffset(), m_chunk_buffer_idx, chunk.GetBuffer());
197 m_current_op.first = m_current_op.second = -1;
198 m_multipart_boundary = true;
200 }
201 }
202 }
203 if (m_skip_bytes) {
204 continue;
205 }
206
207 // We are at the boundary between chunks; we must parse header lines to understand the
208 // next thing to do.
209
210 // The following lambda function returns a string view to the next complete header line,
211 // potentially partially from the previous buffer from curl. If the second item in
212 // the returned pair is false, then we ran out of buffer from curl before finding a
213 // complete line.
214 auto get_next_line = [&]() {
215 std::string_view chunk_header(buffer, length);
216 auto pos = chunk_header.find("\r\n");
217 if (pos == std::string_view::npos) {
218 m_response_headers += chunk_header;
219 length = 0;
220 return std::make_pair(std::string_view(), false);
221 } else {
222 auto line_part = chunk_header.substr(0, pos);
223 if (!m_response_headers.empty()) {
224 m_response_headers += line_part;
226 } else {
227 m_header_line.assign(line_part);
228 }
229 buffer += pos + 2;
230 length -= pos + 2;
231 return std::make_pair(std::string_view(m_header_line), true);
232 }
233 };
234
235 // Consume the boundary line.
236 bool last_segment = false;
237 if (m_multipart_boundary) {
238 while (true) {
239 auto [line, ok] = get_next_line();
240 if (!ok) {
241 return orig_length;
242 }
243 // Per RFC7233, Appendix A, Implementation note 1, multiple CRLF might precede the
244 // first boundary string in the body. However, the XRootD server appears to have an
245 // extra CRLF in front of every boundary string.
246 if (line.empty()) {continue;}
247 if (line == m_headers.MultipartSeparator()) {
248 break;
249 }
250 if (line == m_headers.MultipartSeparator() + "--") {
251 last_segment = true;
252 break;
253 }
254 std::stringstream ss;
255 ss << "Server has responded with an invalid boundary line: '" << line << "' (expected '" << m_headers.MultipartSeparator() << "')";
256 return FailCallback(kXR_ServerError, ss.str());
257 }
258 }
259 if (last_segment) {
260 length = 0;
261 break;
262 }
263 // Consume the header lines
264 while (true) {
265 auto [line, ok] = get_next_line();
266 if (!ok) {
267 m_multipart_boundary = false;
268 return orig_length;
269 }
270 if (line.empty()) {
271 break;
272 }
273 auto header_name_end = line.find(':');
274 if (header_name_end == std::string_view::npos) {
275 std::stringstream ss; ss << "Invalid header line in response from server: " << line;
276 return FailCallback(kXR_ServerError, ss.str());
277 }
278 auto header_name = line.substr(0, header_name_end);
279 // Cannot use strcasecmp here as a string_view's data is not necessarily nul-terminated.
280 // len("content-type") == 13
281 if (header_name.size() != 13 || strncasecmp(header_name.data(), "content-range", 13)) {
282 continue;
283 }
284 // We are parsing a Content-Range value.
285 // Example: Content-Range: bytes 7000-7999/8000
286 auto value = line.substr(header_name_end + 1);
287
288 // Advance whitespace
289 while (!value.empty() && value[0] == ' ') {
290 value = value.substr(1);
291 }
292
293 if (value.substr(0, 5) != "bytes") {
294 std::stringstream ss; ss << "Invalid Content-Range value (no 'bytes' unit): " << value;
295 return FailCallback(kXR_ServerError, ss.str());
296 }
297
298 value = value.substr(5);
299 while (!value.empty() && value[0] == ' ') {
300 value = value.substr(1);
301 }
302
303 // Example: 500-999/8000
304 size_t count;
305 long long bytes_val;
306 try {
307 // It may seem strange to see the string_view data being passed to std::stoll here
308 // as it's not guaranteed to be null-terminated. However, by this point, we do know
309 // there's a CRLF in the buffer -- that is sufficient to guarantee the stoll search
310 // terminates before it goes out-of-bounds.
311 bytes_val = std::stoll(value.data(), &count);
312 } catch (std::invalid_argument &) {
313 std::stringstream ss; ss << "Invalid Content-Range value (no integer in range start): " << value;
314 return FailCallback(kXR_ServerError, ss.str());
315 } catch (std::out_of_range &) {
316 std::stringstream ss; ss << "Invalid Content-Range value (out of range): " << value;
317 return FailCallback(kXR_ServerError, ss.str());
318 }
319 if (value.size() <= count || value[count] != '-') {
320 std::stringstream ss; ss << "Invalid Content-Range value (no dash in range): " << value;
321 return FailCallback(kXR_ServerError, ss.str());
322 }
323 m_current_op.first = bytes_val;
324 value = value.substr(count + 1);
325 try {
326 bytes_val = std::stoll(value.data(), &count);
327 } catch (std::invalid_argument &) {
328 std::stringstream ss; ss << "Invalid Content-Range value (no integer in range end): " << value;
329 return FailCallback(kXR_ServerError, ss.str());
330 } catch (std::out_of_range &) {
331 std::stringstream ss; ss << "Invalid Content-Range value (out of range in range end): " << value;
332 return FailCallback(kXR_ServerError, ss.str());
333 }
334 if (value.size() <= count || value[count] != '/') {
335 std::stringstream ss; ss << "Invalid Content-Range value (no trailing /): " << value;
336 return FailCallback(kXR_ServerError, ss.str());
337 }
338 auto length = bytes_val + 1 - m_current_op.first;
339 if (length < 0) {
340 std::stringstream ss; ss << "Invalid Content-Range value (negative length): " << line;
341 return FailCallback(kXR_ServerError, ss.str());
342 }
343 if (length > std::numeric_limits<decltype(m_current_op.second)>::max()) {
344 std::stringstream ss; ss << "Invalid Content-Range value (length too long): " << line;
345 return FailCallback(kXR_ServerError, ss.str());
346 }
347 m_current_op.second = length;
348
349 // We now have a valid response range; locate a buffer where we will copy the bytes into.
350 CalculateNextBuffer();
351 }
352 m_multipart_boundary = true;
353
354 // Check to see if the Content-Range was missing.
355 if (!last_segment && (m_current_op.first == -1 || m_current_op.second == -1)) {
356 return FailCallback(kXR_ServerError, "Response segment is missing a Content-Range header");
357 }
358 }
359 return orig_length;
360}
@ kXR_ServerError
int FailCallback(XErrorCode ecode, const std::string &emsg)
void UpdateBytes(uint64_t bytes)
std::pair< off_t, off_t > m_current_op
bool HTTPStatusIsError(unsigned status)

References XrdClHttp::CurlOperation::FailCallback(), XrdClHttp::CurlOperation::GetStatusCode(), XrdClHttp::HTTPStatusIsError(), kXR_ServerError, m_bytes_consumed, m_chunk_buffer_idx, m_chunk_list, m_current_op, m_header_line, XrdClHttp::CurlOperation::m_headers, m_response_headers, m_response_idx, m_skip_bytes, m_vr, and XrdClHttp::CurlOperation::UpdateBytes().

Here is the call graph for this function:

Member Data Documentation

◆ m_bytes_consumed

off_t XrdClHttp::CurlVectorReadOp::m_bytes_consumed {0}
protected

Definition at line 739 of file XrdClHttpOps.hh.

739{0}; // Total number of bytes used for results serving the request.

Referenced by Success(), and Write().

◆ m_chunk_buffer_idx

off_t XrdClHttp::CurlVectorReadOp::m_chunk_buffer_idx {0}
protected

Definition at line 738 of file XrdClHttpOps.hh.

738{0}; // Current offset in requested chunk where we are writing bytes.

Referenced by Success(), and Write().

◆ m_chunk_list

XrdCl::ChunkList XrdClHttp::CurlVectorReadOp::m_chunk_list
protected

Definition at line 745 of file XrdClHttpOps.hh.

Referenced by CurlVectorReadOp(), Fail(), Setup(), Success(), and Write().

◆ m_current_op

std::pair<off_t, off_t> XrdClHttp::CurlVectorReadOp::m_current_op {-1, -1}
protected

Definition at line 743 of file XrdClHttpOps.hh.

743{-1, -1}; // The (offset, length) of the current response chunk.

Referenced by Write().

◆ m_header_line

std::string XrdClHttp::CurlVectorReadOp::m_header_line
protected

Definition at line 742 of file XrdClHttpOps.hh.

Referenced by Write().

◆ m_response_headers

std::string XrdClHttp::CurlVectorReadOp::m_response_headers
protected

Definition at line 741 of file XrdClHttpOps.hh.

Referenced by Write().

◆ m_response_idx

size_t XrdClHttp::CurlVectorReadOp::m_response_idx {0}
protected

Definition at line 737 of file XrdClHttpOps.hh.

737{0}; // The offset in the m_chunk_list which the current response chunk will write into.

Referenced by Success(), and Write().

◆ m_skip_bytes

uint64_t XrdClHttp::CurlVectorReadOp::m_skip_bytes {0}
protected

Definition at line 740 of file XrdClHttpOps.hh.

740{0}; // Count of bytes to skip in the next response (if response chunk contains unneeded bytes).

Referenced by Write().

◆ m_vr

std::unique_ptr<XrdCl::VectorReadInfo> XrdClHttp::CurlVectorReadOp::m_vr
protected

Definition at line 744 of file XrdClHttpOps.hh.

Referenced by CurlVectorReadOp(), Success(), and Write().


The documentation for this class was generated from the following files: