https://bz.apache.org/bugzilla/show_bug.cgi?id=58605

            Bug ID: 58605
           Summary: Provide value for request.getProtocol() for HTTP/2
                    connections
           Product: Tomcat 9
           Version: unspecified
          Hardware: PC
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: knst.koli...@gmail.com

Testing current Tomcat trunk (Updated to revision 1713973)
+ Tomcat Native 1.2.2
Using Java 8u66 (32-bit) on Windows 7, Firefox 42.0

Steps to reproduce:
Configure Tomcat:
1. Install Tomcat Native 1.2.2: copy tcnative-1.dll into ${catalina.home}/bin

2. Install certificates for HTTPS connector.
I am using certificates included in Tomcat test suite:
Copy the following files from source directory test\org\apache\tomcat\util\net\
 into ${catalina.home}/conf:

localhost-cert.pem
localhost-key.pem

3. Configure a HTTPS connector with HTTP/2 support,

    <Connector port="8443"
protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig honorCipherOrder="false" >
            <Certificate certificateKeyFile="conf/localhost-key.pem"
                         certificateFile="conf/localhost-cert.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>

(It is the same as commented sample in server.xml, but certificateKeyFile and
certificateFile were updated to match file names, s/-rsa-/-/ )

4. Start Tomcat
catalina.bat start

Use browser (Firefox) to access examples:
https://localhost:8443/examples/servlets/servlet/RequestInfoExample


Observed behaviour:
-------------------
1. Access log (logs/localhost_access_log.2015-11-12.txt) contains:

127.0.0.1 - - [12/Nov/2015:12:03:10 +0300] "GET
/examples/servlets/servlet/RequestInfoExample null" 200 730

2. RequestInfoExample servlet prints the following line:

Protocol:     null 

Expected behaviour:
--------------------
1. Do not print "null" in access log.
2. Provide a non-null value for request.getProtocol()


Notes:
-------
1) A HTTP 0.9 request [1] results in empty string for request.getProtocol(), so
it is distinct from this "null".

It is good that they are different. I was concerned that a HTTP/2 request
cannot be distinguished from HTTP 0.9 one.

(Actually, I think we can drop support for HTTP 0.9 if it impedes us in any
way).

Steps to reproduce:
Connect with telnet to port 8080 and type the following line:
GET /examples/servlets/servlet/RequestInfoExample

The following line is written into access log:
127.0.0.1 - - [12/Nov/2015:12:16:59 +0300] "GET
/examples/servlets/servlet/RequestInfoExample " 200 726

[1] https://wiki.apache.org/tomcat/Specifications#HTTP


2) I expect that the value for request.getProtocol() will be defined by Servlet
4.0 specification. The format of access log is up for us to define.


3) A web application may test for support of HTTP/1.1 features by asking for
request.getProtocol().

It that is a concern, one can use fake "HTTP/1.1" as the value for
request.getProtocol().

On a longer perspective it is better to provide a different string for HTTP/2
and update the application to recognize it. There has to be a way for an
application to test for availability of HTTP/2 features.


4) For a reference:
HTTP/2 specification RFC7540 itself defines no way to transmit a version string
both in requests and responses.

ch.8.1.2.3.  Request Pseudo-Header Fields:

> HTTP/2 does not define a way to carry the version identifier that is
> included in the HTTP/1.1 request line.

ch.8.1.2.4.  Response Pseudo-Header Fields:

> HTTP/2 does not define a way to carry the version or reason phrase
> that is included in an HTTP/1.1 status line.


Protocol is identified by "h2", "h2c" strings when protocol is negotiated.
(ch.3.1. HTTP/2 Version Identification)


In HTTP/1.1 specification RFC7230
ch 2.6. Protocol Versioning says:

     HTTP-version  = HTTP-name "/" DIGIT "." DIGIT
     HTTP-name     = %x48.54.54.50 ; "HTTP", case-sensitive

So "HTTP/2.0" is better than "HTTP/2", but "HTTP/2" is how the protocol names
itself in the title of RFC7540.


5) It may be a good idea to follow Apache HTTPD here.

In Apache HTTPD support for HTTP/2 was introduced a month ago in HTTPD 2.4.17
with an experimental mod_http2 module.

(Warning: It is known that mod_http2 1.0.0 included with 2.4.17 may crash the
server when processing certain requests, 
http://markmail.org/message/oadvmtwui23h6w32
"[users@httpd] Crash in http/2" thread from 20 Oct 2015
)

Changelog for an updated "2.4.18-dev" build at Apache Lounge including
mod_http2 1.0.3 [2] mentions:

> *) 'HTTP/2.0' is written in log files when requests are served via mod_http2. 

[2] http://www.apachelounge.com/viewtopic.php?t=6842

I have not tested whether that is actually "HTTP/2.0" yet. Looking at source
code changes, it looks that the related change in httpd trunk is r1708319. If I
am reading that correctly, I think it prints "HTTP/2", not "HTTP/2.0".


As such, we can make the value configurable between none, "HTTP/1.1",
"HTTP/2.0", "HTTP/2". Personally, I prefer "HTTP/2.0".

-- 
You are receiving this mail because:
You are the assignee for the bug.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to