/* * send response to server */ static void sendResponse(HTTPResponse *resp) { String *resphdrs; #ifndef PROFILE FCGX_FPrintF(out,"Status: %d %s" CRLF,resp->status,resp->statusMsg); #endif resphdrs = resp_packageHeaders(resp); #ifndef PROFILE FCGX_PutS(resphdrs->text,out); #endif str_free(resphdrs); #ifndef PROFILE FCGX_PutS(CRLF, out); #endif #ifndef PROFILE /* resp->content_valid will be 0 for HEAD requests and empty responses */ if (resp->content_valid) { while (resp->content_read < resp->content_length) { //fwrite(resp->content,sizeof(char),resp->content_valid,stdout); FCGX_PutStr(resp->content, resp->content_valid, out); if (resp_getResponseContent(resp, 1) == -1) { break; } } //fwrite(resp->content,sizeof(char),resp->content_valid,stdout); FCGX_PutStr(resp->content, resp->content_valid, out); } FCGX_FFlush(out); #endif return; }
static void sendResponse(EXTENSION_CONTROL_BLOCK *p, HTTPResponse *resp) { String *resphdrs; char status[128]; DWORD len; p->dwHttpStatusCode = resp->status; sprintf(status, "%d %s",resp->status, resp->statusMsg); /* * send the headers (collected into one buffer) */ resphdrs = resp_packageHeaders(resp); if (resphdrs) { len = resphdrs->length; /* ccording to the Microsoft web site, HSE_REQ_SEND_RESPONSE_HEADER is depreciated */ /* HSE_REQ_SEND_RESPONSE_HEADER_EX is preferred. */ /* However, moving to HSE_REQ_SEND_RESPONSE_HEADER_EX will not work if we must support IIS 3.0. */ if (p->ServerSupportFunction(p->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, status, &len, (LPDWORD)resphdrs->text) != TRUE) { WOLog(WO_ERR,"Failed to send response headers (%d)", GetLastError()); } else { len = 2; if (p->WriteClient(p->ConnID, CRLF, &len, 0) != TRUE) WOLog(WO_ERR,"Failed to send \\r\\n (%d)", GetLastError()); /* * send the content data */ len = resp->content_length; if (len && (p->WriteClient(p->ConnID, resp->content, &len, 0) != TRUE)) WOLog(WO_ERR,"Failed to send content (%d)", GetLastError()); } str_free(resphdrs); } /* else? return warning */ return; }
static void sendResponse(EXTENSION_CONTROL_BLOCK *p, HTTPResponse *resp) { String *resphdrs; char status[128]; int browserStatus = 0; DWORD len; p->dwHttpStatusCode = resp->status; sprintf(status, "%d %s",resp->status, resp->statusMsg); /* * send the headers (collected into one buffer) */ resphdrs = resp_packageHeaders(resp); if (resphdrs) { len = resphdrs->length; /* ccording to the Microsoft web site, HSE_REQ_SEND_RESPONSE_HEADER is depreciated */ /* HSE_REQ_SEND_RESPONSE_HEADER_EX is preferred. */ /* However, moving to HSE_REQ_SEND_RESPONSE_HEADER_EX will not work if we must support IIS 3.0. */ if (p->ServerSupportFunction(p->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, status, &len, (LPDWORD)resphdrs->text) != TRUE) { browserStatus = -1; WOLog(WO_ERR,"Failed to send response headers (%d)", GetLastError()); } else { len = 2; // 2009/06/10: The 4th. parameter is only allowed to be '0' if // this code would belong to a filter plugin. But // this code realizes an IIS extension and therefore // only HSE_IO_SYNC and ..._ASYNC is allowed! if (p->WriteClient(p->ConnID, CRLF, &len, HSE_IO_SYNC) != TRUE) { browserStatus = -1; WOLog(WO_ERR,"Failed to send \\r\\n (%d)", GetLastError()); } /* resp->content_valid will be 0 for HEAD requests and empty responses */ if (resp->content_valid) { long count; while (resp->content_read < resp->content_length && (resp->flags & RESP_LENGTH_INVALID) != RESP_LENGTH_INVALID && browserStatus == 0) { len = resp->content_valid; // 2009/06/10: The 4th. parameter is only allowed to be '0' if // this code would belong to a filter plugin. But // this code realizes an IIS extension and therefore // only HSE_IO_SYNC and ..._ASYNC is allowed! if (len && (p->WriteClient(p->ConnID, resp->content, &len, HSE_IO_SYNC) != TRUE)) { browserStatus = -1; WOLog(WO_ERR,"Failed to send content (%d)", GetLastError()); } if(browserStatus == 0) { // read next response chunk from the WebObjects application count = resp_getResponseContent(resp, 1); if(count > 0) { // 2009/06/09: handle situations where content_length is wrong or // unset. Read as much data as possible from the // WebObjects application and send the data to the // client-side. resp->content_read += count; resp->content_valid = count; } if(count != 0) { // 2009/04/30: error while reading response content (this can happen // if the instance dies during sending the response - e.g. // during a file download - or if the content_length is // wrong/unset). Stop the loop to avoid endless looping! WOLog(WO_WARN, "sendResponse(): received an incomplete data package. Please look for a dead instance or adjust content-length value."); } } } if(browserStatus == 0) { len = resp->content_valid; // 2009/06/10: The 4th. parameter is only allowed to be '0' if // this code would belong to a filter plugin. But // this code realizes an IIS extension and therefore // only HSE_IO_SYNC and ..._ASYNC is allowed! if (len && (p->WriteClient(p->ConnID, resp->content, &len, HSE_IO_SYNC) != TRUE)) { browserStatus = -1; WOLog(WO_ERR,"Failed to send content (%d)", GetLastError()); } } } } str_free(resphdrs); } /* else? return warning */ if(resp->content_read < resp->content_length) { // 2009/06/08: in case of an unset/wrong content length value, we // must close the client socket connection to signalize // the client application the end-of-stream. closeClientConnection(p, resp); if(resp->keepConnection != 0) { // 2009/04/30: it is possible, that the user (=browser) cancels the last started // request. The existing mechanism of the nbsocket.c implementation // (starting a reset operation that cleans/consumes the remaining // content of the socket buffer) fails sometimes in such situations. // E.g. during an huge file download, the reset operation doesn't consume // the complete download stream (such a behaviour would be very expensive!), // but only the local socket buffer. If such a connection is reused // in another request-response-cycle, the adaptor/browser gets unexpected // data garbage. This can lead to situations, where the adaptor marks an // existing and fully functional instance as death. Therefore: dump // such connections! WOLog(WO_INFO, "Forget the existing connection."); resp->keepConnection = 0; resp->flags |= RESP_CLOSE_CONNECTION; // after calling the resp_free function, the connection doesn't longer exist! } } return; }