65void D4Connect::process_dmr(
DMR &dmr,
Response &rs) {
66 DBG(cerr <<
"Entering D4Connect::process_dmr" << endl);
68 dmr.set_dap_version(rs.get_protocol());
70 DBG(cerr <<
"Entering process_data. Response.getVersion() = " << rs.get_version() << endl);
71 switch (rs.get_type()) {
75 if (!e.parse(rs.get_stream()))
76 throw InternalErr(__FILE__, __LINE__,
"Could not parse the Error object returned by the server!");
79 throw InternalErr(__FILE__, __LINE__,
"DAP4 errors not processed yet: FIXME!");
85 throw InternalErr(__FILE__, __LINE__,
86 "An error was reported by the remote httpd; this should have been processed by HTTPConnect.");
96 parser.intern(*rs.get_cpp_stream(), &dmr);
98 cerr <<
"Exception: " << e.get_error_message() << endl;
100 }
catch (std::exception &e) {
101 cerr <<
"Exception: " << e.what() << endl;
104 cerr <<
"Exception: unknown error" << endl;
112 throw Error(
"Unknown response type");
118void D4Connect::process_data(
DMR &data,
Response &rs) {
119 DBG(cerr <<
"Entering D4Connect::process_data" << endl);
121 assert(rs.get_cpp_stream());
123 data.set_dap_version(rs.get_protocol());
125 DBG(cerr <<
"Entering process_data. Response.getVersion() = " << rs.get_version() << endl);
126 switch (rs.get_type()) {
128 throw InternalErr(__FILE__, __LINE__,
"DAP4 errors not processed yet: FIXME!");
136 "An error was reported by the remote httpd; this should have been processed by HTTPConnect..");
139 chunked_istream cis(*(rs.get_cpp_stream()),
CHUNK_SIZE);
144 int chunk_size = cis.read_next_chunk();
146 throw Error(
"Found an unexpected end of input (EOF) while reading a DAP4 data response. (1)");
149 char chunk[chunk_size];
150 cis.read(chunk, chunk_size);
155 parser.set_strict(
false);
158 parser.intern(chunk, chunk_size - 2, &data);
160 cerr <<
"Exception: " << e.get_error_message() << endl;
162 }
catch (std::exception &e) {
163 cerr <<
"Exception: " << e.what() << endl;
166 cerr <<
"Exception: unknown error" << endl;
170 D4StreamUnMarshaller um(cis, cis.twiddle_bytes());
171 data.root()->deserialize(um, data);
177 throw Error(
"Unknown response type");
189void D4Connect::parse_mime(
Response &rs) {
190 rs.set_version(
"dods/0.0");
191 rs.set_protocol(
"2.0");
193 istream &data_source = *rs.get_cpp_stream();
195 while (!mime.empty()) {
196 string header, value;
200 if (header ==
"content-description") {
201 DBG(cout << header <<
": " << value << endl);
205 else if (header ==
"xdods-server" && rs.get_version() ==
"dods/0.0") {
206 DBG(cout << header <<
": " << value << endl);
207 rs.set_version(value);
210 else if (header ==
"xopendap-server") {
211 DBG(cout << header <<
": " << value << endl);
212 rs.set_version(value);
213 }
else if (header ==
"xdap") {
214 DBG(cout << header <<
": " << value << endl);
215 rs.set_protocol(value);
218 else if (rs.get_version() ==
"dods/0.0" && header ==
"server") {
219 DBG(cout << header <<
": " << value << endl);
220 rs.set_version(value);
236 : d_http(0), d_local(false), d_URL(
""), d_UrlQueryString(
""), d_server(
"unknown"), d_protocol(
"4.0") {
241 if (name.find(
"http") == 0) {
242 DBG(cerr <<
"Connect: The identifier is an http URL" << endl);
244 d_http->set_use_cpp_streams(
true);
249 string::size_type dotpos = name.find(
'?');
250 if (dotpos != std::string::npos) {
251 d_URL = name.substr(0, dotpos);
253 d_UrlQueryString = name.substr(dotpos + 1);
256 std::stringstream msg;
258 msg <<
"WARNING: A DAP4 constraint expression key was found in the query string!" << endl;
259 msg <<
"The submitted dataset URL: " << name << endl;
260 msg <<
"Contains the query string: " << d_UrlQueryString << endl;
261 msg <<
"This will cause issues when making DAP4 requests that specify additional constraints. " << endl;
262 cerr << msg.str() << endl;
267 DBG(cerr <<
"Connect: The identifier is a local data source." << endl);
279std::string D4Connect::build_dap4_ce(
const string requestSuffix,
const string dap4ce) {
280 std::stringstream url;
281 bool needsAmpersand =
false;
283 url << d_URL << requestSuffix <<
"?";
285 if (d_UrlQueryString.length() > 0) {
286 url << d_UrlQueryString;
287 needsAmpersand =
true;
290 if (dap4ce.length() > 0) {
297 DBG(cerr <<
"D4Connect::build_dap4_ce() - Source URL: " << d_URL << endl);
298 DBG(cerr <<
"D4Connect::build_dap4_ce() - Source URL Query String: " << d_UrlQueryString << endl);
299 DBG(cerr <<
"D4Connect::build_dap4_ce() - dap4ce: " << dap4ce << endl);
300 DBG(cerr <<
"D4Connect::build_dap4_ce() - request URL: " << url.str() << endl);
306 string url = build_dap4_ce(
".dmr", expr);
310 rs = d_http->fetch_url(url);
317 DBG(cerr <<
"Response type unknown, assuming it's a DMR response." << endl);
326 throw InternalErr(__FILE__, __LINE__,
"DAP4 errors are not processed yet.");
331 throw InternalErr(__FILE__, __LINE__,
"Web error found where it should never be.");
346 string url = build_dap4_ce(
".dap", expr);
350 rs = d_http->fetch_url(url);
357 DBG(cerr <<
"Response type unknown, assuming it's a DAP4 Data response." << endl);
369 throw Error(
"Found an unexpected end of input (EOF) while reading a DAP4 data response. (2)");
372 char chunk[chunk_size];
373 cis.read(chunk, chunk_size);
379 parser.
intern(chunk, chunk_size - 2, &dmr,
false );
389 throw InternalErr(__FILE__, __LINE__,
"DAP4 errors are not processed yet.");
394 throw InternalErr(__FILE__, __LINE__,
"Web error found where it should never be.");
411 throw Error(
"Unknown response type.");
423 process_dmr(dmr, rs);
428 throw Error(
"Expected a DAP4 DMR response.");
435 throw Error(
"Unknown response type.");
447 process_data(data, rs);
452 throw Error(
"Expected a DAP4 Data response.");
463 d_http->set_credentials(u, p);
471 d_http->set_accept_deflate(
deflate);
481 d_http->set_xdap_protocol(major, minor);
489 d_http->set_cache_enabled(cache);
494 return d_http->is_cache_enabled();
#define DAP4_CE_QUERY_KEY
virtual void read_dmr_no_mime(DMR &dmr, Response &rs)
virtual void read_data_no_mime(DMR &data, Response &rs)
virtual void request_dap4_data(DMR &dmr, const std::string expr="")
virtual void read_data(DMR &data, Response &rs)
void set_accept_deflate(bool deflate)
virtual void request_dmr(DMR &dmr, const std::string expr="")
virtual void read_dmr(DMR &dmr, Response &rs)
void set_cache_enabled(bool enabled)
void set_xdap_protocol(int major, int minor)
void set_credentials(std::string u, std::string p)
Set the credentials for responding to challenges while dereferencing URLs.
void deserialize(D4StreamUnMarshaller &um, DMR &dmr) override
void intern(istream &f, DMR *dest_dmr, bool debug=false)
Read data from the stream made by D4StreamMarshaller.
std::string dap_version() const
A class for error processing.
A class for software fault reporting.
static RCReader * instance()
virtual std::string get_protocol() const
virtual void set_type(ObjectType o)
virtual std::istream * get_cpp_stream() const
virtual ObjectType get_type() const
virtual std::string get_version() const
bool twiddle_bytes() const
void set_strict(bool s)
Set the 'strict' mode to true or false.
top level DAP object to house generic methods
ObjectType get_description_type(const string &value)
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)
string id2www_ce(string in, const string &allowable)
string get_next_mime_header(FILE *in)