Commit bf05606e authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

http2-tests: test1700 is the first real HTTP/2 test

It requires that 'nghttpx' is in the PATH, and it will run the tests
using nghttpx as a front-end proxy in front of the standard HTTP/1 test
server. This uses HTTP/2 over plain TCP.

If you like me have nghttpx installed in a custom path, you can run test 1700
like this:

$ PATH=$PATH:$HOME/build-nghttp2/bin/ ./runtests.pl 1700
parent c53d8a0b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -159,6 +159,8 @@ test1525 test1526 test1527 test1528 test1529 test1530 test1531 \
\
test1600 test1601 test1602 test1603 test1604 \
\
test1700 \
\
test1800 test1801 \
\
test1900 test1901 test1902 test1903 \

tests/data/test1700

0 → 100644
+98 −0
Original line number Diff line number Diff line
<testcase>
<info>
<keywords>
HTTP
HTTP GET
HTTP/2
</keywords>
</info>

#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
ETag: "21025-dc7-39462498"
Accept-Ranges: bytes
Content-Length: 6
Connection: close
Content-Type: text/html
Funny-head: yesyes

-foo-
</data>
<data1>
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Content-Length: 6
Connection: close
Content-Type: text/html

-maa-
</data1>
</reply>

#
# Client-side
<client>
<server>
http
http2
</server>
 <name>
HTTP/2 GET with Upgrade:
 </name>
 <command>
http://%HOSTIP:9015/1700 --http2 http://%HOSTIP:9015/17000001
</command>
</client>

#
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
^X-Forwarded-Proto:.*
^Via:.*
</strip>
<protocol>
GET /1700 HTTP/1.1
Host: %HOSTIP:9015
Accept: */*

GET /17000001 HTTP/1.1
Host: %HOSTIP:9015
Accept: */*

</protocol>
<stdout>
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h2c

HTTP/2 200 
date: Thu, 09 Nov 2010 14:49:00 GMT
last-modified: Tue, 13 Jun 2000 12:10:00 GMT
etag: "21025-dc7-39462498"
accept-ranges: bytes
content-length: 6
content-type: text/html
funny-head: yesyes
server: nghttpx nghttp2/1.12.0-DEV
via: 1.1 nghttpx

-foo-
HTTP/2 200 
date: Thu, 09 Nov 2010 14:49:00 GMT
content-length: 6
content-type: text/html
server: nghttpx nghttp2/1.12.0-DEV
via: 1.1 nghttpx

-maa-
</stdout>
</verify>
</testcase>

tests/http2-server.pl

0 → 100755
+75 −0
Original line number Diff line number Diff line
#!/usr/bin/env perl
#***************************************************************************
#                                  _   _ ____  _
#  Project                     ___| | | |  _ \| |
#                             / __| | | | |_) | |
#                            | (__| |_| |  _ <| |___
#                             \___|\___/|_| \_\_____|
#
# Copyright (C) 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
#***************************************************************************

# This script invokes nghttpx properly to have it serve HTTP/2 for us.
# nghttpx runs as a proxy in front of our "actual" HTTP/1 server.

my $pidfile = "log/nghttpx.pid";
my $logfile = "log/http2.log";
my $nghttpx = "nghttpx";
my $listenport = 9015;

#***************************************************************************
# Process command line options
#
while(@ARGV) {
    if($ARGV[0] eq '--verbose') {
        $verbose = 1;
    }
    elsif($ARGV[0] eq '--pidfile') {
        if($ARGV[1]) {
            $pidfile = $ARGV[1];
            shift @ARGV;
        }
    }
    elsif($ARGV[0] eq '--nghttpx') {
        if($ARGV[1]) {
            $nghttpx = $ARGV[1];
            shift @ARGV;
        }
    }
    elsif($ARGV[0] eq '--port') {
        if($ARGV[1]) {
            $listenport = $ARGV[1];
            shift @ARGV;
        }
    }
    elsif($ARGV[0] eq '--logfile') {
        if($ARGV[1]) {
            $logfile = $ARGV[1];
            shift @ARGV;
        }
    }
    else {
        print STDERR "\nWarning: http2-server.pl unknown parameter: $ARGV[0]\n";
    }
    shift @ARGV;
}

my $cmdline="$nghttpx --backend=127.0.0.1,8990 ".
    "--frontend=\"*,$listenport;no-tls\" ".
    "--log-level=INFO ".
    "--pid-file=$pidfile ".
    "--errorlog-file=$logfile";
print "RUN: $cmdline\n" if($verbose);
system("$cmdline");
+75 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
#                            | (__| |_| |  _ <| |___
#                             \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -144,6 +144,7 @@ my $HTTPTLS6PORT; # HTTP TLS (non-stunnel) IPv6 server port
my $HTTPPROXYPORT;       # HTTP proxy port, when using CONNECT
my $HTTPPIPEPORT;        # HTTP pipelining port
my $HTTPUNIXPATH;        # HTTP server Unix domain socket path
my $HTTP2PORT;           # HTTP/2 server port

