Commit 46e37b4e authored by Stefan Eissing's avatar Stefan Eissing
Browse files

update of mod_http2 with current trunk version

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1715371 13f79535-47bb-0310-9956-ffa450edef68
parent 9dda72f0
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -2,6 +2,47 @@

Changes with Apache 2.4.18

  *) mod_http2: incoming trailers (headers after request body) are properly
     forwarded to the processing engine. [Stefan Eissing]

  *) mod_http2: new directive 'H2Push' to en-/disable HTTP/2 server
     pushes a server/virtual host. Pushes are initiated by the presence
     of 'Link:' headers with relation 'preload' on a response. [Stefan Eissing]
     
  *) mod_http2: write performance of http2 improved for larger resources,
     especially static files. [Stefan Eissing]
     
  *) core: if the first HTTP/1.1 request on a connection goes to a server that
     prefers different protocols, these protocols are announced in a Upgrade:
     header on the response, mentioning the preferred protocols.
     [Stefan Eissing]
     
  *) mod_http2: new directives 'H2TLSWarmUpSize' and 'H2TLSCoolDownSecs'
     to control TLS record sizes during connection lifetime.
     [Stefan Eissing]
     
  *) mod_http2: new directive 'H2ModernTLSOnly' to enforce security
     requirements of RFC 7540 on TLS connections. [Stefan Eissing]
     
  *) core: add ap_get_protocol_upgrades() to retrieve the list of protocols
     that a client could possibly upgrade to. Use in first request on a 
     connection to announce protocol choices. [Stefan Eissing]

  *) mod_http2: reworked deallocation on connection shutdown and worker
     abort. Separate parent pool for all workers. worker threads are joined
     on planned worker shutdown. [Yann Ylavic, Stefan Eissing]
     
  *) mod_ssl: when receiving requests for other virtual hosts than the handshake
     server, the SSL parameters are checked for equality. With equal 
     configuration, requests are passed for processing. Any change will trigger
     the old behaviour of "421 Misdirected Request".
     SSL now remembers the cipher suite that was used for the last handshake.
     This is compared against for any vhost/directory cipher specification. 
     Detailed examination of renegotiation is only done when these do not
     match.
     Renegotiation is 403ed when a master connection is present. Exact reason
     is given additionally in a request note. [Stefan Eissing]

  *) core: Fix scoreboard crash (SIGBUS) on hardware requiring strict 64bit
     alignment (SPARC64, PPC64).  [Yann Ylavic]

+292 −5
Original line number Diff line number Diff line
@@ -42,13 +42,22 @@
          release relative to other standard modules. Users are encouraged to 
          consult the "CHANGES" file for potential updates.</p>
        </note>

        <p>You must enable HTTP/2 via <directive
        module="core">Protocols</directive> in order to use the
        functionality described in this document:</p>

        <highlight language="config">
            Protocols h2 http/1.1
        </highlight>

    </summary>
    
    <directivesynopsis>
        <name>H2Direct</name>
        <description>H2 Direct Protocol Switch</description>
        <syntax>H2Direct on|off</syntax>
        <default>H2Direct on (for non TLS)</default>
        <default>H2Direct on for h2c, off for h2 protocol</default>
        <contextlist>
            <context>server config</context>
            <context>virtual host</context>
@@ -60,12 +69,31 @@
                should be used inside a 
                <directive module="core" type="section">VirtualHost</directive> 
                section to enable direct HTTP/2 communication for that virtual host. 
            </p>
            <p>
                Direct communication means that if the first bytes received by the 
                server on a connection match the HTTP/2 preamble, the HTTP/2
                protocol is switched to immediately without further negotiation.
                This mode falls outside the RFC 7540 but has become widely implemented
                as it is very convenient for development and testing. 
                By default the direct HTTP/2 mode is enabled.
                This mode is defined in RFC 7540 for the cleartext (h2c) case. Its
                use on TLS connections not mandated by the standard.
            </p>
            <p>
                When a server/vhost does not have h2 or h2c enabled via
                <directive module="core" type="section">Protocols</directive>,
                the connection is never inspected for a HTTP/2 preamble. H2Direct
                does not matter then. This is important for connections that
                use protocols where an initial read might hang indefinitely, such
                as NNTP.
            </p>
            <p>
                For clients that have out-of-band knowledge about a server
                supporting h2c, direct HTTP/2 saves the client from having to
                perform an HTTP/1.1 upgrade, resulting in better performance
                and avoiding the Upgrade restrictions on request bodies.
            </p>
            <p>
                This makes direct h2c attractive for server to server communication
                as well, when the connection can be trusted or is secured by other means.
            </p>
            <example><title>Example</title>
                <highlight language="config">
