Add support to detect authorization errors to DAP

This commit is contained in:
dmh 2014-03-11 11:58:22 -06:00
parent f3f7a9814b
commit c7086dd04b
11 changed files with 94 additions and 25 deletions

View File

@ -523,20 +523,34 @@ AM_PROG_CC_C_O
AC_C_CONST
# CURLOPT_KEYPASSWD is not defined until curl version 7.16.4
# CURLOPT_RESPONSE_CODE is not defined until curl version 7.10.7
# Save/restore CFLAGS
SAVECFLAGS="$CFLAGS"
CFLAGS="${curl_cflags}"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[#include "curl/curl.h"],
[[int x = CURLOPT_KEYPASSWD;]])],
[havekeypassword=yes],
[havekeypassword=no])
AC_MSG_CHECKING([whether a CURLOPT_KEYPASSWD is defined])
AC_MSG_CHECKING([whether CURLOPT_KEYPASSWD is defined])
AC_MSG_RESULT([${havekeypassword}])
if test $havekeypassword = yes; then
AC_DEFINE([HAVE_CURLOPT_KEYPASSWD],[1],[Is CURLOPT_KEYPASSWD defined])
fi
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[#include "curl/curl.h"],
[[int x = CURLOPT_RESPONSE_CODE;]])],
[haveresponsecode=yes],
[haveresponsecode=no])
AC_MSG_CHECKING([whether CURLOPT_RESPONSE_CODE is defined])
AC_MSG_RESULT([${haveresponsecode}])
if test $haveresponsecode = yes; then
AC_DEFINE([HAVE_CURLOPT_RESPONSE_CODE],[1],[Is CURLOPT_RESPONSE_CODE defined])
fi
CFLAGS="$SAVECFLAGS"
# Set up libtool.

View File

@ -368,9 +368,12 @@ by the desired type. */
#define NC_EDAPURL (-74) /**< Malformed DAP URL */
#define NC_EDAPCONSTRAINT (-75) /**< Malformed DAP Constraint*/
#define NC_ETRANSLATION (-76) /**< Untranslatable construct */
#define NC_EACCESS (-77) /**< Access Failure */
#define NC_EAUTH (-78) /**< Authorization Failure */
/* Misc. additional errors */
#define NC_ECANTREMOVE (-77) /**< Can't remove file */
#define NC_ENOTFOUND (-90) /**< No such file */
#define NC_ECANTREMOVE (-91) /**< Can't remove file */
/* The following was added in support of netcdf-4. Make all netcdf-4
error codes < -100 so that errors can be added to netcdf-3 if

View File

@ -218,9 +218,9 @@ buildcachenode34(NCDAPCOMMON* nccomm,
if((flags & NCF_PREFETCH_ALL) == 0)
ce = buildconstraintstring3(constraint);
ocstat = dap_fetch(nccomm,conn,ce,OCDATADDS,&ocroot);
ncstat = dap_fetch(nccomm,conn,ce,OCDATADDS,&ocroot);
nullfree(ce);
if(ocstat) {THROWCHK(ocerrtoncerr(ocstat)); goto done;}
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto done;}
ncstat = buildcdftree34(nccomm,ocroot,OCDATA,&dxdroot);
if(ncstat) {THROWCHK(ncstat); goto done;}

View File

@ -697,13 +697,15 @@ deltatime()
#endif
/* Provide a wrapper for oc_fetch so we can log what it does */
OCerror
NCerror
dap_fetch(NCDAPCOMMON* nccomm, OClink conn, const char* ce,
OCdxd dxd, OCddsnode* rootp)
{
OCerror ocstat;
char* ext;
NCerror ncstat = NC_NOERR;
OCerror ocstat = OC_NOERR;
char* ext = NULL;
OCflags flags = 0;
int httpcode = 0;
if(dxd == OCDDS) ext = ".dds";
else if(dxd == OCDAS) ext = ".das";
@ -747,7 +749,21 @@ dap_fetch(NCDAPCOMMON* nccomm, OClink conn, const char* ce,
fprintf(stderr,"fetch: dds:\n");
oc_dumpnode(conn,*rootp);
#endif
return ocstat;
/* Look at the HTTP return code */
httpcode = oc_httpcode(conn);
if(httpcode < 400) {
ncstat = ocerrtoncerr(ocstat);
} else if(httpcode >= 500) {
ncstat = NC_EDAPSVC;
} else if(httpcode == 401) {
ncstat = NC_EAUTH;
} else if(httpcode == 404) {
ncstat = NC_ENOTFOUND;
} else {
ncstat = NC_EACCESS;
}
return ncstat;
}
/* Check a name to see if it contains illegal dap characters

View File

@ -79,7 +79,7 @@ extern int nc__testurl(const char* parth, char** basename);
/* Provide a wrapper for oc_fetch so we can log what it does */
extern OCerror dap_fetch(struct NCDAPCOMMON*,OClink,const char*,OCdxd,OCobject*);
extern NCerror dap_fetch(struct NCDAPCOMMON*,OClink,const char*,OCdxd,OCobject*);
extern int dap_badname(char* name);
extern char* dap_repairname(char* name);

View File

@ -223,10 +223,10 @@ fprintf(stderr,"seqcountconstraints: %s\n",ncbytescontents(seqcountconstraints))
/* Fetch the minimal data */
if(FLAGSET(dapcomm->controls,NCF_UNCONSTRAINABLE))
ocstat = dap_fetch(dapcomm,conn,NULL,OCDATADDS,&ocroot);
ncstat = dap_fetch(dapcomm,conn,NULL,OCDATADDS,&ocroot);
else
ocstat = dap_fetch(dapcomm,conn,ncbytescontents(seqcountconstraints),OCDATADDS,&ocroot);
if(ocstat) goto fail;
ncstat = dap_fetch(dapcomm,conn,ncbytescontents(seqcountconstraints),OCDATADDS,&ocroot);
if(ncstat) goto fail;
ncstat = buildcdftree34(dapcomm,ocroot,OCDATA,&dxdroot);
if(ncstat) goto fail;
@ -614,8 +614,8 @@ fetchtemplatemetadata3(NCDAPCOMMON* dapcomm)
ce = nulldup(dapcomm->oc.url->selection);
/* Get selection constrained DDS */
ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDDS,&ocroot);
if(ocstat != OC_NOERR) {
ncstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDDS,&ocroot);
if(ncstat != NC_NOERR) {
/* Special Hack. If the protocol is file, then see if
we can get the dds from the .dods file
*/
@ -623,21 +623,21 @@ fetchtemplatemetadata3(NCDAPCOMMON* dapcomm)
THROWCHK(ocstat); goto done;
}
/* Fetch the data dds */
ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDATADDS,&ocroot);
if(ocstat != OC_NOERR) {
THROWCHK(ocstat); goto done;
ncstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDATADDS,&ocroot);
if(ncstat != NC_NOERR) {
THROWCHK(ncstat); goto done;
}
/* Note what we did */
nclog(NCLOGWARN,"Cannot locate .dds file, using .dods file");
}
/* Get selection constrained DAS */
ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDAS,&dapcomm->oc.ocdasroot);
if(ocstat != OC_NOERR) {
ncstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDAS,&dapcomm->oc.ocdasroot);
if(ncstat != NC_NOERR) {
/* Ignore but complain */
nclog(NCLOGWARN,"Could not read DAS; ignored");
dapcomm->oc.ocdasroot = NULL;
ocstat = OC_NOERR;
ncstat = NC_NOERR;
}
/* Construct the netcdf cdf tree corresponding to the dds tree*/
@ -677,8 +677,8 @@ fetchconstrainedmetadata3(NCDAPCOMMON* dapcomm)
else
ce = buildconstraintstring3(dapcomm->oc.dapconstraint);
{
ocstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDDS,&ocroot);
if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;}
ncstat = dap_fetch(dapcomm,dapcomm->oc.conn,ce,OCDDS,&ocroot);
if(ncstat != NC_NOERR) {THROWCHK(ncstat); goto fail;}
/* Construct our parallel dds tree; including attributes*/
ncstat = buildcdftree34(dapcomm,ocroot,OCDDS,&ddsroot);

