{
int head_present = 1;
int termarg;
+ int res;
+ int old_status;
const char *termch;
apr_size_t ate = 0;
* or the http/x.x xxx message format
*/
if (toklen && apr_isdigit(*stattok)) {
- statlen -= toklen;
+ statlen = toklen;
stat = stattok;
}
}
*
* Parse them out, or die trying
*/
+ old_status = cid->r->status;
+
if (stat) {
- cid->r->status = ap_scan_script_header_err_strs(cid->r, NULL,
- &termch, &termarg, stat, head, NULL);
+ res = ap_scan_script_header_err_strs(cid->r, NULL, &termch, &termarg,
+ stat, head, NULL);
+ }
+ else {
+ res = ap_scan_script_header_err_strs(cid->r, NULL, &termch, &termarg,
+ head, NULL);
+ }
+
+ /* Set our status. */
+ if (res) {
+ /* This is an immediate error result from the parser
+ */
+ cid->r->status = res;
+ cid->r->status_line = ap_get_status_line(cid->r->status);
+ cid->ecb->dwHttpStatusCode = cid->r->status;
+ }
+ else if (cid->r->status) {
+ /* We have a status in r->status, so let's just use it.
+ * This is likely to be the Status: parsed above, and
+ * may also be a delayed error result from the parser.
+ * If it was filled in, status_line should also have
+ * been filled in.
+ */
+ cid->ecb->dwHttpStatusCode = cid->r->status;
+ }
+ else if (cid->ecb->dwHttpStatusCode
+ && cid->ecb->dwHttpStatusCode != HTTP_OK) {
+ /* 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 if (old_status) {
+ /* Well... either there is no dwHttpStatusCode or it's HTTP_OK.
+ * In any case, we don't have a good status to return yet...
+ * Perhaps the one we came in with will be better. Let's use it,
+ * if we were given one (note this is a pendantic case, it would
+ * normally be covered above unless the scan script code unset
+ * the r->status). Should there be a check here as to whether
+ * we are setting a valid response code?
+ */
+ cid->r->status = old_status;
+ cid->r->status_line = ap_get_status_line(cid->r->status);
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;
- }
+ /* None of dwHttpStatusCode, the parser's r->status nor the
+ * old value of r->status were helpful, and nothing was decoded
+ * from Status: string passed to us. Let's just say HTTP_OK
+ * and get the data out, this was the isapi dev's oversight.
+ */
+ cid->r->status = HTTP_OK;
+ cid->r->status_line = ap_get_status_line(cid->r->status);
+ cid->ecb->dwHttpStatusCode = cid->r->status;
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, cid->r,
+ "ISAPI: Could not determine HTTP response code; using %d",
+ cid->r->status);
}
+
if (cid->r->status == HTTP_INTERNAL_SERVER_ERROR) {
return -1;
}
*size_arg, ERROR_WRITE_FAULT);
}
}
- return (rv == OK);
+ return (rv == APR_SUCCESS);
}
int APR_THREAD_FUNC ServerSupportFunction(isapi_cid *cid,
conn_rec *c = r->connection;
char *buf_data = (char*)buf_ptr;
request_rec *subreq;
+ apr_status_t rv;
switch (HSE_code) {
case HSE_REQ_SEND_URL_REDIRECT_RESP:
APR_BRIGADE_INSERT_TAIL(bb, b);
b = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
- ap_pass_brigade(cid->r->output_filters, bb);
+ rv = ap_pass_brigade(cid->r->output_filters, bb);
cid->response_sent = 1;
+ return (rv == APR_SUCCESS);
}
- return 1;
}
case HSE_REQ_DONE_WITH_SESSION:
/* Map a URL to a filename */
char *file = (char *)buf_data;
apr_uint32_t len;
- subreq = ap_sub_req_lookup_uri(apr_pstrndup(r->pool, file, *buf_size),
- r, NULL);
+ subreq = ap_sub_req_lookup_uri(
+ apr_pstrndup(cid->r->pool, file, *buf_size), r, NULL);
+
+ if (!subreq->filename) {
+ ap_destroy_sub_req(subreq);
+ return 0;
+ }
+
+ len = (apr_uint32_t)strlen(r->filename);
- len = apr_cpystrn(file, subreq->filename, *buf_size) - file;
+ if ((subreq->finfo.filetype == APR_DIR)
+ && (!subreq->path_info)
+ && (file[len - 1] != '/'))
+ file = apr_pstrcat(cid->r->pool, subreq->filename, "/", NULL);
+ else
+ file = apr_pstrcat(cid->r->pool, subreq->filename,
+ subreq->path_info, NULL);
+ ap_destroy_sub_req(subreq);
+
+#ifdef WIN32
+ /* We need to make this a real Windows path name */
+ apr_filepath_merge(&file, "", file, APR_FILEPATH_NATIVE, r->pool);
+#endif
+
+ *buf_size = apr_cpystrn(buf_data, file, *buf_size) - buf_data;
- /* IIS puts a trailing slash on directories, Apache doesn't */
- if (subreq->finfo.filetype == APR_DIR) {
- if (len < *buf_size - 1) {
- file[len++] = '\\';
- file[len] = '\0';
- }
- }
- *buf_size = len;
return 1;
}
HSE_TF_INFO *tf = (HSE_TF_INFO*)buf_data;
apr_uint32_t sent = 0;
apr_ssize_t ate = 0;
- apr_status_t rv;
apr_bucket_brigade *bb;
apr_bucket *b;
apr_file_t *fd;
}
sent += (apr_uint32_t)fsize;
-#if APR_HAS_LARGE_FILES
- if (r->finfo.size > AP_MAX_SENDFILE) {
- /* APR_HAS_LARGE_FILES issue; must split into mutiple buckets,
- * no greater than MAX(apr_size_t), and more granular than that
- * in case the brigade code/filters attempt to read it directly.
- */
- b = apr_bucket_file_create(fd, tf->Offset, AP_MAX_SENDFILE,
- r->pool, c->bucket_alloc);
- while (fsize > AP_MAX_SENDFILE) {
- apr_bucket *bc;
- apr_bucket_copy(b, &bc);
- APR_BRIGADE_INSERT_TAIL(bb, bc);
- b->start += AP_MAX_SENDFILE;
- fsize -= AP_MAX_SENDFILE;
- }
- b->length = (apr_size_t)fsize; /* Resize just the last bucket */
- }
- else
-#endif
- b = apr_bucket_file_create(fd, tf->Offset, (apr_size_t)fsize,
- r->pool, c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(bb, b);
+ apr_brigade_insert_file(bb, fd, tf->Offset, fsize, r->pool);
if (tf->pTail && tf->TailLength) {
sent += tf->TailLength;
b = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
- ap_pass_brigade(r->output_filters, bb);
+ rv = ap_pass_brigade(r->output_filters, bb);
cid->response_sent = 1;
/* Use tf->pfnHseIO + tf->pContext, or if NULL, then use cid->fnIOComplete
}
}
}
- return (rv == OK);
+ return (rv == APR_SUCCESS);
}
case HSE_REQ_REFRESH_ISAPI_ACL:
APR_BRIGADE_INSERT_TAIL(bb, b);
b = apr_bucket_flush_create(c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, b);
- ap_pass_brigade(cid->r->output_filters, bb);
+ rv = ap_pass_brigade(cid->r->output_filters, bb);
cid->response_sent = 1;
}
- return 1;
+ return (rv == APR_SUCCESS);
}
case HSE_REQ_CLOSE_CONNECTION: /* Added after ISAPI 4.0 */
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. */
+ return (rv == APR_SUCCESS);
+ /* 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