Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TWebFile.cxx
Go to the documentation of this file.
1// @(#)root/net:$Id$
2// Author: Fons Rademakers 17/01/97
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12//////////////////////////////////////////////////////////////////////////
13// //
14// TWebFile //
15// //
16// A TWebFile is like a normal TFile except that it reads its data //
17// via a standard apache web server. A TWebFile is a read-only file. //
18// //
19//////////////////////////////////////////////////////////////////////////
20
21#include "TWebFile.h"
22#include "TROOT.h"
23#include "TSocket.h"
24#include "Bytes.h"
25#include "TError.h"
26#include "TSystem.h"
27#include "TBase64.h"
28#include "TVirtualPerfStats.h"
29#ifdef R__SSL
30#include "TSSLSocket.h"
31#endif
32
33#include <cerrno>
34#include <cstdlib>
35#include <cstring>
36
37#ifdef WIN32
38# ifndef EADDRINUSE
39# define EADDRINUSE 10048
40# endif
41# ifndef EISCONN
42# define EISCONN 10056
43# endif
44#endif
45
46static const char *gUserAgent = "User-Agent: ROOT-TWebFile/1.1";
47
49
51
52
53// Internal class used to manage the socket that may stay open between
54// calls when HTTP/1.1 protocol is used
56private:
57 TWebFile *fWebFile; // associated web file
58public:
61 void ReOpen();
62};
63
64////////////////////////////////////////////////////////////////////////////////
65/// Open web file socket.
66
68{
69 fWebFile = f;
70 if (!f->fSocket)
71 ReOpen();
72}
73
74////////////////////////////////////////////////////////////////////////////////
75/// Close socket in case not HTTP/1.1 protocol or when explicitly requested.
76
78{
79 if (!fWebFile->fHTTP11) {
80 delete fWebFile->fSocket;
81 fWebFile->fSocket = nullptr;
82 }
83}
84
85////////////////////////////////////////////////////////////////////////////////
86/// Re-open web file socket.
87
89{
90 if (fWebFile->fSocket) {
91 delete fWebFile->fSocket;
92 fWebFile->fSocket = nullptr;
93 }
94
96 if (fWebFile->fProxy.IsValid())
98 else
100
101 for (Int_t i = 0; i < 5; i++) {
102 if (strcmp(connurl.GetProtocol(), "https") == 0) {
103#ifdef R__SSL
104 fWebFile->fSocket = new TSSLSocket(connurl.GetHost(), connurl.GetPort());
105#else
106 ::Error("TWebSocket::ReOpen", "library compiled without SSL, https not supported");
107 return;
108#endif
109 } else
110 fWebFile->fSocket = new TSocket(connurl.GetHost(), connurl.GetPort());
111
112 if (!fWebFile->fSocket || !fWebFile->fSocket->IsValid()) {
113 delete fWebFile->fSocket;
114 fWebFile->fSocket = nullptr;
115 if (gSystem->GetErrno() == EADDRINUSE || gSystem->GetErrno() == EISCONN) {
116 gSystem->Sleep(i*10);
117 } else {
118 ::Error("TWebSocket::ReOpen", "cannot connect to host %s (errno=%d)",
120 return;
121 }
122 } else
123 return;
124 }
125}
126
127
128
129////////////////////////////////////////////////////////////////////////////////
130/// Create a Web file object. A web file is the same as a read-only
131/// TFile except that it is being read via a HTTP server. The url
132/// argument must be of the form: http://host.dom.ain/file.root.
133/// The opt can be "NOPROXY", to bypass any set "http_proxy" shell
134/// variable. The proxy can be specified as (in sh, or equivalent csh):
135/// export http_proxy=http://pcsalo.cern.ch:3128
136/// The proxy can also be specified via the static method TWebFile::SetProxy().
137/// Basic authentication (AuthType Basic) is supported. The user name and
138/// passwd can be specified in the url like this:
139/// http://username:mypasswd@pcsalo.cern.ch/files/aap.root
140/// If the file specified in the URL does not exist or is not accessible
141/// the kZombie bit will be set in the TWebFile object. Use IsZombie()
142/// to see if the file is accessible. The preferred interface to this
143/// constructor is via TFile::Open().
144
146 : TFile(url, strstr(opt, "_WITHOUT_GLOBALREGISTRATION") != nullptr ? "WEB_WITHOUT_GLOBALREGISTRATION" : "WEB"),
147 fSocket(0)
148{
149 TString option = opt;
151 if (option.Contains("NOPROXY", TString::kIgnoreCase))
152 fNoProxy = kTRUE;
153 CheckProxy();
154
156 if (option.Contains("HEADONLY", TString::kIgnoreCase))
157 headOnly = kTRUE;
158
159 if (option == "IO")
160 return;
161
162 Init(headOnly);
163}
164
165////////////////////////////////////////////////////////////////////////////////
166/// Create a Web file object. A web file is the same as a read-only
167/// TFile except that it is being read via a HTTP server. Make sure url
168/// is a valid TUrl object.
169/// The opt can be "NOPROXY", to bypass any set "http_proxy" shell
170/// variable. The proxy can be specified as (in sh, or equivalent csh):
171/// export http_proxy=http://pcsalo.cern.ch:3128
172/// The proxy can also be specified via the static method TWebFile::SetProxy().
173/// Basic authentication (AuthType Basic) is supported. The user name and
174/// passwd can be specified in the url like this:
175/// http://username:mypasswd@pcsalo.cern.ch/files/aap.root
176/// If the file specified in the URL does not exist or is not accessible
177/// the kZombie bit will be set in the TWebFile object. Use IsZombie()
178/// to see if the file is accessible.
179
180TWebFile::TWebFile(TUrl url, Option_t *opt) : TFile(url.GetUrl(), "WEB"), fSocket(0)
181{
182 TString option = opt;
184 if (option.Contains("NOPROXY", TString::kIgnoreCase))
185 fNoProxy = kTRUE;
186 CheckProxy();
187
189 if (option.Contains("HEADONLY", TString::kIgnoreCase))
190 headOnly = kTRUE;
191
192 Init(headOnly);
193}
194
195////////////////////////////////////////////////////////////////////////////////
196/// Cleanup.
197
199{
200 delete fSocket;
201 if (fFullCache) {
203 fFullCache = nullptr;
204 fFullCacheSize = 0;
205 }
206}
207
208////////////////////////////////////////////////////////////////////////////////
209/// Initialize a TWebFile object.
210
212{
213 char buf[4];
214 int err;
215
216 fSocket = nullptr;
217 fSize = -1;
219#if defined(R__WIN32) && defined(R__SSL)
220 fHTTP11 = kTRUE;
221#else
222 fHTTP11 = kFALSE;
223#endif
224 fFullCache = nullptr;
225 fFullCacheSize = 0;
227
228 if ((err = GetHead()) < 0) {
229 if (readHeadOnly) {
230 fD = -1;
231 fWritten = err;
232 return;
233 }
234 if (err == -2) {
235 Error("TWebFile", "%s does not exist", fBasicUrl.Data());
236 MakeZombie();
238 return;
239 }
240 // err == -3 HEAD not supported, fall through and try ReadBuffer()
241 }
242 if (readHeadOnly) {
243 fD = -1;
244 return;
245 }
246
247 if (fIsRootFile) {
248 Seek(0);
249 if (ReadBuffer(buf, 4)) {
250 MakeZombie();
252 return;
253 }
254
255 if (strncmp(buf, "root", 4) && strncmp(buf, "PK", 2)) { // PK is zip file
256 Error("TWebFile", "%s is not a ROOT file", fBasicUrl.Data());
257 MakeZombie();
259 return;
260 }
261 }
262
264 fD = -2; // so TFile::IsOpen() will return true when in TFile::~TFile
265}
266
267////////////////////////////////////////////////////////////////////////////////
268/// Set GET command for use by ReadBuffer(s)10(), handle redirection if
269/// needed. Give full URL so Apache's virtual hosts solution works.
270
272{
273 TUrl oldUrl;
275
276 if (redirectLocation) {
277 if (tempRedirect) { // temp redirect
278 fUrlOrg = fUrl;
280 } else { // permanent redirect
281 fUrlOrg = "";
282 fBasicUrlOrg = "";
283 }
284
285 oldUrl = fUrl;
287
290 fBasicUrl += "://";
292 fBasicUrl += ":";
294 fBasicUrl += "/";
296 // add query string again
298 if (rdl.Index("?") >= 0) {
299 rdl = rdl(rdl.Index("?"), rdl.Length());
300 fBasicUrl += rdl;
301 }
302 }
303
304 if (fMsgReadBuffer10 != "") {
305 // patch up existing command
306 if (oldBasicUrl != "") {
307 // change to redirection location
309 fMsgReadBuffer10.ReplaceAll(TString("Host: ")+oldUrl.GetHost(), TString("Host: ")+fUrl.GetHost());
310 } else if (fBasicUrlOrg != "") {
311 // change back from temp redirection location
314 fUrl = fUrlOrg;
316 fUrlOrg = "";
317 fBasicUrlOrg = "";
318 }
319 }
320
321 if (fBasicUrl == "") {
323 fBasicUrl += "://";
325 fBasicUrl += ":";
327 fBasicUrl += "/";
329 if (strlen(fUrl.GetOptions())) {
330 fBasicUrl += "?";
332 }
333 }
334
335 if (fMsgReadBuffer10 == "") {
336 fMsgReadBuffer10 = "GET ";
338 if (fHTTP11)
339 fMsgReadBuffer10 += " HTTP/1.1";
340 else
341 fMsgReadBuffer10 += " HTTP/1.0";
342 fMsgReadBuffer10 += "\r\n";
343 if (fHTTP11) {
344 fMsgReadBuffer10 += "Host: ";
346 fMsgReadBuffer10 += "\r\n";
347 }
350 fMsgReadBuffer10 += "\r\n";
351 fMsgReadBuffer10 += "Range: bytes=";
352 }
353}
354
355////////////////////////////////////////////////////////////////////////////////
356/// Check if shell var "http_proxy" has been set and should be used.
357
359{
360 if (fNoProxy)
361 return;
362
363 if (fgProxy.IsValid()) {
364 fProxy = fgProxy;
365 return;
366 }
367
368 TString proxy = gSystem->Getenv("http_proxy");
369 if (proxy != "") {
370 TUrl p(proxy);
371 if (strcmp(p.GetProtocol(), "http")) {
372 Error("CheckProxy", "protocol must be HTTP in proxy URL %s",
373 proxy.Data());
374 return;
375 }
376 fProxy = p;
377 if (gDebug > 0)
378 Info("CheckProxy", "using HTTP proxy %s", fProxy.GetUrl());
379 }
380}
381
382////////////////////////////////////////////////////////////////////////////////
383/// A TWebFile that has been correctly constructed is always considered open.
384
386{
387 return IsZombie() ? kFALSE : kTRUE;
388}
389
390////////////////////////////////////////////////////////////////////////////////
391/// Reopen a file with a different access mode, like from READ to
392/// UPDATE or from NEW, CREATE, RECREATE, UPDATE to READ. Thus the
393/// mode argument can be either "READ" or "UPDATE". The method returns
394/// 0 in case the mode was successfully modified, 1 in case the mode
395/// did not change (was already as requested or wrong input arguments)
396/// and -1 in case of failure, in which case the file cannot be used
397/// anymore. A TWebFile cannot be reopened in update mode.
398
400{
401 TString opt = mode;
402 opt.ToUpper();
403
404 if (opt != "READ" && opt != "UPDATE")
405 Error("ReOpen", "mode must be either READ or UPDATE, not %s", opt.Data());
406
407 if (opt == "UPDATE")
408 Error("ReOpen", "update mode not allowed for a TWebFile");
409
410 return 1;
411}
412
413////////////////////////////////////////////////////////////////////////////////
414/// Close a Web file. Close the socket connection and delete the cache
415/// See also the TFile::Close() function
416
418{
419 delete fSocket;
420 fSocket = nullptr;
421 if (fFullCache) {
423 fFullCache = nullptr;
424 fFullCacheSize = 0;
425 }
426 return TFile::Close(option);
427}
428
429////////////////////////////////////////////////////////////////////////////////
430/// Read specified byte range from remote file via HTTP daemon. This
431/// routine connects to the remote host, sends the request and returns
432/// the buffer. Returns kTRUE in case of error.
433
435{
436 Int_t st;
437 if ((st = ReadBufferViaCache(buf, len))) {
438 if (st == 2)
439 return kTRUE;
440 return kFALSE;
441 }
442
443 if (!fHasModRoot)
444 return ReadBuffer10(buf, len);
445
446 // Give full URL so Apache's virtual hosts solution works.
447 // Use protocol 0.9 for efficiency, we are not interested in the 1.0 headers.
448 if (fMsgReadBuffer == "") {
449 fMsgReadBuffer = "GET ";
451 fMsgReadBuffer += "?";
452 }
454 msg += fOffset;
455 msg += ":";
456 msg += len;
457 msg += "\r\n";
458
459 if (GetFromWeb(buf, len, msg) == -1)
460 return kTRUE;
461
462 fOffset += len;
463
464 return kFALSE;
465}
466
467////////////////////////////////////////////////////////////////////////////////
468/// Read specified byte range from remote file via HTTP daemon. This
469/// routine connects to the remote host, sends the request and returns
470/// the buffer. Returns kTRUE in case of error.
471
473{
474 SetOffset(pos);
475 return ReadBuffer(buf, len);
476}
477
478////////////////////////////////////////////////////////////////////////////////
479/// Read specified byte range from remote file via HTTP 1.0 daemon (without
480/// mod-root installed). This routine connects to the remote host, sends the
481/// request and returns the buffer. Returns kTRUE in case of error.
482
484{
486
488 msg += fOffset;
489 msg += "-";
490 msg += fOffset+len-1;
491 msg += "\r\n\r\n";
492
494
495 // in case when server does not support segments, let chance to recover
496 Int_t n = GetFromWeb10(buf, len, msg, 1, &apos, &len);
497 if (n == -1)
498 return kTRUE;
499 // The -2 error condition typically only happens when
500 // GetHead() failed because not implemented, in the first call to
501 // ReadBuffer() in Init(), it is not checked in ReadBuffers10().
502 if (n == -2) {
503 Error("ReadBuffer10", "%s does not exist", fBasicUrl.Data());
504 MakeZombie();
506 return kTRUE;
507 }
508
509 fOffset += len;
510
511 return kFALSE;
512}
513
514////////////////////////////////////////////////////////////////////////////////
515/// Read specified byte ranges from remote file via HTTP daemon.
516/// Reads the nbuf blocks described in arrays pos and len,
517/// where pos[i] is the seek position of block i of length len[i].
518/// Note that for nbuf=1, this call is equivalent to TFile::ReafBuffer
519/// This function is overloaded by TNetFile, TWebFile, etc.
520/// Returns kTRUE in case of failure.
521
523{
524 if (!fHasModRoot)
525 return ReadBuffers10(buf, pos, len, nbuf);
526
527 // Give full URL so Apache's virtual hosts solution works.
528 // Use protocol 0.9 for efficiency, we are not interested in the 1.0 headers.
529 if (fMsgReadBuffer == "") {
530 fMsgReadBuffer = "GET ";
532 fMsgReadBuffer += "?";
533 }
535
536 Int_t k = 0, n = 0, cnt = 0;
537 for (Int_t i = 0; i < nbuf; i++) {
538 if (n) msg += ",";
539 msg += pos[i] + fArchiveOffset;
540 msg += ":";
541 msg += len[i];
542 n += len[i];
543 cnt++;
544 if ((msg.Length() > 8000) || (cnt >= 200)) {
545 msg += "\r\n";
546 if (GetFromWeb(&buf[k], n, msg) == -1)
547 return kTRUE;
549 k += n;
550 n = 0;
551 cnt = 0;
552 }
553 }
554
555 msg += "\r\n";
556
557 if (GetFromWeb(&buf[k], n, msg) == -1)
558 return kTRUE;
559
560 return kFALSE;
561}
562
563////////////////////////////////////////////////////////////////////////////////
564/// Read specified byte ranges from remote file via HTTP 1.0 daemon (without
565/// mod-root installed). Read the nbuf blocks described in arrays pos and len,
566/// where pos[i] is the seek position of block i of length len[i].
567/// Note that for nbuf=1, this call is equivalent to TFile::ReafBuffer
568/// This function is overloaded by TNetFile, TWebFile, etc.
569/// Returns kTRUE in case of failure.
570
572{
574
576
577 Int_t k = 0, n = 0, r, cnt = 0;
578 for (Int_t i = 0; i < nbuf; i++) {
579 if (n) msg += ",";
580 msg += pos[i] + fArchiveOffset;
581 msg += "-";
582 msg += pos[i] + fArchiveOffset + len[i] - 1;
583 n += len[i];
584 cnt++;
585 if ((msg.Length() > 8000) || (cnt >= 200) || (i+1 == nbuf)) {
586 msg += "\r\n\r\n";
587 r = GetFromWeb10(&buf[k], n, msg, cnt, pos + (i+1-cnt), len + (i+1-cnt));
588 if (r == -1)
589 return kTRUE;
591 k += n;
592 n = 0;
593 cnt = 0;
594 }
595 }
596
597 return kFALSE;
598}
599
600////////////////////////////////////////////////////////////////////////////////
601/// Extract requested segments from the cached content.
602/// Such cache can be produced when server suddenly returns full data instead of segments
603/// Returns -1 in case of error, 0 in case of success
604
606{
607 if (!fFullCache) return -1;
608
609 if (gDebug > 0)
610 Info("GetFromCache", "Extract %d segments total len %d from cached data", nseg, len);
611
612 Int_t curr = 0;
613 for (Int_t cnt=0;cnt<nseg;cnt++) {
614 // check that target buffer has enough space
615 if (curr + seg_len[cnt] > len) return -1;
616 // check that segment is inside cached area
617 if (fArchiveOffset + seg_pos[cnt] + seg_len[cnt] > fFullCacheSize) return -1;
618 char* src = (char*) fFullCache + fArchiveOffset + seg_pos[cnt];
619 memcpy(buf + curr, src, seg_len[cnt]);
620 curr += seg_len[cnt];
621 }
622
623 return 0;
624}
625
626////////////////////////////////////////////////////////////////////////////////
627/// Read request from web server. Returns -1 in case of error,
628/// 0 in case of success.
629
631{
632 TSocket *s;
633
634 if (!len) return 0;
635
636 Double_t start = 0;
637 if (gPerfStats) start = TTimeStamp();
638
640 if (fProxy.IsValid())
641 connurl = fProxy;
642 else
643 connurl = fUrl;
644
645 if (strcmp(connurl.GetProtocol(), "https") == 0) {
646#ifdef R__SSL
647 s = new TSSLSocket(connurl.GetHost(), connurl.GetPort());
648#else
649 Error("GetFromWeb", "library compiled without SSL, https not supported");
650 return -1;
651#endif
652 } else
653 s = new TSocket(connurl.GetHost(), connurl.GetPort());
654
655 if (!s->IsValid()) {
656 Error("GetFromWeb", "cannot connect to host %s", fUrl.GetHost());
657 delete s;
658 return -1;
659 }
660
661 if (s->SendRaw(msg.Data(), msg.Length()) == -1) {
662 Error("GetFromWeb", "error sending command to host %s", fUrl.GetHost());
663 delete s;
664 return -1;
665 }
666
667 if (s->RecvRaw(buf, len) == -1) {
668 Error("GetFromWeb", "error receiving data from host %s", fUrl.GetHost());
669 delete s;
670 return -1;
671 }
672
673 // collect statistics
674 fBytesRead += len;
675 fReadCalls++;
676#ifdef R__WIN32
679#else
680 fgBytesRead += len;
681 fgReadCalls++;
682#endif
683
684 if (gPerfStats)
685 gPerfStats->FileReadEvent(this, len, start);
686
687 delete s;
688 return 0;
689}
690
691////////////////////////////////////////////////////////////////////////////////
692/// Read multiple byte range request from web server.
693/// Uses HTTP 1.0 daemon wihtout mod-root.
694/// Returns -2 in case file does not exist, -1 in case
695/// of error and 0 in case of success.
696
698{
699 if (!len) return 0;
700
701 // if file content was cached, reuse it
702 if (fFullCache && (nseg>0))
703 return GetFromCache(buf, len, nseg, seg_pos, seg_len);
704
705 Double_t start = 0;
706 if (gPerfStats) start = TTimeStamp();
707
708 // open fSocket and close it when going out of scope
709 TWebSocket ws(this);
710
711 if (!fSocket || !fSocket->IsValid()) {
712 Error("GetFromWeb10", "cannot connect to host %s", fUrl.GetHost());
713 return -1;
714 }
715
716 if (gDebug > 0)
717 Info("GetFromWeb10", "sending HTTP request:\n%s", msg.Data());
718
719 if (fSocket->SendRaw(msg.Data(), msg.Length()) == -1) {
720 Error("GetFromWeb10", "error sending command to host %s", fUrl.GetHost());
721 return -1;
722 }
723
724 char line[8192];
725 Int_t n, ret = 0, nranges = 0, ltot = 0, redirect = 0;
727 Long64_t first = -1, last = -1, tot, fullsize = 0;
729
730 while ((n = GetLine(fSocket, line, sizeof(line))) >= 0) {
731 if (n == 0) {
732 if (ret < 0)
733 return ret;
734 if (redirect) {
735 if (redir.IsNull()) {
736 // Some sites (s3.amazonaws.com) do not return a Location field on 301
737 Error("GetFromWeb10", "error - redirect without location from host %s", fUrl.GetHost());
738 return -1;
739 }
740
741 ws.ReOpen();
742 // set message to reflect the redirectLocation and add bytes field
744 msg_1 += fOffset;
745 msg_1 += "-";
746 msg_1 += fOffset+len-1;
747 msg_1 += "\r\n\r\n";
748 return GetFromWeb10(buf, len, msg_1);
749 }
750
751 if (first >= 0) {
752 Int_t ll = Int_t(last - first) + 1;
753 Int_t rsize;
754 if ((rsize = fSocket->RecvRaw(&buf[ltot], ll)) == -1) {
755 Error("GetFromWeb10", "error receiving data from host %s", fUrl.GetHost());
756 return -1;
757 }
758 else if (ll != rsize) {
759 Error("GetFromWeb10", "expected %d bytes, got %d", ll, rsize);
760 return -1;
761 }
762 ltot += ll;
763
764 first = -1;
765
766 if (boundary == "")
767 break; // not a multipart response
768 }
769
770 if (fullsize > 0) {
771
772 if (nseg <= 0) {
773 Error("GetFromWeb10","Need segments data to extract parts from full size %lld", fullsize);
774 return -1;
775 }
776
777 if (len > fullsize) {
778 Error("GetFromWeb10","Requested part %d longer than full size %lld", len, fullsize);
779 return -1;
780 }
781
782 if ((fFullCache == 0) && (fullsize <= GetMaxFullCacheSize())) {
783 // try to read file content into cache and than reuse it, limit cache by 2 GB
785 if (fFullCache != 0) {
787 Error("GetFromWeb10", "error receiving data from host %s", fUrl.GetHost());
788 free(fFullCache); fFullCache = nullptr;
789 return -1;
790 }
792 return GetFromCache(buf, len, nseg, seg_pos, seg_len);
793 }
794 // when cache allocation failed, try without cache
795 }
796
797 // check all segemnts are inside range and in sorted order
798 for (Int_t cnt=0;cnt<nseg;cnt++) {
799 if (fArchiveOffset + seg_pos[cnt] + seg_len[cnt] > fullsize) {
800 Error("GetFromWeb10","Requested segment %lld len %d is outside of full range %lld", seg_pos[cnt], seg_len[cnt], fullsize);
801 return -1;
802 }
803 if ((cnt>0) && (seg_pos[cnt-1] + seg_len[cnt-1] > seg_pos[cnt])) {
804 Error("GetFromWeb10","Requested segments are not in sorted order");
805 return -1;
806 }
807 }
808
809 Long64_t pos = 0;
810 char* curr = buf;
811 char dbuf[2048]; // dummy buffer for skip data
812
813 // now read complete file and take only requested segments into the buffer
814 for (Int_t cnt=0; cnt<nseg; cnt++) {
815 // first skip data before segment
816 while (pos < fArchiveOffset + seg_pos[cnt]) {
817 Long64_t ll = fArchiveOffset + seg_pos[cnt] - pos;
818 if (ll > Int_t(sizeof(dbuf))) ll = sizeof(dbuf);
819 if (fSocket->RecvRaw(dbuf, ll) != ll) {
820 Error("GetFromWeb10", "error receiving data from host %s", fUrl.GetHost());
821 return -1;
822 }
823 pos += ll;
824 }
825
826 // reading segment itself
827 if (fSocket->RecvRaw(curr, seg_len[cnt]) != seg_len[cnt]) {
828 Error("GetFromWeb10", "error receiving data from host %s", fUrl.GetHost());
829 return -1;
830 }
831 curr += seg_len[cnt];
832 pos += seg_len[cnt];
833 ltot += seg_len[cnt];
834 }
835
836 // now read file to the end
837 while (pos < fullsize) {
838 Long64_t ll = fullsize - pos;
839 if (ll > Int_t(sizeof(dbuf))) ll = sizeof(dbuf);
840 if (fSocket->RecvRaw(dbuf, ll) != ll) {
841 Error("GetFromWeb10", "error receiving data from host %s", fUrl.GetHost());
842 return -1;
843 }
844 pos += ll;
845 }
846
847 if (gDebug > 0)
848 Info("GetFromWeb10", "Complete reading %d bytes in %d segments out of full size %lld", len, nseg, fullsize);
849
850 break;
851 }
852
853 continue;
854 }
855
856 if (gDebug > 0)
857 Info("GetFromWeb10", "header: %s", line);
858
859 if (boundaryEnd == line) {
860 if (gDebug > 0)
861 Info("GetFromWeb10", "got all headers");
862 break;
863 }
864 if (boundary == line) {
865 nranges++;
866 if (gDebug > 0)
867 Info("GetFromWeb10", "get new multipart byte range (%d)", nranges);
868 }
869
870 TString res = line;
871 res.ToLower();
872 if (res.BeginsWith("HTTP/1.", TString::kIgnoreCase)) {
873 if (res.BeginsWith("HTTP/1.1", TString::kIgnoreCase)) {
874 if (!fHTTP11)
875 fMsgReadBuffer10 = "";
876 fHTTP11 = kTRUE;
877 }
878 TString scode = res(9, 3);
879 Int_t code = scode.Atoi();
880 if (code >= 500) {
881 ret = -1;
882 TString mess = res(13, 1000);
883 Error("GetFromWeb10", "%s: %s (%d)", fBasicUrl.Data(), mess.Data(), code);
884 } else if (code >= 400) {
885 if (code == 404)
886 ret = -2; // file does not exist
887 else {
888 ret = -1;
889 TString mess = res(13, 1000);
890 Error("GetFromWeb10", "%s: %s (%d)", fBasicUrl.Data(), mess.Data(), code);
891 }
892 } else if (code >= 300) {
893 if (code == 301 || code == 303) {
894 redirect = 1; // permanent redirect
895 } else if (code == 302 || code == 307) {
896 // treat 302 as 303: permanent redirect
897 redirect = 1;
898 //redirect = 2; // temp redirect
899 } else {
900 ret = -1;
901 TString mess = res(13, 1000);
902 Error("GetFromWeb10", "%s: %s (%d)", fBasicUrl.Data(), mess.Data(), code);
903 }
904 } else if (code > 200) {
905 if (code != 206) {
906 ret = -1;
907 TString mess = res(13, 1000);
908 Error("GetFromWeb10", "%s: %s (%d)", fBasicUrl.Data(), mess.Data(), code);
909 }
910 } else if (code == 200) {
911 fullsize = -200; // make indication of code 200
912 Warning("GetFromWeb10",
913 "Server %s response with complete file, but only part of it was requested.\n"
914 "Check MaxRanges configuration parameter (if Apache is used)",
915 fUrl.GetHost());
916
917 }
918 } else if (res.BeginsWith("content-type: multipart", TString::kIgnoreCase)) {
919 boundary = res(res.Index("boundary=", TString::kIgnoreCase) + 9, 1000);
920 if (boundary[0] == '"' && boundary[boundary.Length()-1] == '"') {
921 boundary = boundary(1, boundary.Length() - 2);
922 }
923 boundary = "--" + boundary;
924 boundaryEnd = boundary + "--";
925 } else if (res.BeginsWith("content-range:", TString::kIgnoreCase)) {
926 sscanf(res.Data(), "content-range: bytes %lld-%lld/%lld", &first, &last, &tot);
927 if (fSize == -1) fSize = tot;
928 } else if (res.BeginsWith("content-length:", TString::kIgnoreCase) && (fullsize == -200)) {
929 sscanf(res.Data(), "content-length: %lld", &fullsize);
930 } else if (res.BeginsWith("location:", TString::kIgnoreCase) && redirect) {
931 redir = res(10, 1000);
932 if (redirect == 2) // temp redirect
934 else // permanent redirect
936 }
937 }
938
939 if (redirect && redir.IsNull()) {
940 Error("GetFromWeb10", "error - redirect without location from host %s", fUrl.GetHost());
941 }
942
943 if (n == -1 && fHTTP11) {
944 if (gDebug > 0)
945 Info("GetFromWeb10", "HTTP/1.1 socket closed, reopen");
946 if (fBasicUrlOrg != "") {
947 // if we have to close temp redirection, set back to original url
949 }
950 ws.ReOpen();
951 return GetFromWeb10(buf, len, msg);
952 }
953
954 if (ltot != len) {
955 Error("GetFromWeb10", "error receiving expected amount of data (got %d, expected %d) from host %s",
956 ltot, len, fUrl.GetHost());
957 return -1;
958 }
959
960 // collect statistics
961 fBytesRead += len;
962 fReadCalls++;
963#ifdef R__WIN32
966#else
967 fgBytesRead += len;
968 fgReadCalls++;
969#endif
970
971 if (gPerfStats)
972 gPerfStats->FileReadEvent(this, len, start);
973
974 return 0;
975}
976
977////////////////////////////////////////////////////////////////////////////////
978/// Set position from where to start reading.
979
981{
982 switch (pos) {
983 case kBeg:
985 break;
986 case kCur:
987 fOffset += offset;
988 break;
989 case kEnd:
990 // this option is not used currently in the ROOT code
991 if (fArchiveOffset)
992 Error("Seek", "seeking from end in archive is not (yet) supported");
993 fOffset = fEND - offset; // is fEND really EOF or logical EOF?
994 break;
995 }
996}
997
998////////////////////////////////////////////////////////////////////////////////
999/// Return maximum file size.
1000
1002{
1003 if (!fHasModRoot || fSize >= 0)
1004 return fSize;
1005
1006 Long64_t size;
1007 char asize[64];
1008
1009 TString msg = "GET ";
1010 msg += fBasicUrl;
1011 msg += "?";
1012 msg += -1;
1013 msg += "\r\n";
1014
1015 if (const_cast<TWebFile*>(this)->GetFromWeb(asize, 64, msg) == -1)
1016 return kMaxInt;
1017
1018#ifndef R__WIN32
1019 size = atoll(asize);
1020#else
1021 size = _atoi64(asize);
1022#endif
1023
1024 fSize = size;
1025
1026 return size;
1027}
1028
1029////////////////////////////////////////////////////////////////////////////////
1030/// Get the HTTP header. Depending on the return code we can see if
1031/// the file exists and if the server uses mod_root.
1032/// Returns -1 in case of an error, -2 in case the file does not exists,
1033/// -3 in case HEAD is not supported (dCache HTTP door) and
1034/// 0 in case of success.
1035
1037{
1038 // Give full URL so Apache's virtual hosts solution works.
1039 if (fMsgGetHead == "") {
1040 fMsgGetHead = "HEAD ";
1042 if (fHTTP11)
1043 fMsgGetHead += " HTTP/1.1";
1044 else
1045 fMsgGetHead += " HTTP/1.0";
1046 fMsgGetHead += "\r\n";
1047 if (fHTTP11) {
1048 fMsgGetHead += "Host: ";
1050 fMsgGetHead += "\r\n";
1051 }
1054 fMsgGetHead += "\r\n\r\n";
1055 }
1057
1058 TUrl connurl;
1059 if (fProxy.IsValid())
1060 connurl = fProxy;
1061 else
1062 connurl = fUrl;
1063
1064 TSocket *s = nullptr;
1065 for (Int_t i = 0; i < 5; i++) {
1066 if (strcmp(connurl.GetProtocol(), "https") == 0) {
1067#ifdef R__SSL
1068 s = new TSSLSocket(connurl.GetHost(), connurl.GetPort());
1069#else
1070 Error("GetHead", "library compiled without SSL, https not supported");
1071 return -1;
1072#endif
1073 } else
1074 s = new TSocket(connurl.GetHost(), connurl.GetPort());
1075
1076 if (!s->IsValid()) {
1077 delete s;
1078 if (gSystem->GetErrno() == EADDRINUSE || gSystem->GetErrno() == EISCONN) {
1079 s = nullptr;
1080 gSystem->Sleep(i*10);
1081 } else {
1082 Error("GetHead", "cannot connect to host %s (errno=%d)", fUrl.GetHost(),
1083 gSystem->GetErrno());
1084 return -1;
1085 }
1086 } else
1087 break;
1088 }
1089 if (!s)
1090 return -1;
1091
1092 if (gDebug > 0) {
1093 Info("GetHead", "connected to host %s", connurl.GetHost());
1094 Info("GetHead", "sending HTTP request:\n%s", msg.Data());
1095 }
1096
1097 if (s->SendRaw(msg.Data(), msg.Length()) == -1) {
1098 Error("GetHead", "error sending command to host %s", fUrl.GetHost());
1099 delete s;
1100 return -1;
1101 }
1102
1103 char line[8192];
1104 Int_t n, ret = 0, redirect = 0;
1105 TString redir;
1106
1107 while ((n = GetLine(s, line, sizeof(line))) >= 0) {
1108 if (n == 0) {
1109 if (gDebug > 0)
1110 Info("GetHead", "got all headers");
1111 delete s;
1112 if (fBasicUrlOrg != "" && !redirect) {
1113 // set back to original url in case of temp redirect
1115 fMsgGetHead = "";
1116 }
1117 if (ret < 0)
1118 return ret;
1119 if (redirect) {
1120 if (redir.IsNull()) {
1121 // Some sites (s3.amazonaws.com) do not return a Location field on 301
1122 Error("GetHead", "error - redirect without location from host %s", fUrl.GetHost());
1123 return -1;
1124 }
1125 return GetHead();
1126 }
1127 return 0;
1128 }
1129
1130 if (gDebug > 0)
1131 Info("GetHead", "header: %s", line);
1132
1133 TString res = line;
1134 ProcessHttpHeader(res);
1135 if (res.BeginsWith("HTTP/1.")) {
1136 if (res.BeginsWith("HTTP/1.1")) {
1137 if (!fHTTP11) {
1138 fMsgGetHead = "";
1139 fMsgReadBuffer10 = "";
1140 }
1141 fHTTP11 = kTRUE;
1142 }
1143 TString scode = res(9, 3);
1144 Int_t code = scode.Atoi();
1145 if (code >= 500) {
1146 if (code == 500)
1148 else {
1149 ret = -1;
1150 TString mess = res(13, 1000);
1151 Error("GetHead", "%s: %s (%d)", fBasicUrl.Data(), mess.Data(), code);
1152 }
1153 } else if (code >= 400) {
1154 if (code == 400)
1155 ret = -3; // command not supported
1156 else if (code == 404)
1157 ret = -2; // file does not exist
1158 else {
1159 ret = -1;
1160 TString mess = res(13, 1000);
1161 Error("GetHead", "%s: %s (%d)", fBasicUrl.Data(), mess.Data(), code);
1162 }
1163 } else if (code >= 300) {
1164 if (code == 301 || code == 303)
1165 redirect = 1; // permanent redirect
1166 else if (code == 302 || code == 307)
1167 redirect = 2; // temp redirect
1168 else {
1169 ret = -1;
1170 TString mess = res(13, 1000);
1171 Error("GetHead", "%s: %s (%d)", fBasicUrl.Data(), mess.Data(), code);
1172 }
1173 } else if (code > 200) {
1174 ret = -1;
1175 TString mess = res(13, 1000);
1176 Error("GetHead", "%s: %s (%d)", fBasicUrl.Data(), mess.Data(), code);
1177 }
1178 } else if (res.BeginsWith("Content-Length:", TString::kIgnoreCase)) {
1179 TString slen = res(16, 1000);
1180 fSize = slen.Atoll();
1181 } else if (res.BeginsWith("Location:", TString::kIgnoreCase) && redirect) {
1182 redir = res(10, 1000);
1183 if (redirect == 2) // temp redirect
1185 else // permanent redirect
1187 fMsgGetHead = "";
1188 }
1189 }
1190
1191 delete s;
1192
1193 return ret;
1194}
1195
1196////////////////////////////////////////////////////////////////////////////////
1197/// Read a line from the socket. Reads at most one less than the number of
1198/// characters specified by maxsize. Reading stops when a newline character
1199/// is found, The newline (\\n) and cr (\\r), if any, are removed.
1200/// Returns -1 in case of error, or the number of characters read (>= 0)
1201/// otherwise.
1202
1204{
1205 Int_t n = GetHunk(s, line, maxsize);
1206 if (n < 0) {
1207 if (!fHTTP11 || gDebug > 0)
1208 Error("GetLine", "error receiving data from host %s", fUrl.GetHost());
1209 return -1;
1210 }
1211
1212 if (n > 0 && line[n-1] == '\n') {
1213 n--;
1214 if (n > 0 && line[n-1] == '\r')
1215 n--;
1216 line[n] = '\0';
1217 }
1218 return n;
1219}
1220
1221////////////////////////////////////////////////////////////////////////////////
1222/// Read a hunk of data from the socket, up until a terminator. The hunk is
1223/// limited by whatever the TERMINATOR callback chooses as its
1224/// terminator. For example, if terminator stops at newline, the hunk
1225/// will consist of a line of data; if terminator stops at two
1226/// newlines, it can be used to read the head of an HTTP response.
1227/// Upon determining the boundary, the function returns the data (up to
1228/// the terminator) in hunk.
1229///
1230/// In case of read error, -1 is returned. In case of having read some
1231/// data, but encountering EOF before seeing the terminator, the data
1232/// that has been read is returned, but it will (obviously) not contain the
1233/// terminator.
1234///
1235/// The TERMINATOR function is called with three arguments: the
1236/// beginning of the data read so far, the beginning of the current
1237/// block of peeked-at data, and the length of the current block.
1238/// Depending on its needs, the function is free to choose whether to
1239/// analyze all data or just the newly arrived data. If TERMINATOR
1240/// returns 0, it means that the terminator has not been seen.
1241/// Otherwise it should return a pointer to the character immediately
1242/// following the terminator.
1243///
1244/// The idea is to be able to read a line of input, or otherwise a hunk
1245/// of text, such as the head of an HTTP request, without crossing the
1246/// boundary, so that the next call to RecvRaw() etc. reads the data
1247/// after the hunk. To achieve that, this function does the following:
1248///
1249/// 1. Peek at incoming data.
1250///
1251/// 2. Determine whether the peeked data, along with the previously
1252/// read data, includes the terminator.
1253///
1254/// 3a. If yes, read the data until the end of the terminator, and
1255/// exit.
1256///
1257/// 3b. If no, read the peeked data and goto 1.
1258///
1259/// The function is careful to assume as little as possible about the
1260/// implementation of peeking. For example, every peek is followed by
1261/// a read. If the read returns a different amount of data, the
1262/// process is retried until all data arrives safely.
1263///
1264/// Reads at most one less than the number of characters specified by maxsize.
1265
1267{
1268 if (maxsize <= 0) return 0;
1269
1271 Int_t tail = 0; // tail position in HUNK
1272
1273 while (1) {
1274 const char *end;
1276
1277 // First, peek at the available data.
1278 pklen = s->RecvRaw(hunk+tail, bufsize-1-tail, kPeek);
1279 if (pklen < 0) {
1280 return -1;
1281 }
1282 end = HttpTerminator(hunk, hunk+tail, pklen);
1283 if (end) {
1284 // The data contains the terminator: we'll drain the data up
1285 // to the end of the terminator.
1286 remain = end - (hunk + tail);
1287 if (remain == 0) {
1288 // No more data needs to be read.
1289 hunk[tail] = '\0';
1290 return tail;
1291 }
1292 if (bufsize - 1 < tail + remain) {
1293 Error("GetHunk", "hunk buffer too small for data from host %s (%d bytes needed)",
1294 fUrl.GetHost(), tail + remain + 1);
1295 hunk[tail] = '\0';
1296 return -1;
1297 }
1298 } else {
1299 // No terminator: simply read the data we know is (or should
1300 // be) available.
1301 remain = pklen;
1302 }
1303
1304 // Now, read the data. Note that we make no assumptions about
1305 // how much data we'll get. (Some TCP stacks are notorious for
1306 // read returning less data than the previous MSG_PEEK.)
1307 rdlen = s->RecvRaw(hunk+tail, remain, kDontBlock);
1308 if (rdlen < 0) {
1309 return -1;
1310 }
1311 tail += rdlen;
1312 hunk[tail] = '\0';
1313
1314 if (rdlen == 0) {
1315 // in case of EOF: return the data we've read.
1316 return tail;
1317 }
1318 if (end && rdlen == remain) {
1319 // The terminator was seen and the remaining data drained --
1320 // we got what we came for.
1321 return tail;
1322 }
1323
1324 // Keep looping until all the data arrives.
1325
1326 if (tail == bufsize - 1) {
1327 Error("GetHunk", "hunk buffer too small for data from host %s",
1328 fUrl.GetHost());
1329 return -1;
1330 }
1331 }
1332}
1333
1334////////////////////////////////////////////////////////////////////////////////
1335/// Determine whether [START, PEEKED + PEEKLEN) contains an HTTP new
1336/// line [\\r]\\n. If so, return the pointer to the position after the line,
1337/// otherwise return 0. This is used as callback to GetHunk(). The data
1338/// between START and PEEKED has been read and cannot be "unread"; the
1339/// data after PEEKED has only been peeked.
1340
1341const char *TWebFile::HttpTerminator(const char *start, const char *peeked,
1342 Int_t peeklen)
1343{
1344#if 0
1345 const char *p, *end;
1346
1347 // Look for "[\r]\n", and return the following position if found.
1348 // Start one char before the current to cover the possibility that
1349 // part of the terminator (e.g. "\r") arrived in the previous batch.
1350 p = peeked - start < 1 ? start : peeked - 1;
1351 end = peeked + peeklen;
1352
1353 // Check for \r\n anywhere in [p, end-2).
1354 for (; p < end - 1; p++)
1355 if (p[0] == '\r' && p[1] == '\n')
1356 return p + 2;
1357
1358 // p==end-1: check for \r\n directly preceding END.
1359 if (p[0] == '\r' && p[1] == '\n')
1360 return p + 2;
1361#else
1362 (void) start; // start unused, silence compiler
1363 if (peeked) {
1364 const char *p = (const char*) memchr(peeked, '\n', peeklen);
1365 if (p)
1366 // p+1 because the line must include '\n'
1367 return p + 1;
1368 }
1369#endif
1370 return nullptr;
1371}
1372
1373////////////////////////////////////////////////////////////////////////////////
1374/// Return basic authentication scheme, to be added to the request.
1375
1377{
1378 TString msg;
1379 if (strlen(fUrl.GetUser())) {
1381 if (strlen(fUrl.GetPasswd())) {
1382 auth += ":";
1383 auth += fUrl.GetPasswd();
1384 }
1385 msg += "Authorization: Basic ";
1387 msg += "\r\n";
1388 }
1389 return msg;
1390}
1391
1392////////////////////////////////////////////////////////////////////////////////
1393/// Static method setting global proxy URL.
1394
1395void TWebFile::SetProxy(const char *proxy)
1396{
1397 if (proxy && *proxy) {
1398 TUrl p(proxy);
1399 if (strcmp(p.GetProtocol(), "http")) {
1400 :: Error("TWebFile::SetProxy", "protocol must be HTTP in proxy URL %s",
1401 proxy);
1402 return;
1403 }
1404 fgProxy = p;
1405 }
1406}
1407
1408////////////////////////////////////////////////////////////////////////////////
1409/// Static method returning the global proxy URL.
1410
1412{
1413 if (fgProxy.IsValid())
1414 return fgProxy.GetUrl();
1415 return "";
1416}
1417
1418////////////////////////////////////////////////////////////////////////////////
1419/// Process the HTTP header in the argument. This method is intended to be
1420/// overwritten by subclasses that exploit the information contained in the
1421/// HTTP headers.
1422
1424{
1425}
1426
1427////////////////////////////////////////////////////////////////////////////////
1428/// Static method returning maxmimal size of full cache,
1429/// which can be preserved by file instance
1430
1435
1436////////////////////////////////////////////////////////////////////////////////
1437/// Static method, set maxmimal size of full cache,
1438// which can be preserved by file instance
1439
1444
1445
1446////////////////////////////////////////////////////////////////////////////////
1447/// Create helper class that allows directory access via httpd.
1448/// The name must start with '-' to bypass the TSystem singleton check.
1449
1450TWebSystem::TWebSystem() : TSystem("-http", "HTTP Helper System")
1451{
1452 SetName("http");
1453
1454 fDirp = nullptr;
1455}
1456
1457////////////////////////////////////////////////////////////////////////////////
1458/// Make a directory via httpd. Not supported.
1459
1461{
1462 return -1;
1463}
1464
1465////////////////////////////////////////////////////////////////////////////////
1466/// Open a directory via httpd. Returns an opaque pointer to a dir
1467/// structure. Returns 0 in case of error.
1468
1469void *TWebSystem::OpenDirectory(const char *)
1470{
1471 if (fDirp) {
1472 Error("OpenDirectory", "invalid directory pointer (should never happen)");
1473 fDirp = nullptr;
1474 }
1475
1476 fDirp = nullptr; // not implemented for the time being
1477
1478 return fDirp;
1479}
1480
1481////////////////////////////////////////////////////////////////////////////////
1482/// Free directory via httpd.
1483
1485{
1486 if (dirp != fDirp) {
1487 Error("FreeDirectory", "invalid directory pointer (should never happen)");
1488 return;
1489 }
1490
1491 fDirp = nullptr;
1492}
1493
1494////////////////////////////////////////////////////////////////////////////////
1495/// Get directory entry via httpd. Returns 0 in case no more entries.
1496
1498{
1499 if (dirp != fDirp) {
1500 Error("GetDirEntry", "invalid directory pointer (should never happen)");
1501 return 0;
1502 }
1503
1504 return 0;
1505}
1506
1507////////////////////////////////////////////////////////////////////////////////
1508/// Get info about a file. Info is returned in the form of a FileStat_t
1509/// structure (see TSystem.h).
1510/// The function returns 0 in case of success and 1 if the file could
1511/// not be stat'ed.
1512
1514{
1515 TWebFile *f = new TWebFile(path, "HEADONLY");
1516
1517 if (f->fWritten == 0) {
1518
1519 buf.fDev = 0;
1520 buf.fIno = 0;
1521 buf.fMode = 0;
1522 buf.fUid = 0;
1523 buf.fGid = 0;
1524 buf.fSize = f->GetSize();
1525 buf.fMtime = 0;
1526 buf.fIsLink = kFALSE;
1527
1528 delete f;
1529 return 0;
1530 }
1531
1532 delete f;
1533 return 1;
1534}
1535
1536////////////////////////////////////////////////////////////////////////////////
1537/// Returns FALSE if one can access a file using the specified access mode.
1538/// Mode is the same as for the Unix access(2) function.
1539/// Attention, bizarre convention of return value!!
1540
1542{
1543 TWebFile *f = new TWebFile(path, "HEADONLY");
1544 if (f->fWritten == 0) {
1545 delete f;
1546 return kFALSE;
1547 }
1548 delete f;
1549 return kTRUE;
1550}
1551
1552////////////////////////////////////////////////////////////////////////////////
1553/// Unlink, i.e. remove, a file or directory. Returns 0 when successful,
1554/// -1 in case of failure. Not supported for httpd.
1555
1557{
1558 return -1;
1559}
#define f(i)
Definition RSha256.hxx:104
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
constexpr Int_t kMaxInt
Definition RtypesCore.h:119
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
static const std::string gUserAgent
#define gDirectory
Definition TDirectory.h:385
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
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...
Definition TROOT.cxx:627
#define gROOT
Definition TROOT.h:411
@ kDontBlock
Definition TSystem.h:246
@ kPeek
Definition TSystem.h:245
EAccessMode
Definition TSystem.h:51
R__EXTERN TSystem * gSystem
Definition TSystem.h:572
#define gPerfStats
static const char * gUserAgent
Definition TWebFile.cxx:46
#define free
Definition civetweb.c:1578
#define malloc
Definition civetweb.c:1575
static TString Encode(const char *data)
Transform data into a null terminated base64 string.
Definition TBase64.cxx:106
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Definition TFile.h:131
static std::atomic< Long64_t > fgBytesRead
Number of bytes read by all TFile objects.
Definition TFile.h:161
Int_t fReadCalls
Number of read calls ( not counting the cache calls )
Definition TFile.h:168
Long64_t fBytesRead
Number of bytes read from this file.
Definition TFile.h:155
static void SetFileBytesRead(Long64_t bytes=0)
Definition TFile.cxx:4290
static void SetFileReadCalls(Int_t readcalls=0)
Definition TFile.cxx:4296
TUrl fUrl
!URL of file
Definition TFile.h:189
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Definition TFile.cxx:4256
Int_t ReadBufferViaCache(char *buf, Int_t len)
Read buffer via cache.
Definition TFile.cxx:1919
Long64_t fArchiveOffset
!Offset at which file starts in archive
Definition TFile.h:180
virtual void Init(Bool_t create)
Initialize a TFile object.
Definition TFile.cxx:616
ERelativeTo
Definition TFile.h:278
@ kCur
Definition TFile.h:278
@ kBeg
Definition TFile.h:278
@ kEnd
Definition TFile.h:278
Int_t fD
File descriptor.
Definition TFile.h:161
Bool_t fIsRootFile
!True is this is a ROOT file, raw file otherwise
Definition TFile.h:183
virtual void SetOffset(Long64_t offset, ERelativeTo pos=kBeg)
Set position from where to start reading.
Definition TFile.cxx:2283
Long64_t fOffset
!Seek offset cache
Definition TFile.h:175
Long64_t fEND
Last used byte in file.
Definition TFile.h:158
void Close(Option_t *option="") override
Close a file.
Definition TFile.cxx:958
static std::atomic< Int_t > fgReadCalls
Number of bytes read from all TFile objects.
Definition TFile.h:164
Int_t fWritten
Number of objects written so far.
Definition TFile.h:166
static Int_t GetFileReadCalls()
Static function returning the total number of read calls from all files.
Definition TFile.cxx:4273
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:149
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:159
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
void MakeZombie()
Definition TObject.h:53
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition TSocket.cxx:889
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition TSocket.cxx:611
virtual Bool_t IsValid() const
Definition TSocket.h:130
Basic string class.
Definition TString.h:138
void ToLower()
Change string to lower-case.
Definition TString.cxx:1189
const char * Data() const
Definition TString.h:384
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:712
@ kIgnoreCase
Definition TString.h:285
void ToUpper()
Change string to upper case.
Definition TString.cxx:1202
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:631
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:659
Abstract base class defining a generic interface to the underlying Operating System.
Definition TSystem.h:276
static Int_t GetErrno()
Static function returning system error number.
Definition TSystem.cxx:274
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1676
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:435
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition TTimeStamp.h:45
This class represents a WWW compatible URL.
Definition TUrl.h:33
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition TUrl.cxx:395
const char * GetFile() const
Definition TUrl.h:69
void SetUrl(const char *url, Bool_t defaultIsFile=kFALSE)
Parse url character string and split in its different subcomponents.
Definition TUrl.cxx:107
Bool_t IsValid() const
Definition TUrl.h:79
const char * GetUser() const
Definition TUrl.h:65
const char * GetHost() const
Definition TUrl.h:67
const char * GetPasswd() const
Definition TUrl.h:66
const char * GetOptions() const
Definition TUrl.h:71
const char * GetProtocol() const
Definition TUrl.h:64
Int_t GetPort() const
Definition TUrl.h:78
virtual Int_t GetLine(TSocket *s, char *line, Int_t maxsize)
Read a line from the socket.
virtual ~TWebFile()
Cleanup.
Definition TWebFile.cxx:198
virtual Int_t GetHead()
Get the HTTP header.
virtual Int_t GetFromWeb(char *buf, Int_t len, const TString &msg)
Read request from web server.
Definition TWebFile.cxx:630
virtual TString BasicAuthentication()
Return basic authentication scheme, to be added to the request.
Long64_t fSize
Definition TWebFile.h:42
TSocket * fSocket
Definition TWebFile.h:43
static const char * GetProxy()
Static method returning the global proxy URL.
TString fBasicUrl
Definition TWebFile.h:51
static void SetProxy(const char *url)
Static method setting global proxy URL.
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.
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.
Definition TWebFile.cxx:605
TString fBasicUrlOrg
Definition TWebFile.h:53
Bool_t IsOpen() const override
A TWebFile that has been correctly constructed is always considered open.
Definition TWebFile.cxx:385
Bool_t fHTTP11
Definition TWebFile.h:46
virtual void CheckProxy()
Check if shell var "http_proxy" has been set and should be used.
Definition TWebFile.cxx:358
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).
Definition TWebFile.cxx:571
Bool_t ReadBuffer(char *buf, Int_t len) override
Read specified byte range from remote file via HTTP daemon.
Definition TWebFile.cxx:434
Long64_t fFullCacheSize
complete content of the file, some http server may return complete content
Definition TWebFile.h:55
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.
Definition TWebFile.cxx:522
TUrl fProxy
Definition TWebFile.h:44
TString fMsgGetHead
Definition TWebFile.h:50
void Seek(Long64_t offset, ERelativeTo pos=kBeg) override
Set position from where to start reading.
Definition TWebFile.cxx:980
TString fMsgReadBuffer
Definition TWebFile.h:48
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).
Definition TWebFile.cxx:483
void Init(Bool_t readHeadOnly) override
Initialize a TWebFile object.
Definition TWebFile.cxx:211
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.
Definition TWebFile.cxx:697
TWebFile()
Definition TWebFile.h:39
static TUrl fgProxy
size of the cached content
Definition TWebFile.h:57
void * fFullCache
Definition TWebFile.h:54
static void SetMaxFullCacheSize(Long64_t sz)
Static method, set maxmimal size of full cache,.
virtual void SetMsgReadBuffer10(const char *redirectLocation=nullptr, Bool_t tempRedirect=kFALSE)
Set GET command for use by ReadBuffer(s)10(), handle redirection if needed.
Definition TWebFile.cxx:271
TString fMsgReadBuffer10
Definition TWebFile.h:49
TUrl fUrlOrg
Definition TWebFile.h:52
Int_t ReOpen(Option_t *mode) override
Reopen a file with a different access mode, like from READ to UPDATE or from NEW, CREATE,...
Definition TWebFile.cxx:399
static Long64_t GetMaxFullCacheSize()
Static method returning maxmimal size of full cache, which can be preserved by file instance.
Bool_t fHasModRoot
Definition TWebFile.h:45
virtual void ProcessHttpHeader(const TString &headerLine)
Process the HTTP header in the argument.
void Close(Option_t *option="") override
Close a Web file.
Definition TWebFile.cxx:417
virtual Int_t GetHunk(TSocket *s, char *hunk, Int_t maxsize)
Read a hunk of data from the socket, up until a terminator.
static Long64_t fgMaxFullCacheSize
Definition TWebFile.h:58
Bool_t fNoProxy
Definition TWebFile.h:47
TWebFile * fWebFile
Definition TWebFile.cxx:57
~TWebSocket()
Close socket in case not HTTP/1.1 protocol or when explicitly requested.
Definition TWebFile.cxx:77
void ReOpen()
Re-open web file socket.
Definition TWebFile.cxx:88
TWebSocket(TWebFile *f)
Open web file socket.
Definition TWebFile.cxx:67
void * OpenDirectory(const char *name) override
Open a directory via httpd.
Int_t MakeDirectory(const char *name) override
Make a directory via httpd. Not supported.
TWebSystem()
Create helper class that allows directory access via httpd.
void FreeDirectory(void *dirp) override
Free directory via httpd.
Bool_t AccessPathName(const char *path, EAccessMode mode) override
Returns FALSE if one can access a file using the specified access mode.
void * fDirp
Definition TWebFile.h:102
Int_t GetPathInfo(const char *path, FileStat_t &buf) override
Get info about a file.
const char * GetDirEntry(void *dirp) override
Get directory entry via httpd. Returns 0 in case no more entries.
Int_t Unlink(const char *path) override
Unlink, i.e.
TLine * line
const Int_t n
Definition legend1.C:16
Int_t fMode
Definition TSystem.h:135
Long64_t fSize
Definition TSystem.h:138
Long_t fDev
Definition TSystem.h:133
Int_t fGid
Definition TSystem.h:137
Long_t fMtime
Definition TSystem.h:139
Long_t fIno
Definition TSystem.h:134
Bool_t fIsLink
Definition TSystem.h:140
Int_t fUid
Definition TSystem.h:136