libdap++  Updated for version 3.8.2
Connect.cc
Go to the documentation of this file.
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
5 // Access Protocol.
6 
7 // Copyright (c) 2002,2003 OPeNDAP, Inc.
8 // Author: James Gallagher <jgallagher@opendap.org>
9 // Dan Holloway <dholloway@gso.uri.edu>
10 // Reza Nekovei <reza@intcomm.net>
11 //
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation; either
15 // version 2.1 of the License, or (at your option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 //
26 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
27 
28 // (c) COPYRIGHT URI/MIT 1994-2002
29 // Please read the full copyright statement in the file COPYRIGHT_URI.
30 //
31 // Authors:
32 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
33 // dan Dan Holloway <dholloway@gso.uri.edu>
34 // reza Reza Nekovei <reza@intcomm.net>
35 
36 
37 #include "config.h"
38 
39 //#define DODS_DEBUG
40 #define FILE_METHODS 1
41 
42 static char rcsid[] not_used =
43  { "$Id: Connect.cc 22703 2010-05-11 18:10:01Z jimg $"
44  };
45 
46 #include <cstring>
47 #include <fstream>
48 #include <algorithm>
49 
50 #include "debug.h"
51 #include "DataDDS.h"
52 #include "Connect.h"
53 #include "escaping.h"
54 #include "RCReader.h"
55 #include "DDXParserSAX2.h"
56 #if FILE_METHODS
57 #include "XDRFileUnMarshaller.h"
58 #else
59 #include "fdiostream.h"
60 #include "XDRStreamUnMarshaller.h"
61 #endif
62 #include "mime_util.h"
63 
64 using std::cerr;
65 using std::endl;
66 using std::ifstream;
67 using std::ofstream;
68 using std::min;
69 
70 namespace libdap {
71 
74 void
75 Connect::process_data(DataDDS &data, Response *rs)
76 {
77  DBG(cerr << "Entering Connect::process_data" << endl);
78 
79  data.set_version(rs->get_version());
80  data.set_protocol(rs->get_protocol());
81 
82  DBG(cerr << "Entering process_data: d_stream = " << rs << endl);
83  switch (rs->get_type()) {
84  case dods_error: {
85  Error e;
86  if (!e.parse(rs->get_stream()))
87  throw InternalErr(__FILE__, __LINE__,
88  "Could not parse the Error object returned by the server!");
89  throw e;
90  }
91 
92  case web_error:
93  // Web errors (those reported in the return document's MIME header)
94  // are processed by the WWW library.
95  throw InternalErr(__FILE__, __LINE__, "An error was reported by the remote httpd; this should have been processed by HTTPConnect..");
96 
97  case dap4_data_ddx: {
98  // Parse the DDX; throw an exception on error.
99  DDXParser ddx_parser(data.get_factory());
100 
101  // Read the MPM boundary and then read the subsequent headers
102  string boundary = read_multipart_boundary(rs->get_stream());
103  DBG(cerr << "MPM Boundary: " << boundary << endl);
104  read_multipart_headers(rs->get_stream(), "text/xml", dap4_ddx);
105 
106  // Parse the DDX, reading up to and including the next boundary.
107  // Return the CID for the matching data part
108  string data_cid;
109  ddx_parser.intern_stream(rs->get_stream(), &data, data_cid, boundary);
110 
111  // Munge the CID into something we can work with
112  data_cid = cid_to_header_value(data_cid);
113  DBG(cerr << "Data CID: " << data_cid << endl);
114 
115  // Read the data part's MPM part headers (boundary was read by
116  // DDXParse::intern)
117  read_multipart_headers(rs->get_stream(),
118  "application/octet-stream", dap4_data, data_cid);
119 
120  // Now read the data
121 #if FILE_METHODS
122  XDRFileUnMarshaller um( rs->get_stream() ) ;
123 #else
124  fpistream in ( rs->get_stream() );
125  XDRStreamUnMarshaller um( in ) ;
126 #endif
127  try {
128  for (DDS::Vars_iter i = data.var_begin(); i != data.var_end();
129  i++) {
130  (*i)->deserialize(um, &data);
131  }
132  }
133  catch (Error &e) {
134  throw e;
135  }
136 
137  return;
138  }
139 
140  case dods_data:
141  default: {
142  // Parse the DDS; throw an exception on error.
143  data.parse(rs->get_stream());
144 #if FILE_METHODS
145  XDRFileUnMarshaller um( rs->get_stream() ) ;
146 #else
147  fpistream in ( rs->get_stream() );
148  XDRStreamUnMarshaller um( in ) ;
149 #endif
150  // Load the DDS with data.
151  try {
152  for (DDS::Vars_iter i = data.var_begin(); i != data.var_end();
153  i++) {
154  (*i)->deserialize(um, &data);
155  }
156  }
157  catch (Error &e) {
158  throw e;
159  }
160 
161  return;
162  }
163  }
164 }
165 
166 // Barely a parser... This is used when reading from local sources of DODS
167 // Data objects. It simulates the important actions of the libwww MIME header
168 // parser. Those actions fill in certain fields in the Connect object. jhrg
169 // 5/20/97
170 //
171 // Make sure that this parser reads from data_source without disturbing the
172 // information in data_source that follows the MIME header. Since the DDS
173 // (which follows the MIME header) is parsed by a flex/bison scanner/parser,
174 // make sure to use I/O calls that will mesh with ANSI C I/O calls. In the
175 // old GNU libg++, the C++ calls were synchronized with the C calls, but that
176 // may no longer be the case. 5/31/99 jhrg
177 
187 void
188 Connect::parse_mime(Response *rs)
189 {
190  rs->set_version("dods/0.0"); // initial value; for backward compatibility.
191  rs->set_protocol("2.0");
192 
193  FILE *data_source = rs->get_stream();
194  string mime = get_next_mime_header(data_source);
195  while (!mime.empty()) {
196  string header, value;
197  parse_mime_header(mime, header, value);
198 
199  // Note that this is an ordered list
200  if (header == "content-description:") {
201  DBG(cout << header << ": " << value << endl);
202  rs->set_type(get_description_type(value));
203  }
204  // Use the value of xdods-server only if no other value has been read
205  else if (header == "xdods-server:"
206  && rs->get_version() == "dods/0.0") {
207  DBG(cout << header << ": " << value << endl);
208  rs->set_version(value);
209  }
210  // This trumps 'xdods-server' and 'server'
211  else if (header == "xopendap-server:") {
212  DBG(cout << header << ": " << value << endl);
213  rs->set_version(value);
214  }
215  else if (header == "xdap:") {
216  DBG(cout << header << ": " << value << endl);
217  rs->set_protocol(value);
218  }
219  // Only look for 'server' if no other header supplies this info.
220  else if (rs->get_version() == "dods/0.0" && header == "server:") {
221  DBG(cout << header << ": " << value << endl);
222  rs->set_version(value);
223  }
224 
225  mime = get_next_mime_header(data_source);
226  }
227 }
228 
229 // public mfuncs
230 
238 Connect::Connect(const string &n, string uname, string password)
239 throw(Error, InternalErr)
240  : d_http(0), d_version("unknown"), d_protocol("2.0")
241 {
242  string name = prune_spaces(n);
243 
244  // Figure out if the URL starts with 'http', if so, make sure that we
245  // talk to an instance of HTTPConnect.
246  if (name.find("http") == 0) {
247  DBG(cerr << "Connect: The identifier is an http URL" << endl);
248  d_http = new HTTPConnect(RCReader::instance());
249 
250  // Find and store any CE given with the URL.
251  string::size_type dotpos = name.find('?');
252  if (dotpos != name.npos) {
253  _URL = name.substr(0, dotpos);
254  string expr = name.substr(dotpos + 1);
255 
256  dotpos = expr.find('&');
257  if (dotpos != expr.npos) {
258  _proj = expr.substr(0, dotpos);
259  _sel = expr.substr(dotpos); // XXX includes '&'
260  }
261  else {
262  _proj = expr;
263  _sel = "";
264  }
265  }
266  else {
267  _URL = name;
268  _proj = "";
269  _sel = "";
270  }
271 
272  _local = false;
273  }
274  else {
275  DBG(cerr << "Connect: The identifier is a local data source." << endl);
276 
277  d_http = 0;
278  _URL = "";
279  _local = true; // local in this case means non-DAP
280  }
281 
282  set_credentials(uname, password);
283 }
284 
286 {
287  DBG2(cerr << "Entering the Connect dtor" << endl);
288 
289  if (d_http)
290  delete d_http; d_http = 0;
291 
292  DBG2(cerr << "Leaving the Connect dtor" << endl);
293 }
294 
302 string
304 {
305  string version_url = _URL + ".ver";
306  if (_proj.length() + _sel.length())
307  version_url = version_url + "?" + id2www_ce(_proj + _sel);
308 
309  Response *rs = 0;
310  try {
311  rs = d_http->fetch_url(version_url);
312  }
313  catch (Error &e) {
314  delete rs; rs = 0;
315  throw e;
316  }
317 
318  d_version = rs->get_version();
319  d_protocol = rs->get_protocol();
320 
321  delete rs; rs = 0;
322 
323  return d_version;
324 }
325 
337 string
339 {
340  string version_url = _URL + ".ver";
341  if (_proj.length() + _sel.length())
342  version_url = version_url + "?" + id2www_ce(_proj + _sel);
343 
344  Response *rs = 0;
345  try {
346  rs = d_http->fetch_url(version_url);
347  }
348  catch (Error &e) {
349  delete rs; rs = 0;
350  throw e;
351  }
352 
353  d_version = rs->get_version();
354  d_protocol = rs->get_protocol();
355 
356  delete rs; rs = 0;
357 
358  return d_protocol;
359 }
360 
368 void
370 {
371  string das_url = _URL + ".das";
372  if (_proj.length() + _sel.length())
373  das_url = das_url + "?" + id2www_ce(_proj + _sel);
374 
375  Response *rs = 0;
376  try {
377  rs = d_http->fetch_url(das_url);
378  }
379  catch (Error &e) {
380  delete rs; rs = 0;
381  throw e;
382  }
383 
384  d_version = rs->get_version();
385  d_protocol = rs->get_protocol();
386 
387  switch (rs->get_type()) {
388  case dods_error: {
389  Error e;
390  if (!e.parse(rs->get_stream())) {
391  throw InternalErr(__FILE__, __LINE__,
392  "Could not parse error returned from server.");
393  break;
394  }
395  throw e;
396  break;
397  }
398 
399  case web_error:
400  // We should never get here; a web error should be picked up read_url
401  // (called by fetch_url) and result in a thrown Error object.
402  break;
403 
404  case dods_das:
405  default:
406  // DAS::parse throws an exception on error.
407  try {
408  das.parse(rs->get_stream()); // read and parse the das from a file
409  }
410  catch (Error &e) {
411  delete rs; rs = 0;
412  throw e;
413  }
414 
415  break;
416  }
417 
418  delete rs; rs = 0;
419 }
420 
431 void
433 {
434  string use_url = _URL + "?" + _proj + _sel ;
435  Response *rs = 0;
436  try {
437  rs = d_http->fetch_url(use_url);
438  }
439  catch (Error &e) {
440  delete rs; rs = 0;
441  throw e;
442  }
443 
444  d_version = rs->get_version();
445  d_protocol = rs->get_protocol();
446 
447  switch (rs->get_type()) {
448  case dods_error: {
449  Error e;
450  if (!e.parse(rs->get_stream())) {
451  throw InternalErr(__FILE__, __LINE__,
452  "Could not parse error returned from server.");
453  break;
454  }
455  throw e;
456  break;
457  }
458 
459  case web_error:
460  // We should never get here; a web error should be picked up read_url
461  // (called by fetch_url) and result in a thrown Error object.
462  break;
463 
464  case dods_das:
465  default:
466  // DAS::parse throws an exception on error.
467  try {
468  das.parse(rs->get_stream()); // read and parse the das from a file
469  }
470  catch (Error &e) {
471  delete rs; rs = 0;
472  throw e;
473  }
474 
475  break;
476  }
477 
478  delete rs; rs = 0;
479 }
480 
494 void
495 Connect::request_dds(DDS &dds, string expr)
496 {
497  string proj, sel;
498  string::size_type dotpos = expr.find('&');
499  if (dotpos != expr.npos) {
500  proj = expr.substr(0, dotpos);
501  sel = expr.substr(dotpos);
502  }
503  else {
504  proj = expr;
505  sel = "";
506  }
507 
508  string dds_url = _URL + ".dds" + "?"
509  + id2www_ce(_proj + proj + _sel + sel);
510 
511  Response *rs = 0;
512  try {
513  rs = d_http->fetch_url(dds_url);
514  }
515  catch (Error &e) {
516  delete rs; rs = 0;
517  throw e;
518  }
519 
520  d_version = rs->get_version();
521  d_protocol = rs->get_protocol();
522 
523  switch (rs->get_type()) {
524  case dods_error: {
525  Error e;
526  if (!e.parse(rs->get_stream())) {
527  throw InternalErr(__FILE__, __LINE__,
528  "Could not parse error returned from server.");
529  break;
530  }
531  throw e;
532  break;
533  }
534 
535  case web_error:
536  // We should never get here; a web error should be picked up read_url
537  // (called by fetch_url) and result in a thrown Error object.
538  break;
539 
540  case dods_dds:
541  default:
542  // DDS::prase throws an exception on error.
543  try {
544  dds.parse(rs->get_stream()); // read and parse the dds from a file
545  }
546  catch (Error &e) {
547  delete rs; rs = 0;
548  throw e;
549  }
550  break;
551  }
552 
553  delete rs; rs = 0;
554 }
555 
572 void
574 {
575  string use_url = _URL + "?" + _proj + _sel ;
576  Response *rs = 0;
577  try {
578  rs = d_http->fetch_url(use_url);
579  }
580  catch (Error &e) {
581  delete rs; rs = 0;
582  throw e;
583  }
584 
585  d_version = rs->get_version();
586  d_protocol = rs->get_protocol();
587 
588  switch (rs->get_type()) {
589  case dods_error: {
590  Error e;
591  if (!e.parse(rs->get_stream())) {
592  throw InternalErr(__FILE__, __LINE__,
593  "Could not parse error returned from server.");
594  break;
595  }
596  throw e;
597  break;
598  }
599 
600  case web_error:
601  // We should never get here; a web error should be picked up read_url
602  // (called by fetch_url) and result in a thrown Error object.
603  break;
604 
605  case dods_dds:
606  default:
607  // DDS::prase throws an exception on error.
608  try {
609  dds.parse(rs->get_stream()); // read and parse the dds from a file
610  }
611  catch (Error &e) {
612  delete rs; rs = 0;
613  throw e;
614  }
615  break;
616  }
617 
618  delete rs; rs = 0;
619 }
620 
632 void
633 Connect::request_ddx(DDS &dds, string expr)
634 {
635  string proj, sel;
636  string::size_type dotpos = expr.find('&');
637  if (dotpos != expr.npos) {
638  proj = expr.substr(0, dotpos);
639  sel = expr.substr(dotpos);
640  }
641  else {
642  proj = expr;
643  sel = "";
644  }
645 
646  string ddx_url = _URL + ".ddx" + "?"
647  + id2www_ce(_proj + proj + _sel + sel);
648 
649  Response *rs = 0;
650  try {
651  rs = d_http->fetch_url(ddx_url);
652  }
653  catch (Error &e) {
654  delete rs; rs = 0;
655  throw e;
656  }
657 
658  d_version = rs->get_version();
659  d_protocol = rs->get_protocol();
660 
661  switch (rs->get_type()) {
662  case dods_error: {
663  Error e;
664  if (!e.parse(rs->get_stream())) {
665  throw InternalErr(__FILE__, __LINE__,
666  "Could not parse error returned from server.");
667  break;
668  }
669  throw e;
670  break;
671  }
672 
673  case web_error:
674  // We should never get here; a web error should be picked up read_url
675  // (called by fetch_url) and result in a thrown Error object.
676  break;
677 
678  case dap4_ddx:
679  case dods_ddx:
680  try {
681  string blob;
682 
683  DDXParser ddxp(dds.get_factory());
684  ddxp.intern_stream(rs->get_stream(), &dds, blob);
685  }
686  catch (Error &e) {
687  delete rs; rs = 0;
688  throw e;
689  }
690  break;
691 
692  default:
693  throw Error("The site did not return a valid response (it lacked the\n\
694 expected content description header value of 'dap4-ddx' and\n\
695 instead returned '" + long_to_string(rs->get_type()) + "').\n\
696 This may indicate that the server at the site is not correctly\n\
697 configured, or that the URL has changed.");
698  }
699 
700  delete rs; rs = 0;
701 }
702 
705 void
707 {
708  string use_url = _URL + "?" + _proj + _sel ;
709 
710  Response *rs = 0;
711  try {
712  rs = d_http->fetch_url(use_url);
713  }
714  catch (Error &e) {
715  delete rs; rs = 0;
716  throw e;
717  }
718 
719  d_version = rs->get_version();
720  d_protocol = rs->get_protocol();
721 
722  switch (rs->get_type()) {
723  case dods_error: {
724  Error e;
725  if (!e.parse(rs->get_stream())) {
726  throw InternalErr(__FILE__, __LINE__,
727  "Could not parse error returned from server.");
728  break;
729  }
730  throw e;
731  break;
732  }
733 
734  case web_error:
735  // We should never get here; a web error should be picked up read_url
736  // (called by fetch_url) and result in a thrown Error object.
737  break;
738 
739  case dap4_ddx:
740  case dods_ddx:
741  try {
742  string blob;
743 
744  DDXParser ddxp(dds.get_factory());
745  ddxp.intern_stream(rs->get_stream(), &dds, blob);
746  }
747  catch (Error &e) {
748  delete rs; rs = 0;
749  throw e;
750  }
751  break;
752 
753  default:
754  throw Error("The site did not return a valid response (it lacked the\n\
755 expected content description header value of 'dap4-ddx' and\n\
756 instead returned '" + long_to_string(rs->get_type()) + "').\n\
757 This may indicate that the server at the site is not correctly\n\
758 configured, or that the URL has changed.");
759  }
760 
761  delete rs; rs = 0;
762 }
763 
779 void
780 Connect::request_data(DataDDS &data, string expr)
781 {
782  string proj, sel;
783  string::size_type dotpos = expr.find('&');
784  if (dotpos != expr.npos) {
785  proj = expr.substr(0, dotpos);
786  sel = expr.substr(dotpos);
787  }
788  else {
789  proj = expr;
790  sel = "";
791  }
792 
793  string data_url = _URL + ".dods?"
794  + id2www_ce(_proj + proj + _sel + sel);
795 
796  Response *rs = 0;
797  // We need to catch Error exceptions to ensure calling close_output.
798  try {
799  rs = d_http->fetch_url(data_url);
800 
801  d_version = rs->get_version();
802  d_protocol = rs->get_protocol();
803 
804  process_data(data, rs);
805  delete rs; rs = 0;
806  }
807  catch (Error &e) {
808  delete rs; rs = 0;
809  throw e;
810  }
811 }
812 
830 void
832 {
833  string use_url = _URL + "?" + _proj + _sel ;
834  Response *rs = 0;
835  // We need to catch Error exceptions to ensure calling close_output.
836  try {
837  rs = d_http->fetch_url(use_url);
838 
839  d_version = rs->get_version();
840  d_protocol = rs->get_protocol();
841 
842  process_data(data, rs);
843  delete rs; rs = 0;
844  }
845  catch (Error &e) {
846  delete rs; rs = 0;
847  throw e;
848  }
849 }
850 
851 void
853 {
854  string proj, sel;
855  string::size_type dotpos = expr.find('&');
856  if (dotpos != expr.npos) {
857  proj = expr.substr(0, dotpos);
858  sel = expr.substr(dotpos);
859  }
860  else {
861  proj = expr;
862  sel = "";
863  }
864 
865  string data_url = _URL + ".dap?"
866  + id2www_ce(_proj + proj + _sel + sel);
867 
868  Response *rs = 0;
869  // We need to catch Error exceptions to ensure calling close_output.
870  try {
871  rs = d_http->fetch_url(data_url);
872 
873  d_version = rs->get_version();
874  d_protocol = rs->get_protocol();
875 
876  process_data(data, rs);
877  delete rs; rs = 0;
878  }
879  catch (Error &e) {
880  delete rs; rs = 0;
881  throw e;
882  }
883 }
884 
885 void
887 {
888  string use_url = _URL + "?" + _proj + _sel ;
889  Response *rs = 0;
890  // We need to catch Error exceptions to ensure calling close_output.
891  try {
892  rs = d_http->fetch_url(use_url);
893 
894  d_version = rs->get_version();
895  d_protocol = rs->get_protocol();
896 
897  process_data(data, rs);
898  delete rs; rs = 0;
899  }
900  catch (Error &e) {
901  delete rs; rs = 0;
902  throw e;
903  }
904 }
905 
919 void
921 {
922  if (!rs)
923  throw InternalErr(__FILE__, __LINE__, "Response object is null.");
924 
925  // Read from data_source and parse the MIME headers specific to DAP2/4.
926  parse_mime(rs);
927 
928  read_data_no_mime(data, rs);
929 }
930 
931 // This function looks at the input stream and makes its best guess at what
932 // lies in store for downstream processing code. Definitely heuristic.
933 // Assumptions:
934 // #1 The current file position is past any MIME headers (if they were present).
935 // #2 We must reset the FILE* position to the start of the DDS or DDX headers
936 static void
937 divine_type_information(Response *rs)
938 {
939  // Consume whitespace
940  char c = getc(rs->get_stream());
941  while (isspace(c)) {
942  c = getc(rs->get_stream());
943  }
944 
945  // The heuristic here is that a DataDDX is a multipart MIME document and
946  // The first non space character found after the headers is the start of
947  // the first part which looks like '--<boundary>' while a DataDDS starts
948  // with a DDS (;Dataset {' ...). I take into account that our parsers have
949  // accepted both 'Dataset' and 'dataset' for a long time.
950  switch (c) {
951  case '-':
952  rs->set_type(dap4_data_ddx);
953  break;
954  case 'D':
955  case 'd':
956  rs->set_type(dods_data);
957  break;
958  default:
959  throw InternalErr(__FILE__, __LINE__, "Could not determine type of response object in stream.");
960  }
961 
962  ungetc(c, rs->get_stream());
963 }
964 
977 void
979 {
980  if (rs->get_type() == unknown_type)
981  divine_type_information(rs);
982 
983  switch (rs->get_type()) {
984  case dods_data:
985  d_version = rs->get_version();
986  d_protocol = rs->get_protocol();
987  process_data(data, rs);
988  break;
989  case dap4_data_ddx:
990  process_data(data, rs);
991  d_version = rs->get_version();
992  d_protocol = data.get_protocol();
993  break;
994  default:
995  throw InternalErr(__FILE__, __LINE__, "Should have been a DataDDS or DataDDX.");
996  }
997 }
998 
999 bool
1001 {
1002  return _local;
1003 }
1004 
1021 string
1023 {
1024  if (_local)
1025  throw InternalErr(__FILE__, __LINE__,
1026  "URL(): This call is only valid for a DAP data source.");
1027 
1028  if (ce)
1029  return _URL + "?" + _proj + _sel;
1030  else
1031  return _URL;
1032 }
1033 
1042 string
1044 {
1045  if (_local)
1046  throw InternalErr(__FILE__, __LINE__,
1047  "CE(): This call is only valid for a DAP data source.");
1048 
1049  return _proj + _sel;
1050 }
1051 
1057 void
1058 Connect::set_credentials(string u, string p)
1059 {
1060  if (d_http)
1061  d_http->set_credentials(u, p);
1062 }
1063 
1067 void
1069 {
1070  if (d_http)
1071  d_http->set_accept_deflate(deflate);
1072 }
1073 
1079 void
1080 Connect::set_xdap_protocol(int major, int minor)
1081 {
1082  if (d_http)
1083  d_http->set_xdap_protocol(major, minor);
1084 }
1085 
1089 void
1091 {
1092  if (d_http)
1093  d_http->set_cache_enabled(cache);
1094 }
1095 
1096 bool
1098 {
1099  bool status;
1100  DBG(cerr << "Entering is_cache_enabled (" << hex << d_http << dec
1101  << ")... ");
1102  if (d_http)
1103  status = d_http->is_cache_enabled();
1104  else
1105  status = false;
1106  DBGN(cerr << "exiting" << endl);
1107  return status;
1108 }
1109 
1110 } // namespace libdap
virtual string CE()
Get the Connect&#39;s constraint expression.
Definition: Connect.cc:1043
virtual void request_das_url(DAS &das)
Get the DAS from a server.
Definition: Connect.cc:432
void intern_stream(FILE *in, DDS *dds, string &cid, const string &boundary="")
Read the DDX from a stream instead of a file.
virtual void request_ddx(DDS &dds, string expr="")
Get the DDX from a server.
Definition: Connect.cc:633
virtual string URL(bool CE=true)
Get the object&#39;s URL.
Definition: Connect.cc:1022
string get_protocol() const
Definition: DataDDS.h:129
#define not_used
Definition: config.h:521
string id2www_ce(string in, const string &allowable)
Definition: escaping.cc:176
string prune_spaces(const string &name)
Definition: util.cc:96
void set_credentials(const string &u, const string &p)
Definition: HTTPConnect.cc:969
void set_xdap_protocol(int major, int minor)
Definition: Connect.cc:1080
void read_multipart_headers(FILE *in, const string &content_type, const ObjectType object_type, const string &cid)
Definition: mime_util.cc:832
#define DBGN(x)
Definition: debug.h:59
virtual void set_type(ObjectType o)
Definition: Response.h:143
virtual void request_dds_url(DDS &dds)
Get the DDS from a server.
Definition: Connect.cc:573
bool parse(FILE *fp)
Parse an Error object.
Definition: Error.cc:159
void set_cache_enabled(bool enabled)
Definition: HTTPConnect.h:158
string cid_to_header_value(const string &cid)
Definition: mime_util.cc:872
HTTPResponse * fetch_url(const string &url)
Definition: HTTPConnect.cc:567
#define DBG2(x)
Definition: debug.h:73
bool is_local()
Definition: Connect.cc:1000
A class for software fault reporting.
Definition: InternalErr.h:64
void parse(string fname)
Parse a DDS from a file with the given name.
Definition: DDS.cc:858
void parse_mime_header(const string &header, string &name, string &value)
Definition: mime_util.cc:758
virtual void read_data(DataDDS &data, Response *rs)
Read data which is preceded by MIME headers. This method works for both data dds and data ddx respons...
Definition: Connect.cc:920
#define DBG(x)
Definition: debug.h:58
ObjectType get_description_type(const string &value)
Definition: mime_util.cc:333
void set_cache_enabled(bool enabled)
Definition: Connect.cc:1090
virtual FILE * get_stream() const
Definition: Response.h:115
bool is_cache_enabled()
Definition: Connect.cc:1097
std::vector< BaseType * >::iterator Vars_iter
Definition: DDS.h:211
virtual void request_dds(DDS &dds, string expr="")
Get the DDS from a server.
Definition: Connect.cc:495
string get_next_mime_header(FILE *in)
Definition: mime_util.cc:730
void set_accept_deflate(bool deflate)
Definition: Connect.cc:1068
virtual void request_data(DataDDS &data, string expr="")
Get the DAS from a server.
Definition: Connect.cc:780
string read_multipart_boundary(FILE *in, const string &boundary)
Definition: mime_util.cc:798
virtual void read_data_no_mime(DataDDS &data, Response *rs)
Read data from a file which does not have response MIME headers. This method is a companion to read_d...
Definition: Connect.cc:978
virtual void request_das(DAS &das)
Get the DAS from a server.
Definition: Connect.cc:369
void set_accept_deflate(bool defalte)
Definition: HTTPConnect.cc:895
string long_to_string(long val, int base)
Definition: util.cc:440
void set_xdap_protocol(int major, int minor)
Definition: HTTPConnect.cc:932
virtual void parse(string fname)
Reads a DAS from the named file.
Definition: DAS.cc:278
virtual string request_version()
Definition: Connect.cc:303
virtual void request_data_ddx_url(DataDDS &data)
Definition: Connect.cc:886
virtual void request_data_ddx(DataDDS &data, string expr="")
Definition: Connect.cc:852
virtual ObjectType get_type() const
Definition: Response.h:119
void set_credentials(string u, string p)
Set the credentials for responding to challenges while dereferencing URLs.
Definition: Connect.cc:1058
virtual string get_protocol() const
Definition: Response.h:127
virtual string request_protocol()
Definition: Connect.cc:338
Hold attribute data for a DAP2 dataset.
Definition: DAS.h:123
virtual void request_data_url(DataDDS &data)
Get the DAS from a server.
Definition: Connect.cc:831
A class for error processing.
Definition: Error.h:90
BaseTypeFactory * get_factory() const
Definition: DDS.h:230
Holds a DAP2 DDS.
Definition: DataDDS.h:77
virtual void request_ddx_url(DDS &dds)
The &#39;url&#39; version of request_ddx.
Definition: Connect.cc:706
virtual string get_version() const
Definition: Response.h:123
virtual ~Connect()
Definition: Connect.cc:285
static RCReader * instance()
Definition: RCReader.cc:484