@@ -75,6 +103,122 @@
        </usage>
    </directivesynopsis>

    <directivesynopsis>
        <name>H2Push</name>
        <description>H2 Server Push Switch</description>
        <syntax>H2Push on|off</syntax>
        <default>H2Push on</default>
        <contextlist>
            <context>server config</context>
            <context>virtual host</context>
        </contextlist>
        
        <usage>
            <p>
                This directive toggles the usage of the HTTP/2 server push 
                protocol feature. This should be used inside a 
                <directive module="core" type="section">VirtualHost</directive> 
                section to enable direct HTTP/2 communication for that virtual host. 
            </p>
            <p>
                The HTTP/2 protocol allows the server to push other resources to
                a client when it asked for a particular one. This is helpful
                if those resources are connected in some way and the client can
                be expected to ask for it anyway. The pushing then saves the
                time it takes the client to ask for the resources itself. On the
                other hand, pushing resources the client never needs or already
                has is a waste of bandwidth.
            </p>
            <p>
                Server pushes are detected by inspecting the <code>Link</code> headers of
                responses (see https://tools.ietf.org/html/rfc5988 for the 
                specification). When a link thus specified has the <code>rel=preload</code>
                attribute, it is treated as a resource to be pushed.
            </p>
            <p> 
                Link headers in responses are either set by the application or
                can be configured via <module>mod_headers</module> as:
            </p>
            <example><title>mod_headers example</title>
                <highlight language="config">
&lt;Location /index.html&gt;
    Header add Link "&lt;/css/site.css&gt;;rel=preload"
    Header add Link "&lt;/images/logo.jpg&gt;;rel=preload"
&lt;/Location&gt;
                </highlight>
            </example>
            <p>
                As the example shows, there can be several link headers added
                to a response, resulting in several pushes being triggered. There
                are no checks in the module to avoid pushing the same resource
                twice or more to one client. Use with care.
            </p>
            <p> 
                HTTP/2 server pushes are enabled by default. This directive 
                allows it to be switch off on all resources of this server/virtual
                host.
            </p>
            <example><title>Example</title>
                <highlight language="config">
                    H2Push off
                </highlight>
            </example>
            <p>
                Last but not least, pushes happen only when the client signals
                its willingness to accept those. Most browsers do, some, like Safari 9,
                do not.
            </p>
        </usage>
    </directivesynopsis>

    <directivesynopsis>
        <name>H2Upgrade</name>
        <description>H2 Upgrade Protocol Switch</description>
        <syntax>H2Upgrade on|off</syntax>
        <default>H2Upgrade on for h2c, off for h2 protocol</default>
        <contextlist>
            <context>server config</context>
            <context>virtual host</context>
        </contextlist>
        
        <usage>
            <p>
                This directive toggles the usage of the HTTP/1.1 Upgrade method 
                for switching to HTTP/2. This
                should be used inside a 
                <directive module="core" type="section">VirtualHost</directive> 
                section to enable Upgrades to HTTP/2 for that virtual host. 
            </p>
            <p>
                This method of switching protocols is defined in HTTP/1.1 and
                uses the "Upgrade" header (thus the name) to announce willingness
                to use another protocol. This may happen on any request of a
                HTTP/1.1 connection.
            </p>
            <p>
                This method of protocol switching is enabled by default on cleartext
                (potential h2c) connections and disabled on TLS (potential h2), 
                as mandated by RFC 7540. 
            </p>
            <p>
                Please be aware that Upgrades are only accepted for requests
                that carry no body. POSTs and PUTs with content will never
                trigger an upgrade to HTTP/2. 
                See <directive type="section">H2Direct</directive> for an 
                alternative to Upgrade.
            </p>
            <p>
                This mode only has an effect when h2 or h2c is enabled via
                the <directive module="core" type="section">Protocols</directive>.
            </p>
            <example><title>Example</title>
                <highlight language="config">
                    H2Upgrade on
                </highlight>
            </example>
        </usage>
    </directivesynopsis>
    
    <directivesynopsis>
        <name>H2MaxSessionStreams</name>
        <description>Maximum number of active streams per HTTP/2 session.</description>
@@ -230,7 +374,7 @@
            <p>
                This directive sets maximum number of <em>extra</em> file handles
                a HTTP/2 session is allowed to use. A file handle is counted as
                <em>extra</em> when it is transfered from a h2 worker thread to
                <em>extra</em> when it is transferred from a h2 worker thread to
                the main HTTP/2 connection handling. This commonly happens when
                serving static files.
            </p><p>