my $srcdir = $ENV{'srcdir'} || '.';
my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
@@ -1189,6 +1190,64 @@ sub responsiveserver {
    return 0;
}

#######################################################################
# start the http2 server
#
sub runhttp2server {
    my ($verbose, $port) = @_;
    my $server;
    my $srvrname;
    my $pidfile;
    my $logfile;
    my $flags = "";
    my $proto="http2";
    my $ipvnum = 4;
    my $idnum = 0;
    my $exe = "$perl $srcdir/http2-server.pl";
    my $verbose_flag = "--verbose ";

    $server = servername_id($proto, $ipvnum, $idnum);

    $pidfile = $serverpidfile{$server};

    # don't retry if the server doesn't work
    if ($doesntrun{$pidfile}) {
        return (0,0);
    }

    my $pid = processexists($pidfile);
    if($pid > 0) {
        stopserver($server, "$pid");
    }
    unlink($pidfile) if(-f $pidfile);

    $srvrname = servername_str($proto, $ipvnum, $idnum);

    $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);

    $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
    $flags .= "--port $HTTP2PORT ";
    $flags .= $verbose_flag if($debugprotocol);

    my $cmd = "$exe $flags";
    my ($http2pid, $pid2) = startnew($cmd, $pidfile, 15, 0);

    if($http2pid <= 0 || !pidexists($http2pid)) {
        # it is NOT alive
        logmsg "RUN: failed to start the $srvrname server\n";
        stopserver($server, "$pid2");
        displaylogs($testnumcheck);
        $doesntrun{$pidfile} = 1;
        return (0,0);
    }

    if($verbose) {
        logmsg "RUN: $srvrname server is now running PID $http2pid\n";
    }

    return ($http2pid, $pid2);
}

#######################################################################
# start the http server
#
@@ -2484,6 +2543,8 @@ sub checksystem {
            if($feat =~ /HTTP2/) {
                # http2 enabled
                $has_http2=1;

                push @protocols, 'http2';
            }
        }
        #
@@ -2677,6 +2738,7 @@ sub subVariables {
  $$thing =~ s/%HTTPTLSPORT/$HTTPTLSPORT/g;
  $$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
  $$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
  $$thing =~ s/%HTTP2PORT/$HTTP2PORT/g;
  $$thing =~ s/%HTTPPORT/$HTTPPORT/g;
  $$thing =~ s/%HTTPPIPEPORT/$HTTPPIPEPORT/g;
  $$thing =~ s/%PROXYPORT/$HTTPPROXYPORT/g;
@@ -4263,6 +4325,17 @@ sub startservers {
                $run{'gopher-ipv6'}="$pid $pid2";
            }
        }
        elsif($what eq "http2") {
            if(!$run{'http2'}) {
                ($pid, $pid2) = runhttp2server($verbose, $HTTP2PORT);
                if($pid <= 0) {
                    return "failed starting HTTP/2 server";
                }
                logmsg sprintf ("* pid http => %d %d\n", $pid, $pid2)
                    if($verbose);
                $run{'http2'}="$pid $pid2";
            }
        }
        elsif($what eq "http") {
            if($torture && $run{'http'} &&
               !responsive_http_server("http", $verbose, 0, $HTTPPORT)) {
@@ -5003,6 +5076,7 @@ $HTTPTLSPORT = $base++; # HTTP TLS (non-stunnel) server port
$HTTPTLS6PORT    = $base++; # HTTP TLS (non-stunnel) IPv6 server port
$HTTPPROXYPORT   = $base++; # HTTP proxy port, when using CONNECT
$HTTPPIPEPORT    = $base++; # HTTP pipelining port
$HTTP2PORT       = $base++; # HTTP/2 port
$HTTPUNIXPATH    = 'http.sock'; # HTTP server Unix domain socket path

#######################################################################
+2 −2
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
#                            | (__| |_| |  _ <| |___
#                             \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -105,7 +105,7 @@ sub servername_str {

    $proto = uc($proto) if($proto);
    die "unsupported protocol: '$proto'" unless($proto &&
        ($proto =~ /^(((FTP|HTTP|IMAP|POP3|SMTP|HTTP-PIPE)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|GOPHER|HTTPTLS))$/));
        ($proto =~ /^(((FTP|HTTP|IMAP|POP3|SMTP|HTTP-PIPE)S?)|(TFTP|SFTP|SOCKS|SSH|RTSP|GOPHER|HTTPTLS|HTTP2))$/));

    $ipver = (not $ipver) ? 'ipv4' : lc($ipver);
    die "unsupported IP version: '$ipver'" unless($ipver &&