From: Nick Kew Date: Sun, 7 Oct 2007 13:41:50 +0000 (+0000) Subject: Introduce ap_send_interim_response function and API, for interim X-Git-Tag: 2.3.0~1354 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3d1465d445ed7240fd4b26142fc5892a73e3d4a4;p=apache Introduce ap_send_interim_response function and API, for interim (HTTP 1xx) responses sent by an application or backend. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@582630 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/http_protocol.h b/include/http_protocol.h index e8355e17a6..4cf351e13d 100644 --- a/include/http_protocol.h +++ b/include/http_protocol.h @@ -664,6 +664,12 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, const request_rec *r * @param sub_r Subrequest that is now compete */ AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub_r); + +/** + * Send an interim (HTTP 1xx) response immediately. + * @param r The request + */ +AP_DECLARE(void) ap_send_interim_response(request_rec *r); #ifdef __cplusplus } diff --git a/server/protocol.c b/server/protocol.c index b31dbd9106..6a878ca27d 100644 --- a/server/protocol.c +++ b/server/protocol.c @@ -1631,6 +1631,41 @@ AP_DECLARE(void) ap_set_last_modified(request_rec *r) } } +typedef struct hdr_ptr { + ap_filter_t *f; + apr_bucket_brigade *bb; +} hdr_ptr; +static int send_header(void *data, const char *key, const char *val) +{ + ap_fputstrs(((hdr_ptr*)data)->f, ((hdr_ptr*)data)->bb, + key, ": ", val, CRLF, NULL); + return 1; +} +AP_DECLARE(void) ap_send_interim_response(request_rec *r) +{ + hdr_ptr x; + + if (r->proto_num < 1001) { + /* don't send interim response to HTTP/1.0 Client */ + return; + } + if (!ap_is_HTTP_INFO(r->status)) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, NULL, + "Status is %d - not sending interim response", r->status); + return; + } + + x.f = r->connection->output_filters; + x.bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); + ap_fputstrs(x.f, x.bb, AP_SERVER_PROTOCOL, " ", r->status_line, CRLF, NULL); + apr_table_do(send_header, &x, r->headers_out, NULL); + ap_fputs(x.f, x.bb, CRLF); + ap_fflush(x.f, x.bb); + apr_brigade_destroy(x.bb); + apr_table_clear(r->headers_out); +} + + AP_IMPLEMENT_HOOK_RUN_ALL(int,post_read_request, (request_rec *r), (r), OK, DECLINED) AP_IMPLEMENT_HOOK_RUN_ALL(int,log_transaction,