@@ -282,4 +426,147 @@
        </usage>
    </directivesynopsis>

    <directivesynopsis>
        <name>H2ModernTLSOnly</name>
        <description>Require HTTP/2 connections to be "modern TLS" only</description>
        <syntax>H2ModernTLSOnly on|off</syntax>
        <default>H2ModernTLSOnly on</default>
        <contextlist>
            <context>server config</context>
            <context>virtual host</context>
        </contextlist>
        
        <usage>
            <p>
                This directive toggles the security checks on HTTP/2 connections
                in TLS mode (https:). This can be used server wide or for specific
                <directive module="core" type="section">VirtualHost</directive>s. 
            </p>
            <p>
                The security checks require that the TSL protocol is at least
                TLSv1.2 and that none of the ciphers listed in RFC 7540, Appendix A
                is used. These checks will be extended once new security requirements
                come into place.
            </p>
            <p>
                The name stems from the 
                <a href="https://wiki.mozilla.org/Security/Server_Side_TLS">Security/Server Side TLS</a>
                definitions at mozilla where "modern compatibility" is defined. Mozilla Firefox and
                other browsers require modern compatibility for HTTP/2 connections. As everything
                in OpSec, this is a moving target and can be expected to evolve in the future.
            </p>
            <p>
                One purpose of having these checks in mod_http2 is to enforce this
                security level for all connections, not only those from browsers. The other
                purpose is to prevent the negotiation of HTTP/2 as a protocol should
                the requirements not be met.
            </p>
            <p>
                Ultimately, the security of the TLS connection is determined by the
                server configuration directives for mod_ssl.
            </p>
            <example><title>Example</title>
                <highlight language="config">
                    H2ModernTLSOnly off
                </highlight>
            </example>
        </usage>
    </directivesynopsis>

    <directivesynopsis>
        <name>H2TLSWarmUpSize</name>
        <description></description>
        <syntax>H2TLSWarmUpSize amount</syntax>
        <default>H2TLSWarmUpSize 1048576</default>
        <contextlist>
            <context>server config</context>
            <context>virtual host</context>
        </contextlist>
        
        <usage>
            <p>
                This directive sets the number of bytes to be sent in small
                TLS records (~1300 bytes) until doing maximum sized writes (16k)
                on https: HTTP/2 connections.
                This can be used server wide or for specific
                <directive module="core" type="section">VirtualHost</directive>s. 
            </p>
            <p>
                Measurements by <a href="https://www.igvita.com">google performance
                labs</a> show that best performance on TLS connections is reached,
                if initial record sizes stay below the MTU level, to allow a
                complete record to fit into an IP packet.
            </p>
            <p>
                While TCP adjust its flow-control and window sizes, longer TLS
                records can get stuck in queues or get lost and need retransmission.
                This is of course true for all packets. TLS however needs the 
                whole record in order to decrypt it. Any missing bytes at the end
                will stall usage of the received ones.
            </p>
            <p>
                After a sufficient number of bytes have been send successfully,
                the TCP state of the connection is stable and maximum TLS record
                sizes (16 KB) can be used for optimal performance.
            </p>
            <p>
                In deployments where servers are reached locally or over reliable
                connections only, the value might be decreased with 0 disabling
                any warmup phase altogether.
            </p>
            <p>
                The following example sets the size to zero, effectively disabling
                any warmup phase.
            </p>
            <example><title>Example</title>
                <highlight language="config">
                    H2TLSWarmUpSize 0
                </highlight>
            </example>
        </usage>
    </directivesynopsis>
    
    <directivesynopsis>
        <name>H2TLSCoolDownSecs</name>
        <description></description>
        <syntax>H2TLSCoolDownSecs seconds</syntax>
        <default>H2TLSCoolDownSecs 1</default>
        <contextlist>
            <context>server config</context>
            <context>virtual host</context>
        </contextlist>
        
        <usage>
            <p>
                This directive sets the number of seconds of idle time on a TLS
                connection before the TLS write size falls back to small (~1300 bytes)
                length.
                This can be used server wide or for specific
                <directive module="core" type="section">VirtualHost</directive>s. 
            </p>
            <p>
                See <directive type="section">H2TLSWarmUpSize</directive> for a
                description of TLS warmup. H2TLSCoolDownSecs reflects the fact
                that connections may deteriorate over time (and TCP flow adjusts)
                for idle connections as well. It is beneficial to overall performance
                to fall back to the pre-warmup phase after a number of seconds that
                no data has been sent. 
            </p>
            <p>
                In deployments where connections can be considered reliable, this
                timer can be disabled by setting it to 0. 
            </p>
            <p>
                The following example sets the seconds to zero, effectively disabling
                any cool down. Warmed up TLS connections stay on maximum record
                size.
            </p>
            <example><title>Example</title>
                <highlight language="config">
                    H2TLSCoolDownSecs 0
                </highlight>
            </example>
        </usage>
    </directivesynopsis>
    
