38 #define FILE_UN_MARSHALLER 1 51 #include "DDXParserSAX2.h" 52 #if FILE_UN_MARSHALLER 53 #include "XDRFileUnMarshaller.h" 55 #include "fdiostream.h" 56 #include "XDRStreamUnMarshaller.h" 58 #include "mime_util.h" 70 void 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!");
89 throw InternalErr(__FILE__, __LINE__,
90 "An error was reported by the remote httpd; this should have been processed by HTTPConnect..");
97 DDXParser ddx_parser(data.get_factory());
101 DBG(cerr <<
"MPM Boundary: " << boundary << endl);
107 ddx_parser.intern_stream(rs->get_stream(), &data, data_cid, boundary);
111 DBG(cerr <<
"Data CID: " << data_cid << endl);
118 #if FILE_UN_MARSHALLER 119 XDRFileUnMarshaller um(rs->get_stream());
121 fpistream in ( rs->get_stream() );
122 XDRStreamUnMarshaller um( in );
124 for (DDS::Vars_iter i = data.var_begin(); i != data.var_end(); i++) {
125 (*i)->deserialize(um, &data);
134 data.parse(rs->get_stream());
135 #if FILE_UN_MARSHALLER 136 XDRFileUnMarshaller um(rs->get_stream());
138 fpistream in ( rs->get_stream() );
139 XDRStreamUnMarshaller um( in );
142 for (DDS::Vars_iter i = data.var_begin(); i != data.var_end(); i++) {
143 (*i)->deserialize(um, &data);
152 void 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!");
170 throw InternalErr(__FILE__, __LINE__,
171 "An error was reported by the remote web server; this should have been processed by HTTPConnect.");
177 case dods_data_ddx: {
179 DDXParser ddx_parser(data.get_factory());
183 DBG(cerr <<
"MPM Boundary: " << boundary << endl);
189 ddx_parser.intern_stream(rs->get_stream(), &data, data_cid, boundary);
193 DBG(cerr <<
"Data CID: " << data_cid << endl);
200 XDRFileUnMarshaller um(rs->get_stream());
201 for (DDS::Vars_iter i = data.var_begin(); i != data.var_end(); i++) {
202 (*i)->deserialize(um, &data);
211 data.parse(rs->get_stream());
213 XDRFileUnMarshaller um(rs->get_stream());
216 for (DDS::Vars_iter i = data.var_begin(); i != data.var_end(); i++) {
217 (*i)->deserialize(um, &data);
249 void 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);
275 else if (header ==
"xdap:") {
276 DBG(cout << header <<
": " << value << endl);
277 rs->set_protocol(value);
280 else if (rs->get_version() ==
"dods/0.0" && header ==
"server:") {
281 DBG(cout << header <<
": " << value << endl);
282 rs->set_version(value);
298 Connect::Connect(
const string &n,
string uname,
string password) :
299 d_http(0), d_version(
"unknown"), d_protocol(
"2.0")
305 if (name.find(
"http") == 0) {
306 DBG(cerr <<
"Connect: The identifier is an http URL" << endl);
310 string::size_type dotpos = name.find(
'?');
311 if (dotpos != name.npos) {
312 _URL = name.substr(0, dotpos);
313 string expr = name.substr(dotpos + 1);
315 dotpos = expr.find(
'&');
316 if (dotpos != expr.npos) {
317 _proj = expr.substr(0, dotpos);
318 _sel = expr.substr(dotpos);
334 DBG(cerr <<
"Connect: The identifier is a local data source." << endl);
346 DBG2(cerr <<
"Entering the Connect dtor" << endl);
352 DBG2(cerr <<
"Leaving the Connect dtor" << endl);
364 string version_url = _URL +
".ver";
365 if (_proj.length() + _sel.length())
366 version_url = version_url +
"?" +
id2www_ce(_proj + _sel);
378 d_version = rs->get_version();
379 d_protocol = rs->get_protocol();
400 string version_url = _URL +
".ver";
401 if (_proj.length() + _sel.length())
402 version_url = version_url +
"?" +
id2www_ce(_proj + _sel);
414 d_version = rs->get_version();
415 d_protocol = rs->get_protocol();
432 string das_url = _URL +
".das";
433 if (_proj.length() + _sel.length())
434 das_url = das_url +
"?" +
id2www_ce(_proj + _sel);
446 d_version = rs->get_version();
447 d_protocol = rs->get_protocol();
449 switch (rs->get_type()) {
452 if (!e.
parse(rs->get_stream())) {
455 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
471 das.
parse(rs->get_stream());
498 string use_url = _URL +
"?" + _proj + _sel;
509 d_version = rs->get_version();
510 d_protocol = rs->get_protocol();
512 switch (rs->get_type()) {
515 if (!e.
parse(rs->get_stream())) {
518 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
534 das.
parse(rs->get_stream());
565 string::size_type dotpos = expr.find(
'&');
566 if (dotpos != expr.npos) {
567 proj = expr.substr(0, dotpos);
568 sel = expr.substr(dotpos);
575 string dds_url = _URL +
".dds" +
"?" +
id2www_ce(_proj + proj + _sel + sel);
587 d_version = rs->get_version();
588 d_protocol = rs->get_protocol();
590 switch (rs->get_type()) {
593 if (!e.
parse(rs->get_stream())) {
596 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
612 dds.
parse(rs->get_stream());
644 string use_url = _URL +
"?" + _proj + _sel;
655 d_version = rs->get_version();
656 d_protocol = rs->get_protocol();
658 switch (rs->get_type()) {
661 if (!e.
parse(rs->get_stream())) {
664 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
680 dds.
parse(rs->get_stream());
708 string::size_type dotpos = expr.find(
'&');
709 if (dotpos != expr.npos) {
710 proj = expr.substr(0, dotpos);
711 sel = expr.substr(dotpos);
718 string ddx_url = _URL +
".ddx" +
"?" +
id2www_ce(_proj + proj + _sel + sel);
729 d_version = rs->get_version();
730 d_protocol = rs->get_protocol();
732 switch (rs->get_type()) {
735 if (!e.
parse(rs->get_stream())) {
738 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
765 throw Error(
"Invalid response type when requesting a DDX response. Response type: " + long_to_string(ot));
775 string use_url = _URL +
"?" + _proj + _sel;
786 d_version = rs->get_version();
787 d_protocol = rs->get_protocol();
789 switch (rs->get_type()) {
792 if (!e.
parse(rs->get_stream())) {
794 throw InternalErr(__FILE__, __LINE__,
"Could not parse error returned from server.");
804 throw InternalErr(__FILE__, __LINE__,
"Web error.");
823 throw Error(
"Invalid response type when requesting a DDX response. Response type: " + long_to_string(ot));
848 string::size_type dotpos = expr.find(
'&');
849 if (dotpos != expr.npos) {
850 proj = expr.substr(0, dotpos);
851 sel = expr.substr(dotpos);
858 string data_url = _URL +
".dods?" +
id2www_ce(_proj + proj + _sel + sel);
865 d_version = rs->get_version();
866 d_protocol = rs->get_protocol();
868 process_data(data, rs);
898 string use_url = _URL +
"?" + _proj + _sel;
904 d_version = rs->get_version();
905 d_protocol = rs->get_protocol();
907 process_data(data, rs);
919 void Connect::request_data_ddx(
DataDDS &data,
string expr)
922 string::size_type dotpos = expr.find(
'&');
923 if (dotpos != expr.npos) {
924 proj = expr.substr(0, dotpos);
925 sel = expr.substr(dotpos);
932 string data_url = _URL +
".dap?" +
id2www_ce(_proj + proj + _sel + sel);
939 d_version = rs->get_version();
940 d_protocol = rs->get_protocol();
942 process_data(data, rs);
954 void Connect::request_data_ddx_url(
DataDDS &data)
956 string use_url = _URL +
"?" + _proj + _sel;
962 d_version = rs->get_version();
963 d_protocol = rs->get_protocol();
965 process_data(data, rs);
992 throw InternalErr(__FILE__, __LINE__,
"Response object is null.");
1003 throw InternalErr(__FILE__, __LINE__,
"Response object is null.");
1016 static void divine_type_information(
Response *rs)
1019 int c = getc(rs->get_stream());
1020 while (!feof(rs->get_stream()) && !ferror(rs->get_stream()) && isspace(c)) {
1021 c = getc(rs->get_stream());
1025 if (ferror(rs->get_stream()))
1026 throw Error(
"Error reading response type information: " +
string(strerror(errno)));
1027 if (feof(rs->get_stream()))
1028 throw Error(
"Error reading response type information: Found EOF");
1037 rs->set_type(dods_data_ddx);
1041 rs->set_type(dods_data);
1044 throw InternalErr(__FILE__, __LINE__,
"Could not determine type of response object in stream.");
1047 ungetc(c, rs->get_stream());
1064 if (rs->get_type() == unknown_type)
1065 divine_type_information(rs);
1067 switch (rs->get_type()) {
1069 d_version = rs->get_version();
1070 d_protocol = rs->get_protocol();
1071 process_data(data, rs);
1074 process_data(data, rs);
1075 d_version = rs->get_version();
1076 d_protocol = data.get_protocol();
1079 throw InternalErr(__FILE__, __LINE__,
"Should have been a DataDDS or DataDDX.");
1084 if (rs->get_type() == unknown_type)
1085 divine_type_information(rs);
1087 switch (rs->get_type()) {
1089 d_version = rs->get_version();
1090 d_protocol = rs->get_protocol();
1091 process_data(data, rs);
1094 process_data(data, rs);
1095 d_version = rs->get_version();
1098 d_protocol = data.get_dap_version();
1101 throw InternalErr(__FILE__, __LINE__,
"Should have been a DataDDS or DataDDX.");
1130 throw InternalErr(__FILE__, __LINE__,
"URL(): This call is only valid for a DAP data source.");
1133 return _URL +
"?" + _proj + _sel;
1149 throw InternalErr(__FILE__, __LINE__,
"CE(): This call is only valid for a DAP data source.");
1151 return _proj + _sel;
1194 bool Connect::is_cache_enabled()
1197 DBG(cerr <<
"Entering is_cache_enabled (" << hex << d_http << dec
1203 DBGN(cerr <<
"exiting" << endl);
virtual string CE()
Get the Connect's constraint expression.
virtual void request_das_url(DAS &das)
Get the DAS from a server.
string get_next_mime_header(FILE *in)
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.
virtual string URL(bool CE=true)
Get the object's URL.
string id2www_ce(string in, const string &allowable)
string prune_spaces(const string &name)
void set_credentials(const string &u, const string &p)
void set_xdap_protocol(int major, int minor)
void read_multipart_headers(FILE *in, const string &content_type, const ObjectType object_type, const string &cid)
virtual void request_dds_url(DDS &dds)
Get the DDS from a server.
bool parse(FILE *fp)
Parse an Error object.
void set_cache_enabled(bool enabled)
string read_multipart_boundary(FILE *in, const string &boundary)
ObjectType
The type of object in the stream coming from the data server.
HTTPResponse * fetch_url(const string &url)
top level DAP object to house generic methods
A class for software fault reporting.
void parse(string fname)
Parse a DDS from a file with the given d_name.
void parse_mime_header(const string &header, string &name, string &value)
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...
ObjectType get_description_type(const string &value)
void set_cache_enabled(bool enabled)
virtual void request_dds(DDS &dds, string expr="")
Get the DDS from a server.
void set_accept_deflate(bool deflate)
virtual void request_data(DataDDS &data, string expr="")
Get the DAS 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...
string cid_to_header_value(const string &cid)
virtual void request_das(DAS &das)
Get the DAS from a server.
void set_accept_deflate(bool defalte)
void set_xdap_protocol(int major, int minor)
virtual void parse(string fname)
Reads a DAS from the named file.
virtual string request_version()
void set_credentials(string u, string p)
Set the credentials for responding to challenges while dereferencing URLs.
virtual string request_protocol()
Hold attribute data for a DAP2 dataset.
virtual void request_data_url(DataDDS &data)
Get the DAS from a server.
A class for error processing.
BaseTypeFactory * get_factory() const
virtual void request_ddx_url(DDS &dds)
The 'url' version of request_ddx.