00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "config.h"
00038
00039 static char rcsid[] not_used =
00040 {"$Id: DODSFilter.cc 17002 2007-08-27 19:16:51Z pwest $"
00041 };
00042
00043 #include <signal.h>
00044
00045 #ifndef WIN32
00046 #include <unistd.h>
00047 #include <sys/wait.h>
00048 #else
00049 #include <io.h>
00050 #include <fcntl.h>
00051 #include <process.h>
00052 #endif
00053
00054 #include <iostream>
00055 #include <string>
00056 #include <algorithm>
00057
00058 #include <GetOpt.h>
00059
00060 #include "DAS.h"
00061 #include "DDS.h"
00062 #include "debug.h"
00063 #include "cgi_util.h"
00064 #include "util.h"
00065 #include "escaping.h"
00066 #include "DODSFilter.h"
00067 #include "XDRFileMarshaller.h"
00068 #include "XDRStreamMarshaller.h"
00069 #include "InternalErr.h"
00070 #ifndef WIN32
00071 #include "SignalHandler.h"
00072 #include "EventHandler.h"
00073 #include "AlarmHandler.h"
00074 #endif
00075
00076 using namespace std;
00077
00078 const string usage =
00079 "Usage: <handler name> -o <response> -u <url> [options ...] [data set]\n\
00080 \n\
00081 options: -o <response>: DAS, DDS, DataDDS, DDX, BLOB or Version (Required)\n\
00082 -u <url>: The complete URL minus the CE (required for DDX)\n\
00083 -c: Compress the response using the deflate algorithm.\n\
00084 -e <expr>: When returning a DataDDS, use <expr> as the constraint.\n\
00085 -v <version>: Use <version> as the version number\n\
00086 -d <dir>: Look for ancillary file in <dir> (deprecated).\n\
00087 -f <file>: Look for ancillary data in <file> (deprecated).\n\
00088 -r <dir>: Use <dir> as a cache directory\n\
00089 -l <time>: Conditional request; if data source is unchanged since\n\
00090 <time>, return an HTTP 304 response.\n\
00091 -t <seconds>: Timeout the handler after <seconds>.\n\
00092 -h: This message.";
00093
00094 #if 0
00095
00096
00097
00098 #ifdef WIN32
00099 #define WAITPID(pid) while(_cwait(NULL, pid, NULL) > 0)
00100 #else
00101 #define WAITPID(pid) while(waitpid(pid, 0, 0) > 0)
00102 #endif
00103 #endif
00104
00169 DODSFilter::DODSFilter(int argc, char *argv[]) throw(Error)
00170 {
00171 initialize(argc, argv);
00172
00173 DBG(cerr << "d_comp: " << d_comp << endl);
00174 DBG(cerr << "d_ce: " << d_ce << endl);
00175 DBG(cerr << "d_cgi_ver: " << d_cgi_ver << endl);
00176 DBG(cerr << "d_response: " << d_response << endl);
00177 DBG(cerr << "d_anc_dir: " << d_anc_dir << endl);
00178 DBG(cerr << "d_anc_file: " << d_anc_file << endl);
00179 DBG(cerr << "d_cache_dir: " << d_cache_dir << endl);
00180 DBG(cerr << "d_conditional_request: " << d_conditional_request << endl);
00181 DBG(cerr << "d_if_modified_since: " << d_if_modified_since << endl);
00182 DBG(cerr << "d_url: " << d_url << endl);
00183 DBG(cerr << "d_timeout: " << d_timeout << endl);
00184 }
00185
00186 DODSFilter::~DODSFilter()
00187 {
00188 }
00189
00192 void
00193 DODSFilter::initialize()
00194 {
00195
00196
00197 d_comp = false;
00198 d_bad_options = false;
00199 d_conditional_request = false;
00200 d_dataset = "";
00201 d_ce = "";
00202 d_cgi_ver = "";
00203 d_anc_dir = "";
00204 d_anc_file = "";
00205 d_cache_dir = "";
00206 d_response = Unknown_Response;;
00207 d_anc_das_lmt = 0;
00208 d_anc_dds_lmt = 0;
00209 d_if_modified_since = -1;
00210 d_url = "";
00211 d_program_name = "Unknown";
00212 d_timeout = 0;
00213
00214 #ifdef WIN32
00215
00216
00217
00218 _setmode(_fileno(stdout), _O_BINARY);
00219 #endif
00220 }
00221
00233 void
00234 DODSFilter::initialize(int argc, char *argv[])
00235 {
00236 initialize();
00237
00238 d_program_name = argv[0];
00239
00240
00241 int next_arg = process_options(argc, argv);
00242
00243
00244
00245
00246 if (next_arg < argc) {
00247 d_dataset = argv[next_arg];
00248 d_dataset = www2id(d_dataset, "%", "%20");
00249 }
00250 else if (get_response() != Version_Response)
00251 print_usage();
00252 }
00253
00262 int
00263 DODSFilter::process_options(int argc, char *argv[])
00264 {
00265 DBG(cerr << "Entering process_options... ");
00266
00267 int option_char;
00268 GetOpt getopt (argc, argv, "ce: v: d: f: r: l: o: u: t: ");
00269
00270 while ((option_char = getopt()) != EOF) {
00271 switch (option_char) {
00272 case 'c': d_comp = true; break;
00273 case 'e': set_ce(getopt.optarg); break;
00274 case 'v': set_cgi_version(getopt.optarg); break;
00275 case 'd': d_anc_dir = getopt.optarg; break;
00276 case 'f': d_anc_file = getopt.optarg; break;
00277 case 'r': d_cache_dir = getopt.optarg; break;
00278 case 'o': set_response(getopt.optarg); break;
00279 case 'u': set_URL(getopt.optarg); break;
00280 case 't': d_timeout = atoi(getopt.optarg); break;
00281 case 'l':
00282 d_conditional_request = true;
00283 d_if_modified_since
00284 = static_cast<time_t>(strtol(getopt.optarg, NULL, 10));
00285 break;
00286 case 'h': print_usage(); exit(1);
00287 default: print_usage();
00288 }
00289 }
00290
00291 DBGN(cerr << "exiting." << endl);
00292
00293 return getopt.optind;
00294 }
00295
00300 bool
00301 DODSFilter::is_conditional() const
00302 {
00303 return d_conditional_request;
00304 }
00305
00319 void
00320 DODSFilter::set_cgi_version(string version)
00321 {
00322 d_cgi_ver = version;
00323 }
00324
00330 string
00331 DODSFilter::get_cgi_version() const
00332 {
00333 return d_cgi_ver;
00334 }
00335
00342 string
00343 DODSFilter::get_ce() const
00344 {
00345 return d_ce;
00346 }
00347
00348 void
00349 DODSFilter::set_ce(string _ce)
00350 {
00351 d_ce = www2id(_ce, "%", "%20");
00352 }
00353
00362 string
00363 DODSFilter::get_dataset_name() const
00364 {
00365 return d_dataset;
00366 }
00367
00368 void
00369 DODSFilter::set_dataset_name(const string ds)
00370 {
00371 d_dataset = www2id(ds, "%", "%20");
00372 }
00373
00377 string
00378 DODSFilter::get_URL() const
00379 {
00380 return d_url;
00381 }
00382
00385 void
00386 DODSFilter::set_URL(const string &url)
00387 {
00388 if (url.find('?') != url.npos)
00389 print_usage();
00390
00391 d_url = url;
00392 }
00393
00401 string
00402 DODSFilter::get_dataset_version() const
00403 {
00404 return "";
00405 }
00406
00413 void DODSFilter::set_response(const string &r)
00414 {
00415 if (r == "DAS" || r == "das") {
00416 d_response = DAS_Response;
00417 d_action = "das" ;
00418 }
00419 else if (r == "DDS" || r == "dds") {
00420 d_response = DDS_Response;
00421 d_action = "dds" ;
00422 }
00423 else if (r == "DataDDS" || r == "dods") {
00424 d_response = DataDDS_Response;
00425 d_action = "dods" ;
00426 }
00427 else if (r == "DDX" || r == "ddx") {
00428 d_response = DDX_Response;
00429 d_action = "ddx" ;
00430 }
00431 else if (r == "Version") {
00432 d_response = Version_Response;
00433 d_action = "version" ;
00434 }
00435 else
00436 print_usage();
00437 }
00438
00440 DODSFilter::Response
00441 DODSFilter::get_response() const
00442 {
00443 return d_response;
00444 }
00445
00447 string DODSFilter::get_action() const
00448 {
00449 return d_action;
00450 }
00451
00472 time_t
00473 DODSFilter::get_dataset_last_modified_time() const
00474 {
00475 return last_modified_time(d_dataset);
00476 }
00477
00487 time_t
00488 DODSFilter::get_das_last_modified_time(const string &anc_location) const
00489 {
00490 DBG(cerr << "DODSFilter::get_das_last_modified_time(anc_location="
00491 << anc_location << "call faf(das) d_dataset=" << d_dataset
00492 << " d_anc_file=" << d_anc_file << endl);
00493
00494 string name
00495 = find_ancillary_file(d_dataset, "das",
00496 (anc_location == "") ? d_anc_dir : anc_location,
00497 d_anc_file);
00498
00499 return max((name != "") ? last_modified_time(name) : 0,
00500 get_dataset_last_modified_time());
00501 }
00502
00510 time_t
00511 DODSFilter::get_dds_last_modified_time(const string &anc_location) const
00512 {
00513 DBG(cerr << "DODSFilter::get_das_last_modified_time(anc_location="
00514 << anc_location << "call faf(dds) d_dataset=" << d_dataset
00515 << " d_anc_file=" << d_anc_file << endl);
00516
00517 string name
00518 = find_ancillary_file(d_dataset, "dds",
00519 (anc_location == "") ? d_anc_dir : anc_location,
00520 d_anc_file);
00521
00522 return max((name != "") ? last_modified_time(name) : 0,
00523 get_dataset_last_modified_time());
00524 }
00525
00539 time_t
00540 DODSFilter::get_data_last_modified_time(const string &anc_location) const
00541 {
00542 DBG(cerr << "DODSFilter::get_das_last_modified_time(anc_location="
00543 << anc_location << "call faf(both) d_dataset=" << d_dataset
00544 << " d_anc_file=" << d_anc_file << endl);
00545
00546 string dds_name
00547 = find_ancillary_file(d_dataset, "dds",
00548 (anc_location == "") ? d_anc_dir : anc_location,
00549 d_anc_file);
00550 string das_name
00551 = find_ancillary_file(d_dataset, "das",
00552 (anc_location == "") ? d_anc_dir : anc_location,
00553 d_anc_file);
00554
00555 time_t m = max((das_name != "") ? last_modified_time(das_name) : (time_t)0,
00556 (dds_name != "") ? last_modified_time(dds_name) : (time_t)0);
00557
00558 time_t n = get_dataset_last_modified_time();
00559
00560 return max(m, n);
00561 }
00562
00570 time_t
00571 DODSFilter::get_request_if_modified_since() const
00572 {
00573 return d_if_modified_since;
00574 }
00575
00582 string
00583 DODSFilter::get_cache_dir() const
00584 {
00585 return d_cache_dir;
00586 }
00587
00592 void
00593 DODSFilter::set_timeout(int t)
00594 {
00595 d_timeout = t;
00596 }
00597
00599 int
00600 DODSFilter::get_timeout() const
00601 {
00602 return d_timeout;
00603 }
00604
00616 void
00617 DODSFilter::establish_timeout(FILE *stream) const
00618 {
00619 #ifndef WIN32
00620 if (d_timeout > 0) {
00621 SignalHandler *sh = SignalHandler::instance();
00622 sh->register_handler(SIGALRM, new AlarmHandler(stream));
00623 alarm(d_timeout);
00624 }
00625 #endif
00626 }
00627
00628
00629 void
00630 DODSFilter::establish_timeout(ostream &stream) const
00631 {
00632 #ifndef WIN32
00633 if (d_timeout > 0) {
00634 SignalHandler *sh = SignalHandler::instance();
00635 sh->register_handler(SIGALRM, new AlarmHandler(stream));
00636 alarm(d_timeout);
00637 }
00638 #endif
00639 }
00640
00641
00651 void
00652 DODSFilter::read_ancillary_das(DAS &das, const string &anc_location) const
00653 {
00654 string name = find_ancillary_file(d_dataset, "das",
00655 (anc_location == "") ? d_anc_dir : anc_location,
00656 d_anc_file);
00657
00658 FILE *in = fopen(name.c_str(), "r");
00659 if (in) {
00660 das.parse(in);
00661 int res = fclose(in) ;
00662 if (res) {
00663 DBG(cerr << "DODSFilter::read_ancillary_das - Failed to close file " << (void *)in << endl ;) ;
00664 }
00665 }
00666 }
00667
00677 void
00678 DODSFilter::read_ancillary_dds(DDS &dds, const string &anc_location) const
00679 {
00680 string name = find_ancillary_file(d_dataset, "dds",
00681 (anc_location == "") ? d_anc_dir : anc_location,
00682 d_anc_file);
00683 FILE *in = fopen(name.c_str(), "r");
00684 if (in) {
00685 dds.parse(in);
00686 int res = fclose(in) ;
00687 if (res) {
00688 DBG(cerr << "DODSFilter::read_ancillary_dds - Failed to close " << (void *)in << endl ;) ;
00689 }
00690 }
00691 }
00692
00693 static const char *emessage = "DODS internal server error; usage error. Please report this to the dataset maintainer, or to the opendap-tech@opendap.org mailing list.";
00694
00704 void
00705 DODSFilter::print_usage() const
00706 {
00707
00708 ErrMsgT(usage.c_str());
00709
00710 throw Error(unknown_error, emessage);
00711 }
00712
00718 void
00719 DODSFilter::send_version_info() const
00720 {
00721 do_version(d_cgi_ver, get_dataset_version());
00722 }
00723
00735 void
00736 DODSFilter::send_das(FILE *out, DAS &das, const string &anc_location,
00737 bool with_mime_headers) const
00738 {
00739 time_t das_lmt = get_das_last_modified_time(anc_location);
00740 if (is_conditional()
00741 && das_lmt <= get_request_if_modified_since()
00742 && with_mime_headers) {
00743 set_mime_not_modified(out);
00744 }
00745 else {
00746 if (with_mime_headers)
00747 set_mime_text(out, dods_das, d_cgi_ver, x_plain, das_lmt);
00748 das.print(out);
00749 }
00750 fflush(out) ;
00751 }
00752
00764 void
00765 DODSFilter::send_das(ostream &out, DAS &das, const string &anc_location,
00766 bool with_mime_headers) const
00767 {
00768 time_t das_lmt = get_das_last_modified_time(anc_location);
00769 if (is_conditional()
00770 && das_lmt <= get_request_if_modified_since()
00771 && with_mime_headers) {
00772 set_mime_not_modified(out);
00773 }
00774 else {
00775 if (with_mime_headers)
00776 set_mime_text(out, dods_das, d_cgi_ver, x_plain, das_lmt);
00777 das.print(out);
00778 }
00779 out << flush ;
00780 }
00781
00782 void
00783 DODSFilter::send_das(DAS &das, const string &anc_location,
00784 bool with_mime_headers) const
00785 {
00786 send_das(stdout, das, anc_location, with_mime_headers);
00787 }
00788
00805 void
00806 DODSFilter::send_dds(FILE *out, DDS &dds, ConstraintEvaluator &eval,
00807 bool constrained,
00808 const string &anc_location,
00809 bool with_mime_headers) const
00810 {
00811
00812 if (constrained)
00813 eval.parse_constraint(d_ce, dds);
00814
00815 if (eval.functional_expression())
00816 throw Error("Function calls can only be used with data requests. To see the structure\nof the underlying data source, reissue the URL without the function.");
00817
00818 time_t dds_lmt = get_dds_last_modified_time(anc_location);
00819 if (is_conditional()
00820 && dds_lmt <= get_request_if_modified_since()
00821 && with_mime_headers) {
00822 set_mime_not_modified(out);
00823 }
00824 else {
00825 if (with_mime_headers)
00826 set_mime_text(out, dods_dds, d_cgi_ver, x_plain, dds_lmt);
00827 if (constrained)
00828 dds.print_constrained(out);
00829 else
00830 dds.print(out);
00831 }
00832
00833 fflush(out) ;
00834 }
00835
00852 void
00853 DODSFilter::send_dds(ostream &out, DDS &dds, ConstraintEvaluator &eval,
00854 bool constrained,
00855 const string &anc_location,
00856 bool with_mime_headers) const
00857 {
00858
00859 if (constrained)
00860 eval.parse_constraint(d_ce, dds);
00861
00862 if (eval.functional_expression())
00863 throw Error("Function calls can only be used with data requests. To see the structure\nof the underlying data source, reissue the URL without the function.");
00864
00865 time_t dds_lmt = get_dds_last_modified_time(anc_location);
00866 if (is_conditional()
00867 && dds_lmt <= get_request_if_modified_since()
00868 && with_mime_headers) {
00869 set_mime_not_modified(out);
00870 }
00871 else {
00872 if (with_mime_headers)
00873 set_mime_text(out, dods_dds, d_cgi_ver, x_plain, dds_lmt);
00874 if (constrained)
00875 dds.print_constrained(out);
00876 else
00877 dds.print(out);
00878 }
00879
00880 out << flush ;
00881 }
00882
00883 void
00884 DODSFilter::send_dds(DDS &dds, ConstraintEvaluator &eval,
00885 bool constrained, const string &anc_location,
00886 bool with_mime_headers) const
00887 {
00888 send_dds(stdout, dds, eval, constrained, anc_location, with_mime_headers);
00889 }
00890
00891
00892
00893 void
00894 DODSFilter::functional_constraint(BaseType &var, DDS &dds,
00895 ConstraintEvaluator &eval, FILE *out) const
00896 {
00897 fprintf(out, "Dataset {\n");
00898 var.print_decl(out, " ", true, false, true);
00899 fprintf(out, "} function_value;\n");
00900 fprintf(out, "Data:\n");
00901
00902 fflush(out);
00903
00904
00905 XDRFileMarshaller m( out ) ;
00906
00907 try {
00908
00909 var.serialize(d_dataset, eval, dds, m, false);
00910 }
00911 catch (Error &e) {
00912 throw;
00913 }
00914 }
00915
00916
00917
00918 void
00919 DODSFilter::functional_constraint(BaseType &var, DDS &dds,
00920 ConstraintEvaluator &eval, ostream &out) const
00921 {
00922 out << "Dataset {\n" ;
00923 var.print_decl(out, " ", true, false, true);
00924 out << "} function_value;\n" ;
00925 out << "Data:\n" ;
00926
00927 out << flush ;
00928
00929
00930 XDRStreamMarshaller m( out ) ;
00931
00932 try {
00933
00934 var.serialize(d_dataset, eval, dds, m, false);
00935 }
00936 catch (Error &e) {
00937 throw;
00938 }
00939 }
00940
00941 void
00942 DODSFilter::dataset_constraint(DDS & dds, ConstraintEvaluator & eval,
00943 FILE * out) const
00944 {
00945
00946 dds.print_constrained(out);
00947 fprintf(out, "Data:\n");
00948 fflush(out);
00949
00950
00951 XDRFileMarshaller m( out ) ;
00952
00953 try {
00954
00955 for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++)
00956 if ((*i)->send_p()) {
00957 DBG(cerr << "Sending " << (*i)->name() << endl);
00958 (*i)->serialize(d_dataset, eval, dds, m, true);
00959 }
00960 }
00961 catch (Error & e) {
00962 throw;
00963 }
00964 }
00965
00966 void
00967 DODSFilter::dataset_constraint(DDS & dds, ConstraintEvaluator & eval,
00968 ostream &out) const
00969 {
00970
00971 dds.print_constrained(out);
00972 out << "Data:\n" ;
00973 out << flush ;
00974
00975
00976 XDRStreamMarshaller m( out ) ;
00977
00978 try {
00979
00980 for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++)
00981 if ((*i)->send_p()) {
00982 DBG(cerr << "Sending " << (*i)->name() << endl);
00983 (*i)->serialize(d_dataset, eval, dds, m, true);
00984 }
00985 }
00986 catch (Error & e) {
00987 throw;
00988 }
00989 }
00990
01007 void
01008 DODSFilter::send_data(DDS & dds, ConstraintEvaluator & eval,
01009 FILE * data_stream, const string & anc_location,
01010 bool with_mime_headers) const
01011 {
01012
01013
01014
01015 time_t data_lmt = get_data_last_modified_time(anc_location);
01016 if (is_conditional()
01017 && data_lmt <= get_request_if_modified_since()
01018 && with_mime_headers) {
01019 set_mime_not_modified(data_stream);
01020 return;
01021 }
01022
01023 establish_timeout(data_stream);
01024 dds.set_timeout(d_timeout);
01025
01026 eval.parse_constraint(d_ce, dds);
01027
01028
01029 dds.tag_nested_sequences();
01030
01031
01032 #if COMPRESSION_FOR_SERVER3
01033 bool compress = d_comp && deflate_exists();
01034 #endif
01035
01036
01037 if (eval.functional_expression()) {
01038
01039
01040
01041
01042 BaseType *var = eval.eval_function(dds, d_dataset);
01043 if (!var)
01044 throw Error(unknown_error, "Error calling the CE function.");
01045
01046 #if COMPRESSION_FOR_SERVER3
01047 if (with_mime_headers)
01048 set_mime_binary(data_stream, dods_data, d_cgi_ver,
01049 (compress) ? deflate : x_plain, data_lmt);
01050 fflush(data_stream);
01051
01052 int childpid;
01053 if (compress)
01054 data_stream = compressor(data_stream, childpid);
01055 #endif
01056 if (with_mime_headers)
01057 set_mime_binary(data_stream, dods_data, d_cgi_ver, x_plain, data_lmt);
01058
01059 fflush(data_stream);
01060
01061 functional_constraint(*var, dds, eval, data_stream);
01062 delete var;
01063 var = 0;
01064 }
01065 else {
01066 #if COMPRESSION_FOR_SERVER3
01067 if (with_mime_headers)
01068 set_mime_binary(data_stream, dods_data, d_cgi_ver,
01069 (compress) ? deflate : x_plain, data_lmt);
01070 fflush(data_stream);
01071
01072 int childpid;
01073 if (compress)
01074 data_stream = compressor(data_stream, childpid);
01075 #endif
01076 if (with_mime_headers)
01077 set_mime_binary(data_stream, dods_data, d_cgi_ver, x_plain, data_lmt);
01078
01079 dataset_constraint(dds, eval, data_stream);
01080 }
01081
01082 fflush(data_stream);
01083 }
01084
01101 void
01102 DODSFilter::send_data(DDS & dds, ConstraintEvaluator & eval,
01103 ostream & data_stream, const string & anc_location,
01104 bool with_mime_headers) const
01105 {
01106
01107
01108
01109 time_t data_lmt = get_data_last_modified_time(anc_location);
01110 if (is_conditional()
01111 && data_lmt <= get_request_if_modified_since()
01112 && with_mime_headers) {
01113 set_mime_not_modified(data_stream);
01114 return;
01115 }
01116
01117 establish_timeout(data_stream);
01118 dds.set_timeout(d_timeout);
01119
01120 eval.parse_constraint(d_ce, dds);
01121
01122
01123 dds.tag_nested_sequences();
01124
01125
01126 #if COMPRESSION_FOR_SERVER3
01127 bool compress = d_comp && deflate_exists();
01128 #endif
01129
01130
01131 if (eval.functional_expression()) {
01132
01133
01134
01135
01136 BaseType *var = eval.eval_function(dds, d_dataset);
01137 if (!var)
01138 throw Error(unknown_error, "Error calling the CE function.");
01139
01140 #if COMPRESSION_FOR_SERVER3
01141 if (with_mime_headers)
01142 set_mime_binary(data_stream, dods_data, d_cgi_ver,
01143 (compress) ? deflate : x_plain, data_lmt);
01144 data_stream << flush ;
01145
01146 int childpid;
01147 if (compress)
01148 data_stream = compressor(data_stream, childpid);
01149 #endif
01150 if (with_mime_headers)
01151 set_mime_binary(data_stream, dods_data, d_cgi_ver, x_plain, data_lmt);
01152
01153 data_stream << flush ;
01154
01155 functional_constraint(*var, dds, eval, data_stream);
01156 delete var;
01157 var = 0;
01158 }
01159 else {
01160 #if COMPRESSION_FOR_SERVER3
01161 if (with_mime_headers)
01162 set_mime_binary(data_stream, dods_data, d_cgi_ver,
01163 (compress) ? deflate : x_plain, data_lmt);
01164 data_stream << flush ;
01165
01166 int childpid;
01167 if (compress)
01168 data_stream = compressor(data_stream, childpid);
01169 #endif
01170 if (with_mime_headers)
01171 set_mime_binary(data_stream, dods_data, d_cgi_ver, x_plain, data_lmt);
01172
01173 dataset_constraint(dds, eval, data_stream);
01174 }
01175
01176 data_stream << flush ;
01177 }
01178
01189 void
01190 DODSFilter::send_ddx(DDS &dds, ConstraintEvaluator &eval, FILE *out,
01191 bool with_mime_headers) const
01192 {
01193
01194 if (!d_ce.empty())
01195 eval.parse_constraint(d_ce, dds);
01196
01197 time_t dds_lmt = get_dds_last_modified_time(d_anc_dir);
01198
01199
01200
01201
01202 if (is_conditional() && dds_lmt <= get_request_if_modified_since()
01203 && with_mime_headers) {
01204 set_mime_not_modified(out);
01205 return;
01206 }
01207 else {
01208 if (with_mime_headers)
01209 set_mime_text(out, dap4_ddx, d_cgi_ver, x_plain, dds_lmt);
01210 dds.print_xml(out, !d_ce.empty(), d_url + ".blob?" + d_ce);
01211 }
01212 }
01213
01224 void
01225 DODSFilter::send_ddx(DDS &dds, ConstraintEvaluator &eval, ostream &out,
01226 bool with_mime_headers) const
01227 {
01228
01229 if (!d_ce.empty())
01230 eval.parse_constraint(d_ce, dds);
01231
01232 time_t dds_lmt = get_dds_last_modified_time(d_anc_dir);
01233
01234
01235
01236
01237 if (is_conditional() && dds_lmt <= get_request_if_modified_since()
01238 && with_mime_headers) {
01239 set_mime_not_modified(out);
01240 return;
01241 }
01242 else {
01243 if (with_mime_headers)
01244 set_mime_text(out, dap4_ddx, d_cgi_ver, x_plain, dds_lmt);
01245 dds.print_xml(out, !d_ce.empty(), d_url + ".blob?" + d_ce);
01246 }
01247 }
01248
01253 void
01254 DODSFilter::send_blob(DDS &, FILE *, bool)
01255 {
01256 #if 0
01257
01258 bool compress = d_comp && deflate_exists();
01259 time_t data_lmt = get_data_last_modified_time(d_anc_dir);
01260
01261
01262
01263
01264 if (is_conditional() && data_lmt <= get_request_if_modified_since()
01265 && with_mime_headers) {
01266 set_mime_not_modified(out);
01267 return;
01268 }
01269
01270 dds.parse_constraint(d_ce);
01271
01272
01273 if (dds.functional_expression()) {
01274 BaseType *var = dds.eval_function(d_dataset);
01275 if (!var)
01276 throw Error("Error calling the CE function.");
01277
01278 if (with_mime_headers)
01279 set_mime_binary(out, dods_data, d_cgi_ver,
01280 (compress) ? deflate : x_plain, data_lmt);
01281
01282 FILE *comp_sink;
01283 XDR *xdr_sink;
01284 int childpid = get_sinks(out, compress, &comp_sink, &xdr_sink);
01285
01286
01287 if (!var->serialize(d_dataset, dds, xdr_sink, false))
01288 throw Error("Could not send the function result.");
01289
01290 clean_sinks(childpid, compress, xdr_sink, comp_sink);
01291 }
01292 else {
01293 if (with_mime_headers)
01294 set_mime_binary(out, dods_data, d_cgi_ver,
01295 (compress) ? deflate : x_plain, data_lmt);
01296
01297 FILE *comp_sink;
01298 XDR *xdr_sink;
01299 int childpid = get_sinks(out, compress, &comp_sink, &xdr_sink);
01300
01301 for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++)
01302 if ((*i)->send_p())
01303 if (!(*i)->serialize(d_dataset, dds, xdr_sink, true))
01304 throw Error(string("Could not serialize variable '")
01305 + (*i)->name() + string("'."));
01306
01307 clean_sinks(childpid, compress, xdr_sink, comp_sink);
01308 }
01309 #endif
01310 }
01311