View File

@ -189,6 +189,14 @@ nc_strerror(int ncerr1)
return "NetCDF: Malformed or unexpected Constraint";
case NC_ETRANSLATION:
return "NetCDF: Untranslatable construct";
case NC_EACCESS:
return "NetCDF: Access failure";
case NC_EAUTH:
return "NetCDF: Authorization failure";
case NC_ENOTFOUND:
return "NetCDF: file not found";
case NC_ECANTREMOVE:
return "NetCDF: cannot delete file";
case NC_EHDFERR:
return "NetCDF: HDF error";
case NC_ECANTREAD:

View File

@ -1831,6 +1831,23 @@ oc_svcerrordata(OCobject link, char** codep,
return OCTHROW(ocsvcerrordata(state,codep,msgp,httpp));
}
/*!
Obtain the HTTP code (e.g. 200, 404, etc) from the last
fetch command.
\param[in] link The link through which the server is accessed.
\retval the HTTP code
*/
OCerror
oc_httpcode(OCobject link)
{
OCstate* state;
OCVERIFY(OC_State,link);
OCDEREF(OCstate*,state,link);
return state->error.httpcode;
}
/**************************************************/
/* New 10/31/2009: return the size(in bytes)

View File

@ -524,10 +524,16 @@ extern OCerror oc_merge_das(OClink, OCddsnode dasroot, OCddsnode ddsroot);
/* Debugging */
/* When a server error is detected, then it is possible
to get the server error info using this procedure */
to get DODS supplied server error info using this procedure */
extern OCerror oc_svcerrordata(OClink link, char** codep,
char** msgp, long* httpp);
/* Get the HTTP return code from the last call;
note that this may or may not be the same as returned
by oc_svcerrordata.
*/
extern int oc_httpcode(OClink);
/**************************************************/
/* Experimental/Undocumented */

View File

@ -26,7 +26,11 @@ ocfetchhttpcode(CURL* curl)
long httpcode;
CURLcode cstat = CURLE_OK;
/* Extract the http code */
#ifdef HAVE_CURLINFO_RESPONSE_CODE
cstat = curl_easy_getinfo(curl,CURLINFO_RESPONSE_CODE,&httpcode);
#else
cstat = curl_easy_getinfo(curl,CURLINFO_HTTP_CODE,&httpcode);
#endif
if(cstat != CURLE_OK) httpcode = 0;
return httpcode;
}
@ -62,6 +66,7 @@ ocfetchurl_file(CURL* curl, const char* url, FILE* stream,
fetchdata.stream = stream;
fetchdata.size = 0;
cstat = curl_easy_perform(curl);
if (cstat != CURLE_OK)
goto fail;

View File

@ -267,9 +267,9 @@ ocfetch(OCstate* state, const char* constraint, OCdxd kind, OCflags flags,
default:
break;
}/*switch*/
/* Obtain any http code */
state->error.httpcode = ocfetchhttpcode(state->curl);
if(stat != OC_NOERR) {
/* Obtain any http code */
state->error.httpcode = ocfetchhttpcode(state->curl);
if(state->error.httpcode >= 400) {
oclog(OCLOGWARN,"oc_open: Could not read url; http error = %l",state->error.httpcode);
} else {