bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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
42using namespace std;
43using namespace gateway;
44using namespace bes;
45
46
47#define prolog std::string("GatewayContainer::").append(__func__).append("() - ")
48
59GatewayContainer::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
89GatewayContainer::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
100void 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;
108}
109
110BESContainer *
112 GatewayContainer *container = new GatewayContainer;
113 _duplicate(*container);
114 return container;
115}
116
117GatewayContainer::~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->retrieve_resource();
146 }
147 BESDEBUG( MODULE, prolog << "Located remote resource." << endl );
148
149
150 string local_name = d_remoteResource->get_filename();
151 BESDEBUG( MODULE, prolog << "Using local file: " << local_name << endl );
152
153 type = d_remoteResource->get_type();
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 " << local_name << endl);
158 BESDEBUG( MODULE, prolog << "Done accessing " << *this << endl);
159 BESDEBUG( MODULE, prolog << "END" << endl);
160
161 return local_name; // 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
190void 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->get_filename()
197 << endl;
198 } else {
199 strm << BESIndent::LMarg << "response not yet obtained" << endl;
200 }
201 BESIndent::UnIndent();
202}
void set_container_type(const std::string &type)
set the type of data that this container represents, such as cedar or netcdf.
void dump(std::ostream &strm) const override
dumps information about this object
std::string get_container_type() const
retrieve the type of data this container holds, such as cedar or netcdf.
void set_relative_name(const std::string &relative)
Set the relative name of the object in this container.
void _duplicate(BESContainer &copy_to)
duplicate this instance into the passed container
std::string get_real_name() const
retrieve the real name for this container, such as a file name.
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:660
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
Parse a URL into the protocol, host, path and query parts.
Definition url_impl.h:44