27 static char rcsid[]
not_used = {
"$Id: ResponseBuilder.cc 23477 2010-09-02 21:02:59Z jimg $" };
46 #include <uuid/uuid.h>
62 #define CRLF "\r\n" // Change here, expr-test.cc
67 ResponseBuilder::~ResponseBuilder() {
72 void ResponseBuilder::initialize() {
80 #if 0 // Keyword support moved to Keywords class
82 d_known_keywords.insert(
"dap2");
83 d_known_keywords.insert(
"dap2.0");
85 d_known_keywords.insert(
"dap3.2");
86 d_known_keywords.insert(
"dap3.3");
88 d_known_keywords.insert(
"dap4");
89 d_known_keywords.insert(
"dap4.0");
95 _setmode(_fileno(stdout), _O_BINARY);
104 void ResponseBuilder::add_keyword(
const string &kw)
106 d_keywords.insert(kw);
117 return d_keywords.count(kw) != 0;
125 list<string> ResponseBuilder::get_keywords()
const
128 set<string>::const_iterator i;
129 for (i = d_keywords.begin(); i != d_keywords.end(); ++i)
139 bool ResponseBuilder::is_known_keyword(
const string &w)
const
141 return d_known_keywords.count(w) != 0;
151 string ResponseBuilder::get_ce()
const {
155 void ResponseBuilder::set_ce(
string _ce) {
156 d_ce =
www2id(_ce,
"%",
"%20");
160 string projection =
www2id(_ce,
"%",
"%20");
161 string selection =
"";
164 string::size_type amp = projection.find(
'&');
165 if (amp != string::npos) {
166 selection = projection.substr(amp);
167 projection = projection.substr(0, amp);
174 while (!projection.empty()) {
175 string::size_type i = projection.find(
',');
176 string next_word = projection.substr(0, i);
177 if (is_known_keyword(next_word)) {
178 add_keyword(next_word);
179 projection = projection.substr(i + 1);
187 d_ce = projection + selection;
199 string ResponseBuilder::get_dataset_name()
const {
203 void ResponseBuilder::set_dataset_name(
const string ds) {
204 d_dataset =
www2id(ds,
"%",
"%20");
211 void ResponseBuilder::set_timeout(
int t) {
216 int ResponseBuilder::get_timeout()
const {
230 void ResponseBuilder::establish_timeout(ostream &stream)
const {
252 void ResponseBuilder::send_das(ostream &out,
DAS &das,
bool with_mime_headers)
const {
253 if (with_mime_headers)
277 bool with_mime_headers)
const {
284 "Function calls can only be used with data requests. To see the structure of the underlying data source, reissue the URL without the function.");
286 if (with_mime_headers)
309 if ((*i)->send_p()) {
310 DBG(cerr <<
"Sending " << (*i)->name() << endl);
311 (*i)->serialize(eval, dds, m, ce_eval);
313 }
catch (
Error & e) {
319 const string &boundary,
const string &start,
bool ce_eval)
const {
327 uuid_unparse(uu, &uuid[0]);
329 if (getdomainname(domain, 255) != 0 || strlen(domain) == 0)
330 strncpy(domain,
"opendap.org", 255);
332 string cid = string(&uuid[0]) +
"@" + string(&domain[0]);
346 if ((*i)->send_p()) {
347 DBG(cerr <<
"Sending " << (*i)->name() << endl);
348 (*i)->serialize(eval, dds, m, ce_eval);
350 }
catch (
Error & e) {
371 void ResponseBuilder::send_data(ostream & data_stream,
DDS & dds,
ConstraintEvaluator & eval,
bool with_mime_headers)
const {
373 establish_timeout(data_stream);
382 +
"KB is too large; requests for this user are limited to " +
long_to_string(
392 if (with_mime_headers)
395 dataset_constraint(data_stream, *fdds, eval,
false);
399 if (with_mime_headers)
402 dataset_constraint(data_stream, dds, eval);
405 data_stream << flush;
425 "Function calls can only be used with data requests. To see the structure of the underlying data source, reissue the URL without the function.");
427 if (with_mime_headers)
450 const string &boundary,
bool with_mime_headers)
const {
452 establish_timeout(data_stream);
459 +
"KB is too large; requests for this user are limited to " +
long_to_string(
471 if (with_mime_headers)
473 data_stream << flush;
475 dataset_constraint(data_stream, *fdds, eval,
false);
479 if (with_mime_headers)
481 data_stream << flush;
482 dataset_constraint_ddx(data_stream, dds, eval, boundary, start);
485 data_stream << flush;
487 if (with_mime_headers)
488 data_stream <<
CRLF <<
"--" << boundary <<
"--" <<
CRLF;
491 static const char *descrip[] = {
"unknown",
"dods_das",
"dods_dds",
"dods_data",
"dods_error",
"web_error",
"dap4-ddx",
492 "dap4-data",
"dap4-error",
"dap4-data-ddx",
"dods_ddx" };
493 static const char *encoding[] = {
"unknown",
"deflate",
"x-plain",
"gzip",
"binary" };
508 const string &protocol)
const {
509 strm <<
"HTTP/1.0 200 OK" <<
CRLF;
511 strm <<
"XDODS-Server: " <<
DVR <<
CRLF;
512 strm <<
"XOPeNDAP-Server: " <<
DVR <<
CRLF;
515 strm <<
"XDAP: " << d_default_protocol <<
CRLF;
517 strm <<
"XDAP: " << protocol <<
CRLF;
519 const time_t t = time(0);
522 strm <<
"Last-Modified: ";
523 if (last_modified > 0)
529 strm <<
"Content-Type: text/xml" <<
CRLF;
531 strm <<
"Content-Type: text/plain" <<
CRLF;
535 strm <<
"Content-Description: " << descrip[type] <<
CRLF;
537 strm <<
"Cache-Control: no-cache" <<
CRLF;
541 strm <<
"Content-Encoding: " << encoding[enc] <<
CRLF;
556 const string &protocol)
const {
557 strm <<
"HTTP/1.0 200 OK" <<
CRLF;
559 strm <<
"XDODS-Server: " <<
DVR <<
CRLF;
560 strm <<
"XOPeNDAP-Server: " <<
DVR <<
CRLF;
563 strm <<
"XDAP: " << d_default_protocol <<
CRLF;
565 strm <<
"XDAP: " << protocol <<
CRLF;
567 const time_t t = time(0);
570 strm <<
"Last-Modified: ";
571 if (last_modified > 0)
576 strm <<
"Content-type: text/html" <<
CRLF;
578 strm <<
"Content-Description: " << descrip[type] <<
CRLF;
580 strm <<
"Cache-Control: no-cache" <<
CRLF;
584 strm <<
"Content-Encoding: " << encoding[enc] <<
CRLF;
602 const string &protocol)
const {
603 strm <<
"HTTP/1.0 200 OK" <<
CRLF;
605 strm <<
"XDODS-Server: " <<
DVR <<
CRLF;
606 strm <<
"XOPeNDAP-Server: " <<
DVR <<
CRLF;
609 strm <<
"XDAP: " << d_default_protocol <<
CRLF;
611 strm <<
"XDAP: " << protocol <<
CRLF;
613 const time_t t = time(0);
616 strm <<
"Last-Modified: ";
617 if (last_modified > 0)
622 strm <<
"Content-Type: application/octet-stream" <<
CRLF;
623 strm <<
"Content-Description: " << descrip[type] <<
CRLF;
625 strm <<
"Content-Encoding: " << encoding[enc] <<
CRLF;
631 EncodingType enc,
const time_t last_modified,
const string &protocol)
const {
632 strm <<
"HTTP/1.0 200 OK" <<
CRLF;
634 strm <<
"XDODS-Server: " <<
DVR <<
CRLF;
635 strm <<
"XOPeNDAP-Server: " <<
DVR <<
CRLF;
638 strm <<
"XDAP: " << d_default_protocol <<
CRLF;
640 strm <<
"XDAP: " << protocol <<
CRLF;
642 const time_t t = time(0);
645 strm <<
"Last-Modified: ";
646 if (last_modified > 0)
651 strm <<
"Content-Type: Multipart/Related; boundary=" << boundary <<
"; start=\"<" << start
652 <<
">\"; type=\"Text/xml\"" <<
CRLF;
653 strm <<
"Content-Description: " << descrip[type] <<
CRLF;
655 strm <<
"Content-Encoding: " << encoding[enc] <<
CRLF;
662 strm <<
"--" << boundary <<
CRLF;
663 strm <<
"Content-Type: Text/xml; charset=iso-8859-1" <<
CRLF;
664 strm <<
"Content-Id: <" << cid <<
">" <<
CRLF;
665 strm <<
"Content-Description: " << descrip[type] <<
CRLF;
667 strm <<
"Content-Encoding: " << encoding[enc] <<
CRLF;
674 strm <<
"--" << boundary <<
CRLF;
675 strm <<
"Content-Type: application/octet-stream" <<
CRLF;
676 strm <<
"Content-Id: <" << cid <<
">" <<
CRLF;
677 strm <<
"Content-Description: " << descrip[type] <<
CRLF;
679 strm <<
"Content-Encoding: " << encoding[enc] <<
CRLF;
691 strm <<
"HTTP/1.0 " << code <<
" " << reason.c_str() <<
CRLF;
693 strm <<
"XDODS-Server: " <<
DVR <<
CRLF;
694 strm <<
"XOPeNDAP-Server: " <<
DVR <<
CRLF;
697 strm <<
"XDAP: " << d_default_protocol <<
CRLF;
699 strm <<
"XDAP: " << protocol <<
CRLF;
701 const time_t t = time(0);
703 strm <<
"Cache-Control: no-cache" <<
CRLF;