On 07/24/2015 02:09 PM, [email protected] wrote: > Author: icing > Date: Fri Jul 24 12:09:44 2015 > New Revision: 1692486 > > URL: http://svn.apache.org/r1692486 > Log: > new Protocols directive and core API changes to enable protocol switching on > HTTP Upgrade or ALPN, implemented in mod_ssl and mod_h2 > > Added: > httpd/httpd/trunk/modules/http2/h2_switch.c > - copied, changed from r1692482, > httpd/httpd/trunk/modules/http2/h2_alpn.c > httpd/httpd/trunk/modules/http2/h2_switch.h > - copied, changed from r1692482, > httpd/httpd/trunk/modules/http2/h2_alpn.h > Removed: > httpd/httpd/trunk/modules/http2/h2_alpn.c > httpd/httpd/trunk/modules/http2/h2_alpn.h > httpd/httpd/trunk/modules/http2/h2_upgrade.c > httpd/httpd/trunk/modules/http2/h2_upgrade.h > Modified: > httpd/httpd/trunk/docs/log-message-tags/next-number > httpd/httpd/trunk/include/http_core.h > httpd/httpd/trunk/include/http_protocol.h > httpd/httpd/trunk/modules/http2/config.m4 > httpd/httpd/trunk/modules/http2/h2_conn.c > httpd/httpd/trunk/modules/http2/h2_ctx.c > httpd/httpd/trunk/modules/http2/h2_ctx.h > httpd/httpd/trunk/modules/http2/h2_from_h1.c > httpd/httpd/trunk/modules/http2/h2_h2.c > httpd/httpd/trunk/modules/http2/h2_h2.h > httpd/httpd/trunk/modules/http2/h2_mplx.c > httpd/httpd/trunk/modules/http2/h2_request.c > httpd/httpd/trunk/modules/http2/h2_response.c > httpd/httpd/trunk/modules/http2/h2_session.c > httpd/httpd/trunk/modules/http2/h2_task.c > httpd/httpd/trunk/modules/http2/h2_task_input.c > httpd/httpd/trunk/modules/http2/h2_to_h1.c > httpd/httpd/trunk/modules/http2/h2_util.c > httpd/httpd/trunk/modules/http2/h2_util.h > httpd/httpd/trunk/modules/http2/h2_version.h > httpd/httpd/trunk/modules/http2/h2_worker.c > httpd/httpd/trunk/modules/http2/h2_workers.c > httpd/httpd/trunk/modules/http2/mod_h2.c > httpd/httpd/trunk/modules/http2/mod_h2.h > httpd/httpd/trunk/modules/ssl/mod_ssl.c > httpd/httpd/trunk/modules/ssl/mod_ssl.h > httpd/httpd/trunk/modules/ssl/ssl_engine_config.c > httpd/httpd/trunk/modules/ssl/ssl_engine_io.c > httpd/httpd/trunk/modules/ssl/ssl_engine_kernel.c > httpd/httpd/trunk/modules/ssl/ssl_private.h > httpd/httpd/trunk/server/core.c > httpd/httpd/trunk/server/protocol.c >
> Modified: httpd/httpd/trunk/server/core.c > URL: > http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=1692486&r1=1692485&r2=1692486&view=diff > ============================================================================== > --- httpd/httpd/trunk/server/core.c (original) > +++ httpd/httpd/trunk/server/core.c Fri Jul 24 12:09:44 2015 > @@ -478,6 +478,8 @@ static void *create_core_server_config(a > @@ -3799,12 +3803,33 @@ static const char *set_trace_enable(cmd_ > return NULL; > } > > +static const char *set_protocols(cmd_parms *cmd, void *dummy, > + const char *arg) > +{ > + core_server_config *conf = > + ap_get_core_module_config(cmd->server->module_config); > + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE); > + > + if (err) { > + return err; > + } > + > + /* Should we check for some ALPN valid char sequence here? */ > + const char **np = (const char **)apr_array_push(conf->protocols); > + *np = arg; > + > + return NULL; > +} > + > static const char *set_http_protocol(cmd_parms *cmd, void *dummy, > const char *arg) > { > core_server_config *conf = > ap_get_core_module_config(cmd->server->module_config); > > + if (!conf->protocols) { > + > + } What is the purpose of the above? > if (strncmp(arg, "min=", 4) == 0) { > arg += 4; > if (strcmp(arg, "0.9") == 0) > @@ -5226,6 +5253,73 @@ static void core_dump_config(apr_pool_t > } > } > > +static const char *core_protocol_get(const conn_rec *c) > +{ > + return AP_PROTOCOL_HTTP1; > +} > + > +static int core_upgrade_handler(request_rec *r) > +{ > + conn_rec *c = r->connection; > + const char *upgrade = apr_table_get(r->headers_in, "Upgrade"); > + > + if (upgrade && *upgrade) { > + const char *conn = apr_table_get(r->headers_in, "Connection"); > + if (ap_find_token(r->pool, conn, "upgrade")) { > + apr_array_header_t *offers = NULL; > + const char *err; > + > + err = ap_parse_token_list_strict(r->pool, upgrade, &offers, 0); > + if (err) { > + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02910) > + "parsing Upgrade header: %s", err); > + return DECLINED; > + } > + > + if (offers && offers->nelts > 0) { > + const char *protocol = ap_select_protocol(c, r, r->server, > + offers); > + if (strcmp(protocol, ap_run_protocol_get(c))) { > + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, > APLOGNO(02909) > + "Upgrade selects '%s'", protocol); > + /* Let the client know what we are upgrading to. */ > + apr_table_clear(r->headers_out); > + apr_table_setn(r->headers_out, "Upgrade", protocol); > + apr_table_setn(r->headers_out, "Connection", "Upgrade"); > + > + r->status = HTTP_SWITCHING_PROTOCOLS; > + r->status_line = ap_get_status_line(r->status); > + ap_send_interim_response(r, 1); > + > + ap_switch_protocol(c, r, r->server, protocol); > + > + /* make sure httpd closes the connection after this */ > + c->keepalive = AP_CONN_CLOSE; > + ap_lingering_close(c); > + > + if (c->sbh) { > + ap_update_child_status_from_conn(c->sbh, > + SERVER_CLOSING, c); > + } The c->keepalive = AP_CONN_CLOSE looks fine to me, but why should we do the other stuff in a handler. IMHO that should be done by the existing code. > + > + return DONE; > + } > + } > + } > + } > + > + return DECLINED; > +} > + > +static int core_upgrade_storage(request_rec *r) > +{ > + if ((r->method_number == M_OPTIONS) && r->uri && (r->uri[0] == '*') && > + (r->uri[1] == '\0')) { > + return core_upgrade_handler(r); > + } > + return DECLINED; > +} > + Why do we need to handle upgrades on OPTIONS requests? Regards RĂ¼diger
