bes  Updated for version 3.20.10
GatewayContainer.cc
1 // GatewayContainer.cc
2 
3 // -*- mode: c++; c-basic-offset:4 -*-
4 
5 // This file is part of gateway_module, A C++ module that can be loaded in to
6 // the OPeNDAP Back-End Server (BES) and is able to handle remote requests.
7 
8 // Copyright (c) 2002,2003 OPeNDAP, Inc.
9 // Author: Patrick West <pwest@ucar.edu>
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
26 
27 // Authors:
28 // pcw Patrick West <pwest@ucar.edu>
29 
30 #include <memory>
31 
32 #include "BESSyntaxUserError.h"
33 #include "BESInternalError.h"
34 #include "BESDebug.h"
35 #include "BESUtil.h"
36 #include "AllowedHosts.h"
37 
38 #include "GatewayContainer.h"
39 #include "GatewayNames.h"
40 #include "RemoteResource.h"
41 
42 using namespace std;
43 using namespace gateway;
44 using namespace bes;
45 
46 
47 #define prolog std::string("GatewayContainer::").append(__func__).append("() - ")
48 
59 GatewayContainer::GatewayContainer(const string &sym_name,
60  const string &real_name, const string &type) :
61  BESContainer(sym_name, real_name, type), d_remoteResource(0) {
62 
63  if (type.empty())
64  set_container_type(GATEWAY_CONTAINER_TYPE);
65 
66  BESUtil::url url_parts;
67  BESUtil::url_explode(real_name, url_parts);
68  url_parts.uname = "";
69  url_parts.psswd = "";
70  string url_string = BESUtil::url_create(url_parts);
71 
72  std::shared_ptr<http::url> target_url(new http::url(url_string));
73 
74  if (!http::AllowedHosts::theHosts()->is_allowed(target_url)) {
75  string err = (string) "The specified URL " + real_name
76  + " does not match any of the accessible services in"
77  + " the allowed hosts list.";
78  throw BESSyntaxUserError(err, __FILE__, __LINE__);
79  }
80 
81  // Because we know the name is really a URL, then we know the "relative_name" is meaningless
82  // So we set it to be the same as "name"
83  set_relative_name(real_name);
84 }
85 
89 GatewayContainer::GatewayContainer(const GatewayContainer &copy_from) :
90  BESContainer(copy_from), d_remoteResource(copy_from.d_remoteResource) {
91  // we can not make a copy of this container once the request has
92  // been made
93  if (d_remoteResource) {
94  string err = (string) "The Container has already been accessed, "
95  + "can not create a copy of this container.";
96  throw BESInternalError(err, __FILE__, __LINE__);
97  }
98 }
99 
100 void GatewayContainer::_duplicate(GatewayContainer &copy_to) {
101  if (copy_to.d_remoteResource) {
102  string err = (string) "The Container has already been accessed, "
103  + "can not duplicate this resource.";
104  throw BESInternalError(err, __FILE__, __LINE__);
105  }
106  copy_to.d_remoteResource = d_remoteResource;
107  BESContainer::_duplicate(copy_to);
108 }
109 
110 BESContainer *
112  GatewayContainer *container = new GatewayContainer;
113  _duplicate(*container);
114  return container;
115 }
116 
117 GatewayContainer::~GatewayContainer() {
118  if (d_remoteResource) {
119  release();
120  }
121 }
122 
129 
130  BESDEBUG( MODULE, prolog << "BEGIN" << endl);
131 
132  // Since this the Gateway we know that the real_name is a URL.
133  string url = get_real_name();
134 
135  BESDEBUG( MODULE, prolog << "Accessing " << url << endl);
136 
137  string type = get_container_type();
138  if (type == GATEWAY_CONTAINER_TYPE)
139  type = "";
140 
141  if(!d_remoteResource) {
142  BESDEBUG( MODULE, prolog << "Building new RemoteResource." << endl );
143  std::shared_ptr<http::url> url_ptr(new http::url(url));
144  d_remoteResource = new http::RemoteResource(url_ptr);
145  d_remoteResource->retrieveResource();
146  }
147  BESDEBUG( MODULE, prolog << "Located remote resource." << endl );
148 
149 
150  string cachedResource = d_remoteResource->getCacheFileName();
151  BESDEBUG( MODULE, prolog << "Using local cache file: " << cachedResource << endl );
152 
153  type = d_remoteResource->getType();
154  set_container_type(type);
155  BESDEBUG( MODULE, prolog << "Type: " << type << endl );
156 
157  BESDEBUG( MODULE, prolog << "Done accessing " << get_real_name() << " returning cached file " << cachedResource << endl);
158  BESDEBUG( MODULE, prolog << "Done accessing " << *this << endl);
159  BESDEBUG( MODULE, prolog << "END" << endl);
160 
161  return cachedResource; // this should return the file name from the GatewayCache
162 }
163 
164 
165 
173  BESDEBUG( MODULE, prolog << "BEGIN" << endl);
174  if (d_remoteResource) {
175  BESDEBUG( MODULE, prolog << "Releasing RemoteResource" << endl);
176  delete d_remoteResource;
177  d_remoteResource = 0;
178  }
179  BESDEBUG( MODULE, prolog << "END" << endl);
180  return true;
181 }
182 
190 void GatewayContainer::dump(ostream &strm) const {
191  strm << BESIndent::LMarg << "GatewayContainer::dump - (" << (void *) this
192  << ")" << endl;
193  BESIndent::Indent();
194  BESContainer::dump(strm);
195  if (d_remoteResource) {
196  strm << BESIndent::LMarg << "RemoteResource.getCacheFileName(): " << d_remoteResource->getCacheFileName()
197  << endl;
198  strm << BESIndent::LMarg << "response headers: ";
199  vector<string> *hdrs = d_remoteResource->getResponseHeaders();
200  if (hdrs) {
201  strm << endl;
202  BESIndent::Indent();
203  vector<string>::const_iterator i = hdrs->begin();
204  vector<string>::const_iterator e = hdrs->end();
205  for (; i != e; i++) {
206  string hdr_line = (*i);
207  strm << BESIndent::LMarg << hdr_line << endl;
208  }
209  BESIndent::UnIndent();
210  } else {
211  strm << "none" << endl;
212  }
213  } else {
214  strm << BESIndent::LMarg << "response not yet obtained" << endl;
215  }
216  BESIndent::UnIndent();
217 }
A container is something that holds data. E.G., a netcdf file or a database entry.
Definition: BESContainer.h:65
void set_container_type(const std::string &type)
set the type of data that this container represents, such as cedar or netcdf.
Definition: BESContainer.h:161
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESContainer.cc:73
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
Definition: BESContainer.h:232
void set_relative_name(const std::string &relative)
Set the relative name of the object in this container.
Definition: BESContainer.h:152
void _duplicate(BESContainer &copy_to)
duplicate this instance into the passed container
Definition: BESContainer.cc:54
std::string get_real_name() const
retrieve the real name for this container, such as a file name.
Definition: BESContainer.h:180
exception thrown if internal error encountered
error thrown if there is a user syntax error in the request or any other user error
static void url_explode(const std::string &url_str, BESUtil::url &url_parts)
Given a url, break the url into its different parts.
Definition: BESUtil.cc:697
Container representing a remote request.
virtual std::string access()
access the remote target response by making the remote request
virtual bool release()
release the resources
virtual BESContainer * ptr_duplicate()
pure abstract method to duplicate this instances of BESContainer
virtual void dump(std::ostream &strm) const
dumps information about this object
static AllowedHosts * theHosts()
Static accessor for the singleton.
Definition: AllowedHosts.cc:69
std::string getCacheFileName()
std::vector< std::string > * getResponseHeaders()
std::string getType()