static int readpacket(NCD4INFO* state, NCURI* url, NCbytes* packet, NCD4mode dxx, long* lastmodified) { int stat = NC_NOERR; int fileprotocol = 0; const char* suffix = dxxextension(dxx); CURL* curl = state->curl->curl; #ifdef HAVE_GETTIMEOFDAY struct timeval time0; struct timeval time1; #endif fileprotocol = (strcmp(url->protocol,"file")==0); if(fileprotocol) { /* Short circuit file://... urls*/ /* We do this because the test code always needs to read files*/ stat = readfile(state, url,suffix,packet); } else { char* fetchurl = NULL; int flags = NCURIBASE; if(!fileprotocol) flags |= NCURIQUERY; flags |= NCURIENCODE; fetchurl = ncuribuild(url,NULL,suffix,flags); MEMCHECK(fetchurl); if(FLAGSET(state->controls.flags,NCF_SHOWFETCH)) { nclog(NCLOGDBG,"fetch url=%s",fetchurl); #ifdef HAVE_GETTIMEOFDAY gettimeofday(&time0,NULL); #endif } stat = NCD4_fetchurl(curl,fetchurl,packet,lastmodified); nullfree(fetchurl); if(stat) goto fail; if(FLAGSET(state->controls.flags,NCF_SHOWFETCH)) { double secs = 0; #ifdef HAVE_GETTIMEOFDAY gettimeofday(&time1,NULL); secs = deltatime(time0,time1); #endif nclog(NCLOGDBG,"fetch complete: %0.3f",secs); } } #ifdef D4DEBUG { fprintf(stderr,"readpacket: packet.size=%lu\n", (unsigned long)ncbyteslength(packet)); } #endif fail: return THROW(stat); }
static int readfile(NCD4INFO* state, const NCURI* uri, const char* suffix, NCbytes* packet) { int stat = NC_NOERR; NCbytes* tmp = ncbytesnew(); char* filename = NULL; ncbytescat(tmp,uri->path); if(suffix != NULL) ncbytescat(tmp,suffix); ncbytesnull(tmp); filename = ncbytesextract(tmp); ncbytesfree(tmp); #ifdef HAVE_GETTIMEOFDAY struct timeval time0; struct timeval time1; #endif state->fileproto.filename = filename; /* filename is alloc'd here anyway */ if(FLAGSET(state->controls.flags,NCF_SHOWFETCH)) { char* surl = NULL; #ifdef HAVE_GETTIMEOFDAY gettimeofday(&time0,NULL); #endif surl = ncuribuild((NCURI*)uri,NULL,NULL,NCURIALL); nclog(NCLOGDBG,"fetch uri=%s file=%s",surl,filename); } stat = NC_readfile(filename,packet); if(FLAGSET(state->controls.flags,NCF_SHOWFETCH)) { double secs; #ifdef HAVE_GETTIMEOFDAY gettimeofday(&time1,NULL); secs = deltatime(time0,time1); #endif nclog(NCLOGDBG,"fetch complete: %0.3f",secs); } return THROW(stat); }
int NCD4_readDAP(NCD4INFO* state, int flags) { int stat = NC_NOERR; long lastmod = -1; if((flags & NCF_ONDISK) == 0) { stat = readpacket(state,state->uri,state->curl->packet,NCD4_DAP,&lastmod); if(stat == NC_NOERR) state->data.daplastmodified = lastmod; } else { /*((flags & NCF_ONDISK) != 0) */ NCURI* url = state->uri; int fileprotocol = (strcmp(url->protocol,"file")==0); if(fileprotocol) { stat = readfiletofile(state, url, ".dap", state->data.ondiskfile, &state->data.datasize); } else { char* readurl = NULL; int flags = 0; if(!fileprotocol) flags |= NCURIQUERY; flags |= NCURIENCODE; flags |= NCURIPWD; #ifdef FIX ncurisetconstraints(url,state->constraint); #endif readurl = ncuribuild(url,NULL,".dods",NCURISVC); if(readurl == NULL) return THROW(NC_ENOMEM); stat = NCD4_fetchurl_file(state->curl, readurl, state->data.ondiskfile, &state->data.datasize, &lastmod); nullfree(readurl); if(stat == NC_NOERR) state->data.daplastmodified = lastmod; } } return THROW(stat); }
static int processuri(const char* path, NCURI** urip, char** newpathp, NClist* modeargs) { int stat = NC_NOERR; int found = 0; const char** fragp = NULL; struct NCPROTOCOLLIST* protolist; NCURI* uri = NULL; size_t pathlen = strlen(path); if(path == NULL || pathlen == 0) {stat = NC_EURL; goto done;} /* Defaults */ if(newpathp) *newpathp = NULL; if(urip) *urip = NULL; if(ncuriparse(path,&uri) != NCU_OK) goto done; /* not url */ /* Look up the protocol */ for(found=0,protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(uri->protocol,protolist->protocol) == 0) { found = 1; break; } } if(!found) {stat = NC_EINVAL; goto done;} /* unrecognized URL form */ /* process the corresponding mode arg */ if(protolist->mode != NULL) nclistpush(modeargs,strdup(protolist->mode)); /* Substitute the protocol in any case */ if(protolist->substitute) ncurisetprotocol(uri,protolist->substitute); /* Iterate over the url fragment parameters */ for(fragp=ncurifragmentparams(uri);fragp && *fragp;fragp+=2) { const char* name = fragp[0]; const char* value = fragp[1]; if(strcmp(name,"protocol")==0) { nclistpush(modeargs,strdup(value)); } else if(strcmp(name,"mode")==0) { if((stat = parseurlmode(value,modeargs))) goto done; } else if(issingleton(name) && (value == NULL || strlen(value)==0)) { nclistpush(modeargs,strdup(name)); } /*else ignore*/ } /* At this point modeargs should contain all mode args from the URL */ /* Rebuild the path (including fragment)*/ if(newpathp) *newpathp = ncuribuild(uri,NULL,NULL,NCURIALL); if(urip) { *urip = uri; uri = NULL; } done: if(uri != NULL) ncurifree(uri); return check(stat); }
int NC_urlmodel(const char* path, int cmode, char** newurl, NCmode* model) { int stat = NC_NOERR; int found = 0; struct NCPROTOCOLLIST* protolist; NCURI* url = NULL; const char** fragp = NULL; if(path == NULL) return 0; /* Parse the url */ if(ncuriparse(path,&url) != NCU_OK) return NC_EINVAL; /* Not parseable as url */ /* Look up the protocol */ for(found=0,protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(url->protocol,protolist->protocol) == 0) { found = 1; break; } } if(found) { model->implementation = protolist->implementation; /* Substitute the protocol in any case */ if(protolist->substitute) ncurisetprotocol(url,protolist->substitute); } else {stat = NC_EINVAL; goto done;} /* Again, does not look like a url */ /* Iterate over the url fragment parameters */ for(fragp=ncurifragmentparams(url);fragp && *fragp;fragp+=2) { const char* name = fragp[0]; const char* value = fragp[1]; if(strcmp(name,"protocol")==0) name = value; if(strcasecmp(name,"dap2") == 0) { model->format = NC_FORMAT_NC3; model->implementation = NC_FORMATX_DAP2; /* No need to set iosp field */ } else if(strcasecmp(name,"dap4") == 0) { model->format = NC_FORMAT_NETCDF4; model->implementation = NC_FORMATX_DAP4; /* No need to set iosp field */ } else if(strcmp(name,"mode")==0) { if((stat = url_getmodel(value,model))) goto done; } } if(model->implementation == 0) {/* Last resort: use the cmode */ /* If mode specifies netcdf-4, then this is assumed to be dap4 */ if(cmode & NC_NETCDF4) { model->implementation = NC_FORMATX_DAP4; } else {/* Default is DAP2 */ model->implementation = NC_FORMATX_DAP2; } } if(model->implementation == 0) goto done; /* could not interpret */ switch (model->implementation) { case NC_FORMATX_NC3: model->format = NC_FORMAT_NC3; break; case NC_FORMATX_NC4: model->format = NC_FORMAT_NETCDF4; break; case NC_FORMATX_DAP2: model->format = NC_FORMAT_NC3; break; case NC_FORMATX_DAP4: model->format = NC_FORMAT_NETCDF4; break; case NC_FORMATX_ZARR: model->format = NC_FORMAT_NETCDF4; break; default: stat = NC_EINVAL; goto done; } done: if(newurl) *newurl = ncuribuild(url,NULL,NULL,NCURIALL); if(url) ncurifree(url); return stat; }
/* Provide a wrapper for oc_fetch so we can log what it does */ NCerror dap_fetch(NCDAPCOMMON* nccomm, OClink conn, const char* ce, OCdxd dxd, OCddsnode* rootp) { 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"; else ext = ".dods"; if(ce != NULL && strlen(ce) == 0) ce = NULL; if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) { ce = NULL; } if(FLAGSET(nccomm->controls,NCF_ONDISK)) { flags |= OCONDISK; } if(SHOWFETCH) { /* Build uri string minus the constraint and #tag */ char* baseurl = ncuribuild(nccomm->oc.url,NULL,ext,NCURIBASE); if(ce == NULL) LOG1(NCLOGNOTE,"fetch: %s",baseurl); else LOG2(NCLOGNOTE,"fetch: %s?%s",baseurl,ce); nullfree(baseurl); #ifdef HAVE_GETTIMEOFDAY gettimeofday(&time0,NULL); #endif } ocstat = oc_fetch(conn,ce,dxd,flags,rootp); if(FLAGSET(nccomm->controls,NCF_SHOWFETCH)) { #ifdef HAVE_GETTIMEOFDAY double secs; gettimeofday(&time1,NULL); secs = deltatime(); nclog(NCLOGNOTE,"fetch complete: %0.3f secs",secs); #else nclog(NCLOGNOTE,"fetch complete."); #endif } #ifdef DEBUG2 fprintf(stderr,"fetch: dds:\n"); oc_dumpnode(conn,*rootp); #endif /* 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; }
int NC_urlmodel(const char* path, int mode, char** newurl) { int found, model = 0; struct NCPROTOCOLLIST* protolist; NCURI* url = NULL; char* p; if(path == NULL) return 0; /* find leading non-blank */ for(p=(char*)path;*p;p++) {if(*p != ' ') break;} /* Do some initial checking to see if this looks like a file path */ if(*p == '/') return 0; /* probably an absolute file path */ /* Parse the url */ if(ncuriparse(path,&url) != NCU_OK) goto fail; /* Not parseable as url */ /* Look up the protocol */ for(found=0,protolist=ncprotolist;protolist->protocol;protolist++) { if(strcmp(url->protocol,protolist->protocol) == 0) { found = 1; break; } } if(found) { model = protolist->model; /* Substitute the protocol in any case */ if(protolist->substitute) ncurisetprotocol(url,protolist->substitute); } else goto fail; /* Again, does not look like a url */ if(model != NC_FORMATX_DAP2 && model != NC_FORMATX_DAP4) { /* Look for and of the following params: "dap2", "protocol=dap2", "dap4", "protocol=dap4" */ const char* proto = NULL; const char* match = NULL; if((proto=ncurilookup(url,"protocol")) == NULL) proto = NULL; if(proto == NULL) proto = ""; if((match=ncurilookup(url,"dap2")) != NULL || strcmp(proto,"dap2") == 0) model = NC_FORMATX_DAP2; else if((match=ncurilookup(url,"dap4")) != NULL || strcmp(proto,"dap4") == 0) model = NC_FORMATX_DAP4; else model = 0; /* Still don't know */ } if(model == 0) {/* Last resort: use the mode */ /* If mode specifies netcdf-4, then this is assumed to be dap4 */ if(mode & NC_NETCDF4) model = NC_FORMATX_DAP4; else model = NC_FORMATX_DAP2; /* Default */ } if(newurl) *newurl = ncuribuild(url,NULL,NULL,NCURIALL); if(url) ncurifree(url); return model; fail: if(url) ncurifree(url); return 0; }