diff --git a/site_ansto/anstohttp.c b/site_ansto/anstohttp.c index b755b0d0..c5571c52 100644 --- a/site_ansto/anstohttp.c +++ b/site_ansto/anstohttp.c @@ -554,32 +554,77 @@ static int AnstoHttpGetHistogram(pHistDriver self, SConnection *pCon, pAnstoHttp pPriv = NULL; int status, len, i; - pPriv = (pAnstoHttp)self->pPriv; - assert(pPriv != NULL); + // For the ANSTO Histogram Server, the transfer size may be large + // and this can lead to transmission of the data from the server in chunks. + // This is apparent from the presence of 'xxxxx; chunk length nnnnnn' in the + // data when the transfer size is greater than 128K. + // e.g. a request for 64K elements is split into two chunks, + // and each has the header '20000; chunk length 131072'. + // However for some reason ghttp_get_body_len returns only the data size, + // even though there are header(s) added to the data. + // So, for the time being we play it safe and divide the transfer + // into chunks of less than 128KB. + // + // MJL 22/11/06: Found that AppWeb 2.1.0 supports HTTP 1.1 chunking, + // but this can be turned off by specifying HttpChunking off in the AppWeb + // config file, which is what we do currently, so the transfer size limitation code below + // is no longer needed. I've left it in with a much larger size restriction, + // just in case it's required later on for any reason (to improve transfer reliability?). + // Apparently the AppWeb 2.1.0 HTTP chunking feature is broken, because when the + // data is opened directly from the web server using an editor like KHexEdit, the open + // stalls for large data sizes unless chunking is disabled. This shows it is + // an AppWeb problem, not a ghttp problem. + // For AppWeb versions before 2.1.0, HTTP chunking is not available anyway. - snprintf(command,255,"%s?bank=%d&start=%d&end=%d",gethm,bank, - start,end); + pPriv = (pAnstoHttp)self->pPriv; + assert(pPriv != NULL); - status = anstoHttpGet(pPriv,command); - if(status != 1){ - return HWFault; - } - - len = ghttp_get_body_len(pPriv->syncRequest); - if(len < (end-start)*sizeof(int)){ - pPriv->errorCode = BODYSHORT; - strncpy(pPriv->hmError,"Not enough data received from HM",511); - return HWFault; - } - hmdata = (HistInt *)ghttp_get_body(pPriv->syncRequest); - if(hmdata == NULL){ // MJL check ghttp_get_body for NULL return - pPriv->errorCode = NOBODY; - strncpy(pPriv->hmError,"No body in HM data response",511); - return HWFault; - } - for(i = 0; i < (end - start); i++){ - data[i] = ntohl(hmdata[i]); - } +// How this limit is set in the server is not obvious... anyway, it should not change. +// MJL 22/11/06: Turned HTTP 1.1 chunking off at the histogram server, so we no longer +// need a size restriction. Leave the code in just in case it's needed for other reasons, +// but set a larger maximum request size. +//#define MAX_HTTP_REQUEST_BYTES 131072 +#define MAX_HTTP_REQUEST_BYTES 1048576 +// Do the HTTP data transfer in bite sized pieces + while(end>start) + { + int size=((end-start)>(MAX_HTTP_REQUEST_BYTES/sizeof(int))) + ?(MAX_HTTP_REQUEST_BYTES/sizeof(int)):(end-start); + + snprintf(command,255,"%s?bank=%d&start=%d&end=%d",gethm,bank, + start,start+size); + + status = anstoHttpGet(pPriv,command); + if(status != 1){ + return HWFault; + } + + len = ghttp_get_body_len(pPriv->syncRequest); + if(len < size*sizeof(int)){ + pPriv->errorCode = BODYSHORT; + strncpy(pPriv->hmError,"Not enough data received from HM",511); + return HWFault; + } + + hmdata = (HistInt *)ghttp_get_body(pPriv->syncRequest); + if(hmdata == NULL){ // MJL check ghttp_get_body for NULL return + pPriv->errorCode = NOBODY; + strncpy(pPriv->hmError,"No body in HM data response",511); + return HWFault; + } + + // MJL removed the ntohl, our histogram server doesn't apply htonl, + // so the data arrives in LE format. (Would have to buffer data + // at the server otherwise...) + // Doubt this will raise any conpatibility issues. + for(i = 0; i < size; i++){ + //data[i] = ntohl(hmdata[i]); + data[i] = hmdata[i]; + } + + data+=size; + start+=size; + } return OKOK; } /*--------------------------------------------------------------------*/