38#define FILE_UN_MARSHALLER 1
71void Connect::process_data(DataDDS &data, Response *rs) {
72 DBG(cerr <<
"Entering Connect::process_data" << endl);
74 data.set_version(rs->get_version());
75 data.set_protocol(rs->get_protocol());
77 DBG(cerr <<
"Entering process_data: d_stream = " << rs << endl);
78 switch (rs->get_type()) {
81 if (!e.parse(rs->get_stream()))
82 throw InternalErr(__FILE__, __LINE__,
"Could not parse the Error object returned by the server!");
91 "An error was reported by the remote httpd; this should have been processed by HTTPConnect..");
98 DDXParser ddx_parser(data.get_factory());
102 DBG(cerr <<
"MPM Boundary: " << boundary << endl);
108 ddx_parser.intern_stream(rs->get_stream(), &data, data_cid, boundary);
112 DBG(cerr <<
"Data CID: " << data_cid << endl);
119#if FILE_UN_MARSHALLER
120 XDRFileUnMarshaller um(rs->get_stream());
122 fpistream in ( rs->get_stream() );
123 XDRStreamUnMarshaller um( in );
125 for (
DDS::Vars_iter i = data.var_begin(); i != data.var_end(); i++) {
126 (*i)->deserialize(um, &data);
135 data.parse(rs->get_stream());
136#if FILE_UN_MARSHALLER
137 XDRFileUnMarshaller um(rs->get_stream());
139 fpistream in(rs->get_stream());
140 XDRStreamUnMarshaller um(in);
143 for (
DDS::Vars_iter i = data.var_begin(); i != data.var_end(); i++) {
144 (*i)->deserialize(um, &data);
153void Connect::process_data(DDS &data, Response *rs) {
154 DBG(cerr <<
"Entering Connect::process_data" << endl);
156 data.set_dap_version(rs->get_protocol());
158 DBG(cerr <<
"Entering process_data: d_stream = " << rs << endl);
159 switch (rs->get_type()) {
162 if (!e.parse(rs->get_stream()))
163 throw InternalErr(__FILE__, __LINE__,
"Could not parse the Error object returned by the server!");
172 "An error was reported by the remote web server; this should have been processed by HTTPConnect.");
180 DDXParser ddx_parser(data.get_factory());
184 DBG(cerr <<
"MPM Boundary: " << boundary << endl);
190 ddx_parser.intern_stream(rs->get_stream(), &data, data_cid, boundary);
194 DBG(cerr <<
"Data CID: " << data_cid << endl);
201 XDRFileUnMarshaller um(rs->get_stream());
202 for (
DDS::Vars_iter i = data.var_begin(); i != data.var_end(); i++) {
203 (*i)->deserialize(um, &data);
212 data.parse(rs->get_stream());
214 XDRFileUnMarshaller um(rs->get_stream());
217 for (
DDS::Vars_iter i = data.var_begin(); i != data.var_end(); i++) {
218 (*i)->deserialize(um, &data);
250void Connect::parse_mime(Response *rs) {
251 rs->set_version(
"dods/0.0");
252 rs->set_protocol(
"2.0");
254 FILE *data_source = rs->get_stream();
256 while (!mime.empty()) {
257 string header, value;
261 if (header ==
"content-description:") {
262 DBG(cout << header <<
": " << value << endl);
266 else if (header ==
"xdods-server:" && rs->get_version() ==
"dods/0.0") {
267 DBG(cout << header <<
": " << value << endl);
268 rs->set_version(value);
271 else if (header ==
"xopendap-server:") {
272 DBG(cout << header <<
": " << value << endl);
273 rs->set_version(value);
274 }
else if (header ==
"xdap:") {
275 DBG(cout << header <<
": " << value << endl);
276 rs->set_protocol(value);
279 else if (rs->get_version() ==
"dods/0.0" && header ==
"server:") {
280 DBG(cout << header <<
": " << value << endl);
281 rs->set_version(value);
297Connect::Connect(
const string &n,
string uname,
string password) : d_http(0), d_version(
"unknown"), d_protocol(
"2.0") {
302 if (name.find(
"http") == 0) {
303 DBG(cerr <<
"Connect: The identifier is an http URL" << endl);
307 string::size_type dotpos = name.find(
'?');
308 if (dotpos != name.npos) {
309 _URL = name.substr(0, dotpos);
310 string expr = name.substr(dotpos + 1);
312 dotpos = expr.find(
'&');
313 if (dotpos != expr.npos) {
314 _proj = expr.substr(0, dotpos);
315 _sel = expr.substr(dotpos);
328 DBG(cerr <<
"Connect: The identifier is a local data source." << endl);
339 DBG2(cerr <<
"Entering the Connect dtor" << endl);
345 DBG2(cerr <<
"Leaving the Connect dtor" << endl);
356 string version_url = _URL +
".ver";
357 if (_proj.length() + _sel.length())
358 version_url = version_url +
"?" +
id2www_ce(_proj + _sel);
362 rs = d_http->fetch_url(version_url);
390 string version_url = _URL +
".ver";
391 if (_proj.length() + _sel.length())
392 version_url = version_url +
"?" +
id2www_ce(_proj + _sel);
396 rs = d_http->fetch_url(version_url);
420 string das_url = _URL +
".das";
421 if (_proj.length() + _sel.length())
422 das_url = das_url +
"?" +
id2www_ce(_proj + _sel);
426 rs = d_http->fetch_url(das_url);
442 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
483 string use_url = _URL +
"?" + _proj + _sel;
486 rs = d_http->fetch_url(use_url);
502 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
547 string::size_type dotpos = expr.find(
'&');
548 if (dotpos != expr.npos) {
549 proj = expr.substr(0, dotpos);
550 sel = expr.substr(dotpos);
556 string dds_url = _URL +
".dds" +
"?" +
id2www_ce(_proj + proj + _sel + sel);
560 rs = d_http->fetch_url(dds_url);
576 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
622 string use_url = _URL +
"?" + _proj + _sel;
625 rs = d_http->fetch_url(use_url);
641 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
683 string::size_type dotpos = expr.find(
'&');
684 if (dotpos != expr.npos) {
685 proj = expr.substr(0, dotpos);
686 sel = expr.substr(dotpos);
692 string ddx_url = _URL +
".ddx" +
"?" +
id2www_ce(_proj + proj + _sel + sel);
696 rs = d_http->fetch_url(ddx_url);
711 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
737 throw Error(
"Invalid response type when requesting a DDX response. Response type: " +
long_to_string(ot));
746 string use_url = _URL +
"?" + _proj + _sel;
750 rs = d_http->fetch_url(use_url);
764 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
774 throw InternalErr(__FILE__, __LINE__,
"Web error.");
792 throw Error(
"Invalid response type when requesting a DDX response. Response type: " +
long_to_string(ot));
816 string::size_type dotpos = expr.find(
'&');
817 if (dotpos != expr.npos) {
818 proj = expr.substr(0, dotpos);
819 sel = expr.substr(dotpos);
825 string data_url = _URL +
".dods?" +
id2www_ce(_proj + proj + _sel + sel);
830 rs = d_http->fetch_url(data_url);
835 process_data(data, rs);
863 string use_url = _URL +
"?" + _proj + _sel;
867 rs = d_http->fetch_url(use_url);
872 process_data(data, rs);
885 string::size_type dotpos = expr.find(
'&');
886 if (dotpos != expr.npos) {
887 proj = expr.substr(0, dotpos);
888 sel = expr.substr(dotpos);
894 string data_url = _URL +
".dap?" +
id2www_ce(_proj + proj + _sel + sel);
899 rs = d_http->fetch_url(data_url);
904 process_data(data, rs);
916 string use_url = _URL +
"?" + _proj + _sel;
920 rs = d_http->fetch_url(use_url);
925 process_data(data, rs);
950 throw InternalErr(__FILE__, __LINE__,
"Response object is null.");
959 throw InternalErr(__FILE__, __LINE__,
"Response object is null.");
972static void divine_type_information(
Response *rs) {
980 throw Error(
"Error reading response type information: " +
string(strerror(errno)));
982 throw Error(
"Error reading response type information: Found EOF");
998 throw InternalErr(__FILE__, __LINE__,
"Could not determine type of response object in stream.");
1018 divine_type_information(rs);
1024 process_data(data, rs);
1027 process_data(data, rs);
1032 throw InternalErr(__FILE__, __LINE__,
"Should have been a DataDDS or DataDDX.");
1037 divine_type_information(rs);
1043 process_data(data, rs);
1046 process_data(data, rs);
1053 throw InternalErr(__FILE__, __LINE__,
"Should have been a DataDDS or DataDDX.");
1077 throw InternalErr(__FILE__, __LINE__,
"URL(): This call is only valid for a DAP data source.");
1080 return _URL +
"?" + _proj + _sel;
1095 throw InternalErr(__FILE__, __LINE__,
"CE(): This call is only valid for a DAP data source.");
1097 return _proj + _sel;
1107 d_http->set_credentials(u, p);
1115 d_http->set_accept_deflate(
deflate);
1125 d_http->set_xdap_protocol(major, minor);
1133 d_http->set_cache_enabled(cache);
1138 DBG(cerr <<
"Entering is_cache_enabled (" << hex << d_http << dec <<
")... ");
1140 status = d_http->is_cache_enabled();
1143 DBGN(cerr <<
"exiting" << endl);
virtual void request_dds_url(DDS &dds)
Get the DDS from a server.
virtual string CE()
Get the Connect's constraint expression.
void set_accept_deflate(bool deflate)
void set_cache_enabled(bool enabled)
virtual void request_ddx(DDS &dds, string expr="")
Get the DDX from a server.
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...
void set_xdap_protocol(int major, int minor)
virtual string URL(bool CE=true)
Get the object's URL.
virtual void request_data(DataDDS &data, string expr="")
Get the DAS from a server.
virtual void request_das(DAS &das)
Get the DAS from a server.
void set_credentials(string u, string p)
Set the credentials for responding to challenges while dereferencing URLs.
virtual void request_ddx_url(DDS &dds)
The 'url' version of request_ddx.
virtual string request_protocol()
virtual void request_data_ddx_url(DataDDS &data)
virtual void request_dds(DDS &dds, string expr="")
Get the DDS from a server.
virtual void request_data_ddx(DataDDS &data, string expr="")
virtual void request_das_url(DAS &das)
Get the DAS from a server.
virtual string request_version()
virtual void request_data_url(DataDDS &data)
Get the DAS from a server.
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...
Hold attribute data for a DAP2 dataset.
virtual void parse(string fname)
Reads a DAS from the named file.
string get_dap_version() const
void parse(string fname)
Parse a DDS from a file with the given d_name.
BaseTypeFactory * get_factory() const
std::vector< BaseType * >::iterator Vars_iter
void intern_stream(FILE *in, DDS *dds, string &cid, const string &boundary="")
Read the DDX from a stream instead of a file.
string get_protocol() const
A class for error processing.
bool parse(FILE *fp)
Parse an Error object.
A class for software fault reporting.
static RCReader * instance()
virtual std::string get_protocol() const
virtual void set_type(ObjectType o)
virtual ObjectType get_type() const
virtual FILE * get_stream() const
virtual std::string get_version() const
top level DAP object to house generic methods
string read_multipart_boundary(FILE *in, const string &boundary)
ObjectType get_description_type(const string &value)
string cid_to_header_value(const string &cid)
string long_to_string(long val, int base)
void parse_mime_header(const string &header, string &name, string &value)
string prune_spaces(const string &name)
void read_multipart_headers(FILE *in, const string &content_type, const ObjectType object_type, const string &cid)
string id2www_ce(string in, const string &allowable)
ObjectType
The type of object in the stream coming from the data server.
string get_next_mime_header(FILE *in)