Blame unit-tests/HTTPConnectTest.cc

Packit a4aae4
// -*- mode: c++; c-basic-offset:4 -*-
Packit a4aae4
Packit a4aae4
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
Packit a4aae4
// Access Protocol.
Packit a4aae4
Packit a4aae4
// Copyright (c) 2002,2003,2013 OPeNDAP, Inc.
Packit a4aae4
// Author: James Gallagher <jgallagher@opendap.org>
Packit a4aae4
//
Packit a4aae4
// This library is free software; you can redistribute it and/or
Packit a4aae4
// modify it under the terms of the GNU Lesser General Public
Packit a4aae4
// License as published by the Free Software Foundation; either
Packit a4aae4
// version 2.1 of the License, or (at your option) any later version.
Packit a4aae4
//
Packit a4aae4
// This library is distributed in the hope that it will be useful,
Packit a4aae4
// but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a4aae4
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit a4aae4
// Lesser General Public License for more details.
Packit a4aae4
//
Packit a4aae4
// You should have received a copy of the GNU Lesser General Public
Packit a4aae4
// License along with this library; if not, write to the Free Software
Packit a4aae4
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit a4aae4
//
Packit a4aae4
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
Packit a4aae4
Packit a4aae4
#include <cppunit/TextTestRunner.h>
Packit a4aae4
#include <cppunit/extensions/TestFactoryRegistry.h>
Packit a4aae4
#include <cppunit/extensions/HelperMacros.h>
Packit a4aae4
Packit a4aae4
#include <cstring>
Packit a4aae4
#include <iterator>
Packit a4aae4
#include <string>
Packit a4aae4
#include <algorithm>
Packit a4aae4
#include <functional>
Packit a4aae4
Packit a4aae4
#include "GNURegex.h"
Packit a4aae4
#include "HTTPConnect.h"
Packit a4aae4
#include "RCReader.h"
Packit a4aae4
Packit a4aae4
#include "debug.h"
Packit a4aae4
Packit a4aae4
#include "test_config.h"
Packit a4aae4
Packit a4aae4
using namespace CppUnit;
Packit a4aae4
using namespace std;
Packit a4aae4
Packit a4aae4
#include"GetOpt.h"
Packit a4aae4
Packit a4aae4
static bool debug = false;
Packit a4aae4
Packit a4aae4
#undef DBG
Packit a4aae4
#define DBG(x) do { if (debug) (x); } while(false);
Packit a4aae4
Packit a4aae4
namespace libdap {
Packit a4aae4
Packit a4aae4
class HTTPConnectTest: public TestFixture {
Packit a4aae4
private:
Packit a4aae4
    HTTPConnect * http;
Packit a4aae4
    string localhost_url, localhost_pw_url, localhost_digest_pw_url;
Packit a4aae4
    string etag;
Packit a4aae4
    string lm;
Packit a4aae4
    string netcdf_das_url;
Packit a4aae4
Packit a4aae4
    // char env_data[128];
Packit a4aae4
Packit a4aae4
protected:
Packit a4aae4
    bool re_match(Regex & r, const char *s)
Packit a4aae4
    {
Packit a4aae4
        return r.match(s, strlen(s)) == (int) strlen(s);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    struct REMatch: public unary_function<const string &, bool> {
Packit a4aae4
        Regex &d_re;
Packit a4aae4
        REMatch(Regex &re) :
Packit a4aae4
            d_re(re)
Packit a4aae4
        {
Packit a4aae4
        }
Packit a4aae4
        ~REMatch()
Packit a4aae4
        {
Packit a4aae4
        }
Packit a4aae4
        bool operator()(const string &str)
Packit a4aae4
        {
Packit a4aae4
            const char *s = str.c_str();
Packit a4aae4
            return d_re.match(s, strlen(s)) == (int) strlen(s);
Packit a4aae4
        }
Packit a4aae4
    };
Packit a4aae4
Packit a4aae4
    // This is defined in HTTPConnect.cc but has to be defined here as well.
Packit a4aae4
    // Don't know why... jhrg
Packit a4aae4
    class HeaderMatch: public unary_function<const string &, bool> {
Packit a4aae4
        const string &d_header;
Packit a4aae4
    public:
Packit a4aae4
        HeaderMatch(const string &header) :
Packit a4aae4
            d_header(header)
Packit a4aae4
        {
Packit a4aae4
        }
Packit a4aae4
        bool operator()(const string &arg)
Packit a4aae4
        {
Packit a4aae4
            return arg.find(d_header) == 0;
Packit a4aae4
        }
Packit a4aae4
    };
Packit a4aae4
Packit a4aae4
public:
Packit a4aae4
    HTTPConnectTest()
Packit a4aae4
    {
Packit a4aae4
    }
Packit a4aae4
    ~HTTPConnectTest()
Packit a4aae4
    {
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void setUp()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << "Setting the DODS_CONF env var" << endl);
Packit a4aae4
        setenv("DODS_CONF", "cache-testsuite/dodsrc", 1);
Packit a4aae4
        http = new HTTPConnect(RCReader::instance());
Packit a4aae4
Packit a4aae4
        localhost_url = "http://test.opendap.org/test-304.html";
Packit a4aae4
Packit a4aae4
        // Two request header values that will generate a 304 response to the
Packit a4aae4
        // above URL. The values below much match the etag and last-modified
Packit a4aae4
        // time returned by the server. Run this test with DODS_DEBUG defined
Packit a4aae4
        // to see the values it's returning.
Packit a4aae4
        // On 10/13/14 we moved to a new httpd and the etag value changed.
Packit a4aae4
        // jhrg 10/14/14
Packit a4aae4
        etag = "\"181893-157-3fbcd139c2680\""; //"\"2a008e-157-3fbcd139c2680\""; //\"a10df-157-139c2680\""; // a10df-157-139c2680a
Packit a4aae4
        lm = "Wed, 13 Jul 2005 19:32:26 GMT";
Packit a4aae4
Packit a4aae4
        localhost_pw_url = "http://jimg:dods_test@test.opendap.org/basic/page.txt";
Packit a4aae4
        localhost_digest_pw_url = "http://jimg:dods_digest@test.opendap.org/digest/page.txt";
Packit a4aae4
        netcdf_das_url = "http://test.opendap.org/dap/data/nc/fnoc1.nc.das";
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void tearDown()
Packit a4aae4
    {
Packit a4aae4
        // normal code doesn't do this - it happens at exit() but not doing
Packit a4aae4
        // this here make valgrind think there are leaks.
Packit a4aae4
        http->d_http_cache->delete_instance();
Packit a4aae4
        delete http;
Packit a4aae4
        http = 0;
Packit a4aae4
        unsetenv("DODS_CONF");
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST_SUITE (HTTPConnectTest);
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST (read_url_test);
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST (fetch_url_test_1);
Packit a4aae4
    CPPUNIT_TEST (fetch_url_test_2);
Packit a4aae4
    CPPUNIT_TEST (fetch_url_test_3);
Packit a4aae4
    CPPUNIT_TEST (fetch_url_test_4);
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST (fetch_url_test_1_cpp);
Packit a4aae4
    CPPUNIT_TEST (fetch_url_test_2_cpp);
Packit a4aae4
    CPPUNIT_TEST (fetch_url_test_3_cpp);
Packit a4aae4
    CPPUNIT_TEST (fetch_url_test_4_cpp);
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST (get_response_headers_test);
Packit a4aae4
    CPPUNIT_TEST (server_version_test);
Packit a4aae4
    CPPUNIT_TEST (type_test);
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST (cache_test);
Packit a4aae4
    CPPUNIT_TEST (cache_test_cpp);
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST (set_accept_deflate_test);
Packit a4aae4
    CPPUNIT_TEST (set_xdap_protocol_test);
Packit a4aae4
    CPPUNIT_TEST (read_url_password_test);
Packit a4aae4
    CPPUNIT_TEST (read_url_password_test2);
Packit a4aae4
Packit a4aae4
    // CPPUNIT_TEST(read_url_password_proxy_test);
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST_SUITE_END();
Packit a4aae4
Packit a4aae4
    void read_url_test()
Packit a4aae4
    {
Packit a4aae4
        vector<string> *resp_h = new vector<string>;
Packit a4aae4
        ;
Packit a4aae4
Packit a4aae4
        try {
Packit a4aae4
            DBG(cerr << "Entering read_url_test... " << endl);
Packit a4aae4
Packit a4aae4
            FILE *dump = fopen("/dev/null", "w");
Packit a4aae4
            long status = http->read_url(localhost_url, dump, resp_h);
Packit a4aae4
            CPPUNIT_ASSERT(status == 200);
Packit a4aae4
Packit a4aae4
            vector<string> request_h;
Packit a4aae4
Packit a4aae4
            // First test using a time with if-modified-since
Packit a4aae4
            request_h.push_back(string("If-Modified-Since: ") + lm);
Packit a4aae4
            status = http->read_url(localhost_url, dump, resp_h, &request_h);
Packit a4aae4
            DBG(cerr << "If modified since test, status: " << status << endl);
Packit a4aae4
            DBG(copy(resp_h->begin(), resp_h->end(), ostream_iterator<string>(cerr, "\n")));
Packit a4aae4
            DBG(cerr << endl);
Packit a4aae4
            CPPUNIT_ASSERT(status == 304);
Packit a4aae4
Packit a4aae4
            // Now test an etag
Packit a4aae4
            resp_h->clear();
Packit a4aae4
            request_h.clear();
Packit a4aae4
            request_h.push_back(string("If-None-Match: ") + etag);
Packit a4aae4
            status = http->read_url(localhost_url, dump, resp_h, &request_h);
Packit a4aae4
            DBG(cerr << "If none match test, status: " << status << endl);
Packit a4aae4
            DBG(copy(resp_h->begin(), resp_h->end(), ostream_iterator<string>(cerr, "\n")));
Packit a4aae4
            DBG(cerr << endl);
Packit a4aae4
            CPPUNIT_ASSERT(status == 304);
Packit a4aae4
Packit a4aae4
            // now test a combined etag and time4
Packit a4aae4
            resp_h->clear();
Packit a4aae4
            request_h.clear();
Packit a4aae4
            request_h.push_back(string("If-None-Match: ") + etag);
Packit a4aae4
            request_h.push_back(string("If-Modified-Since: ") + lm);
Packit a4aae4
            status = http->read_url(localhost_url, dump, resp_h, &request_h);
Packit a4aae4
            DBG(cerr << "Combined test, status: " << status << endl);
Packit a4aae4
            DBG(copy(resp_h->begin(), resp_h->end(), ostream_iterator<string>(cerr, "\n")));
Packit a4aae4
            CPPUNIT_ASSERT(status == 304);
Packit a4aae4
Packit a4aae4
            delete resp_h;
Packit a4aae4
            resp_h = 0;
Packit a4aae4
Packit a4aae4
        }
Packit a4aae4
        catch (Error & e) {
Packit a4aae4
            delete resp_h;
Packit a4aae4
            resp_h = 0;
Packit a4aae4
            CPPUNIT_FAIL("Error: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void fetch_url_test_1()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << "Entering fetch_url_test 1" << endl);
Packit a4aae4
        HTTPResponse *stuff = 0;
Packit a4aae4
        char c;
Packit a4aae4
        try {
Packit a4aae4
            stuff = http->fetch_url(localhost_url);
Packit a4aae4
            CPPUNIT_ASSERT(
Packit a4aae4
                fread(&c, 1, 1, stuff->get_stream()) == 1 && !ferror(stuff->get_stream())
Packit a4aae4
                    && !feof(stuff->get_stream()));
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (Error & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        // Catch the exception from a failed ASSERT and clean up. Deleting a
Packit a4aae4
        // Response object also unlocks the HTTPCache in some cases. If delete
Packit a4aae4
        // is not called, then a failed test can leave the cache with locked
Packit a4aae4
        // entries
Packit a4aae4
        catch (...) {
Packit a4aae4
            cerr << "Caught unknown exception" << endl;
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void fetch_url_test_1_cpp()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << "Entering fetch_url_test 1" << endl);
Packit a4aae4
        HTTPResponse *stuff = 0;
Packit a4aae4
        http->set_use_cpp_streams(true);
Packit a4aae4
        char c;
Packit a4aae4
        try {
Packit a4aae4
            stuff = http->fetch_url(localhost_url);
Packit a4aae4
            stuff->get_cpp_stream()->read(&c, 1);
Packit a4aae4
            CPPUNIT_ASSERT(*(stuff->get_cpp_stream()));
Packit a4aae4
            CPPUNIT_ASSERT(!stuff->get_cpp_stream()->bad());
Packit a4aae4
            CPPUNIT_ASSERT(!stuff->get_cpp_stream()->eof());
Packit a4aae4
Packit a4aae4
            delete stuff;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr &e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (Error &e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (std::exception &e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            CPPUNIT_FAIL(string("Caught an std::exception from fetch_url: ") + e.what());
Packit a4aae4
        }
Packit a4aae4
        // Catch the exception from a failed ASSERT and clean up. Deleting a
Packit a4aae4
        // Response object also unlocks the HTTPCache in some cases. If delete
Packit a4aae4
        // is not called, then a failed test can leave the cache with locked
Packit a4aae4
        // entries
Packit a4aae4
        catch (...) {
Packit a4aae4
            cerr << "Caught unknown exception" << endl;
Packit a4aae4
            delete stuff;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void fetch_url_test_2()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << "Entering fetch_url_test 2" << endl);
Packit a4aae4
        HTTPResponse *stuff = 0;
Packit a4aae4
        char c;
Packit a4aae4
        try {
Packit a4aae4
            stuff = http->fetch_url(netcdf_das_url);
Packit a4aae4
            DBG2(char ln[1024]; while (!feof(stuff->get_stream())) {
Packit a4aae4
                    fgets(ln, 1024, stuff->get_stream()); cerr << ln;}
Packit a4aae4
                rewind(stuff->get_stream()));
Packit a4aae4
Packit a4aae4
            CPPUNIT_ASSERT(
Packit a4aae4
                fread(&c, 1, 1, stuff->get_stream()) == 1 && !ferror(stuff->get_stream())
Packit a4aae4
                    && !feof(stuff->get_stream()));
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (Error & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        // Catch the exception from a failed ASSERT and clean up. Deleting a
Packit a4aae4
        // Response object also unlocks the HTTPCache in some cases. If delete
Packit a4aae4
        // is not called, then a failed test can leave the cache with locked
Packit a4aae4
        // entries
Packit a4aae4
        catch (...) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void fetch_url_test_2_cpp()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << "Entering fetch_url_test 2" << endl);
Packit a4aae4
        http->set_use_cpp_streams(true);
Packit a4aae4
Packit a4aae4
        HTTPResponse *stuff = 0;
Packit a4aae4
        char c;
Packit a4aae4
Packit a4aae4
        try {
Packit a4aae4
            stuff = http->fetch_url(netcdf_das_url);
Packit a4aae4
Packit a4aae4
            stuff->get_cpp_stream()->read(&c, 1);
Packit a4aae4
            CPPUNIT_ASSERT(
Packit a4aae4
                *(stuff->get_cpp_stream()) && !stuff->get_cpp_stream()->bad() && !stuff->get_cpp_stream()->eof());
Packit a4aae4
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (Error & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        // Catch the exception from a failed ASSERT and clean up. Deleting a
Packit a4aae4
        // Response object also unlocks the HTTPCache in some cases. If delete
Packit a4aae4
        // is not called, then a failed test can leave the cache with locked
Packit a4aae4
        // entries
Packit a4aae4
        catch (...) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void fetch_url_test_3()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << "Entering fetch_url_test 3" << endl);
Packit a4aae4
        HTTPResponse *stuff = 0;
Packit a4aae4
        char c;
Packit a4aae4
        try {
Packit a4aae4
            stuff = http->fetch_url("file:///etc/passwd");
Packit a4aae4
            CPPUNIT_ASSERT(
Packit a4aae4
                fread(&c, 1, 1, stuff->get_stream()) == 1 && !ferror(stuff->get_stream())
Packit a4aae4
                    && !feof(stuff->get_stream()));
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr from fetch_url" + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (Error & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        // Catch the exception from a failed ASSERT and clean up. Deleting a
Packit a4aae4
        // Response object also unlocks the HTTPCache in some cases. If delete
Packit a4aae4
        // is not called, then a failed test can leave the cache with locked
Packit a4aae4
        // entries
Packit a4aae4
        catch (...) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void fetch_url_test_3_cpp()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << "Entering fetch_url_test 3" << endl);
Packit a4aae4
        http->set_use_cpp_streams(true);
Packit a4aae4
Packit a4aae4
        HTTPResponse *stuff = 0;
Packit a4aae4
        char c;
Packit a4aae4
        try {
Packit a4aae4
            stuff = http->fetch_url("file:///etc/passwd");
Packit a4aae4
Packit a4aae4
            stuff->get_cpp_stream()->read(&c, 1);
Packit a4aae4
            CPPUNIT_ASSERT(
Packit a4aae4
                *(stuff->get_cpp_stream()) && !stuff->get_cpp_stream()->bad() && !stuff->get_cpp_stream()->eof());
Packit a4aae4
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr from fetch_url" + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (Error & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        // Catch the exception from a failed ASSERT and clean up. Deleting a
Packit a4aae4
        // Response object also unlocks the HTTPCache in some cases. If delete
Packit a4aae4
        // is not called, then a failed test can leave the cache with locked
Packit a4aae4
        // entries
Packit a4aae4
        catch (...) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void fetch_url_test_4()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << "Entering fetch_url_test 4" << endl);
Packit a4aae4
        HTTPResponse *stuff = 0;
Packit a4aae4
        char c;
Packit a4aae4
        try {
Packit a4aae4
            string url = (string) "file://" + TEST_SRC_DIR + "/test_config.h";
Packit a4aae4
            stuff = http->fetch_url(url);
Packit a4aae4
            CPPUNIT_ASSERT(
Packit a4aae4
                fread(&c, 1, 1, stuff->get_stream()) == 1 && !ferror(stuff->get_stream())
Packit a4aae4
                    && !feof(stuff->get_stream()));
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr from fetch_url" + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (Error & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        // Catch the exception from a failed ASSERT and clean up. Deleting a
Packit a4aae4
        // Response object also unlocks the HTTPCache in some cases. If delete
Packit a4aae4
        // is not called, then a failed test can leave the cache with locked
Packit a4aae4
        // entries
Packit a4aae4
        catch (...) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void fetch_url_test_4_cpp()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << "Entering fetch_url_test 4" << endl);
Packit a4aae4
        http->set_use_cpp_streams(true);
Packit a4aae4
Packit a4aae4
        HTTPResponse *stuff = 0;
Packit a4aae4
        char c;
Packit a4aae4
        try {
Packit a4aae4
            string url = (string) "file://" + TEST_SRC_DIR + "/test_config.h";
Packit a4aae4
            stuff = http->fetch_url(url);
Packit a4aae4
Packit a4aae4
            stuff->get_cpp_stream()->read(&c, 1);
Packit a4aae4
            CPPUNIT_ASSERT(
Packit a4aae4
                *(stuff->get_cpp_stream()) && !stuff->get_cpp_stream()->bad() && !stuff->get_cpp_stream()->eof());
Packit a4aae4
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr from fetch_url" + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (Error & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        // Catch the exception from a failed ASSERT and clean up. Deleting a
Packit a4aae4
        // Response object also unlocks the HTTPCache in some cases. If delete
Packit a4aae4
        // is not called, then a failed test can leave the cache with locked
Packit a4aae4
        // entries
Packit a4aae4
        catch (...) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void get_response_headers_test()
Packit a4aae4
    {
Packit a4aae4
        HTTPResponse *r = 0;
Packit a4aae4
Packit a4aae4
        try {
Packit a4aae4
            r = http->fetch_url(netcdf_das_url);
Packit a4aae4
            vector<string> *h = r->get_headers();
Packit a4aae4
Packit a4aae4
            DBG(copy(h->begin(), h->end(), ostream_iterator<string>(cerr, "\n")));
Packit a4aae4
Packit a4aae4
            // Should get five or six headers back.
Packit a4aae4
            Regex header("X.*-Server: .*/.*");
Packit a4aae4
Packit a4aae4
            CPPUNIT_ASSERT(find_if(h->begin(), h->end(), REMatch(header)) != h->end());
Packit a4aae4
Packit a4aae4
            Regex protocol_header("X.*DAP: .*");	// Matches both XDAP and X-DAP
Packit a4aae4
            CPPUNIT_ASSERT(find_if(h->begin(), h->end(), REMatch(protocol_header)) != h->end());
Packit a4aae4
Packit a4aae4
            delete r;
Packit a4aae4
            r = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete r;
Packit a4aae4
            r = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr exception from get_response_headers: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (...) {
Packit a4aae4
            delete r;
Packit a4aae4
            r = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void server_version_test()
Packit a4aae4
    {
Packit a4aae4
        Response *r = 0;
Packit a4aae4
        Regex protocol("^[0-9]+\\.[0-9]+$");
Packit a4aae4
        try {
Packit a4aae4
            r = http->fetch_url(netcdf_das_url);
Packit a4aae4
Packit a4aae4
            DBG(cerr << "r->get_version().c_str(): " << r->get_protocol().c_str() << endl);
Packit a4aae4
Packit a4aae4
            CPPUNIT_ASSERT(re_match(protocol, r->get_protocol().c_str()));
Packit a4aae4
            delete r;
Packit a4aae4
            r = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete r;
Packit a4aae4
            r = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr exception from server_version: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
        catch (...) {
Packit a4aae4
            delete r;
Packit a4aae4
            r = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void type_test()
Packit a4aae4
    {
Packit a4aae4
        Response *r = 0;
Packit a4aae4
        try {
Packit a4aae4
            r = http->fetch_url(netcdf_das_url);
Packit a4aae4
            DBG(cerr << "r->get_type(): " << r->get_type() << endl);
Packit a4aae4
            CPPUNIT_ASSERT(r->get_type() == dods_das);
Packit a4aae4
            delete r;
Packit a4aae4
            r = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete r;
Packit a4aae4
            r = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErr exception from type(): " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void set_credentials_test()
Packit a4aae4
    {
Packit a4aae4
        http->set_credentials("jimg", "was_quit");
Packit a4aae4
        Response *stuff = http->fetch_url("http://localhost/secret");
Packit a4aae4
Packit a4aae4
        try {
Packit a4aae4
            char c;
Packit a4aae4
            CPPUNIT_ASSERT(
Packit a4aae4
                fread(&c, 1, 1, stuff->get_stream()) == 1 && !ferror(stuff->get_stream())
Packit a4aae4
                    && !feof(stuff->get_stream()));
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (InternalErr & e) {
Packit a4aae4
            delete stuff;
Packit a4aae4
            stuff = 0;
Packit a4aae4
            CPPUNIT_FAIL("Caught an InternalErrexception from output: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void cache_test()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << endl << "Entering Caching tests." << endl);
Packit a4aae4
        try {
Packit a4aae4
            // The cache-testsuite/dodsrc file turns this off; all the other
Packit a4aae4
            // params are set up. It used to be that HTTPConnect had an option to
Packit a4aae4
            // turn caching on, but that no longer is present. This hack enables
Packit a4aae4
            // caching for this test. 06/18/04 jhrg
Packit a4aae4
            http->d_http_cache = HTTPCache::instance(http->d_rcr->get_dods_cache_root(), true);
Packit a4aae4
            DBG(cerr << "Instantiate the cache" << endl);
Packit a4aae4
Packit a4aae4
            CPPUNIT_ASSERT(http->d_http_cache != 0);
Packit a4aae4
            http->d_http_cache->set_cache_enabled(true);
Packit a4aae4
            DBG(cerr << "Enable the cache" << endl);
Packit a4aae4
Packit a4aae4
            fetch_url_test_4();
Packit a4aae4
            DBG(cerr << "fetch_url_test" << endl);
Packit a4aae4
            get_response_headers_test();
Packit a4aae4
            DBG(cerr << "get_response_headers_test" << endl);
Packit a4aae4
            server_version_test();
Packit a4aae4
            DBG(cerr << "server_version_test" << endl);
Packit a4aae4
            type_test();
Packit a4aae4
            DBG(cerr << "type_test" << endl);
Packit a4aae4
        }
Packit a4aae4
        catch (Error &e) {
Packit a4aae4
            CPPUNIT_FAIL((string) "Error: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void cache_test_cpp()
Packit a4aae4
    {
Packit a4aae4
        DBG(cerr << endl << "Entering Caching tests." << endl);
Packit a4aae4
        try {
Packit a4aae4
            // The cache-testsuite/dodsrc file turns this off; all the other
Packit a4aae4
            // params are set up. It used to be that HTTPConnect had an option to
Packit a4aae4
            // turn caching on, but that no longer is present. This hack enables
Packit a4aae4
            // caching for this test. 06/18/04 jhrg
Packit a4aae4
            http->d_http_cache = HTTPCache::instance(http->d_rcr->get_dods_cache_root(), true);
Packit a4aae4
            DBG(cerr << "Instantiate the cache" << endl);
Packit a4aae4
Packit a4aae4
            CPPUNIT_ASSERT(http->d_http_cache != 0);
Packit a4aae4
            http->d_http_cache->set_cache_enabled(true);
Packit a4aae4
            DBG(cerr << "Enable the cache" << endl);
Packit a4aae4
Packit a4aae4
            fetch_url_test_4_cpp();
Packit a4aae4
            DBG(cerr << "fetch_url_test_4_cpp" << endl);
Packit a4aae4
Packit a4aae4
            get_response_headers_test();
Packit a4aae4
            DBG(cerr << "get_response_headers_test" << endl);
Packit a4aae4
Packit a4aae4
            server_version_test();
Packit a4aae4
            DBG(cerr << "server_version_test" << endl);
Packit a4aae4
Packit a4aae4
            type_test();
Packit a4aae4
            DBG(cerr << "type_test" << endl);
Packit a4aae4
        }
Packit a4aae4
        catch (Error &e) {
Packit a4aae4
            CPPUNIT_FAIL((string) "Error: " + e.get_error_message());
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void set_accept_deflate_test()
Packit a4aae4
    {
Packit a4aae4
        http->set_accept_deflate(false);
Packit a4aae4
        CPPUNIT_ASSERT(
Packit a4aae4
            count(http->d_request_headers.begin(), http->d_request_headers.end(),
Packit a4aae4
                "Accept-Encoding: deflate, gzip, compress") == 0);
Packit a4aae4
Packit a4aae4
        http->set_accept_deflate(true);
Packit a4aae4
        CPPUNIT_ASSERT(
Packit a4aae4
            count(http->d_request_headers.begin(), http->d_request_headers.end(),
Packit a4aae4
                "Accept-Encoding: deflate, gzip, compress") == 1);
Packit a4aae4
Packit a4aae4
        http->set_accept_deflate(true);
Packit a4aae4
        CPPUNIT_ASSERT(
Packit a4aae4
            count(http->d_request_headers.begin(), http->d_request_headers.end(),
Packit a4aae4
                "Accept-Encoding: deflate, gzip, compress") == 1);
Packit a4aae4
Packit a4aae4
        http->set_accept_deflate(false);
Packit a4aae4
        CPPUNIT_ASSERT(
Packit a4aae4
            count(http->d_request_headers.begin(), http->d_request_headers.end(),
Packit a4aae4
                "Accept-Encoding: deflate, gzip, compress") == 0);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void set_xdap_protocol_test()
Packit a4aae4
    {
Packit a4aae4
        // Initially there should be no header and the protocol should be 2.0
Packit a4aae4
        CPPUNIT_ASSERT(http->d_dap_client_protocol_major == 2 && http->d_dap_client_protocol_minor == 0);
Packit a4aae4
Packit a4aae4
        CPPUNIT_ASSERT(
Packit a4aae4
            count_if(http->d_request_headers.begin(), http->d_request_headers.end(), HeaderMatch("XDAP-Accept:")) == 0);
Packit a4aae4
Packit a4aae4
        http->set_xdap_protocol(8, 9);
Packit a4aae4
        CPPUNIT_ASSERT(http->d_dap_client_protocol_major == 8 && http->d_dap_client_protocol_minor == 9);
Packit a4aae4
        CPPUNIT_ASSERT(count(http->d_request_headers.begin(), http->d_request_headers.end(), "XDAP-Accept: 8.9") == 1);
Packit a4aae4
Packit a4aae4
        http->set_xdap_protocol(3, 2);
Packit a4aae4
        CPPUNIT_ASSERT(http->d_dap_client_protocol_major == 3 && http->d_dap_client_protocol_minor == 2);
Packit a4aae4
        CPPUNIT_ASSERT(count(http->d_request_headers.begin(), http->d_request_headers.end(), "XDAP-Accept: 3.2") == 1);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void read_url_password_test()
Packit a4aae4
    {
Packit a4aae4
        FILE *dump = fopen("/dev/null", "w");
Packit a4aae4
        vector<string> *resp_h = new vector<string>;
Packit a4aae4
        long status = http->read_url(localhost_pw_url, dump, resp_h);
Packit a4aae4
Packit a4aae4
        DBG(cerr << endl << http->d_upstring << endl);
Packit a4aae4
        CPPUNIT_ASSERT(http->d_upstring == "jimg:dods_test");
Packit a4aae4
        DBG(cerr << "Status: " << status << endl);
Packit a4aae4
        CPPUNIT_ASSERT(status == 200);
Packit a4aae4
        delete resp_h;
Packit a4aae4
        resp_h = 0;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void read_url_password_test2()
Packit a4aae4
    {
Packit a4aae4
        FILE *dump = fopen("/dev/null", "w");
Packit a4aae4
        vector<string> *resp_h = new vector<string>;
Packit a4aae4
        long status = http->read_url(localhost_digest_pw_url, dump, resp_h);
Packit a4aae4
Packit a4aae4
        DBG(cerr << endl << http->d_upstring << endl);
Packit a4aae4
        CPPUNIT_ASSERT(http->d_upstring == "jimg:dods_digest");
Packit a4aae4
        DBG(cerr << "Status: " << status << endl);
Packit a4aae4
        CPPUNIT_ASSERT(status == 200);
Packit a4aae4
        delete resp_h;
Packit a4aae4
        resp_h = 0;
Packit a4aae4
    }
Packit a4aae4
};
Packit a4aae4
Packit a4aae4
CPPUNIT_TEST_SUITE_REGISTRATION (HTTPConnectTest);
Packit a4aae4
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
int main(int argc, char*argv[])
Packit a4aae4
{
Packit a4aae4
    GetOpt getopt(argc, argv, "dh");
Packit a4aae4
    int option_char;
Packit a4aae4
Packit a4aae4
    while ((option_char = getopt()) != -1)
Packit a4aae4
        switch (option_char) {
Packit a4aae4
        case 'd':
Packit a4aae4
            debug = 1;  // debug is a static global
Packit a4aae4
            break;
Packit a4aae4
        case 'h': {     // help - show test names
Packit a4aae4
            cerr << "Usage: HTTPConnectTest has the following tests:" << endl;
Packit a4aae4
            const std::vector<Test*> &tests = libdap::HTTPConnectTest::suite()->getTests();
Packit a4aae4
            unsigned int prefix_len = libdap::HTTPConnectTest::suite()->getName().append("::").length();
Packit a4aae4
            for (std::vector<Test*>::const_iterator i = tests.begin(), e = tests.end(); i != e; ++i) {
Packit a4aae4
                cerr << (*i)->getName().replace(0, prefix_len, "") << endl;
Packit a4aae4
            }
Packit a4aae4
            break;
Packit a4aae4
        }
Packit a4aae4
        default:
Packit a4aae4
            break;
Packit a4aae4
        }
Packit a4aae4
Packit a4aae4
    CppUnit::TextTestRunner runner;
Packit a4aae4
    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
Packit a4aae4
Packit a4aae4
    bool wasSuccessful = true;
Packit a4aae4
    string test = "";
Packit a4aae4
    int i = getopt.optind;
Packit a4aae4
    if (i == argc) {
Packit a4aae4
        // run them all
Packit a4aae4
        wasSuccessful = runner.run("");
Packit a4aae4
    }
Packit a4aae4
    else {
Packit a4aae4
        for (; i < argc; ++i) {
Packit a4aae4
            if (debug) cerr << "Running " << argv[i] << endl;
Packit a4aae4
            test = libdap::HTTPConnectTest::suite()->getName().append("::").append(argv[i]);
Packit a4aae4
            wasSuccessful = wasSuccessful && runner.run(test);
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    return wasSuccessful ? 0 : 1;
Packit a4aae4
}