You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by wr...@apache.org on 2002/11/04 14:44:30 UTC
cvs commit: httpd-2.0/modules/arch/win32 mod_isapi.c
wrowe 2002/11/04 05:44:30
Modified: modules/arch/win32 mod_isapi.c
Log:
Fix for PR 10216 ... we should not return the status unless we want the
core to ap_die for us. If we've handled the response (as determined
by a new response_sent flag) then the server does not need to do so.
Revision Changes Path
1.85 +60 -14 httpd-2.0/modules/arch/win32/mod_isapi.c
Index: mod_isapi.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/arch/win32/mod_isapi.c,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -r1.84 -r1.85
--- mod_isapi.c 26 Aug 2002 20:16:33 -0000 1.84
+++ mod_isapi.c 4 Nov 2002 13:44:30 -0000 1.85
@@ -520,7 +520,8 @@
isapi_dir_conf dconf;
isapi_loaded *isa;
request_rec *r;
- int headers_sent;
+ int headers_set;
+ int response_sent;
PFN_HSE_IO_COMPLETION completion;
void *completion_arg;
apr_thread_mutex_t *completed;
@@ -642,6 +643,7 @@
b = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
rv = ap_pass_brigade(r->output_filters, bb);
+ cid->response_sent = 1;
if ((flags & HSE_IO_ASYNC) && cid->completion) {
if (rv == OK) {
@@ -763,21 +765,36 @@
if (stat) {
cid->r->status = ap_scan_script_header_err_strs(cid->r, NULL,
&termch, &termarg, stat, head, NULL);
+ cid->ecb->dwHttpStatusCode = cid->r->status;
}
else {
cid->r->status = ap_scan_script_header_err_strs(cid->r, NULL,
&termch, &termarg, head, NULL);
+ if (cid->ecb->dwHttpStatusCode && cid->r->status == HTTP_OK
+ && cid->ecb->dwHttpStatusCode != HTTP_OK) {
+ /* We tried every way to Sunday to get the status...
+ * so now we fall back on dwHttpStatusCode if it appears
+ * ap_scan_script_header fell back on the default code.
+ * Any other results set dwHttpStatusCode to the decoded
+ * status value.
+ */
+ cid->r->status = cid->ecb->dwHttpStatusCode;
+ cid->r->status_line = ap_get_status_line(cid->r->status);
+ }
+ else {
+ cid->ecb->dwHttpStatusCode = cid->r->status;
+ }
}
- cid->ecb->dwHttpStatusCode = cid->r->status;
- if (cid->r->status == HTTP_INTERNAL_SERVER_ERROR)
+ if (cid->r->status == HTTP_INTERNAL_SERVER_ERROR) {
return -1;
+ }
/* If only Status was passed, we consumed nothing
*/
if (!head_present)
return 0;
- cid->headers_sent = 1;
+ cid->headers_set = 1;
/* If all went well, tell the caller we consumed the headers complete
*/
@@ -816,6 +833,8 @@
*/
apr_table_set (r->headers_out, "Location", buf_data);
cid->r->status = cid->ecb->dwHttpStatusCode = HTTP_MOVED_TEMPORARILY;
+ cid->r->status_line = ap_get_status_line(cid->r->status);
+ cid->headers_set = 1;
return 1;
case HSE_REQ_SEND_URL:
@@ -863,6 +882,7 @@
b = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
ap_pass_brigade(cid->r->output_filters, bb);
+ cid->response_sent = 1;
}
return 1;
}
@@ -1001,8 +1021,8 @@
strlen(tf->pszStatusCode),
tf->HeadLength);
}
- else if (!cid->headers_sent && tf->pHead && tf->HeadLength
- && *(char*)tf->pHead) {
+ else if (!cid->headers_set && tf->pHead && tf->HeadLength
+ && *(char*)tf->pHead) {
ate = send_response_header(cid, NULL, (char*)tf->pHead,
0, tf->HeadLength);
if (ate < 0)
@@ -1054,6 +1074,7 @@
b = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
ap_pass_brigade(r->output_filters, bb);
+ cid->response_sent = 1;
/* Use tf->pfnHseIO + tf->pContext, or if NULL, then use cid->fnIOComplete
* pass pContect to the HseIO callback.
@@ -1253,6 +1274,7 @@
b = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
ap_pass_brigade(cid->r->output_filters, bb);
+ cid->response_sent = 1;
}
return 1;
}
@@ -1376,7 +1398,7 @@
cid->ecb->ConnID = cid;
cid->isa = isa;
cid->r = r;
- cid->r->status = 0;
+ r->status = 0;
cid->ecb->cbSize = sizeof(EXTENSION_CONTROL_BLOCK);
cid->ecb->dwVersion = isa->report_version;
@@ -1512,29 +1534,53 @@
"ISAPI: asynch I/O result HSE_STATUS_PENDING "
"from HttpExtensionProc() is not supported: %s",
r->filename);
- cid->r->status = HTTP_INTERNAL_SERVER_ERROR;
+ r->status = HTTP_INTERNAL_SERVER_ERROR;
}
break;
case HSE_STATUS_ERROR:
/* end response if we have yet to do so.
*/
- cid->r->status = HTTP_INTERNAL_SERVER_ERROR;
+ r->status = HTTP_INTERNAL_SERVER_ERROR;
break;
default:
/* TODO: log unrecognized retval for debugging
*/
- cid->r->status = HTTP_INTERNAL_SERVER_ERROR;
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ "ISAPI: return code %d from HttpExtensionProc() "
+ "was not not recognized", rv);
+ r->status = HTTP_INTERNAL_SERVER_ERROR;
break;
}
- /* Set the status (for logging) */
- if (cid->ecb->dwHttpStatusCode) {
- cid->r->status = cid->ecb->dwHttpStatusCode;
+ /* Flush the response now, including headers-only responses */
+ if (cid->headers_set) {
+ conn_rec *c = r->connection;
+ apr_bucket_brigade *bb;
+ apr_bucket *b;
+ apr_status_t rv;
+
+ bb = apr_brigade_create(r->pool, c->bucket_alloc);
+ b = apr_bucket_eos_create(c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, b);
+ rv = ap_pass_brigade(r->output_filters, bb);
+ cid->response_sent = 1;
+
+ return OK; /* NOT r->status or cid->r->status, even if it has changed. */
+ }
+
+ /* As the client returned no error, and if we did not error out
+ * ourselves, trust dwHttpStatusCode to say something relevant.
+ */
+ if (!ap_is_HTTP_SERVER_ERROR(r->status) && cid->ecb->dwHttpStatusCode) {
+ r->status = cid->ecb->dwHttpStatusCode;
}
- return cid->r->status;
+ /* For all missing-response situations simply return the status.
+ * and let the core deal respond to the client.
+ */
+ return r->status;
}
/**********************************************************