39# define EADDRINUSE 10048
46static const char *
gUserAgent =
"User-Agent: ROOT-TWebFile/1.1";
82 if (!fWebFile->fHTTP11) {
83 delete fWebFile->fSocket;
84 fWebFile->fSocket =
nullptr;
93 if (fWebFile->fSocket) {
94 delete fWebFile->fSocket;
95 fWebFile->fSocket =
nullptr;
99 if (fWebFile->fProxy.IsValid())
104 for (
Int_t i = 0; i < 5; i++) {
109 ::Error(
"TWebSocket::ReOpen",
"library compiled without SSL, https not supported");
115 if (!fWebFile->fSocket || !fWebFile->fSocket->IsValid()) {
116 delete fWebFile->fSocket;
117 fWebFile->fSocket =
nullptr;
121 ::Error(
"TWebSocket::ReOpen",
"cannot connect to host %s (errno=%d)",
149 :
TFile(
url,
strstr(opt,
"_WITHOUT_GLOBALREGISTRATION") != nullptr ?
"WEB_WITHOUT_GLOBALREGISTRATION" :
"WEB"),
206 fFullCache =
nullptr;
222#if defined(R__WIN32) && defined(R__SSL)
227 fFullCache =
nullptr;
229 SetMsgReadBuffer10();
231 if ((err = GetHead()) < 0) {
238 Error(
"TWebFile",
"%s does not exist", fBasicUrl.Data());
259 Error(
"TWebFile",
"%s is not a ROOT file", fBasicUrl.Data());
282 fBasicUrlOrg = fBasicUrl;
292 fBasicUrl = fUrl.GetProtocol();
294 fBasicUrl += fUrl.GetHost();
296 fBasicUrl += fUrl.GetPort();
298 fBasicUrl += fUrl.GetFile();
301 if (
rdl.Index(
"?") >= 0) {
307 if (fMsgReadBuffer10 !=
"") {
311 fMsgReadBuffer10.ReplaceAll(
oldBasicUrl, fBasicUrl);
312 fMsgReadBuffer10.ReplaceAll(
TString(
"Host: ")+
oldUrl.GetHost(),
TString(
"Host: ")+fUrl.GetHost());
313 }
else if (fBasicUrlOrg !=
"") {
315 fMsgReadBuffer10.ReplaceAll(fBasicUrl, fBasicUrlOrg);
316 fMsgReadBuffer10.ReplaceAll(
TString(
"Host: ")+fUrl.GetHost(),
TString(
"Host: ")+fUrlOrg.GetHost());
318 fBasicUrl = fBasicUrlOrg;
324 if (fBasicUrl ==
"") {
325 fBasicUrl += fUrl.GetProtocol();
327 fBasicUrl += fUrl.GetHost();
329 fBasicUrl += fUrl.GetPort();
331 fBasicUrl += fUrl.GetFile();
332 if (
strlen(fUrl.GetOptions())) {
334 fBasicUrl += fUrl.GetOptions();
338 if (fMsgReadBuffer10 ==
"") {
339 fMsgReadBuffer10 =
"GET ";
340 fMsgReadBuffer10 += fBasicUrl;
342 fMsgReadBuffer10 +=
" HTTP/1.1";
344 fMsgReadBuffer10 +=
" HTTP/1.0";
345 fMsgReadBuffer10 +=
"\r\n";
347 fMsgReadBuffer10 +=
"Host: ";
348 fMsgReadBuffer10 += fUrl.GetHost();
349 fMsgReadBuffer10 +=
"\r\n";
351 fMsgReadBuffer10 += BasicAuthentication();
353 fMsgReadBuffer10 +=
"\r\n";
354 fMsgReadBuffer10 +=
"Range: bytes=";
366 if (fgProxy.IsValid()) {
374 if (
strcmp(
p.GetProtocol(),
"http")) {
375 Error(
"CheckProxy",
"protocol must be HTTP in proxy URL %s",
381 Info(
"CheckProxy",
"using HTTP proxy %s", fProxy.GetUrl());
407 if (opt !=
"READ" && opt !=
"UPDATE")
408 Error(
"ReOpen",
"mode must be either READ or UPDATE, not %s", opt.
Data());
411 Error(
"ReOpen",
"update mode not allowed for a TWebFile");
426 fFullCache =
nullptr;
440 if ((
st = ReadBufferViaCache(buf,
len))) {
447 return ReadBuffer10(buf,
len);
451 if (fMsgReadBuffer ==
"") {
452 fMsgReadBuffer =
"GET ";
453 fMsgReadBuffer += fBasicUrl;
454 fMsgReadBuffer +=
"?";
462 if (GetFromWeb(buf,
len,
msg) == -1)
488 SetMsgReadBuffer10();
506 Error(
"ReadBuffer10",
"%s does not exist", fBasicUrl.Data());
528 return ReadBuffers10(buf, pos,
len,
nbuf);
532 if (fMsgReadBuffer ==
"") {
533 fMsgReadBuffer =
"GET ";
534 fMsgReadBuffer += fBasicUrl;
535 fMsgReadBuffer +=
"?";
539 Int_t k = 0,
n = 0, cnt = 0;
542 msg += pos[i] + fArchiveOffset;
547 if ((
msg.Length() > 8000) || (cnt >= 200)) {
549 if (GetFromWeb(&buf[k],
n,
msg) == -1)
551 msg = fMsgReadBuffer;
560 if (GetFromWeb(&buf[k],
n,
msg) == -1)
576 SetMsgReadBuffer10();
580 Int_t k = 0,
n = 0,
r, cnt = 0;
583 msg += pos[i] + fArchiveOffset;
585 msg += pos[i] + fArchiveOffset +
len[i] - 1;
588 if ((
msg.Length() > 8000) || (cnt >= 200) || (i+1 ==
nbuf)) {
590 r = GetFromWeb10(&buf[k],
n,
msg, cnt, pos + (i+1-cnt),
len + (i+1-cnt));
593 msg = fMsgReadBuffer10;
610 if (!fFullCache)
return -1;
613 Info(
"GetFromCache",
"Extract %d segments total len %d from cached data",
nseg,
len);
620 if (fArchiveOffset +
seg_pos[cnt] +
seg_len[cnt] > fFullCacheSize)
return -1;
621 char*
src = (
char*) fFullCache + fArchiveOffset +
seg_pos[cnt];
643 if (fProxy.IsValid())
652 Error(
"GetFromWeb",
"library compiled without SSL, https not supported");
659 Error(
"GetFromWeb",
"cannot connect to host %s", fUrl.GetHost());
665 Error(
"GetFromWeb",
"error sending command to host %s", fUrl.GetHost());
671 Error(
"GetFromWeb",
"error receiving data from host %s", fUrl.GetHost());
680 SetFileBytesRead(GetFileBytesRead() +
len);
681 SetFileReadCalls(GetFileReadCalls() + 1);
706 if (fFullCache && (
nseg>0))
715 if (!fSocket || !fSocket->IsValid()) {
716 Error(
"GetFromWeb10",
"cannot connect to host %s", fUrl.GetHost());
721 Info(
"GetFromWeb10",
"sending HTTP request:\n%s",
msg.Data());
723 if (fSocket->SendRaw(
msg.Data(),
msg.Length()) == -1) {
724 Error(
"GetFromWeb10",
"error sending command to host %s", fUrl.GetHost());
734 while ((
n = GetLine(fSocket,
line,
sizeof(
line))) >= 0) {
739 if (
redir.IsNull()) {
741 Error(
"GetFromWeb10",
"error - redirect without location from host %s", fUrl.GetHost());
752 return GetFromWeb10(buf,
len,
msg_1);
758 if ((
rsize = fSocket->RecvRaw(&buf[
ltot],
ll)) == -1) {
759 Error(
"GetFromWeb10",
"error receiving data from host %s", fUrl.GetHost());
763 Error(
"GetFromWeb10",
"expected %d bytes, got %d",
ll,
rsize);
777 Error(
"GetFromWeb10",
"Need segments data to extract parts from full size %lld",
fullsize);
782 Error(
"GetFromWeb10",
"Requested part %d longer than full size %lld",
len,
fullsize);
786 if ((fFullCache == 0) && (
fullsize <= GetMaxFullCacheSize())) {
789 if (fFullCache != 0) {
791 Error(
"GetFromWeb10",
"error receiving data from host %s", fUrl.GetHost());
792 free(fFullCache); fFullCache =
nullptr;
808 Error(
"GetFromWeb10",
"Requested segments are not in sorted order");
820 while (pos < fArchiveOffset +
seg_pos[cnt]) {
823 if (fSocket->RecvRaw(
dbuf,
ll) !=
ll) {
824 Error(
"GetFromWeb10",
"error receiving data from host %s", fUrl.GetHost());
832 Error(
"GetFromWeb10",
"error receiving data from host %s", fUrl.GetHost());
844 if (fSocket->RecvRaw(
dbuf,
ll) !=
ll) {
845 Error(
"GetFromWeb10",
"error receiving data from host %s", fUrl.GetHost());
852 Info(
"GetFromWeb10",
"Complete reading %d bytes in %d segments out of full size %lld",
len,
nseg,
fullsize);
861 Info(
"GetFromWeb10",
"header: %s",
line);
865 Info(
"GetFromWeb10",
"got all headers");
871 Info(
"GetFromWeb10",
"get new multipart byte range (%d)",
nranges);
879 fMsgReadBuffer10 =
"";
887 Error(
"GetFromWeb10",
"%s: %s (%d)", fBasicUrl.Data(),
mess.Data(), code);
888 }
else if (code >= 400) {
894 Error(
"GetFromWeb10",
"%s: %s (%d)", fBasicUrl.Data(),
mess.Data(), code);
896 }
else if (code >= 300) {
897 if (code == 301 || code == 303) {
899 }
else if (code == 302 || code == 307) {
906 Error(
"GetFromWeb10",
"%s: %s (%d)", fBasicUrl.Data(),
mess.Data(), code);
908 }
else if (code > 200) {
912 Error(
"GetFromWeb10",
"%s: %s (%d)", fBasicUrl.Data(),
mess.Data(), code);
914 }
else if (code == 200) {
917 "Server %s response with complete file, but only part of it was requested.\n"
918 "Check MaxRanges configuration parameter (if Apache is used)",
930 sscanf(res.
Data(),
"content-range: bytes %lld-%lld/%lld", &first, &last, &
tot);
935 redir = res(10, 1000);
944 Error(
"GetFromWeb10",
"error - redirect without location from host %s", fUrl.GetHost());
947 if (
n == -1 && fHTTP11) {
949 Info(
"GetFromWeb10",
"HTTP/1.1 socket closed, reopen");
950 if (fBasicUrlOrg !=
"") {
952 SetMsgReadBuffer10();
955 return GetFromWeb10(buf,
len,
msg);
959 Error(
"GetFromWeb10",
"error receiving expected amount of data (got %d, expected %d) from host %s",
968 SetFileBytesRead(GetFileBytesRead() +
len);
969 SetFileReadCalls(GetFileReadCalls() + 1);
988 fOffset =
offset + fArchiveOffset;
996 Error(
"Seek",
"seeking from end in archive is not (yet) supported");
1007 if (!fHasModRoot ||
fSize >= 0)
1043 if (fMsgGetHead ==
"") {
1044 fMsgGetHead =
"HEAD ";
1045 fMsgGetHead += fBasicUrl;
1047 fMsgGetHead +=
" HTTP/1.1";
1049 fMsgGetHead +=
" HTTP/1.0";
1050 fMsgGetHead +=
"\r\n";
1052 fMsgGetHead +=
"Host: ";
1053 fMsgGetHead += fUrl.GetHost();
1054 fMsgGetHead +=
"\r\n";
1056 fMsgGetHead += BasicAuthentication();
1058 fMsgGetHead +=
"\r\n\r\n";
1063 if (fProxy.IsValid())
1069 for (
Int_t i = 0; i < 5; i++) {
1074 Error(
"GetHead",
"library compiled without SSL, https not supported");
1086 Error(
"GetHead",
"cannot connect to host %s (errno=%d)", fUrl.GetHost(),
1097 Info(
"GetHead",
"connected to host %s",
connurl.GetHost());
1098 Info(
"GetHead",
"sending HTTP request:\n%s",
msg.Data());
1102 Error(
"GetHead",
"error sending command to host %s", fUrl.GetHost());
1111 while ((
n = GetLine(s,
line,
sizeof(
line))) >= 0) {
1114 Info(
"GetHead",
"got all headers");
1116 if (fBasicUrlOrg !=
"" && !
redirect) {
1118 SetMsgReadBuffer10();
1124 if (
redir.IsNull()) {
1126 Error(
"GetHead",
"error - redirect without location from host %s", fUrl.GetHost());
1135 Info(
"GetHead",
"header: %s",
line);
1138 ProcessHttpHeader(res);
1143 fMsgReadBuffer10 =
"";
1151 fHasModRoot =
kTRUE;
1155 Error(
"GetHead",
"%s: %s (%d)", fBasicUrl.Data(),
mess.Data(), code);
1157 }
else if (code >= 400) {
1160 else if (code == 404)
1165 Error(
"GetHead",
"%s: %s (%d)", fBasicUrl.Data(),
mess.Data(), code);
1167 }
else if (code >= 300) {
1168 if (code == 301 || code == 303)
1170 else if (code == 302 || code == 307)
1175 Error(
"GetHead",
"%s: %s (%d)", fBasicUrl.Data(),
mess.Data(), code);
1177 }
else if (code > 200) {
1180 Error(
"GetHead",
"%s: %s (%d)", fBasicUrl.Data(),
mess.Data(), code);
1186 redir = res(10, 1000);
1211 if (!fHTTP11 ||
gDebug > 0)
1212 Error(
"GetLine",
"error receiving data from host %s", fUrl.GetHost());
1216 if (
n > 0 &&
line[
n-1] ==
'\n') {
1218 if (
n > 0 &&
line[
n-1] ==
'\r')
1297 Error(
"GetHunk",
"hunk buffer too small for data from host %s (%d bytes needed)",
1298 fUrl.GetHost(), tail +
remain + 1);
1331 Error(
"GetHunk",
"hunk buffer too small for data from host %s",
1349 const char *
p, *end;
1358 for (;
p < end - 1;
p++)
1359 if (
p[0] ==
'\r' &&
p[1] ==
'\n')
1363 if (
p[0] ==
'\r' &&
p[1] ==
'\n')
1383 if (
strlen(fUrl.GetUser())) {
1385 if (
strlen(fUrl.GetPasswd())) {
1387 auth += fUrl.GetPasswd();
1389 msg +=
"Authorization: Basic ";
1403 if (
strcmp(
p.GetProtocol(),
"http")) {
1404 :: Error(
"TWebFile::SetProxy",
"protocol must be HTTP in proxy URL %s",
1417 if (fgProxy.IsValid())
1418 return fgProxy.GetUrl();
1437 return fgMaxFullCacheSize;
1446 fgMaxFullCacheSize =
sz;
1476 Error(
"OpenDirectory",
"invalid directory pointer (should never happen)");
1490 if (
dirp != fDirp) {
1491 Error(
"FreeDirectory",
"invalid directory pointer (should never happen)");
1503 if (
dirp != fDirp) {
1504 Error(
"GetDirEntry",
"invalid directory pointer (should never happen)");
1521 if (
f->fWritten == 0) {
1528 buf.
fSize =
f->GetSize();
1548 if (
f->fWritten == 0) {
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int)
long long Long64_t
Portable signed long integer 8 bytes.
const char Option_t
Option string (const char)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
static const std::string gUserAgent
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
void ReadBuffer(char *&buffer) override
R__EXTERN TSystem * gSystem
static const char * gUserAgent
static void SetProxy(const char *url)
Static method setting global proxy URL.
virtual Int_t GetFromWeb(char *buf, Int_t len, const TString &msg)
Read request from web server.
static Long64_t fgMaxFullCacheSize
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).
virtual Int_t GetFromWeb10(char *buf, Int_t len, const TString &msg, Int_t nseg=0, Long64_t *seg_pos=nullptr, Int_t *seg_len=nullptr)
Read multiple byte range request from web server.
void Seek(Long64_t offset, ERelativeTo pos=kBeg) override
Set position from where to start reading.
virtual void CheckProxy()
Check if shell var "http_proxy" has been set and should be used.
Bool_t ReadBuffer(char *buf, Int_t len) override
Read specified byte range from remote file via HTTP daemon.
virtual TString BasicAuthentication()
Return basic authentication scheme, to be added to the request.
static const char * GetProxy()
Static method returning the global proxy URL.
void Init(Bool_t readHeadOnly) override
Initialize a TWebFile object.
virtual Int_t GetHunk(TSocket *s, char *hunk, Int_t maxsize)
Read a hunk of data from the socket, up until a terminator.
virtual ~TWebFile()
Cleanup.
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.
Bool_t IsOpen() const override
A TWebFile that has been correctly constructed is always considered open.
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).
static void SetMaxFullCacheSize(Long64_t sz)
Static method, set maxmimal size of full cache,.
Int_t ReOpen(Option_t *mode) override
Reopen a file with a different access mode, like from READ to UPDATE or from NEW, CREATE,...
virtual Int_t GetHead()
Get the HTTP header.
virtual void SetMsgReadBuffer10(const char *redirectLocation=nullptr, Bool_t tempRedirect=kFALSE)
Set GET command for use by ReadBuffer(s)10(), handle redirection if needed.
void Close(Option_t *option="") override
Close a Web file.
virtual const char * HttpTerminator(const char *start, const char *peeked, Int_t peeklen)
Determine whether [START, PEEKED + PEEKLEN) contains an HTTP new line [\r]\n.
Long64_t GetSize() const override
Return maximum file size.
Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf) override
Read specified byte ranges from remote file via HTTP daemon.
virtual Int_t GetFromCache(char *buf, Int_t len, Int_t nseg, Long64_t *seg_pos, Int_t *seg_len)
Extract requested segments from the cached content.
static Long64_t GetMaxFullCacheSize()
Static method returning maxmimal size of full cache, which can be preserved by file instance.
~TWebSocket()
Close socket in case not HTTP/1.1 protocol or when explicitly requested.
TWebSocket(TWebFile *f)
Open web file socket.
void ReOpen()
Re-open web file socket.
TWebSystem()
Create helper class that allows directory access via httpd.
Bool_t AccessPathName(const char *path, EAccessMode mode) override
Returns FALSE if one can access a file using the specified access mode.
const char * GetDirEntry(void *dirp) override
Get directory entry via httpd. Returns 0 in case no more entries.
void FreeDirectory(void *dirp) override
Free directory via httpd.
Int_t GetPathInfo(const char *path, FileStat_t &buf) override
Get info about a file.
Int_t Unlink(const char *path) override
Unlink, i.e.
Int_t MakeDirectory(const char *name) override
Make a directory via httpd. Not supported.
void * OpenDirectory(const char *name) override
Open a directory via httpd.
static TString Encode(const char *data)
Transform data into a null terminated base64 string.
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
virtual void Init(Bool_t create)
Initialize a TFile object.
void Close(Option_t *option="") override
Close a file.
virtual void SetName(const char *name)
Set the name of the TNamed.
A TSocket wrapped in by SSL.
This class implements client sockets.
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
virtual Bool_t IsValid() const
void ToLower()
Change string to lower-case.
const char * Data() const
void ToUpper()
Change string to upper case.
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Abstract base class defining a generic interface to the underlying Operating System.
static Int_t GetErrno()
Static function returning system error number.
virtual const char * Getenv(const char *env)
Get environment variable.
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
The TTimeStamp encapsulates seconds and ns since EPOCH.
This class represents a WWW compatible URL.