static void getBody(xmlrpc_env * const envP, TSession * const abyssSessionP, size_t const contentSize, const char * const trace, xmlrpc_mem_block ** const bodyP) { /*---------------------------------------------------------------------------- Get the entire body, which is of size 'contentSize' bytes, from the Abyss session and return it as the new memblock *bodyP. The first chunk of the body may already be in Abyss's buffer. We retrieve that before reading more. -----------------------------------------------------------------------------*/ xmlrpc_mem_block * body; if (trace) fprintf(stderr, "XML-RPC handler processing body. " "Content Size = %u bytes\n", (unsigned)contentSize); body = xmlrpc_mem_block_new(envP, 0); if (!envP->fault_occurred) { size_t bytesRead; const char * chunkPtr; size_t chunkLen; bytesRead = 0; while (!envP->fault_occurred && bytesRead < contentSize) { SessionGetReadData(abyssSessionP, contentSize - bytesRead, &chunkPtr, &chunkLen); bytesRead += chunkLen; assert(bytesRead <= contentSize); XMLRPC_MEMBLOCK_APPEND(char, envP, body, chunkPtr, chunkLen); if (bytesRead < contentSize) refillBufferFromConnection(envP, abyssSessionP, trace); } if (envP->fault_occurred) xmlrpc_mem_block_free(body); else *bodyP = body; } }
string const AbyssServer::Session::Impl::body() { /*----------------------------------------------------------------------------- The body of the HTTP request (client may send a body with PUT or POST). We throw an error if there is no content-size header field. That means we don't work with a chunked request. Some of the body may already be in Abyss's buffer. We retrieve that before reading more, but then do the network I/O while we run, waiting as necessary for the body to arrive. This works only once. If you call it a second time, it throws an error. -----------------------------------------------------------------------------*/ if (this->requestBodyDelivered) throwf("The request body has already been delivered; you cannot " "retrieve it twice"); this->requestBodyDelivered = true; size_t const contentLength(this->contentLength()); string body; size_t bytesRead; body.reserve(contentLength); bytesRead = 0; while (body.size() < contentLength) { const char * chunkPtr; size_t chunkLen; SessionGetReadData(this->cSessionP, contentLength - bytesRead, &chunkPtr, &chunkLen); body += string(chunkPtr, chunkPtr + chunkLen); if (body.size() < contentLength) this->refillBufferFromConnection(); } return body; }
void AbyssServer::Session::Impl::readRequestBody(unsigned char * const buffer, size_t const size) { for (size_t bytesXferredCt = 0; bytesXferredCt < size; ) { const char * chunkPtr; size_t chunkLen; SessionGetReadData(this->cSessionP, size - bytesXferredCt, &chunkPtr, &chunkLen); assert(bytesXferredCt + chunkLen <= size); memcpy(&buffer[bytesXferredCt], chunkPtr, chunkLen); bytesXferredCt += chunkLen; if (bytesXferredCt < size) this->refillBufferFromConnection(); } }
/************************************** * GetBody Devuelve el body de una peticion **************************************/ int XmlRpcServer::GetBody(TSession *ses,char *body,short bodyLen) { int len=0; //MIentras no hayamos leido del todo while (len<bodyLen) { char * buffer; size_t readed; //If there is no data available if (!SessionReadDataAvail(ses)) //Refill buffer SessionRefillBuffer(ses); //Read data SessionGetReadData(ses,bodyLen-len,(const char**)&buffer,&readed); //If not readed if (!readed) //error return Error("Not enought data readed"); //Copy memcpy(body+len,buffer,readed); //Increased readed len+=readed; } //Return return len; /*/ //Obtenemos lo que quedaba en el buffer ConnReadInit(r->conn); //Obtenemos lo que hay en la conexion if (r->conn->buffersize > bodyLen) len = bodyLen; else len = r->conn->buffersize; //Copiamos memcpy(body,r->conn->buffer,len); //MIentras no hayamos leido del todo while (len<bodyLen) { int size; //Iniciamos la lectura ConnReadInit(r->conn); //Leemos if(!ConnRead(r->conn,100)) return 0; //Obtenemos lo que hay en la conexion if (r->conn->buffersize > bodyLen - len) size = bodyLen - len; else size = r->conn->buffersize; //Copiamos memcpy(body+len,r->conn->buffer,size); //Incrementamos el buffer len += size; //Increase buffer pos r->conn->bufferpos += len; } //Reset buffer r->conn->buffersize = 0; r->conn->bufferpos = 0; //Clean buffer ConnReadInit(r->conn); //Salimos bien return 1; * */ }