diff --git a/libdap2/env b/libdap2/env index a70e8e8f7..6c0f3852f 100644 --- a/libdap2/env +++ b/libdap2/env @@ -6,7 +6,7 @@ alias q0=;alias qq=;alias qv=;alias q=;alias qh=;alias qqh=;alias qall=;alias q #TOP="/home/dmh/mach/netcdf-c" TOP="/cygdrive/f/git/netcdf-c" -F="http://tiggeUser:tigge@thredds-test.ucar.edu/thredds/dodsC/restrict/testData.nc" +F="http://tiggeUser:tigge@thredds-test.ucar.edu/thredds/dodsC/restrict/testData.nc.dds" #CON='SPEED.SPEED' #VAR=SPEED diff --git a/libdispatch/ddispatch.c b/libdispatch/ddispatch.c index 484e230f4..64770f895 100644 --- a/libdispatch/ddispatch.c +++ b/libdispatch/ddispatch.c @@ -32,9 +32,6 @@ static struct NCPROTOCOLLIST { */ static const char* servers[] = { "http://remotetest.unidata.ucar.edu", -"http://thredds-test.unidata.ucar.edu", -"http://remotetest.ucar.edu", -"http://thredds-test.ucar.edu", NULL }; diff --git a/libdispatch/defcheck.c b/libdispatch/defcheck.c index 5facde137..7d2207597 100644 --- a/libdispatch/defcheck.c +++ b/libdispatch/defcheck.c @@ -4,7 +4,7 @@ #include #include -#define URL "http://thredds-test.ucar.edu/dts/test.02" +#define URL "http://remotetest.unidata.ucar.edu/dts/test.02" #define VAR "i32" #define ERRCODE 2 diff --git a/man4/guide.dox b/man4/guide.dox index 84b06dfd0..803e13d6b 100644 --- a/man4/guide.dox +++ b/man4/guide.dox @@ -1878,7 +1878,7 @@ In order to access an OPeNDAP data source through the netCDF API, the file name normally used is replaced with a URL with a specific format. The URL is composed of three parts. - URL - this is a standard form URL such as - http://thredds-test.ucar.edu/dts/test.01 + http://remotetest.unidata.ucar.edu/dts/test.01 - Constraints - these are suffixed to the URL and take the form “?\&\”. The meaning of the terms projection @@ -1907,15 +1907,15 @@ will return the DDS for the specified dataset, and the second URL will return the DAS for the specified dataset. \code - http://thredds-test.ucar.edu/dts/test.01.dds - http://thredds-test.ucar.edu/dts/test.01.das + http://remotetest.unidata.ucar.edu/dts/test.01.dds + http://remotetest.unidata.ucar.edu/dts/test.01.das \endcode Then by using the following ncdump command, it is possible to see the equivalent netCDF Classic translation. \code - ncdump -h http://thredds-test.ucar.edu/dts/test.01 + ncdump -h http://remotetest.unidata.ucar.edu/dts/test.01 \endcode The DDS output from the web server should look like this. @@ -1994,7 +1994,7 @@ using the client parameters mechanism . In this case, the parameter the following command \code - ncdump -h http://thredds-test.ucar.edu/dts/test.01.dds#show=dds + ncdump -h http://remotetest.unidata.ucar.edu/dts/test.01.dds#show=dds \endcode The ncdump -h command will then show both the translation and the diff --git a/man4/netcdf.texi b/man4/netcdf.texi index d95d6b2de..6e11b778e 100644 --- a/man4/netcdf.texi +++ b/man4/netcdf.texi @@ -3174,7 +3174,7 @@ URL with a specific format. The URL is composed of three parts. @enumerate @item URL - this is a standard form URL such as -http://thredds-test.ucar.edu/dts/test.01 +http://remotetest.unidata.ucar.edu/dts/test.01 @item Constraints - these are suffixed to the URL and take the form ``?&selections''. The meaning of the terms projection and selection is somewhat complicated; @@ -3209,13 +3209,13 @@ For example, if a web browser is given the following, the first URL will return the DDS for the specified dataset, and the second URL will return the DAS for the specified dataset. @example -http://thredds-test.ucar.edu/dts/test.01.dds -http://thredds-test.ucar.edu/dts/test.01.das +http://remotetest.unidata.ucar.edu/dts/test.01.dds +http://remotetest.unidata.ucar.edu/dts/test.01.das @end example Then by using the following ncdump command, it is possible to see the equivalent netCDF Classic translation. @example -ncdump -h http://thredds-test.ucar.edu/dts/test.01 +ncdump -h http://remotetest.unidata.ucar.edu/dts/test.01 @end example The DDS output from the web server should look like this. @@ -3291,7 +3291,7 @@ mechanism . In this case, the parameter ``show=dds'' can be prefixed to the URL and the data retrieved using the following command @example -ncdump -h http://thredds-test.ucar.edu/dts/test.01.dds#show=dds +ncdump -h http://remotetest.unidata.ucar.edu/dts/test.01.dds#show=dds @end example The ncdump -h command will then show both the translation and the original DDS. In the above example, the DDS would appear as the global @@ -4776,7 +4776,7 @@ ncdump -v omega -f fortran -n omega foo.nc > Z.cdl Examine the translated DDS for the DAP source from the specified URL. -ncdump -h http://thredds-test.ucar.edu/dts/test.01 +ncdump -h http://remotetest.unidata.ucar.edu/dts/test.01 @node nccopy, ncgen3, ncdump, NetCDF Utilities @section nccopy diff --git a/ncdap_test/t_auth.c b/ncdap_test/t_auth.c index afaa30fa2..e2ce29c5f 100644 --- a/ncdap_test/t_auth.c +++ b/ncdap_test/t_auth.c @@ -2,9 +2,12 @@ #include #include #include -#include +#include "netcdf.h" -#define BASICAUTHURL "http://tiggeUser:tigge@remotetest.unidata.ucar.edu/thredds/dodsC/restrict/testData.nc" +static char* URLS[] = { +"http://tiggeUser:tigge@remotetest.unidata.ucar.edu/thredds/dodsC/restrict/testData.nc", +NULL +}; static void CHECK(int e, const char* msg) @@ -18,12 +21,26 @@ CHECK(int e, const char* msg) int main() { - int ncid,retval; + int ncid,retval,pass; + char** url; printf("Testing: Http Basic Authorization\n"); - retval = nc_open(BASICAUTHURL, 0, &ncid); - CHECK(retval,"*** Fail: Http Basic Authorization"); - retval = nc_close(ncid); - printf("*** PASS: Http Basic Authorization\n"); - return 0; + pass = 0; + for(url=URLS;*url;url++) { + retval = nc_open(*url, 0, &ncid); + if(retval == NC_NOERR) { + printf("URL: %s\n",*url); + pass = 1; + break; + } + printf("fail: %s: %s\n", nc_strerror(retval),*url); + } + if(pass) { + retval = nc_close(ncid); + printf("*** PASS: Http Basic Authorization\n"); + return 0; + } else { + CHECK(retval,"*** Fail: Http Basic Authorization"); + return 1; + } } diff --git a/ncdap_test/tst_remote.sh b/ncdap_test/tst_remote.sh index 257e3a883..d34922a22 100755 --- a/ncdap_test/tst_remote.sh +++ b/ncdap_test/tst_remote.sh @@ -130,13 +130,6 @@ REMOTETESTSC3="\ argo_all.cdp;1;&location.LATITUDE<1&location.LATITUDE>-1\ " -# Test string access -# this test cannot be used because the -# dataset has a limited lifetime -#REMOTEURLC4="http://thredds-test.ucar.edu/thredds/dodsC/station/metar" -#REMOTETESTSC4="\ -#Surface_METAR_20120101_0000.nc;1;weather[0:10]" - # Constrained long tests REMOTEURLLC1="$DTS" REMOTETESTSLC1="\ diff --git a/oc2/oc.h b/oc2/oc.h index f2aadea9e..b8ed7edcc 100644 --- a/oc2/oc.h +++ b/oc2/oc.h @@ -127,6 +127,7 @@ OC_EINDEX=-26, OC_EBADTYPE=-27, OC_ESCALAR=-28, OC_EOVERRUN=-29, +OC_EAUTH=-30, } OCerror; /*!\def OCLOGNOTE diff --git a/oc2/occurlfunctions.c b/oc2/occurlfunctions.c index 44d03830e..0e4d1ee2a 100644 --- a/oc2/occurlfunctions.c +++ b/oc2/occurlfunctions.c @@ -6,6 +6,9 @@ #include "ocdebug.h" #include "ocrc.h" +#define OC_MAX_REDIRECTS 10L + + /* Condition on libcurl version */ /* Set up an alias as needed */ #ifndef HAVE_CURLOPT_KEYPASSWD @@ -103,8 +106,10 @@ Do not think this is correct /* Following are always set */ cstat = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); OCDBG1(1,"CURLOPT_FOLLOWLOCATION=%ld",1L); - cstat = curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10L); - OCDBG1(1,"CURLOPT_MAXREDIRS=%ld",10L); + cstat = curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, 1L); + OCDBG1(1,"CURLOPT_UNRESTRICTED_AUTH=%ld",1L); + cstat = curl_easy_setopt(curl, CURLOPT_MAXREDIRS, OC_MAX_REDIRECTS); + OCDBG1(1,"CURLOPT_MAXREDIRS=%ld",OC_MAX_REDIRECTS); #if 0 cstat = curl_setopt(curl,CURLOPT_RETURNTRANSFER, 1L); OCDBG1(1,"CURLOPT_RETURNTRANSFER=%ld",1L); diff --git a/oc2/ochttp.c b/oc2/ochttp.c index 781a46307..1a80d2b2e 100644 --- a/oc2/ochttp.c +++ b/oc2/ochttp.c @@ -23,7 +23,7 @@ struct Fetchdata { long ocfetchhttpcode(CURL* curl) { - long httpcode; + long httpcode = 200; CURLcode cstat = CURLE_OK; /* Extract the http code */ #ifdef HAVE_CURLINFO_RESPONSE_CODE @@ -90,17 +90,29 @@ fail: } int -ocfetchurl(CURL* curl, const char* url, OCbytes* buf, long* filetime) +ocfetchurl(CURL* curl, const char* url, OCbytes* buf, long* filetime, + struct OCcredentials* creds) { int stat = OC_NOERR; CURLcode cstat = CURLE_OK; size_t len; + long httpcode = 0; /* Set the URL */ cstat = curl_easy_setopt(curl, CURLOPT_URL, (void*)url); if (cstat != CURLE_OK) goto fail; + if(creds != NULL && creds->password != NULL && creds->username != NULL) { + /* Set user and password */ + cstat = curl_easy_setopt(curl, CURLOPT_USERNAME, creds->username); + if (cstat != CURLE_OK) + goto fail; + cstat = curl_easy_setopt(curl, CURLOPT_PASSWORD, creds->password); + if (cstat != CURLE_OK) + goto fail; + } + /* send all data to this function */ cstat = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); if (cstat != CURLE_OK) @@ -115,12 +127,15 @@ ocfetchurl(CURL* curl, const char* url, OCbytes* buf, long* filetime) cstat = curl_easy_setopt(curl, CURLOPT_FILETIME, (long)1); cstat = curl_easy_perform(curl); + if(cstat == CURLE_PARTIAL_FILE) { /* Log it but otherwise ignore */ oclog(OCLOGWARN, "curl error: %s; ignored", curl_easy_strerror(cstat)); cstat = CURLE_OK; } + httpcode = ocfetchhttpcode(curl); + if(cstat != CURLE_OK) goto fail; /* Get the last modified time */ @@ -140,7 +155,14 @@ ocfetchurl(CURL* curl, const char* url, OCbytes* buf, long* filetime) fail: oclog(OCLOGERR, "curl error: %s", curl_easy_strerror(cstat)); - return OCTHROW(OC_ECURL); + switch (httpcode) { + case 401: stat = OC_EAUTH; break; + case 404: stat = OC_ENOFILE; break; + case 500: stat = OC_EDAPSVC; break; + case 200: break; + default: stat = OC_ECURL; break; + } + return OCTHROW(stat); } static size_t @@ -312,7 +334,7 @@ ocping(const char* url) /* Try to get the file */ buf = ocbytesnew(); - stat = ocfetchurl(curl,url,buf,NULL); + stat = ocfetchurl(curl,url,buf,NULL,NULL); if(stat == OC_NOERR) { /* Don't trust curl to return an error when request gets 404 */ long http_code = 0; diff --git a/oc2/ochttp.h b/oc2/ochttp.h index 5b97db92e..707fae777 100644 --- a/oc2/ochttp.h +++ b/oc2/ochttp.h @@ -7,7 +7,7 @@ extern int curlopen(CURL** curlp); extern void curlclose(CURL*); -extern int ocfetchurl(CURL*, const char*, OCbytes*, long*); +extern int ocfetchurl(CURL*, const char*, OCbytes*, long*, struct OCcredentials*); extern int ocfetchurl_file(CURL*, const char*, FILE*, off_t*, long*); extern long ocfetchhttpcode(CURL* curl); diff --git a/oc2/ocread.c b/oc2/ocread.c index d200506b6..618a7a447 100644 --- a/oc2/ocread.c +++ b/oc2/ocread.c @@ -106,14 +106,13 @@ readpacket(OCstate* state, OCURI* url,OCbytes* packet,OCdxd dxd,long* lastmodifi int flags = 0; if(!fileprotocol) { flags |= OCURICONSTRAINTS; - flags |= OCURIUSERPWD; } flags |= OCURIENCODE; fetchurl = ocuribuild(url,NULL,suffix,flags); MEMCHECK(fetchurl,OC_ENOMEM); if(ocdebug > 0) {fprintf(stderr,"fetch url=%s\n",fetchurl); fflush(stderr);} - stat = ocfetchurl(curl,fetchurl,packet,lastmodified); + stat = ocfetchurl(curl,fetchurl,packet,lastmodified,&state->creds); if(stat) oc_curl_printerror(state); if(ocdebug > 0) diff --git a/oc2/ocutil.c b/oc2/ocutil.c index a685d0679..445410fa6 100644 --- a/oc2/ocutil.c +++ b/oc2/ocutil.c @@ -359,11 +359,11 @@ ocerrstring(int err) case OC_EDIMSIZE: return "OC_EDIMSIZE: Invalid dimension size"; case OC_EDAP: - return "OC_EDAP: DAP failure"; + return "OC_EDAP: unspecified DAP failure"; case OC_EXDR: return "OC_EXDR: XDR failure"; case OC_ECURL: - return "OC_ECURL: libcurl failure"; + return "OC_ECURL: unspecified libcurl failure"; case OC_EBADURL: return "OC_EBADURL: malformed url"; case OC_EBADVAR: @@ -398,6 +398,11 @@ ocerrstring(int err) /* String concatenation overrun */ case OC_EOVERRUN: return "OC_EOVERRUN: internal concatenation failed"; + + /* Authorization Error */ + case OC_EAUTH: + return "OC_EAUTH: authorization failure"; + default: break; } return "";