24 posix_flags |= O_CREAT | O_EXCL;
27 posix_flags |= O_CREAT | O_TRUNC;
30 posix_flags |= O_RDONLY;
33 posix_flags |= O_WRONLY;
36 posix_flags |= O_RDWR;
59 std::string origin = getenv(
"XRDXROOTD_PROXY")? getenv(
"XRDXROOTD_PROXY") :
"";
60 if ( origin.empty() || origin.find(
"=") == 0) {
61 davix_context_ =
new Davix::Context();
62 davix_client_ =
new Davix::DavPosix(davix_context_);
67 if (getenv(
"DAVIX_LOAD_GRID_MODULE_IN_XRD"))
80 delete davix_context_;
92 if (
XrdCl::URL(url).GetProtocol().find(
"https") == 0)
93 isChannelEncrypted =
true;
95 isChannelEncrypted =
false;
103 if (search != CGIs.end())
107 Davix::RequestParams params;
109 struct timespec ts = {timeout, 0};
110 params.setOperationTimeout(&ts);
115 auto pos = full_path.find_last_of(
'/');
117 pos != std::string::npos ? full_path.substr(0, pos) : full_path;
121 if (mkdir_status.IsError()) {
123 "Could not create parent directories when opening: %s",
132 auto status =
Posix::Stat(*davix_client_, url, timeout, stat_info);
134 auto unlink_status =
Posix::Unlink(*davix_client_, url, timeout);
135 if (unlink_status.IsError()) {
138 "Could not delete existing destination file: %s. Error: %s",
139 url.c_str(), unlink_status.GetErrorMessage().c_str());
140 return unlink_status;
147 auto status =
Posix::Stat(*davix_client_, url, timeout, stat_info);
149 filesize = stat_info->GetSize();
154 auto posix_open_flags = MakePosixOpenFlags(flags);
157 "Open: URL: %s, XRootD flags: %d, POSIX flags: %d",
158 url.c_str(), flags, posix_open_flags);
161 auto res =
Posix::Open(*davix_client_, url, posix_open_flags, timeout);
164 res.second.ToStr().c_str());
168 davix_fd_ = res.first;
185 "Cannot close. URL hasn't been previously opened");
192 if (status.IsError()) {
194 davix_fd_, status.ToStr().c_str());
210 "Cannot stat. URL hasn't been previously opened");
215 auto status =
Posix::Stat(*davix_client_, url_, timeout, stat_info);
219 if (status.IsError() && status.code == 400 && status.errNo == 3011) {
220 std::ostringstream data;
221 data << 140737018595560 <<
" " << filesize <<
" " << 33261 <<
" " << time(NULL);
222 stat_info->ParseServerResponse(data.str().c_str());
224 else if (status.IsError()) {
244 "Cannot read. URL hasn't previously been opened");
249 size = (offset + size > filesize)? filesize - offset : size;
250 std::pair<int, XRootDStatus> res;
251 if (! avoid_pread_) {
252 res =
Posix::PRead(*davix_client_, davix_fd_, buffer, size, offset);
255 offset_locker.lock();
256 if (offset == curr_offset) {
257 res =
Posix::Read(*davix_client_, davix_fd_, buffer, size);
260 res =
Posix::PRead(*davix_client_, davix_fd_, buffer, size, offset);
264 if (res.second.IsError()) {
266 url_.c_str(), res.second.ToStr().c_str());
267 if (avoid_pread_) offset_locker.unlock();
271 int num_bytes_read = res.first;
272 curr_offset = offset + num_bytes_read;
273 if (avoid_pread_) offset_locker.unlock();
276 num_bytes_read, (
unsigned long long) offset, url_.c_str());
279 auto chunk_info =
new ChunkInfo(offset, num_bytes_read, buffer);
281 obj->Set(chunk_info);
290 bool isChannelEncrypted;
294 bool isHttps) : realHandler(a), isChannelEncrypted(isHttps) {}
300 if( !status->
IsOK() )
312 std::vector<uint32_t> cksums;
313 if( isChannelEncrypted )
318 cksums.reserve( nbpages );
320 size_t size = chunk->
length;
321 char *buffer =
reinterpret_cast<char*
>( chunk->
buffer );
323 for(
size_t pg = 0; pg < nbpages; ++pg )
326 if( pgsize > size ) pgsize = size;
328 cksums.push_back( crcval );
337 response->
Set( pages );
357 "Cannot write. URL hasn't previously been opened");
363 Posix::PWrite(*davix_client_, davix_fd_, offset, size, buffer, timeout);
364 if (res.second.IsError()) {
366 url_.c_str(), res.second.ToStr().c_str());
370 filesize += res.first;
373 res.first, (
unsigned long long) offset, url_.c_str());
386 std::vector<uint32_t> &cksums,
390 return Write(offset, size, buffer, handler, timeout);
408 "Cannot read. URL hasn't previously been opened");
412 const auto num_chunks = chunks.size();
413 std::vector<Davix::DavIOVecInput> input_vector(num_chunks);
414 std::vector<Davix::DavIOVecOuput> output_vector(num_chunks);
416 for (
size_t i = 0; i < num_chunks; ++i) {
417 input_vector[i].diov_offset = chunks[i].offset;
418 input_vector[i].diov_size = chunks[i].length;
419 input_vector[i].diov_buffer = chunks[i].buffer;
424 if (res.second.IsError()) {
426 url_.c_str(), res.second.ToStr().c_str());
430 int num_bytes_read = res.first;
433 num_bytes_read, url_.c_str());
435 char *output =
static_cast<char *
>(buffer);
436 for (
size_t i = 0; i < num_chunks; ++i) {
437 std::memcpy(output + input_vector[i].diov_offset,
438 output_vector[i].diov_buffer, output_vector[i].diov_size);
443 read_info->SetSize(num_bytes_read);
444 read_info->GetChunks() = chunks;
455 const std::string &value) {
456 properties_[name] = value;
461 std::string &value)
const {
462 const auto p = properties_.find(name);
463 if (p == std::end(properties_)) {
#define HTTP_FILE_PLUG_IN_AVOIDRANGE_ENV
#define HTTP_FILE_PLUG_IN_AVOIDRANGE_CGI
void Set(Type object, bool own=true)
void Get(Type &object)
Retrieve the object being held.
virtual XRootDStatus PgRead(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, uint16_t timeout) override
virtual XRootDStatus PgWrite(uint64_t offset, uint32_t size, const void *buffer, std::vector< uint32_t > &cksums, ResponseHandler *handler, uint16_t timeout) override
virtual XRootDStatus Sync(ResponseHandler *handler, uint16_t timeout) override
virtual XRootDStatus Stat(bool force, ResponseHandler *handler, uint16_t timeout) override
virtual XRootDStatus Write(uint64_t offset, uint32_t size, const void *buffer, ResponseHandler *handler, uint16_t timeout) override
virtual XRootDStatus Read(uint64_t offset, uint32_t size, void *buffer, ResponseHandler *handler, uint16_t timeout) override
virtual XRootDStatus VectorRead(const ChunkList &chunks, void *buffer, XrdCl::ResponseHandler *handler, uint16_t timeout) override
virtual ~HttpFilePlugIn() noexcept
virtual XRootDStatus Open(const std::string &url, OpenFlags::Flags flags, Access::Mode mode, ResponseHandler *handler, uint16_t timeout) override
virtual bool GetProperty(const std::string &name, std::string &value) const override
virtual XRootDStatus Close(ResponseHandler *handler, uint16_t timeout) override
virtual bool SetProperty(const std::string &name, const std::string &value) override
virtual bool IsOpen() const override
void Error(uint64_t topic, const char *format,...)
Report an error.
void Debug(uint64_t topic, const char *format,...)
Print a debug message.
void HandleResponse(XrdCl::XRootDStatus *status, XrdCl::AnyObject *rdresp)
PgReadSubstitutionHandler(XrdCl::ResponseHandler *a, bool isHttps)
Handle an async response.
virtual void HandleResponse(XRootDStatus *status, AnyObject *response)
std::map< std::string, std::string > ParamsMap
std::string GetLocation() const
Get location (protocol://host:port/path)
const ParamsMap & GetParams() const
Get the URL params.
static uint32_t Calc32C(const void *data, size_t count, uint32_t prevcs=0)
std::pair< int, XrdCl::XRootDStatus > PReadVec(Davix::DavPosix &davix_client, DAVIX_FD *fd, const XrdCl::ChunkList &chunks, void *buffer)
std::pair< int, XRootDStatus > Read(Davix::DavPosix &davix_client, DAVIX_FD *fd, void *buffer, uint32_t size)
std::pair< int, XrdCl::XRootDStatus > PWrite(Davix::DavPosix &davix_client, DAVIX_FD *fd, uint64_t offset, uint32_t size, const void *buffer, uint16_t timeout)
std::pair< DAVIX_FD *, XRootDStatus > Open(Davix::DavPosix &davix_client, const std::string &url, int flags, uint16_t timeout)
std::pair< int, XRootDStatus > PRead(Davix::DavPosix &davix_client, DAVIX_FD *fd, void *buffer, uint32_t size, uint64_t offset)
XRootDStatus Close(Davix::DavPosix &davix_client, DAVIX_FD *fd)
XRootDStatus Unlink(Davix::DavPosix &davix_client, const std::string &url, uint16_t timeout)
XRootDStatus MkDir(Davix::DavPosix &davix_client, const std::string &path, XrdCl::MkDirFlags::Flags flags, XrdCl::Access::Mode, uint16_t timeout)
XRootDStatus Stat(Davix::DavPosix &davix_client, const std::string &url, uint16_t timeout, StatInfo *stat_info)
const uint16_t stError
An error occurred that could potentially be retried.
const uint16_t errInvalidOp
Davix::Context * root_davix_context_
std::vector< ChunkInfo > ChunkList
List of chunks.
Davix::DavPosix * root_davix_client_file_
void SetUpLogging(Log *logger)
static const uint64_t kLogXrdClHttp
static const int PageSize
Describe a data chunk for vector read.
void * buffer
length of the chunk
uint32_t length
offset in the file
@ MakePath
create the entire directory tree if it doesn't exist
Flags
Open flags, may be or'd when appropriate.
@ Read
Open only for reading.
@ Write
Open only for writing.
@ Update
Open for reading and writing.
bool IsOK() const
We're fine.