static int req_internal_redirect(lua_State* L) { request_rec *r = CHECK_REQUEST_OBJECT(1); const char *new_uri = luaL_optstring(L, 2, r->uri); ap_internal_redirect(new_uri, r); return 0; }
CAMLprim value netcgi2_apache_request_internal_redirect (value new_uri, value rv) { CAMLparam2 (new_uri, rv); request_rec *r = Request_rec_val (rv); ap_internal_redirect (String_val (new_uri), r); CAMLreturn (Val_unit); }
static int apreq_redirect_test_handler(request_rec *r) { apreq_handle_t *req; const apreq_param_t *loc; if (strcmp(r->handler, "apreq_redirect_test") != 0) return DECLINED; req = apreq_handle_apache2(r); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, "looking for new location"); loc = apreq_param(req, "location"); if (!loc) return DECLINED; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, "redirecting to %s", loc->v.data); ap_internal_redirect(loc->v.data, r); return OK; }
static am_status_t set_custom_response(am_request_t *rq, const char *text, const char *cont_type) { request_rec *r = (request_rec *) (rq != NULL ? rq->ctx : NULL); if (r == NULL || !ISVALID(text)) return AM_EINVAL; if (rq->status == AM_INTERNAL_REDIRECT) { ap_internal_redirect(text, r); rq->status = AM_DONE; } else if (rq->status == AM_REDIRECT) { apr_table_add(r->headers_out, "Location", text); ap_custom_response(r, HTTP_MOVED_TEMPORARILY, text); } else { if (rq->status == AM_PDP_DONE) { request_rec *sr = ap_sub_req_method_uri(am_method_num_to_str(rq->method), rq->post_data_url, r, NULL); sr->headers_in = r->headers_in; sr->notes = r->notes; am_log_debug(rq->instance_id, "set_custom_response(): issuing sub-request %s to %s", sr->method, rq->post_data_url); ap_run_sub_req(sr); ap_destroy_sub_req(sr); rq->status = AM_DONE; } else { size_t tl = strlen(text); if (ISVALID(cont_type)) { ap_set_content_type(r, cont_type); } ap_set_content_length(r, tl); ap_rwrite(text, (int) tl, r); ap_custom_response(r, am_status_value(rq->status == AM_SUCCESS || rq->status == AM_DONE ? AM_SUCCESS : rq->status), text); ap_rflush(r); } } am_log_info(rq->instance_id, "set_custom_response(): status: %s", am_strerror(rq->status)); return AM_SUCCESS; }
/* XXX: Is there is still an O(n^2) attack possible here? Please detail. */ BOOL WINAPI ServerSupportFunction (HCONN hConn, DWORD dwHSERequest, LPVOID lpvBuffer, LPDWORD lpdwSize, LPDWORD lpdwDataType) { isapi_cid *cid = (isapi_cid *)hConn; request_rec *r = cid->r; request_rec *subreq; switch (dwHSERequest) { case 1: /* HSE_REQ_SEND_URL_REDIRECT_RESP */ /* Set the status to be returned when the HttpExtensionProc() * is done. * WARNING: Microsoft now advertises HSE_REQ_SEND_URL_REDIRECT_RESP * and HSE_REQ_SEND_URL as equivalant per the Jan 2000 SDK. * They most definately are not, even in their own samples. */ ap_table_set(r->headers_out, "Location", lpvBuffer); cid->status = cid->r->status = cid->ecb->dwHttpStatusCode = HTTP_MOVED_TEMPORARILY; return TRUE; case 2: /* HSE_REQ_SEND_URL */ /* Soak up remaining input (there should be none) */ if (r->remaining > 0) { char argsbuffer[HUGE_STRING_LEN]; while (ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0); } /* Reset the method to GET */ r->method = ap_pstrdup(r->pool, "GET"); r->method_number = M_GET; /* Don't let anyone think there's still data */ ap_table_unset(r->headers_in, "Content-Length"); /* AV fault per PR3598 - redirected path is lost! */ (char*)lpvBuffer = ap_pstrdup(r->pool, (char*)lpvBuffer); ap_internal_redirect((char*)lpvBuffer, r); return TRUE; case 3: /* HSE_REQ_SEND_RESPONSE_HEADER */ { /* Parse them out, or die trying */ DWORD statlen = 0, headlen = 0; if (lpvBuffer) statlen = strlen((char*) lpvBuffer); if (lpdwDataType) headlen = strlen((char*) lpdwDataType); return SendResponseHeaderEx(cid, (char*) lpvBuffer, (char*) lpdwDataType, statlen, headlen); } case 4: /* HSE_REQ_DONE_WITH_SESSION */ /* Do nothing... since we don't support async I/O, they'll * return from HttpExtensionProc soon */ return TRUE; case 1001: /* HSE_REQ_MAP_URL_TO_PATH */ { /* Map a URL to a filename */ char *file = (char *)lpvBuffer; DWORD len; subreq = ap_sub_req_lookup_uri(ap_pstrndup(r->pool, file, *lpdwSize), r); len = ap_cpystrn(file, subreq->filename, *lpdwSize) - file; /* IIS puts a trailing slash on directories, Apache doesn't */ if (S_ISDIR (subreq->finfo.st_mode)) { if (len < *lpdwSize - 1) { file[len++] = '\\'; file[len] = '\0'; } } *lpdwSize = len; return TRUE; } case 1002: /* HSE_REQ_GET_SSPI_INFO */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction HSE_REQ_GET_SSPI_INFO " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1003: /* HSE_APPEND_LOG_PARAMETER */ /* Log lpvBuffer, of lpdwSize bytes, in the URI Query (cs-uri-query) field * This code will do for now... */ ap_table_set(r->notes, "isapi-parameter", (char*) lpvBuffer); if (AppendLogToQuery) { if (r->args) r->args = ap_pstrcat(r->pool, r->args, (char*) lpvBuffer, NULL); else r->args = ap_pstrdup(r->pool, (char*) lpvBuffer); } if (AppendLogToErrors) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r, "ISAPI %s: %s", cid->r->filename, (char*) lpvBuffer); return TRUE; /* We don't support all this async I/O, Microsoft-specific stuff */ case 1005: /* HSE_REQ_IO_COMPLETION */ case 1006: /* HSE_REQ_TRANSMIT_FILE */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI asynchronous I/O not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1007: /* HSE_REQ_REFRESH_ISAPI_ACL */ /* Since we don't override the user ID and access, we can't reset. */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction " "HSE_REQ_REFRESH_ISAPI_ACL " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1008: /* HSE_REQ_IS_KEEP_CONN */ *((LPBOOL) lpvBuffer) = (r->connection->keepalive == 1); return TRUE; case 1010: /* HSE_REQ_ASYNC_READ_CLIENT */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI asynchronous I/O not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1011: /* HSE_REQ_GET_IMPERSONATION_TOKEN Added in ISAPI 4.0 */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction " "HSE_REQ_GET_IMPERSONATION_TOKEN " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; #ifdef HSE_REQ_MAP_URL_TO_PATH_EX case 1012: /* HSE_REQ_MAP_URL_TO_PATH_EX */ { /* Map a URL to a filename */ LPHSE_URL_MAPEX_INFO info = (LPHSE_URL_MAPEX_INFO) lpdwDataType; char* test_uri = ap_pstrndup(r->pool, (char *)lpvBuffer, *lpdwSize); subreq = ap_sub_req_lookup_uri(test_uri, r); info->cchMatchingURL = strlen(test_uri); info->cchMatchingPath = ap_cpystrn(info->lpszPath, subreq->filename, MAX_PATH) - info->lpszPath; /* Mapping started with assuming both strings matched. * Now roll on the path_info as a mismatch and handle * terminating slashes for directory matches. */ if (subreq->path_info && *subreq->path_info) { ap_cpystrn(info->lpszPath + info->cchMatchingPath, subreq->path_info, MAX_PATH - info->cchMatchingPath); info->cchMatchingURL -= strlen(subreq->path_info); if (S_ISDIR(subreq->finfo.st_mode) && info->cchMatchingPath < MAX_PATH - 1) { /* roll forward over path_info's first slash */ ++info->cchMatchingPath; ++info->cchMatchingURL; } } else if (S_ISDIR(subreq->finfo.st_mode) && info->cchMatchingPath < MAX_PATH - 1) { /* Add a trailing slash for directory */ info->lpszPath[info->cchMatchingPath++] = '/'; info->lpszPath[info->cchMatchingPath] = '\0'; } /* If the matched isn't a file, roll match back to the prior slash */ if (!subreq->finfo.st_mode) { while (info->cchMatchingPath && info->cchMatchingURL) { if (info->lpszPath[info->cchMatchingPath - 1] == '/') break; --info->cchMatchingPath; --info->cchMatchingURL; } } /* Paths returned with back slashes */ for (test_uri = info->lpszPath; *test_uri; ++test_uri) if (*test_uri == '/') *test_uri = '\\'; /* is a combination of: * HSE_URL_FLAGS_READ 0x001 Allow read * HSE_URL_FLAGS_WRITE 0x002 Allow write * HSE_URL_FLAGS_EXECUTE 0x004 Allow execute * HSE_URL_FLAGS_SSL 0x008 Require SSL * HSE_URL_FLAGS_DONT_CACHE 0x010 Don't cache (VRoot only) * HSE_URL_FLAGS_NEGO_CERT 0x020 Allow client SSL cert * HSE_URL_FLAGS_REQUIRE_CERT 0x040 Require client SSL cert * HSE_URL_FLAGS_MAP_CERT 0x080 Map client SSL cert to account * HSE_URL_FLAGS_SSL128 0x100 Require 128-bit SSL cert * HSE_URL_FLAGS_SCRIPT 0x200 Allow script execution * * XxX: As everywhere, EXEC flags could use some work... * and this could go further with more flags, as desired. */ info->dwFlags = (subreq->finfo.st_mode & _S_IREAD ? 0x001 : 0) | (subreq->finfo.st_mode & _S_IWRITE ? 0x002 : 0) | (subreq->finfo.st_mode & _S_IEXEC ? 0x204 : 0); return TRUE; } #endif case 1014: /* HSE_REQ_ABORTIVE_CLOSE */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction HSE_REQ_ABORTIVE_CLOSE" " is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1015: /* HSE_REQ_GET_CERT_INFO_EX Added in ISAPI 4.0 */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction " "HSE_REQ_GET_CERT_INFO_EX " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; #ifdef HSE_REQ_SEND_RESPONSE_HEADER_EX case 1016: /* HSE_REQ_SEND_RESPONSE_HEADER_EX Added in ISAPI 4.0 */ { LPHSE_SEND_HEADER_EX_INFO shi = (LPHSE_SEND_HEADER_EX_INFO) lpvBuffer; /* XXX: ignore shi->fKeepConn? We shouldn't need the advise */ /* r->connection->keepalive = shi->fKeepConn; */ return SendResponseHeaderEx(cid, shi->pszStatus, shi->pszHeader, shi->cchStatus, shi->cchHeader); } #endif case 1017: /* HSE_REQ_CLOSE_CONNECTION Added after ISAPI 4.0 */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction " "HSE_REQ_CLOSE_CONNECTION " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; case 1018: /* HSE_REQ_IS_CONNECTED Added after ISAPI 4.0 */ /* Returns True if client is connected c.f. MSKB Q188346 * XXX: That statement is very ambigious... assuming the * identical return mechanism as HSE_REQ_IS_KEEP_CONN. */ *((LPBOOL) lpvBuffer) = (r->connection->aborted == 0); return TRUE; case 1020: /* HSE_REQ_EXTENSION_TRIGGER Added after ISAPI 4.0 */ /* Undocumented - defined by the Microsoft Jan '00 Platform SDK */ if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction " "HSE_REQ_EXTENSION_TRIGGER " "is not supported: %s", r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; default: if (LogNotSupported) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, r, "ISAPI ServerSupportFunction (%d) not supported: " "%s", dwHSERequest, r->filename); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } }
/** * Performs the make, if necessary */ static int make_fixup(request_rec *r) { if (!r) return HTTP_INTERNAL_SERVER_ERROR; if (r->prev) return DECLINED; // We're running in a sub-request, ignore. dir_cfg* cfg=ap_get_module_config(r->per_dir_config,&make_module); if (!cfg->onoff) // Is module turned on? return DECLINED; const char* docroot=ap_document_root(r); if (cfg->debug) { ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cfg:onoff:%d",cfg->onoff); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cfg:sourceRoot:%s",cfg->sourceRoot); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cfg:makefileName:%s",cfg->makefileName); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cfg:makeProgram:%s",cfg->makeProgram); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cfg:makeOptions:%s",cfg->makeOptions); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cfg:includeFileTypes:%s",cfg->includeFileTypes); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cfg:excludeFileTypes:%s",cfg->excludeFileTypes); // ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cfg:excludeRegex:%s",cfg->excludeRegex); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cfg:errorURI:%s",cfg->errorURI); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cfg:errorCSS:%s",cfg->errorCSS); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: DocumentRoot:%s",docroot); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: URI:%s",r->uri); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: Canonical Filename:%s",r->canonical_filename); } // Determine if this is a request I care about, i.e., the following is true: // The file type is in MakeIncludeFileTypes (if specified) and is not in MakeExcludeFileTypes (if specified) if (cfg->includeFileTypes || cfg->excludeFileTypes) { // Get file extension char* fname=basename(r->canonical_filename); char* ext=strchr(fname,'.'); if (ext) { if (cfg->includeFileTypes && !strcasestr(cfg->includeFileTypes,ext)) { return DECLINED; } if (cfg->excludeFileTypes && strcasestr(cfg->excludeFileTypes,ext)) { return DECLINED; } } } // Locate Makefile: The Makefile should be in SourceRoot/REL_PATH/Makefile char relpath[256]; char makefile[256]; char make_target[256]; // Determine the relative path part of r->canonical_filename, i.e., the part with the DocumentRoot removed strncpy(relpath,r->canonical_filename+strlen(docroot),sizeof(relpath)-1); // Truncate it before the basename char* p=strrchr(relpath,'/'); if (p) *++p='\0'; else { relpath[0]='/'; relpath[1]='\0'; } if (cfg->debug) { ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: relpath:%s",relpath); } int bFoundMakefile=FALSE; int bGiveUp=FALSE; do { // Determine the make target, i.e., the basename of r->canonical_filename strncpy(make_target,r->canonical_filename+strlen(docroot)+strlen(relpath),sizeof(make_target)-1); make_target[sizeof(make_target)-1]='\0'; if (strlen(cfg->sourceRoot)) strncpy(makefile,cfg->sourceRoot,sizeof(makefile)-1); else strncpy(makefile,docroot,sizeof(makefile)-1); strncat(makefile,relpath,sizeof(makefile)-strlen(makefile)-1); strncat(makefile,cfg->makefileName,sizeof(makefile)-strlen(makefile)-1); makefile[sizeof(makefile)-1]='\0'; // If Makefile not found, ignore it (we only care if there •is* a Makefile) struct stat ss; if (!stat(makefile,&ss)) bFoundMakefile=TRUE; else { if (cfg->debug) ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: Makefile not found:%s. Trying parent directory...",makefile); // Go up one dir until we find a Makefile (but don't go past cfg->sourceRoot) // Take a directory off relpath, move it to the start of make_target and retry looking for the Makefile // Find 2nd-to-last / in relpath, that's the start of the last directory name char* p=strrchr(relpath,'/'); if (p) { do --p; while (p>=relpath && *p!='/'); if (p>=relpath) *(p+1)='\0'; else bGiveUp=TRUE; } else bGiveUp=TRUE; } } while (bFoundMakefile==FALSE && bGiveUp==FALSE); if (bFoundMakefile==FALSE) // Never found a Makefile { if (cfg->debug) ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: Unable to find a Makefile named:%s",cfg->makefileName); return DECLINED; } if (cfg->debug) { ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: relpath:%s",relpath); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: makefile:%s",makefile); ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: make_target:%s",make_target); } // Build make command char* cmd=apr_psprintf(r->pool,"WWWDOCROOT=%s WWWRELPATH=%s %s -f %s -C %s %s %s 2>&1", docroot, relpath, cfg->makeProgram, cfg->makefileName, (const char*)dirname(makefile), cfg->makeOptions, make_target); if (cfg->debug) ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: cmd:%s",cmd); // Run Makefile to make target FILE* makep=popen(cmd,"r"); if (!makep) { // If launching make fails, output errors from make and return HTTP error if (cfg->debug) ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: failed to popen:%s",cmd); return HTTP_INTERNAL_SERVER_ERROR; } // Compile regex regex_t regex; char* regexstr=apr_psprintf(r->pool, "^make:[[:space:]]+\\*\\*\\*[[:space:]]+No[[:space:]]+rule[[:space:]]+to[[:space:]]+make[[:space:]]+target[[:space:]]+`%s'\\.[[:space:]]+Stop\\.", make_target ); if (regcomp(®ex,regexstr,REG_EXTENDED)) { if (cfg->debug) ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: regcomp failed"); return HTTP_INTERNAL_SERVER_ERROR; } int bSilentFail=FALSE; // Read output of make size_t make_output_size=10240; // TODO: allow the buffer to grow beyond 10K char* make_output=apr_palloc(r->pool,make_output_size); make_output[0]='\0'; make_output_size--; p=make_output; // reuse p do { const char* newp=fgets(p,make_output_size,makep); if (newp) { if (cfg->debug) ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: make output:%s",newp); make_output_size-=strlen(newp); p+=strlen(newp); if (regexec(®ex,newp,0,0,0)==0) { if (cfg->debug) ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: regex match:%s",newp); bSilentFail=TRUE; } } } while (!feof(makep) && make_output_size>1); if (!make_output_size) { if (cfg->debug) ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: make output exceeded max length"); // TODO: add appropriate message to make_output } int ret=pclose(makep); if (cfg->debug) ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: make exit code:%d",WEXITSTATUS(ret)); if (WEXITSTATUS(ret)) {// make did not complete successfully, output make's output and tell Apache to stop. if (bSilentFail) { if (cfg->debug) ap_log_rerror(APLOG_MARK,APLOG_ERR,0,r,"mod_make: silently failing."); return DECLINED; } // Store make_output in request_rec so that the handler can display it apr_table_set(r->notes,"make_output",make_output); // Redirect to our own content handler ap_internal_redirect(cfg->errorURI,r); return OK; } return DECLINED; }
/* * ic_transfer_response() * ---------------------- * Read the response from the Interchange server * and relay it to the client */ static int ic_transfer_response(request_rec *r,BUFF *ic_buff) { const char *location; int rc,ic_sock; char sbuf[MAX_STRING_LEN],argsbuffer[MAX_STRING_LEN]; /* * get the socket we are using to talk to the * Interchange server, and wait for Interchange to * send us some data */ ic_sock = ap_bfileno(ic_buff,B_RD); rc = ic_select(ic_sock,0,IC_DEFAULT_TIMEOUT,0); if (rc < 0){ ap_log_reason("Failed to select the response header",r->uri,r); return HTTP_INTERNAL_SERVER_ERROR; } /* * check the HTTP header to make sure that it looks valid */ if ((rc = ap_scan_script_header_err_buff(r,ic_buff,sbuf)) != OK) { if (rc == HTTP_INTERNAL_SERVER_ERROR) { ap_log_rerror(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO,r,"Malformed header return by Interchange: %s",sbuf); } return rc; } /* * check the header for an HTTP redirect request */ location = ap_table_get(r->headers_out,"Location"); if (r->status == 200 && location){ fd_set sock_set; /* * check if we need to do an external redirect */ if (*location != '/') return REDIRECT; /* * we are here because we need to do an internal redirect * * soak up any data from the Interchange socket */ rc = ic_select(ic_sock,0,IC_DEFAULT_TIMEOUT,0); if (rc < 0){ ap_log_reason("Failed to select the response text",r->uri,r); return HTTP_INTERNAL_SERVER_ERROR; } /* * soak up any body-text sent by the Interchange server */ ap_soft_timeout("mod_interchange: Interchange read",r); while (ap_bgets(argsbuffer,MAX_STRING_LEN,ic_buff) > 0) ; ap_kill_timeout(r); /* * always use the GET method for internal redirects * also, unset the Content-Length so that nothing * else tries to re-read the text we just soaked up */ r->method = ap_pstrdup(r->pool,"GET"); r->method_number = M_GET; ap_table_unset(r->headers_in,"Content-Length"); ap_internal_redirect(location,r); return OK; } /* * we were not redirected, so send the HTTP headers * to the client */ ap_hard_timeout("mod_interchange: Client write",r); ap_send_http_header(r); if (ap_rflush(r) < 0){ ap_log_reason("error sending headers to client",r->uri,r); return HTTP_INTERNAL_SERVER_ERROR; } /* * if Interchange is sending body text (HTML), then * relay this to the client */ if (!r->header_only){ ap_reset_timeout(r); if ((rc = ap_bnonblock(ic_buff,B_RD)) != 0){ ap_log_reason("error turning non blocking I/O on Interchange socket",r->uri,r); return HTTP_INTERNAL_SERVER_ERROR; } ap_bsetflag(ic_buff,B_SAFEREAD,1); if (ap_send_fb(ic_buff,r) <= 0){ ap_log_reason("error sending response body to client",r->uri,r); return HTTP_INTERNAL_SERVER_ERROR; } } ap_kill_timeout(r); return OK; }