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
00038 #include "config.h"
00039 #undef FILE_METHODS
00040
00041 static char rcsid[] not_used =
00042 {"$Id: mime_util.cc 21701 2009-11-06 00:35:54Z jimg $"
00043 };
00044
00045 #include <cstring>
00046 #include <cstdio>
00047 #include <ctype.h>
00048
00049 #ifndef TM_IN_SYS_TIME
00050 #include <time.h>
00051 #else
00052 #include <sys/time.h>
00053 #endif
00054
00055 #include <sys/types.h>
00056 #include <sys/stat.h>
00057
00058 #ifndef WIN32
00059 #include <unistd.h>
00060 #include <sys/wait.h>
00061 #else
00062 #include <io.h>
00063 #include <fcntl.h>
00064 #include <process.h>
00065
00066 #define F_OK 0
00067 #endif
00068
00069 #include <iostream>
00070 #include <sstream>
00071 #include <fstream>
00072 #include <string>
00073
00074 #include "mime_util.h"
00075 #include "Ancillary.h"
00076 #include "util.h"
00077 #include "debug.h"
00078
00079 #ifdef WIN32
00080 #define FILE_DELIMITER '\\'
00081 #else // default to unix
00082 #define FILE_DELIMITER '/'
00083 #endif
00084
00085
00086 #define CRLF "\r\n" // Change here, expr-test.cc and DODSFilter.cc
00087
00088 using namespace std;
00089
00090 namespace libdap {
00091
00092 static const int TimLen = 26;
00093 static const int CLUMP_SIZE = 1024;
00094
00108 bool
00109 do_version(const string &script_ver, const string &dataset_ver)
00110 {
00111 fprintf(stdout, "HTTP/1.0 200 OK%s", CRLF) ;
00112 fprintf(stdout, "XDODS-Server: %s%s", DVR, CRLF) ;
00113 fprintf(stdout, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
00114 fprintf(stdout, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
00115 fprintf(stdout, "Content-Type: text/plain%s", CRLF) ;
00116 fprintf(stdout, CRLF) ;
00117
00118 fprintf(stdout, "Core software version: %s%s", DVR, CRLF) ;
00119
00120 if (script_ver != "")
00121 fprintf(stdout, "Server Script Revision: %s%s", script_ver.c_str(), CRLF) ;
00122
00123 if (dataset_ver != "")
00124 fprintf(stdout, "Dataset version: %s%s", dataset_ver.c_str(), CRLF) ;
00125
00126 fflush(stdout) ;
00127
00128 return true;
00129 }
00130
00140 void
00141 ErrMsgT(const string &Msgt)
00142 {
00143 time_t TimBin;
00144 char TimStr[TimLen];
00145
00146 if (time(&TimBin) == (time_t) - 1)
00147 strncpy(TimStr, "time() error ", TimLen-1);
00148 else {
00149 strncpy(TimStr, ctime(&TimBin), TimLen-1);
00150 TimStr[TimLen - 2] = '\0';
00151 }
00152
00153 cerr << "[" << TimStr << "] DAP server error: " << Msgt << endl;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00177 string
00178 name_path(const string &path)
00179 {
00180 if (path == "")
00181 return string("");
00182
00183 string::size_type delim = path.find_last_of(FILE_DELIMITER);
00184 string::size_type pound = path.find_last_of("#");
00185 string new_path;
00186
00187 if (pound != string::npos)
00188 new_path = path.substr(pound + 1);
00189 else
00190 new_path = path.substr(delim + 1);
00191
00192 return new_path;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 static const char *days[] =
00228 {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
00229 };
00230 static const char *months[] =
00231 {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
00232 "Aug", "Sep", "Oct", "Nov", "Dec"
00233 };
00234
00235 #ifdef _MSC_VER
00236 #define snprintf sprintf_s
00237 #endif
00238
00246 string
00247 rfc822_date(const time_t t)
00248 {
00249 struct tm *stm = gmtime(&t);
00250 char d[256];
00251
00252 snprintf(d, 255, "%s, %02d %s %4d %02d:%02d:%02d GMT", days[stm->tm_wday],
00253 stm->tm_mday, months[stm->tm_mon],
00254 1900 + stm->tm_year,
00255 stm->tm_hour, stm->tm_min, stm->tm_sec);
00256 d[255] = '\0';
00257 return string(d);
00258 }
00259
00265 time_t
00266 last_modified_time(const string &name)
00267 {
00268 struct stat m;
00269
00270 if (stat(name.c_str(), &m) == 0 && (S_IFREG & m.st_mode))
00271 return m.st_mtime;
00272 else
00273 return time(0);
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 static const char *descrip[] =
00287 {"unknown", "dods_das", "dods_dds", "dods_data",
00288 "dods_error", "web_error", "dap4-ddx", "dap4-data", "dap4-error",
00289 "dap4-data-ddx", "dods_ddx"
00290 };
00291 static const char *encoding[] =
00292 {"unknown", "deflate", "x-plain", "gzip", "binary"
00293 };
00294
00300 ObjectType
00301 get_type(const string &value)
00302 {
00303 if ((value == "dods_das") | (value == "dods-das"))
00304 return dods_das;
00305 else if ((value == "dods_dds") | (value == "dods-dds"))
00306 return dods_dds;
00307 else if ((value == "dods_data") | (value == "dods-data"))
00308 return dods_data;
00309 else if ((value == "dods_error") | (value == "dods-error"))
00310 return dods_error;
00311 else if ((value == "web_error") | (value == "web-error"))
00312 return web_error;
00313 else if ((value == "dap4_ddx") | (value == "dap4-ddx"))
00314 return dap4_ddx;
00315 else if ((value == "dap4_data") | (value == "dap4-data"))
00316 return dap4_data;
00317 else if ((value == "dap4_error") | (value == "dap4-error"))
00318 return dap4_error;
00319 else if ((value == "dap4_data_ddx") | (value == "dap4-data-ddx"))
00320 return dap4_data_ddx;
00321 else if ((value == "dods_ddx") | (value == "dods-ddx"))
00322 return dods_ddx;
00323 else
00324 return unknown_type;
00325 }
00326
00332 ObjectType
00333 get_description_type(const string &value)
00334 {
00335 if ((value == "dods_das") | (value == "dods-das"))
00336 return dods_das;
00337 else if ((value == "dods_dds") | (value == "dods-dds"))
00338 return dods_dds;
00339 else if ((value == "dods_data") | (value == "dods-data"))
00340 return dods_data;
00341 else if ((value == "dods_error") | (value == "dods-error"))
00342 return dods_error;
00343 else if ((value == "web_error") | (value == "web-error"))
00344 return web_error;
00345 else if ((value == "dods_ddx") | (value == "dods-ddx"))
00346 return dods_ddx;
00347 else if ((value == "dap4_ddx") | (value == "dap4-ddx"))
00348 return dap4_ddx;
00349 else if ((value == "dap4_data") | (value == "dap4-data"))
00350 return dap4_data;
00351 else if ((value == "dap4_error") | (value == "dap4-error"))
00352 return dap4_error;
00353 else if ((value == "dap4_data_ddx") | (value == "dap4-data-ddx"))
00354 return dap4_data_ddx;
00355 else if ((value == "dods_ddx") | (value == "dods-ddx"))
00356 return dods_ddx;
00357 else
00358 return unknown_type;
00359 }
00360
00361 #if FILE_METHODS
00362
00374 void
00375 set_mime_text(FILE *out, ObjectType type, const string &ver,
00376 EncodingType enc, const time_t last_modified)
00377 {
00378 fprintf(out, "HTTP/1.0 200 OK%s", CRLF) ;
00379 if (ver == "") {
00380 fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
00381 fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
00382 }
00383 else {
00384 fprintf(out, "XDODS-Server: %s%s", ver.c_str(), CRLF) ;
00385 fprintf(out, "XOPeNDAP-Server: %s%s", ver.c_str(), CRLF) ;
00386 }
00387 fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
00388
00389 const time_t t = time(0);
00390 fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
00391
00392 fprintf(out, "Last-Modified: ") ;
00393 if (last_modified > 0)
00394 fprintf(out, "%s%s", rfc822_date(last_modified).c_str(), CRLF) ;
00395 else
00396 fprintf(out, "%s%s", rfc822_date(t).c_str(), CRLF) ;
00397
00398 if (type == dap4_ddx)
00399 fprintf(out, "Content-Type: text/xml%s", CRLF) ;
00400 else
00401 fprintf(out, "Content-Type: text/plain%s", CRLF) ;
00402
00403
00404
00405 fprintf(out, "Content-Description: %s%s", descrip[type], CRLF) ;
00406 if (type == dods_error)
00407 fprintf(out, "Cache-Control: no-cache%s", CRLF) ;
00408
00409
00410 if (enc != x_plain)
00411 fprintf(out, "Content-Encoding: %s%s", encoding[enc], CRLF) ;
00412 fprintf(out, CRLF) ;
00413 }
00414 #endif
00415
00428 void
00429 set_mime_text(ostream &strm, ObjectType type, const string &ver,
00430 EncodingType enc, const time_t last_modified)
00431 {
00432 strm << "HTTP/1.0 200 OK" << CRLF ;
00433 if (ver == "") {
00434 strm << "XDODS-Server: " << DVR << CRLF ;
00435 strm << "XOPeNDAP-Server: " << DVR << CRLF ;
00436 }
00437 else {
00438 strm << "XDODS-Server: " << ver.c_str() << CRLF ;
00439 strm << "XOPeNDAP-Server: " << ver.c_str() << CRLF ;
00440 }
00441 strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
00442
00443 const time_t t = time(0);
00444 strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00445
00446 strm << "Last-Modified: " ;
00447 if (last_modified > 0)
00448 strm << rfc822_date(last_modified).c_str() << CRLF ;
00449 else
00450 strm << rfc822_date(t).c_str() << CRLF ;
00451
00452 if (type == dap4_ddx)
00453 strm << "Content-Type: text/xml" << CRLF ;
00454 else
00455 strm << "Content-Type: text/plain" << CRLF ;
00456
00457
00458
00459 strm << "Content-Description: " << descrip[type] << CRLF ;
00460 if (type == dods_error)
00461 strm << "Cache-Control: no-cache" << CRLF ;
00462
00463
00464 if (enc != x_plain)
00465 strm << "Content-Encoding: " << encoding[enc] << CRLF ;
00466 strm << CRLF ;
00467 }
00468
00469 #if FILE_METHODS
00470
00480 void
00481 set_mime_html(FILE *out, ObjectType type, const string &ver,
00482 EncodingType enc, const time_t last_modified)
00483 {
00484 fprintf(out, "HTTP/1.0 200 OK%s", CRLF) ;
00485 if (ver == "") {
00486 fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
00487 fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
00488 }
00489 else {
00490 fprintf(out, "XDODS-Server: %s%s", ver.c_str(), CRLF) ;
00491 fprintf(out, "XOPeNDAP-Server: %s%s", ver.c_str(), CRLF) ;
00492 }
00493 fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
00494
00495 const time_t t = time(0);
00496 fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
00497
00498 fprintf(out, "Last-Modified: ") ;
00499 if (last_modified > 0)
00500 fprintf(out, "%s%s", rfc822_date(last_modified).c_str(), CRLF) ;
00501 else
00502 fprintf(out, "%s%s", rfc822_date(t).c_str(), CRLF) ;
00503
00504 fprintf(out, "Content-type: text/html%s", CRLF) ;
00505
00506 fprintf(out, "Content-Description: %s%s", descrip[type], CRLF) ;
00507 if (type == dods_error)
00508 fprintf(out, "Cache-Control: no-cache%s", CRLF) ;
00509
00510
00511 if (enc != x_plain)
00512 fprintf(out, "Content-Encoding: %s%s", encoding[enc], CRLF) ;
00513 fprintf(out, CRLF) ;
00514 }
00515 #endif
00516
00527 void
00528 set_mime_html(ostream &strm, ObjectType type, const string &ver,
00529 EncodingType enc, const time_t last_modified)
00530 {
00531 strm << "HTTP/1.0 200 OK" << CRLF ;
00532 if (ver == "") {
00533 strm << "XDODS-Server: " << DVR << CRLF ;
00534 strm << "XOPeNDAP-Server: " << DVR << CRLF ;
00535 }
00536 else {
00537 strm << "XDODS-Server: " << ver.c_str() << CRLF ;
00538 strm << "XOPeNDAP-Server: " << ver.c_str() << CRLF ;
00539 }
00540 strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
00541
00542 const time_t t = time(0);
00543 strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00544
00545 strm << "Last-Modified: " ;
00546 if (last_modified > 0)
00547 strm << rfc822_date(last_modified).c_str() << CRLF ;
00548 else
00549 strm << rfc822_date(t).c_str() << CRLF ;
00550
00551 strm << "Content-type: text/html" << CRLF ;
00552
00553 strm << "Content-Description: " << descrip[type] << CRLF ;
00554 if (type == dods_error)
00555 strm << "Cache-Control: no-cache" << CRLF ;
00556
00557
00558 if (enc != x_plain)
00559 strm << "Content-Encoding: " << encoding[enc] << CRLF ;
00560 strm << CRLF ;
00561 }
00562
00563 #if FILE_METHODS
00564
00577 void
00578 set_mime_binary(FILE *out, ObjectType type, const string &ver,
00579 EncodingType enc, const time_t last_modified)
00580 {
00581 fprintf(out, "HTTP/1.0 200 OK%s", CRLF) ;
00582 if (ver == "") {
00583 fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
00584 fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
00585 }
00586 else {
00587 fprintf(out, "XDODS-Server: %s%s", ver.c_str(), CRLF) ;
00588 fprintf(out, "XOPeNDAP-Server: %s%s", ver.c_str(), CRLF) ;
00589 }
00590 fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
00591
00592 const time_t t = time(0);
00593 fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
00594
00595 fprintf(out, "Last-Modified: ") ;
00596 if (last_modified > 0)
00597 fprintf(out, "%s%s", rfc822_date(last_modified).c_str(), CRLF) ;
00598 else
00599 fprintf(out, "%s%s", rfc822_date(t).c_str(), CRLF) ;
00600
00601 fprintf(out, "Content-Type: application/octet-stream%s", CRLF) ;
00602 fprintf(out, "Content-Description: %s%s", descrip[type], CRLF) ;
00603 if (enc != x_plain)
00604 fprintf(out, "Content-Encoding: %s%s", encoding[enc], CRLF) ;
00605
00606 fprintf(out, CRLF) ;
00607 }
00608 #endif
00609
00623 void
00624 set_mime_binary(ostream &strm, ObjectType type, const string &ver,
00625 EncodingType enc, const time_t last_modified)
00626 {
00627 strm << "HTTP/1.0 200 OK" << CRLF ;
00628 if (ver == "") {
00629 strm << "XDODS-Server: " << DVR << CRLF ;
00630 strm << "XOPeNDAP-Server: " << DVR << CRLF ;
00631 }
00632 else {
00633 strm << "XDODS-Server: " << ver.c_str() << CRLF ;
00634 strm << "XOPeNDAP-Server: " << ver.c_str() << CRLF ;
00635 }
00636 strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
00637
00638 const time_t t = time(0);
00639 strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00640
00641 strm << "Last-Modified: " ;
00642 if (last_modified > 0)
00643 strm << rfc822_date(last_modified).c_str() << CRLF ;
00644 else
00645 strm << rfc822_date(t).c_str() << CRLF ;
00646
00647 strm << "Content-Type: application/octet-stream" << CRLF ;
00648 strm << "Content-Description: " << descrip[type] << CRLF ;
00649 if (enc != x_plain)
00650 strm << "Content-Encoding: " << encoding[enc] << CRLF ;
00651
00652 strm << CRLF ;
00653 }
00654
00655 void set_mime_multipart(ostream &strm, const string &boundary,
00656 const string &start, ObjectType type,
00657 const string &version, EncodingType enc,
00658 const time_t last_modified)
00659 {
00660 strm << "HTTP/1.0 200 OK" << CRLF ;
00661 if (version == "") {
00662 strm << "XDODS-Server: " << DVR << CRLF ;
00663 strm << "XOPeNDAP-Server: " << DVR << CRLF ;
00664 }
00665 else {
00666 strm << "XDODS-Server: " << version.c_str() << CRLF ;
00667 strm << "XOPeNDAP-Server: " << version.c_str() << CRLF ;
00668 }
00669 strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
00670
00671 const time_t t = time(0);
00672 strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00673
00674 strm << "Last-Modified: " ;
00675 if (last_modified > 0)
00676 strm << rfc822_date(last_modified).c_str() << CRLF ;
00677 else
00678 strm << rfc822_date(t).c_str() << CRLF ;
00679
00680 strm << "Content-Type: Multipart/Related; boundary=" << boundary
00681 << "; start=\"<" << start << ">\"; type=\"Text/xml\"" << CRLF ;
00682 strm << "Content-Description: " << descrip[type] << CRLF ;
00683 if (enc != x_plain)
00684 strm << "Content-Encoding: " << encoding[enc] << CRLF ;
00685
00686 strm << CRLF ;
00687 }
00688
00689 void set_mime_ddx_boundary(ostream &strm, const string &boundary,
00690 const string &cid, ObjectType type, EncodingType enc)
00691 {
00692 strm << "--" << boundary << CRLF;
00693 strm << "Content-Type: Text/xml; charset=iso-8859-1" << CRLF;
00694 strm << "Content-Id: <" << cid << ">" << CRLF;
00695 strm << "Content-Description: " << descrip[type] << CRLF ;
00696 if (enc != x_plain)
00697 strm << "Content-Encoding: " << encoding[enc] << CRLF ;
00698
00699 strm << CRLF;
00700 }
00701
00702 void set_mime_data_boundary(ostream &strm, const string &boundary,
00703 const string &cid, ObjectType type, EncodingType enc)
00704 {
00705 strm << "--" << boundary << CRLF;
00706 strm << "Content-Type: application/octet-stream" << CRLF;
00707 strm << "Content-Id: <" << cid << ">" << CRLF;
00708 strm << "Content-Description: " << descrip[type] << CRLF ;
00709 if (enc != x_plain)
00710 strm << "Content-Encoding: " << encoding[enc] << CRLF ;
00711
00712 strm << CRLF;
00713 }
00714
00715 const size_t line_length = 1024;
00716
00730 string get_next_mime_header(FILE *in)
00731 {
00732
00733
00734 char line[line_length];
00735 while (!feof(in)) {
00736 if (fgets(line, line_length, in)
00737 && (strncmp(line, CRLF, 2) == 0 || line[0] == '\n'))
00738 return "";
00739 else {
00740 size_t slen = min(strlen(line), line_length);
00741 line[slen - 1] = '\0';
00742 if (line[slen - 2] == '\r')
00743 line[slen - 2] = '\0';
00744 return string(line);
00745 }
00746 }
00747
00748 throw Error("I expected to find a MIME header, but got EOF instead.");
00749 }
00750
00758 void parse_mime_header(const string &header, string &name, string &value)
00759 {
00760 istringstream iss(header);
00761
00762 char s[line_length];
00763 iss.getline(s, 1023, ':');
00764 name = s;
00765
00766 iss.ignore(1023, ' ');
00767 iss.getline(s, 1023);
00768 value = s;
00769
00770 downcase(name);
00771 downcase(value);
00772 }
00773
00781 bool is_boundary(const char *line, const string &boundary)
00782 {
00783 if (!(line[0] == '-' && line[1] == '-'))
00784 return false;
00785 else {
00786 return strncmp(line, boundary.c_str(), boundary.length()) == 0;
00787 }
00788 }
00789
00798 string read_multipart_boundary(FILE *in, const string &boundary)
00799 {
00800 string boundary_line = get_next_mime_header(in);
00801
00802
00803
00804 if ((!boundary.empty() && is_boundary(boundary_line.c_str(), boundary))
00805 || boundary_line.find("--") != 0)
00806 throw Error(
00807 "The DAP4 data response document is broken - missing or malformed boundary.");
00808
00809 return boundary_line;
00810 }
00811
00832 void read_multipart_headers(FILE *in, const string &content_type,
00833 const ObjectType object_type, const string &cid)
00834 {
00835 bool ct = false, cd = false, ci = false;
00836
00837 string header = get_next_mime_header(in);
00838 while (!header.empty()) {
00839 string name, value;
00840 parse_mime_header(header, name, value);
00841
00842 if (name =="content-type") {
00843 ct = true;
00844 if (value.find(content_type) == string::npos)
00845 throw Error("Content-Type for this part of a DAP4 data response must be " + content_type + ".");
00846 }
00847 else if (name == "content-description") {
00848 cd = true;
00849 if (get_description_type(value) != object_type)
00850 throw Error("Content-Description for this part of a DAP4 data response must be dap4-ddx or dap4-data-ddx");
00851 }
00852 else if (name == "content-id") {
00853 ci = true;
00854 if (!cid.empty() && value != cid)
00855 throw Error("Content-Id mismatch. Expected: " + cid
00856 + ", but got: " + value);
00857 }
00858
00859 header = get_next_mime_header(in);
00860 }
00861
00862 if (!(ct && cd && ci))
00863 throw Error("The DAP4 data response document is broken - missing header.");
00864 }
00872 string cid_to_header_value(const string &cid)
00873 {
00874 string::size_type offset = cid.find("cid:");
00875 if (offset != 0)
00876 throw Error("expected CID to start with 'cid:'");
00877
00878 string value = "<";
00879 value.append(cid.substr(offset + 4));
00880 value.append(">");
00881 downcase(value);
00882
00883 return value;
00884 }
00885
00886 #if FILE_METHODS
00887
00893 void
00894 set_mime_error(FILE *out, int code, const string &reason,
00895 const string &version)
00896 {
00897 fprintf(out, "HTTP/1.0 %d %s%s", code, reason.c_str(), CRLF) ;
00898 if (version == "") {
00899 fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
00900 fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
00901 }
00902 else {
00903 fprintf(out, "XDODS-Server: %s%s", version.c_str(), CRLF) ;
00904 fprintf(out, "XOPeNDAP-Server: %s%s", version.c_str(), CRLF) ;
00905 }
00906 fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
00907
00908 const time_t t = time(0);
00909 fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
00910 fprintf(out, "Cache-Control: no-cache%s", CRLF) ;
00911 fprintf(out, CRLF) ;
00912 }
00913 #endif
00914
00921 void
00922 set_mime_error(ostream &strm, int code, const string &reason,
00923 const string &version)
00924 {
00925 strm << "HTTP/1.0 " << code << " " << reason.c_str() << CRLF ;
00926 if (version == "") {
00927 strm << "XDODS-Server: " << DVR << CRLF ;
00928 strm << "XOPeNDAP-Server: " << DVR << CRLF ;
00929 }
00930 else {
00931 strm << "XDODS-Server: " << version.c_str() << CRLF ;
00932 strm << "XOPeNDAP-Server: " << version.c_str() << CRLF ;
00933 }
00934 strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
00935
00936 const time_t t = time(0);
00937 strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00938 strm << "Cache-Control: no-cache" << CRLF ;
00939 strm << CRLF ;
00940 }
00941
00942 #if FILE_METHODS
00943
00949 void
00950 set_mime_not_modified(FILE *out)
00951 {
00952 fprintf(out, "HTTP/1.0 304 NOT MODIFIED%s", CRLF) ;
00953 const time_t t = time(0);
00954 fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
00955 fprintf(out, CRLF) ;
00956 }
00957 #endif
00958
00965 void
00966 set_mime_not_modified(ostream &strm)
00967 {
00968 strm << "HTTP/1.0 304 NOT MODIFIED" << CRLF ;
00969 const time_t t = time(0);
00970 strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
00971 strm << CRLF ;
00972 }
00973
00982 bool
00983 found_override(string name, string &doc)
00984 {
00985 ifstream ifs((name + ".ovr").c_str());
00986 if (!ifs)
00987 return false;
00988
00989 char tmp[256];
00990 doc = "";
00991 while (!ifs.eof()) {
00992 ifs.getline(tmp, 255);
00993 strcat(tmp, "\n");
00994 doc += tmp;
00995 }
00996
00997 ifs.close();
00998 return true;
00999 }
01000
01009 bool
01010 remove_mime_header(FILE *in)
01011 {
01012 char tmp[256];
01013 while (!feof(in)) {
01014 char *s = fgets(tmp, 255, in);
01015 if (s && strncmp(s, CRLF, 2) == 0)
01016 return true;
01017 }
01018
01019 return false;
01020 }
01021
01022 }
01023