XRootD
Loading...
Searching...
No Matches
XrdClHttpOpOpen.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* Copyright (C) 2025, Pelican Project, Morgridge Institute for Research */
3/* */
4/* This file is part of the XrdClHttp client plugin for XRootD. */
5/* */
6/* XRootD is free software: you can redistribute it and/or modify it under */
7/* the terms of the GNU Lesser General Public License as published by the */
8/* Free Software Foundation, either version 3 of the License, or (at your */
9/* option) any later version. */
10/* */
11/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
12/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
13/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
14/* License for more details. */
15/* */
16/* The copyright holder's institutional names and contributor's names may not */
17/* be used to endorse or promote products derived from this software without */
18/* specific prior written permission of the institution or contributor. */
19/******************************************************************************/
20
21#include "XrdClHttpFile.hh"
22#include "XrdClHttpOps.hh"
24#include "XrdClHttpResponses.hh"
25
26#include <XrdCl/XrdClLog.hh>
27
28using namespace XrdClHttp;
29
30CurlOpenOp::CurlOpenOp(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout,
31 XrdCl::Log *logger, XrdClHttp::File *file, bool response_info, CreateConnCalloutType callout,
32 HeaderCallout *header_callout)
33:
34 CurlStatOp(handler, url, timeout, logger, response_info, callout, header_callout),
35 m_file(file)
36{}
37
38void
40{
41 curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETFUNCTION, nullptr);
42 curl_easy_setopt(m_curl.get(), CURLOPT_OPENSOCKETDATA, nullptr);
43 curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTFUNCTION, nullptr);
44 curl_easy_setopt(m_curl.get(), CURLOPT_SOCKOPTDATA, nullptr);
46}
47
48void
49CurlOpenOp::SetOpenProperties(bool setSize)
50{
51 char *url = nullptr;
52 curl_easy_getinfo(m_curl.get(), CURLINFO_EFFECTIVE_URL, &url);
53 if (url && m_file) {
54 m_file->SetProperty("LastURL", url);
55 }
56
57 if (setSize) {
58 auto [size, isdir] = GetStatInfo();
59 if (!isdir && size >= 0) {
60 m_file->SetProperty("XrdClHttpPrefetchSize", std::to_string(size));
61 }
62 }
63
64 if (!m_headers.GetETag().empty())
65 {
66 std::string etag = m_headers.GetETag();
67 m_file->SetProperty("ETag", etag);
68 }
69 m_file->SetProperty("Cache-Control", m_headers.GetCacheControl());
70}
71
72void
74{
75 SetDone(false);
76 SetOpenProperties(true);
77 auto [size, isdir] = GetStatInfo();
78 if (isdir) {
79 m_logger->Error(kLogXrdClHttp, "Cannot open a directory");
80 Fail(XrdCl::errErrorResponse, kXR_isDirectory, "Cannot open a directory");
81 return;
82 }
83 if (size >= 0) {
84 m_file->SetProperty("ContentLength", std::to_string(size));
85 }
86 SuccessImpl(false);
87}
88
89void
90CurlOpenOp::Fail(uint16_t errCode, uint32_t errNum, const std::string &msg)
91{
92 // Note: OpenFlags::New is equivalent to O_CREAT | O_EXCL; OpenFlags::Write is equivalent to O_WRONLY | O_CREAT;
93 // OpenFlags::Delete is equivalent to O_CREAT | O_TRUNC;
95 m_logger->Debug(kLogXrdClHttp, "CurlOpenOp succeeds as 404 was expected");
96 SetOpenProperties(false);
97 m_file->SetProperty("ContentLength", "0");
98 SuccessImpl(false);
99 return;
100 }
101 CurlOperation::Fail(errCode, errNum, msg);
102}
103
105{
106 if (m_first_pause) {
107 m_first_pause = false;
108 } else {
110 return;
111 }
112
113 // Set the various file-open properties. Note that we only invoke Pause() if the status code
114 // of the response is 200.
115 char *url = nullptr;
116 curl_easy_getinfo(m_curl.get(), CURLINFO_EFFECTIVE_URL, &url);
117 if (url) {
118 m_file.SetProperty("LastURL", url);
119 }
120
121 auto length = m_headers.GetContentLength();
122 m_file.SetProperty("XrdClHttpPrefetchSize", std::to_string(length));
123
124 if (!m_headers.GetETag().empty())
125 {
126 std::string etag = m_headers.GetETag();
127 m_file.SetProperty("ETag", etag);
128 }
129 m_file.SetProperty("Cache-Control", m_headers.GetCacheControl());
130
132}
@ kXR_NotFound
@ kXR_isDirectory
void ReleaseHandle() override
void Success() override
void Fail(uint16_t errCode, uint32_t errNum, const std::string &) override
CurlOpenOp(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *logger, XrdClHttp::File *file, bool response_info, CreateConnCalloutType callout, HeaderCallout *header_callout)
void SetDone(bool has_failed)
std::unique_ptr< CURL, void(*)(CURL *)> m_curl
virtual void Pause() override
void ReleaseHandle() override
void SuccessImpl(bool returnObj)
std::pair< int64_t, bool > GetStatInfo()
CurlStatOp(XrdCl::ResponseHandler *handler, const std::string &url, struct timespec timeout, XrdCl::Log *log, bool response_info, CreateConnCalloutType callout, HeaderCallout *header_callout)
virtual bool SetProperty(const std::string &name, const std::string &value) override
Handle diagnostics.
Definition XrdClLog.hh:101
Handle an async response.
ConnectionCallout *(*)(const std::string &, const ResponseInfo &) CreateConnCalloutType
const uint64_t kLogXrdClHttp
const uint16_t errErrorResponse
@ Write
Open only for writing.