mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-27 08:49:16 +08:00
e632d02041
The thredds-test server now has some password protected datasets that can be used to test DAP2 authorization support. The general location is ```` https://thredds.ucar.edu/thredds/tdscapabilities/authTest.html ```` and specifically: ```` https://thredds.ucar.edu/thredds/dodsC/test3/testData.nc.html ```` This PR replaces old testcases with ncdap_test/testauth.sh. This testcase allows us to test use of the .dodsrc file and .netrc file and embedded user+pwd. As part of this, I had to create a program (ncdap_test/pathcvt.c) that is essentially the equivalent to cygpath. Given a path in windows, unix, msys or cygwin format, it converts it to the equivalent format in one of those four cases. So it can be used to convert a cygwin path to a windows path, for example. This is needed in testpathcvt and testauth to make sure that the paths in .daprc (e.g. the reference to .netrc) are of the proper format. Misc. Other Changes: 1. Fix some memory leaks in libdap2 2. Setting the env variable CURLOPT_VERBOSE allows tracking of curl operations. 3. Make tst_charvlenbug be conditional on NC_VLEN_NOTEST.
160 lines
4.6 KiB
C
160 lines
4.6 KiB
C
/*********************************************************************
|
|
* Copyright 2018, UCAR/Unidata
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
*********************************************************************/
|
|
|
|
#include "dapincludes.h"
|
|
|
|
#define OCCHECK(exp) if((ocstat = (exp))) {THROWCHK(ocstat); goto done;}
|
|
|
|
/* Forward */
|
|
static NCerror buildattribute(char*,nc_type,size_t,char**,NCattribute**);
|
|
|
|
/*
|
|
Invoke oc_merge_das and then extract special
|
|
attributes such as "strlen" and "dimname"
|
|
and stuff from DODS_EXTRA.
|
|
*/
|
|
int
|
|
dapmerge(NCDAPCOMMON* nccomm, CDFnode* ddsroot, OCddsnode dasroot)
|
|
{
|
|
int i,j;
|
|
NCerror ncstat = NC_NOERR;
|
|
OCerror ocstat = OC_NOERR;
|
|
NClist* allnodes;
|
|
OClink conn;
|
|
char* ocname = NULL;
|
|
char** values = NULL;
|
|
conn = nccomm->oc.conn;
|
|
|
|
if(ddsroot == NULL || dasroot == NULL)
|
|
return NC_NOERR;
|
|
/* Merge the das tree onto the dds tree */
|
|
ocstat = oc_merge_das(nccomm->oc.conn,dasroot,ddsroot->ocnode);
|
|
if(ocstat != OC_NOERR) goto done;
|
|
|
|
/* Create attributes on CDFnodes */
|
|
allnodes = ddsroot->tree->nodes;
|
|
for(i=0;i<nclistlength(allnodes);i++) {
|
|
CDFnode* node = (CDFnode*)nclistget(allnodes,i);
|
|
OCddsnode ocnode = node->ocnode;
|
|
size_t attrcount;
|
|
OCtype ocetype;
|
|
|
|
OCCHECK(oc_dds_attr_count(conn,ocnode,&attrcount));
|
|
for(j=0;j<attrcount;j++) {
|
|
size_t nvalues;
|
|
|
|
NCattribute* att = NULL;
|
|
|
|
if(ocname != NULL) {
|
|
free(ocname); ocname = NULL;
|
|
} /* from last loop */
|
|
|
|
OCCHECK(oc_dds_attr(conn,ocnode,j,&ocname,&ocetype,&nvalues,NULL));
|
|
if(nvalues > 0) {
|
|
values = (char**)malloc(sizeof(char*)*nvalues);
|
|
if(values == NULL) {ncstat = NC_ENOMEM; goto done;}
|
|
OCCHECK(oc_dds_attr(conn,ocnode,j,NULL,NULL,NULL,values));
|
|
}
|
|
ncstat = buildattribute(ocname,octypetonc(ocetype),nvalues,values,&att);
|
|
if(ncstat != NC_NOERR) goto done;
|
|
if(node->attributes == NULL)
|
|
node->attributes = nclistnew();
|
|
nclistpush(node->attributes,(void*)att);
|
|
if(strncmp(ocname,"DODS",strlen("DODS"))==0) {
|
|
att->invisible = 1;
|
|
/* Define extra semantics associated with
|
|
DODS and DODS_EXTRA attributes */
|
|
if(strcmp(ocname,"DODS.strlen")==0
|
|
|| strcmp(ocname,"DODS_EXTRA.strlen")==0) {
|
|
unsigned int maxstrlen = 0;
|
|
if(values != NULL) {
|
|
if(0==sscanf(values[0],"%u",&maxstrlen))
|
|
maxstrlen = 0;
|
|
}
|
|
node->dodsspecial.maxstrlen = maxstrlen;
|
|
#ifdef DEBUG
|
|
fprintf(stderr,"%s.maxstrlen=%d\n",node->ocname,(int)node->dodsspecial.maxstrlen);
|
|
#endif
|
|
} else if(strcmp(ocname,"DODS.dimName")==0
|
|
|| strcmp(ocname,"DODS_EXTRA.dimName")==0) {
|
|
nullfree(node->dodsspecial.dimname); /* in case repeated */
|
|
node->dodsspecial.dimname = NULL;
|
|
if(values != NULL) {
|
|
nullfree(node->dodsspecial.dimname);
|
|
node->dodsspecial.dimname = nulldup(values[0]);
|
|
#ifdef DEBUG
|
|
fprintf(stderr,"%s.dimname=%s\n",node->ocname,node->dodsspecial.dimname);
|
|
#endif
|
|
} else {
|
|
nullfree(node->dodsspecial.dimname);
|
|
node->dodsspecial.dimname = NULL;
|
|
}
|
|
} else if(strcmp(ocname,"DODS.Unlimited_Dimension")==0
|
|
|| strcmp(ocname,"DODS_EXTRA.Unlimited_Dimension")==0) {
|
|
char* val0 = NULL;
|
|
if(values != NULL)
|
|
val0 = values[0];
|
|
if(val0 != NULL) {
|
|
if(nccomm->cdf.recorddimname != NULL) {
|
|
if(strcmp(nccomm->cdf.recorddimname,val0)!=0)
|
|
nclog(NCLOGWARN,"Duplicate DODS_EXTRA:Unlimited_Dimension specifications");
|
|
} else {
|
|
nccomm->cdf.recorddimname = nulldup(values[0]);
|
|
#ifdef DEBUG
|
|
fprintf(stderr,"%s.Unlimited_Dimension=%s\n",node->ocname,nccomm->cdf.recorddimname);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* clean up */
|
|
if(values) {
|
|
oc_reclaim_strings(nvalues,values);
|
|
free(values);
|
|
values = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
done:
|
|
if(values != NULL) free(values);
|
|
if(ocname != NULL) free(ocname);
|
|
if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat);
|
|
return THROW(ncstat);
|
|
}
|
|
|
|
/*
|
|
Build an NCattribute
|
|
from a DAP attribute.
|
|
As of Jun 27, 2017, we modify
|
|
to suppress nul characters and terminate
|
|
the name at the first nul.
|
|
*/
|
|
static NCerror
|
|
buildattribute(char* name, nc_type ptype,
|
|
size_t nvalues, char** values, NCattribute** attp)
|
|
{
|
|
int i;
|
|
NCerror ncstat = NC_NOERR;
|
|
NCattribute* att = NULL;
|
|
|
|
att = (NCattribute*)calloc(1,sizeof(NCattribute));
|
|
MEMCHECK(att,NC_ENOMEM);
|
|
att->name = nulldup(name);
|
|
att->etype = ptype;
|
|
|
|
att->values = nclistnew();
|
|
for(i=0;i<nvalues;i++) {
|
|
char* copy = nulldup(values[i]);
|
|
nclistpush(att->values,(void*)copy);
|
|
}
|
|
if(attp) *attp = att;
|
|
else
|
|
free(att);
|
|
|
|
return THROW(ncstat);
|
|
}
|
|
|