</modulesynopsis>
+3 −1
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ dnl # list of module object files
http2_objs="dnl
mod_http2.lo dnl
h2_alt_svc.lo dnl
h2_bucket_eoc.lo dnl
h2_bucket_eos.lo dnl
h2_config.lo dnl
h2_conn.lo dnl
h2_conn_io.lo dnl
@@ -29,6 +31,7 @@ h2_h2.lo dnl
h2_io.lo dnl
h2_io_set.lo dnl
h2_mplx.lo dnl
h2_push.lo dnl
h2_request.lo dnl
h2_response.lo dnl
h2_session.lo dnl
@@ -39,7 +42,6 @@ h2_task.lo dnl
h2_task_input.lo dnl
h2_task_output.lo dnl
h2_task_queue.lo dnl
h2_to_h1.lo dnl
h2_util.lo dnl
h2_worker.lo dnl
h2_workers.lo dnl
+108 −0
Original line number Diff line number Diff line
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <assert.h>
#include <stddef.h>

#include <httpd.h>
#include <http_core.h>
#include <http_connection.h>
#include <http_log.h>

#include "h2_private.h"
#include "h2_mplx.h"
#include "h2_session.h"
#include "h2_bucket_eoc.h"

typedef struct {
    apr_bucket_refcount refcount;
    h2_session *session;
} h2_bucket_eoc;

static apr_status_t bucket_cleanup(void *data)
{
    h2_session **psession = data;

    if (*psession) {
        /*
         * If bucket_destroy is called after us, this prevents
         * bucket_destroy from trying to destroy the pool again.
         */
        *psession = NULL;
    }
    return APR_SUCCESS;
}

static apr_status_t bucket_read(apr_bucket *b, const char **str,
                                apr_size_t *len, apr_read_type_e block)
{
    (void)b;
    (void)block;
    *str = NULL;
    *len = 0;
    return APR_SUCCESS;
}

apr_bucket * h2_bucket_eoc_make(apr_bucket *b, h2_session *session)
{
    h2_bucket_eoc *h;

    h = apr_bucket_alloc(sizeof(*h), b->list);
    h->session = session;

    b = apr_bucket_shared_make(b, h, 0, 0);
    b->type = &h2_bucket_type_eoc;
    
    return b;
}

apr_bucket * h2_bucket_eoc_create(apr_bucket_alloc_t *list, h2_session *session)
{
    apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);

    APR_BUCKET_INIT(b);
    b->free = apr_bucket_free;
    b->list = list;
    b = h2_bucket_eoc_make(b, session);
    if (session) {
        h2_bucket_eoc *h = b->data;
        apr_pool_pre_cleanup_register(session->pool, &h->session, bucket_cleanup);
    }
    return b;
}

static void bucket_destroy(void *data)
{
    h2_bucket_eoc *h = data;

    if (apr_bucket_shared_destroy(h)) {
        h2_session *session = h->session;
        if (session) {
            h2_session_eoc_callback(session);
        }
        apr_bucket_free(h);
    }
}

const apr_bucket_type_t h2_bucket_type_eoc = {
    "H2EOC", 5, APR_BUCKET_METADATA,
    bucket_destroy,
    bucket_read,
    apr_bucket_setaside_noop,
    apr_bucket_split_notimpl,
    apr_bucket_shared_copy
};
+31 −0
Original line number Diff line number Diff line
/* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef mod_http2_h2_bucket_eoc_h
#define mod_http2_h2_bucket_eoc_h

struct h2_session;

/** End Of HTTP/2 SESSION (H2EOC) bucket */
extern const apr_bucket_type_t h2_bucket_type_eoc;


apr_bucket * h2_bucket_eoc_make(apr_bucket *b, 
                                struct h2_session *session);

apr_bucket * h2_bucket_eoc_create(apr_bucket_alloc_t *list,
                                  struct h2_session *session);

#endif /* mod_http2_h2_bucket_eoc_h */
Loading