libdap  Updated for version 3.17.0
HTTPResponse.h
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2002,2003 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Lesser General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2.1 of the License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 #ifndef http_response_h
00027 #define http_response_h
00028 
00029 #include <unistd.h>
00030 
00031 #include <cstdio>
00032 
00033 #include <string>
00034 #include <iostream>
00035 #include <algorithm>
00036 #include <iterator>
00037 #include <vector>
00038 
00039 #include "Response.h"
00040 #include "util.h"
00041 #include "debug.h"
00042 
00043 namespace libdap
00044 {
00045 
00046 // defined in HTTPConnect.cc
00047 extern int dods_keep_temps;
00048 extern void close_temp(FILE *s, const string &name);
00049 
00056 class HTTPResponse : public Response
00057 {
00058 private:
00059     std::vector<std::string> *d_headers; // Response headers
00060     std::string d_file;  // Temp file that holds response body
00061 
00062 protected:
00065     HTTPResponse();
00066     HTTPResponse(const HTTPResponse &rs);
00067     HTTPResponse &operator=(const HTTPResponse &);
00069 
00070 public:
00087     HTTPResponse(FILE *s, int status, std::vector<std::string> *h, const std::string &temp_file)
00088             : Response(s, status), d_headers(h), d_file(temp_file)
00089     {
00090         DBG(cerr << "Headers: " << endl);
00091         DBGN(copy(d_headers->begin(), d_headers->end(),
00092                   ostream_iterator<string>(cerr, "\n")));
00093         DBGN(cerr << "end of headers." << endl);
00094     }
00095 
00105     HTTPResponse(std::fstream *s, int status, std::vector<std::string> *h, const std::string &temp_file)
00106             : Response(s, status), d_headers(h), d_file(temp_file)
00107     {
00108         DBG(cerr << "Headers: " << endl);
00109         DBGN(copy(d_headers->begin(), d_headers->end(),
00110                   ostream_iterator<string>(cerr, "\n")));
00111         DBGN(cerr << "end of headers." << endl);
00112     }
00113 
00117     virtual ~HTTPResponse()
00118     {
00119         DBG(cerr << "Freeing HTTPConnect resources (" + d_file + ")... ");
00120 
00121         // This can always be done - if the cpp_stream is null, delete has no effect;
00122         // if non-null in this class it was allocated in HTTPConnect::plain_fetch_url
00123         // (or caching_fetch_url when that's implemented)
00124                 delete get_cpp_stream();
00125                 set_cpp_stream(0);
00126 
00127         if (!dods_keep_temps && !d_file.empty()) {
00128                         if (get_stream()) {
00129                                 close_temp(get_stream(), d_file);
00130                                 set_stream(0);
00131                         }
00132                         else {
00133                                 long res = unlink(d_file.c_str());
00134                                 if (res != 0) throw InternalErr(__FILE__, __LINE__, "!FAIL! " + long_to_string(res));
00135                         }
00136         }
00137 
00138         delete d_headers;
00139 
00140         DBGN(cerr << endl);
00141     }
00142 
00148     void transform_to_cpp() {
00149         // ~Response() will take care of closing the FILE*. A better version of this
00150         // code would not leave the FILE* open when it's not needed, but this implementation
00151         // can use the existing HTTPConnect and HTTPCache software with very minimal
00152         // (or no) modification. jhrg 11/8/13
00153         set_cpp_stream(new std::fstream(d_file.c_str(), std::ios::in|std::ios::binary));
00154     }
00155 
00158     virtual std::vector<std::string> *get_headers() const { return d_headers; }
00159     virtual std::string get_file() const { return d_file; }
00161 
00164     virtual void set_headers(std::vector<std::string> *h) { d_headers = h; }
00165     virtual void set_file(const std::string &n) { d_file = n; }
00167 };
00168 
00169 } // namespace libdap
00170 
00171 #endif // http_response_h