static int sendResponse(Session *sn, Request *rq, HTTPResponse *resp) { pb_param *pb_entry; /* * collect up the headers */ pb_entry = pblock_remove(CONTENT_TYPE,rq->srvhdrs); /* remove default */ param_free(pb_entry); /* aB. Need to free parameters we remove from pblocks !!! */ st_perform(resp->headers,gethdr,rq); /* * ensure a content length */ if (pblock_findval(CONTENT_LENGTH, rq->srvhdrs) == NULL) { char length[64]; util_itoa(resp->content_length,length); pblock_nvinsert(CONTENT_LENGTH,length, rq->srvhdrs); } protocol_status(sn, rq, resp->status, resp->statusMsg); if (protocol_start_response(sn, rq) == REQ_NOACTION) { WOLog(WO_ERR,"protocol_start_response() returned REQ_NOACTION (!?)"); return REQ_PROCEED; } if (resp->content_length) if (net_write(sn->csd, resp->content, resp->content_length) == IO_ERROR) { WOLog(WO_ERR,"Failed to send content to client"); return REQ_EXIT; } return REQ_PROCEED; }
String *resp_packageHeaders(HTTPResponse *resp) { String *result; result = str_create(NULL, 1000); if (result) st_perform(resp->headers, (st_perform_callback)resp_appendHeader, result); return result; }
int req_sendRequest(HTTPRequest *req, net_fd socket) { struct iovec *buffers, *bufferIterator; int bufferCount, result; buffers = WOMALLOC((st_count(req->headers) * 4 + 3) * sizeof(struct iovec)); buffers[0].iov_base = req->request_str; buffers[0].iov_len = strlen(req->request_str); bufferIterator = &buffers[1]; st_perform(req->headers, (st_perform_callback)setupIOVec, &bufferIterator); bufferIterator->iov_base = "\r\n"; bufferIterator->iov_len = 2; bufferCount = st_count(req->headers) * 4 + 2; if (req->content_length > 0) { bufferCount++; bufferIterator++; bufferIterator->iov_base = req->content; bufferIterator->iov_len = req->content_buffer_size; } result = transport->sendBuffers(socket, buffers, bufferCount); /* If we are streaming the content data, continue until we have sent everything. */ /* Note that we reuse buffers, and the existing content-data buffer. */ if (req->content_length > req->content_buffer_size) { long total_sent = req->content_buffer_size; long len_read, amount_to_read; req->haveReadStreamedData = 1; while (total_sent < req->content_length && result == 0) { amount_to_read = req->content_length - total_sent; if (amount_to_read > req->content_buffer_size) amount_to_read = req->content_buffer_size; len_read = req->getMoreContent(req, req->content, amount_to_read, 0); if (len_read > 0) { buffers[0].iov_base = req->content; buffers[0].iov_len = len_read; result = transport->sendBuffers(socket, buffers, 1); total_sent += len_read; } else if (len_read < 0) { WOLog(WO_ERR, "Failed to read streamed content."); result = -1; } } } WOFREE(buffers); if (result == 0) result = transport->flush_connection(socket); else WOLog(WO_ERR, "error sending request"); return result; }
char *st_description(strtbl *st) { String *str; char *desc; str = str_create("String table:\n", 0); if (str) { st_perform(st, st_description_callback, str); str->text[str->length-1] = 0; /* strip of the extra newline */ desc = str_unwrap(str); } else desc = WOSTRDUP("empty string table"); return desc; }
int req_sendRequest(HTTPRequest *req, net_fd socket) { struct iovec *buffers; int bufferCount, appStatus; int browserStatus = 0; String *headersString; buffers = WOMALLOC(3 * sizeof(struct iovec)); headersString = str_create(req->request_str, 0); if (headersString) { st_perform(req->headers, (st_perform_callback)req_appendHeader, headersString); } buffers[0].iov_base = headersString->text; buffers[0].iov_len = headersString->length; buffers[1].iov_base = "\r\n"; buffers[1].iov_len = 2; bufferCount = 2; if (req->content_length > 0) { bufferCount++; buffers[2].iov_base = req->content; buffers[2].iov_len = req->content_buffer_size; } appStatus = transport->sendBuffers(socket, buffers, bufferCount); str_free(headersString); /* If we are streaming the content data, continue until we have sent everything. */ /* Note that we reuse buffers, and the existing content-data buffer. */ if (req->content_length > req->content_buffer_size) { long total_sent = req->content_buffer_size; long len_read, amount_to_read; req->haveReadStreamedData = 1; while (total_sent < req->content_length) { amount_to_read = req->content_length - total_sent; if (amount_to_read > req->content_buffer_size) amount_to_read = req->content_buffer_size; len_read = req->getMoreContent(req, req->content, amount_to_read, 0); if (len_read > 0) { if(appStatus == 0) { buffers[0].iov_base = req->content; buffers[0].iov_len = len_read; appStatus = transport->sendBuffers(socket, buffers, 1); // 2009/04/28: in case of a transport error, carry on with reading // incoming input stream (= browser data). That way, // the browser (hopefully) switch to the receive mode // after sending the complete request and receives/shows // the adaptor error message (old behaviour: endless // sending/uploading view). if(appStatus != 0) { WOLog(WO_ERR, "Failed to send streamed content."); } } total_sent += len_read; } else if (len_read < 0) { WOLog(WO_ERR, "Failed to read streamed content."); browserStatus = -1; break; } } } WOFREE(buffers); if(browserStatus != 0) WOLog(WO_ERR, "error receiving request"); if (appStatus == 0) { // 2009/04/30: as long as we haven't received any error message from // the instance, flush the socket to complete the data // transfer! appStatus = transport->flush_connection(socket); } else WOLog(WO_ERR, "error sending request"); return ((appStatus != 0) ? appStatus : browserStatus); }