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