38 # define EADDRINUSE 10048
41 # define EISCONN 10056
45 static const char *
gUserAgent =
"User-Agent: ROOT-TWebFile/1.1";
74 TWebSocket::~TWebSocket()
76 if (!fWebFile->fHTTP11) {
77 delete fWebFile->fSocket;
78 fWebFile->fSocket = 0;
85 void TWebSocket::ReOpen()
87 if (fWebFile->fSocket) {
88 delete fWebFile->fSocket;
89 fWebFile->fSocket = 0;
93 if (fWebFile->fProxy.IsValid())
94 connurl = fWebFile->fProxy;
96 connurl = fWebFile->
fUrl;
103 ::Error(
"TWebSocket::ReOpen",
"library compiled without SSL, https not supported");
109 if (!fWebFile->fSocket || !fWebFile->fSocket->IsValid()) {
111 fWebFile->fSocket = 0;
115 ::Error(
"TWebSocket::ReOpen",
"cannot connect to host %s (errno=%d)",
241 if (strncmp(buf,
"root", 4) && strncmp(buf,
"PK", 2)) {
262 if (redirectLocation) {
284 if (rdl.
Index(
"?") >= 0) {
292 if (oldBasicUrl !=
"") {
356 Error(
"CheckProxy",
"protocol must be HTTP in proxy URL %s",
388 if (opt !=
"READ" && opt !=
"UPDATE")
389 Error(
"ReOpen",
"mode must be either READ or UPDATE, not %s", opt.
Data());
392 Error(
"ReOpen",
"update mode not allowed for a TWebFile");
502 for (
Int_t i = 0; i < nbuf; i++) {
508 if (msg.
Length() > 8000) {
541 for (
Int_t i = 0; i < nbuf; i++) {
545 msg += pos[i] + fArchiveOffset + len[i] - 1;
547 if (msg.
Length() > 8000) {
590 Error(
"GetFromWeb",
"library compiled without SSL, https not supported");
608 if (s->
RecvRaw(buf, len) == -1) {
654 Info(
"GetFromWeb10",
"sending HTTP request:\n%s", msg.
Data());
662 Int_t n, ret = 0, nranges = 0, ltot = 0, redirect = 0;
664 Long64_t first = -1, last = -1, tot;
674 Error(
"GetFromWeb10",
"error - redirect without location from host %s",
fUrl.
GetHost());
695 else if (ll != rsize) {
696 Error(
"GetFromWeb10",
"expected %d bytes, got %d", ll, rsize);
711 Info(
"GetFromWeb10",
"header: %s", line);
713 if (boundaryEnd == line) {
715 Info(
"GetFromWeb10",
"got all headers");
718 if (boundary == line) {
721 Info(
"GetFromWeb10",
"get new multipart byte range (%d)", nranges);
738 }
else if (code >= 400) {
746 }
else if (code >= 300) {
747 if (code == 301 || code == 303) {
749 }
else if (code == 302 || code == 307) {
758 }
else if (code > 200) {
765 }
else if (res.
BeginsWith(
"Content-Type: multipart")) {
766 boundary = res(res.
Index(
"boundary=")+9, 1000);
767 if (boundary[0]==
'"' && boundary[boundary.
Length()-1]==
'"') {
768 boundary = boundary(1,boundary.
Length()-2);
770 boundary =
"--" + boundary;
771 boundaryEnd = boundary +
"--";
772 }
else if (res.
BeginsWith(
"Content-range:")) {
774 sscanf(res.
Data(),
"Content-range: bytes %I64d-%I64d/%I64d", &first, &last, &tot);
776 sscanf(res.
Data(),
"Content-range: bytes %lld-%lld/%lld", &first, &last, &tot);
779 }
else if (res.
BeginsWith(
"Content-Range:")) {
781 sscanf(res.
Data(),
"Content-Range: bytes %I64d-%I64d/%I64d", &first, &last, &tot);
783 sscanf(res.
Data(),
"Content-Range: bytes %lld-%lld/%lld", &first, &last, &tot);
786 }
else if (res.
BeginsWith(
"Location:") && redirect) {
787 redir = res(10, 1000);
795 if (redirect && redir.
IsNull()) {
797 Error(
"GetFromWeb10",
"error - redirect without location from host %s",
fUrl.
GetHost());
802 Info(
"GetFromWeb10",
"HTTP/1.1 socket closed, reopen");
812 Error(
"GetFromWeb10",
"error receiving expected amount of data (got %d, expected %d) from host %s",
849 Error(
"Seek",
"seeking from end in archive is not (yet) supported");
872 if (const_cast<TWebFile*>(
this)->
GetFromWeb(asize, 64, msg) == -1)
878 size = _atoi64(asize);
922 for (
Int_t i = 0; i < 5; i++) {
927 Error(
"GetHead",
"library compiled without SSL, https not supported");
950 Info(
"GetHead",
"connected to host %s", connurl.
GetHost());
951 Info(
"GetHead",
"sending HTTP request:\n%s", msg.
Data());
961 Int_t n, ret = 0, redirect = 0;
964 while ((n =
GetLine(s, line,
sizeof(line))) >= 0) {
967 Info(
"GetHead",
"got all headers");
979 Error(
"GetHead",
"error - redirect without location from host %s",
fUrl.
GetHost());
988 Info(
"GetHead",
"header: %s", line);
1010 }
else if (code >= 400) {
1013 else if (code == 404)
1020 }
else if (code >= 300) {
1021 if (code == 301 || code == 303)
1023 else if (code == 302 || code == 307)
1030 }
else if (code > 200) {
1035 }
else if (res.
BeginsWith(
"Content-Length:")) {
1038 }
else if (res.
BeginsWith(
"Location:") && redirect) {
1039 redir = res(10, 1000);
1069 if (n > 0 && line[n-1] ==
'\n') {
1071 if (n > 0 && line[n-1] ==
'\r')
1125 if (maxsize <= 0)
return 0;
1132 Int_t pklen, rdlen, remain;
1143 remain = end - (hunk + tail);
1149 if (bufsize - 1 < tail + remain) {
1150 Error(
"GetHunk",
"hunk buffer too small for data from host %s (%d bytes needed)",
1180 if (end && rdlen == remain) {
1188 if (tail == bufsize - 1) {
1189 Error(
"GetHunk",
"hunk buffer too small for data from host %s",
1207 const char *p, *end;
1212 p = peeked - start < 1 ? start : peeked - 1;
1213 end = peeked + peeklen;
1216 for (; p < end - 1; p++)
1217 if (p[0] ==
'\r' && p[1] ==
'\n')
1221 if (p[0] ==
'\r' && p[1] ==
'\n')
1225 const char *p = (
const char*) memchr(peeked,
'\n', peeklen);
1245 msg +=
"Authorization: Basic ";
1257 if (proxy && *proxy) {
1260 :: Error(
"TWebFile::SetProxy",
"protocol must be HTTP in proxy URL %s",
1313 Error(
"OpenDirectory",
"invalid directory pointer (should never happen)");
1327 if (dirp !=
fDirp) {
1328 Error(
"FreeDirectory",
"invalid directory pointer (should never happen)");
1340 if (dirp !=
fDirp) {
1341 Error(
"GetDirEntry",
"invalid directory pointer (should never happen)");
const char * GetHost() const
virtual Bool_t ReadBuffer10(char *buf, Int_t len)
Read specified byte range from remote file via HTTP 1.0 daemon (without mod-root installed).
virtual Bool_t IsOpen() const
A TWebFile that has been correctly constructed is always considered open.
virtual Long64_t GetSize() const
Return maximum file size.
static std::atomic< Long64_t > fgBytesRead
Number of bytes read by all TFile objects.
virtual TString BasicAuthentication()
Return basic authentication scheme, to be added to the request.
virtual Bool_t IsValid() const
virtual void SetOffset(Long64_t offset, ERelativeTo pos=kBeg)
Set position from where to start reading.
This class represents a WWW compatible URL.
TString & ReplaceAll(const TString &s1, const TString &s2)
virtual void SetName(const char *name)
Change (i.e.
const char * GetProtocol() const
void SetUrl(const char *url, Bool_t defaultIsFile=kFALSE)
Parse url character string and split in its different subcomponents.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Int_t MakeDirectory(const char *name)
Make a directory via httpd. Not supported.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
virtual Int_t GetHunk(TSocket *s, char *hunk, Int_t maxsize)
Read a hunk of data from the socket, up until a terminator.
static void SetFileReadCalls(Int_t readcalls=0)
void ToUpper()
Change string to upper case.
virtual void SetMsgReadBuffer10(const char *redirectLocation=0, Bool_t tempRedirect=kFALSE)
Set GET command for use by ReadBuffer(s)10(), handle redirection if needed.
Int_t fReadCalls
Number of read calls ( not counting the cache calls )
const char * GetOptions() const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
static void SetProxy(const char *url)
Static method setting global proxy URL.
virtual void ProcessHttpHeader(const TString &headerLine)
Process the HTTP header in the argument.
virtual Int_t GetLine(TSocket *s, char *line, Int_t maxsize)
Read a line from the socket.
static Int_t GetErrno()
Static function returning system error number.
virtual Int_t GetFromWeb10(char *buf, Int_t len, const TString &msg)
Read multiple byte range request from web server.
const char * Data() const
static const char * GetProxy()
Static method returning the global proxy URL.
static TString Encode(const char *data)
Transform data into a null terminated base64 string.
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
virtual const char * HttpTerminator(const char *start, const char *peeked, Int_t peeklen)
Determine whether [START, PEEKED + PEEKLEN) contains an HTTP new line [] .
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
void Init(TClassEdit::TInterpreterLookupHelper *helper)
const char * GetPasswd() const
virtual const char * Getenv(const char *env)
Get environment variable.
const char * GetDirEntry(void *dirp)
Get directory entry via httpd. Returns 0 in case no more entries.
Int_t Atoi() const
Return integer value of string.
virtual Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Read specified byte ranges from remote file via HTTP daemon.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
static const char * gUserAgent
void Error(const char *location, const char *msgfmt,...)
ClassImp(TWebFile) TWebFile
Create a Web file object.
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read specified byte range from remote file via HTTP daemon.
Long64_t fEND
Last used byte in file.
R__EXTERN TSystem * gSystem
Int_t Unlink(const char *path)
Unlink, i.e.
static std::atomic< Int_t > fgReadCalls
Number of bytes read from all TFile objects.
static Int_t GetFileReadCalls()
Static function returning the total number of read calls from all files.
virtual void Init(Bool_t create)
Initialize a TFile object.
Int_t ReadBufferViaCache(char *buf, Int_t len)
Read buffer via cache.
virtual void Seek(Long64_t offset, ERelativeTo pos=kBeg)
Set position from where to start reading.
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
void FreeDirectory(void *dirp)
Free directory via httpd.
virtual void CheckProxy()
Check if shell var "http_proxy" has been set and should be used.
virtual ~TWebFile()
Cleanup.
Long64_t Atoll() const
Return long long value of string.
The TTimeStamp encapsulates seconds and ns since EPOCH.
Bool_t fIsRootFile
!True is this is a ROOT file, raw file otherwise
void * OpenDirectory(const char *name)
Open a directory via httpd.
Int_t GetPathInfo(const char *path, FileStat_t &buf)
Get info about a file.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
virtual Int_t GetHead()
Get the HTTP header.
virtual void Init(Bool_t readHeadOnly)
Initialize a TWebFile object.
Long64_t fArchiveOffset
!Offset at which file starts in archive
TWebSystem()
Create helper class that allows directory access via httpd.
Int_t fWritten
Number of objects written so far.
Long64_t fOffset
!Seek offset cache
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
static void SetFileBytesRead(Long64_t bytes=0)
Abstract base class defining a generic interface to the underlying Operating System.
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
const char * GetUser() const
virtual Bool_t ReadBuffers10(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Read specified byte ranges from remote file via HTTP 1.0 daemon (without mod-root installed)...
Long64_t fBytesRead
Number of bytes read from this file.
virtual Int_t GetFromWeb(char *buf, Int_t len, const TString &msg)
Read request from web server.
const char * GetFile() const
Bool_t AccessPathName(const char *path, EAccessMode mode)
Returns FALSE if one can access a file using the specified access mode.
virtual Int_t ReOpen(Option_t *mode)
Reopen a file with a different access mode, like from READ to UPDATE or from NEW, CREATE...