You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2015/07/17 16:55:15 UTC
svn commit: r1691583 [3/3] - in /httpd/test/framework/trunk: ./ t/conf/
t/conf/ssl/ t/htdocs/modules/h2/ t/htdocs/modules/h2/003/
t/htdocs/modules/h2/004/ t/htdocs/modules/h2/006/ t/htdocs/modules/h2/007/
t/htdocs/modules/h2/files/ t/modules/
Added: httpd/test/framework/trunk/t/htdocs/modules/h2/upload.pl
URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/htdocs/modules/h2/upload.pl?rev=1691583&view=auto
==============================================================================
--- httpd/test/framework/trunk/t/htdocs/modules/h2/upload.pl (added)
+++ httpd/test/framework/trunk/t/htdocs/modules/h2/upload.pl Fri Jul 17 14:55:13 2015
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+import cgi, os
+import cgitb; cgitb.enable()
+
+status = '200 Ok'
+
+try: # Windows needs stdio set for binary mode.
+ import msvcrt
+ msvcrt.setmode (0, os.O_BINARY) # stdin = 0
+ msvcrt.setmode (1, os.O_BINARY) # stdout = 1
+except ImportError:
+ pass
+
+form = cgi.FieldStorage()
+
+# Test if the file was uploaded
+if 'file' in form:
+ # A nested FieldStorage instance holds the file
+ fileitem = form['file']
+
+ # strip leading path from file name to avoid directory traversal attacks
+ fn = os.path.basename(fileitem.filename)
+ open('./files/' + fn, 'wb').write(fileitem.file.read())
+ message = 'The file "' + fn + '" was uploaded successfully'
+
+elif 'remove' in form:
+ remove = form['remove'].value
+ try:
+ fn = os.path.basename(remove)
+ os.remove('./files/' + fn)
+ message = 'The file "' + fn + '" was removed successfully'
+ except OSError, e:
+ message = 'Error removing ' + fn + ': ' + e.strerror
+ status = '404 File Not Found'
+else:
+ message = '''\
+ Upload File<form method="POST" enctype="multipart/form-data">
+ <input type="file" name="file">
+ <button type="submit">Upload</button></form>
+ '''
+
+print "Status: %s" % (status,)
+print """\
+ Content-Type: text/html\n
+ <html><body>
+ <p>%s</p>
+ </body></html>""" % (message,)
Propchange: httpd/test/framework/trunk/t/htdocs/modules/h2/upload.pl
------------------------------------------------------------------------------
svn:executable = *
Added: httpd/test/framework/trunk/t/htdocs/modules/h2/upload.py
URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/htdocs/modules/h2/upload.py?rev=1691583&view=auto
==============================================================================
--- httpd/test/framework/trunk/t/htdocs/modules/h2/upload.py (added)
+++ httpd/test/framework/trunk/t/htdocs/modules/h2/upload.py Fri Jul 17 14:55:13 2015
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+import cgi, os
+import cgitb; cgitb.enable()
+
+status = '200 Ok'
+
+try: # Windows needs stdio set for binary mode.
+ import msvcrt
+ msvcrt.setmode (0, os.O_BINARY) # stdin = 0
+ msvcrt.setmode (1, os.O_BINARY) # stdout = 1
+except ImportError:
+ pass
+
+form = cgi.FieldStorage()
+
+# Test if the file was uploaded
+if 'file' in form:
+ # A nested FieldStorage instance holds the file
+ fileitem = form['file']
+
+ # strip leading path from file name to avoid directory traversal attacks
+ fn = os.path.basename(fileitem.filename)
+ open('./files/' + fn, 'wb').write(fileitem.file.read())
+ message = 'The file "' + fn + '" was uploaded successfully'
+
+elif 'remove' in form:
+ remove = form['remove'].value
+ try:
+ fn = os.path.basename(remove)
+ os.remove('./files/' + fn)
+ message = 'The file "' + fn + '" was removed successfully'
+ except OSError, e:
+ message = 'Error removing ' + fn + ': ' + e.strerror
+ status = '404 File Not Found'
+else:
+ message = '''\
+ Upload File<form method="POST" enctype="multipart/form-data">
+ <input type="file" name="file">
+ <button type="submit">Upload</button></form>
+ '''
+
+print "Status: %s" % (status,)
+print """\
+ Content-Type: text/html\n
+ <html><body>
+ <p>%s</p>
+ </body></html>""" % (message,)
Propchange: httpd/test/framework/trunk/t/htdocs/modules/h2/upload.py
------------------------------------------------------------------------------
svn:executable = *
Added: httpd/test/framework/trunk/t/htdocs/modules/h2/xxx-1.0.2a.tar.gz
URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/htdocs/modules/h2/xxx-1.0.2a.tar.gz?rev=1691583&view=auto
==============================================================================
Binary file - no diff available.
Propchange: httpd/test/framework/trunk/t/htdocs/modules/h2/xxx-1.0.2a.tar.gz
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: httpd/test/framework/trunk/t/modules/h2.t
URL: http://svn.apache.org/viewvc/httpd/test/framework/trunk/t/modules/h2.t?rev=1691583&view=auto
==============================================================================
--- httpd/test/framework/trunk/t/modules/h2.t (added)
+++ httpd/test/framework/trunk/t/modules/h2.t Fri Jul 17 14:55:13 2015
@@ -0,0 +1,347 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+use Apache::TestConfig ();
+
+use Protocol::HTTP2::Client;
+
+my $num_suite = 26;
+my $total_tests = 2 * $num_suite;
+
+plan tests => $total_tests, need_module 'h2';
+
+Apache::TestRequest::module("h2");
+
+my $config = Apache::Test::config();
+my $host = $config->{vars}->{servername};
+my $port = $config->{vars}->{port};
+
+my $ssl_module = $config->{vars}->{ssl_module_name};
+my $shost = $config->{vhosts}->{$ssl_module}->{servername};
+my $sport = $config->{vhosts}->{$ssl_module}->{port};
+my $serverdir = $config->{vars}->{t_dir};
+my $htdocs = $serverdir . "/htdocs";
+
+use AnyEvent;
+use AnyEvent::Socket;
+use AnyEvent::Handle;
+use Net::SSLeay;
+use AnyEvent::TLS;
+
+Net::SSLeay::initialize();
+
+my $alpn_available = exists &Net::SSLeay::CTX_set_alpn_protos;
+
+sub connect_and_do {
+ my %args = (
+ @_
+ );
+ my $scheme = $args{ctx}->{scheme};
+ my $host = $args{ctx}->{host};
+ my $port = $args{ctx}->{port};
+ my $client = $args{ctx}->{client};
+ my $w = AnyEvent->condvar;
+
+ tcp_connect $host, $port, sub {
+ my ($fh) = @_ or do {
+ print "connection failed: $!\n";
+ $w->send;
+ return;
+ };
+
+ my $tls;
+ my $tls_ctx;
+ if ($scheme eq 'https') {
+ $tls = "connect";
+ eval {
+ # ALPN (Net-SSLeay > 1.55, openssl >= 1.0.1)
+ if ( $alpn_available ) {
+ $tls_ctx = AnyEvent::TLS->new( method => "TLSv1_2", );
+ Net::SSLeay::CTX_set_alpn_protos( $tls_ctx->ctx, ['h2'] );
+ }
+ else {
+ $tls_ctx = AnyEvent::TLS->new();
+ }
+ };
+ if ($@) {
+ print "Some problem with SSL CTX: $@\n";
+ $w->send;
+ return;
+ }
+ }
+
+ my $handle;
+ $handle = AnyEvent::Handle->new(
+ fh => $fh,
+ tls => $tls,
+ tls_ctx => $tls_ctx,
+ autocork => 1,
+ on_error => sub {
+ $_[0]->destroy;
+ print "connection error\n";
+ $w->send;
+ },
+ on_eof => sub {
+ $handle->destroy;
+ $w->send;
+ }
+ );
+
+ # First write preface to peer
+ while ( my $frame = $client->next_frame ) {
+ $handle->push_write($frame);
+ }
+
+ $handle->on_read(sub {
+ my $handle = shift;
+
+ $client->feed( $handle->{rbuf} );
+ $handle->{rbuf} = undef;
+
+ while ( my $frame = $client->next_frame ) {
+ $handle->push_write($frame);
+ }
+
+ # Terminate connection if all done
+ $handle->push_shutdown if $client->shutdown;
+ });
+ };
+ $w->recv;
+
+}
+
+sub add_request {
+ my ($scheme, $client, $host, $port);
+ my %args = (
+ method => 'GET',
+ headers => [],
+ rc => 200,
+ on_done => sub {
+ my %args = ( @_ );
+ my $ctx = $args{ctx};
+ my $req = $args{request};
+ my $resp = $args{response};
+ my $hr = $resp->{headers};
+ my %headers = @$hr;
+ ok t_cmp($headers{':status'}, $req->{rc},
+ "$req->{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{path}");
+ },
+ @_
+ );
+ $client = $args{ctx}->{client};
+ $scheme = $args{ctx}->{scheme};
+ $host = $args{ctx}->{host};
+ $port = $args{ctx}->{port};
+
+ $client->request(
+ ':scheme' => $scheme,
+ ':authority' => $args{authority} || $host . ':' . $port,
+ ':path' => $args{path},
+ ':method' => $args{method},
+ headers => $args{headers},
+ on_done => sub {
+ my ($headers, $data) = @_;
+ $args{on_done}(
+ ctx => $args{ctx},
+ request => \%args,
+ response => { headers => \@$headers, data => $data }
+ );
+ }
+ );
+}
+
+sub cmp_content_length {
+ my %args = ( @_ );
+ my $ctx = $args{ctx};
+ my $req = $args{request};
+ my $resp = $args{response};
+ my $hr = $resp->{headers};
+ my %headers = @$hr;
+ ok t_cmp($headers{':status'}, $req->{rc},
+ "$req->{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{path}");
+ ok t_cmp(length $resp->{data}, $req->{content_length}, "content-length of $req->{path}");
+}
+
+sub cmp_content {
+ my %args = ( @_ );
+ my $ctx = $args{ctx};
+ my $req = $args{request};
+ my $resp = $args{response};
+ my $hr = $resp->{headers};
+ my %headers = @$hr;
+ ok t_cmp($headers{':status'}, $req->{rc},
+ "$req->{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{path}");
+ ok t_cmp($resp->{data}, $req->{content}, "content of $req->{path}");
+}
+
+sub cmp_file_response {
+ my %args = ( @_ );
+ my $ctx = $args{ctx};
+ my $req = $args{request};
+ my $resp = $args{response};
+ my $hr = $resp->{headers};
+ my %headers = @$hr;
+ ok t_cmp($headers{':status'}, $req->{rc},
+ "$req->{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{path}");
+ open(FILE, "<$htdocs$req->{path}") or die "cannot open $req->{path}";
+ undef $/;
+ my $content = <FILE>;
+ close(FILE);
+ ok t_is_equal($resp->{data}, $content);
+}
+
+sub check_redir {
+ my %args = ( @_ );
+ my $ctx = $args{ctx};
+ my $req = $args{request};
+ my $resp = $args{response};
+ my $hr = $resp->{headers};
+ my %headers = @$hr;
+ ok t_cmp($headers{':status'}, 302,
+ "$req->{method} $ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{path}");
+ ok t_cmp(
+ $headers{location},
+ "$ctx->{scheme}://$ctx->{host}:$ctx->{port}$req->{redir_path}",
+ "location header check"
+ );
+}
+
+sub do_suite {
+ my %args = (
+ scheme => 'http',
+ host => 'localhost',
+ port => 80,
+ @_
+ );
+ my $true_tls = ($args{scheme} eq 'https' and $alpn_available);
+
+ $args{client} = Protocol::HTTP2::Client->new( upgrade => 0 );
+
+ print "connect to $args{scheme}:$args{host}:$args{port}\n";
+
+ add_request(
+ ctx => \%args,
+ path => '/'
+ );
+ add_request(
+ ctx => \%args,
+ rc => 404,
+ path => '/not_here'
+ );
+ add_request(
+ ctx => \%args,
+ rc => $true_tls? 421 : 404,
+ path => '/misdirected',
+ header => [ 'host' => 'xxx.yyy.zzz' ]
+ );
+ add_request(
+ ctx => \%args,
+ rc => $true_tls? 421 : 404,
+ path => '/misdirected',
+ authority => 'xxx.yyy.zzz:1234'
+ );
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/index.html',
+ on_done => \&cmp_file_response
+ );
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/003/003_img.jpg',
+ on_done => \&cmp_file_response
+ );
+ if (have_module 'mod_rewrite') {
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/latest.tar.gz',
+ redir_path => "/modules/h2/xxx-1.0.2a.tar.gz",
+ on_done => \&check_redir
+ );
+ }
+ else {
+ skip "skipping test as mod_rewrite not available" foreach(1..2);
+ }
+ if (have_cgi) {
+ my $ssl_protocol = $true_tls? 'TLSv1.2' : '';
+ my $content = <<EOF;
+<html><body>
+<h2>Hello World!</h2>
+SSL_PROTOCOL="$ssl_protocol"
+</body></html>
+EOF
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/hello.pl',
+ content => $content,
+ on_done => \&cmp_content,
+ );
+
+ $content = <<EOF;
+<html><body>
+<p>No query was specified.</p>
+</body></html>
+EOF
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/necho.pl',
+ content => $content,
+ rc => 400,
+ on_done => \&cmp_content,
+ );
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/necho.pl?count=2&text=0123456789',
+ content => "01234567890123456789",
+ on_done => \&cmp_content,
+ );
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/necho.pl?count=10&text=0123456789',
+ content_length => 100,
+ on_done => \&cmp_content_length,
+ );
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/necho.pl?count=100&text=0123456789',
+ content_length => 1000,
+ on_done => \&cmp_content_length,
+ );
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/necho.pl?count=1000&text=0123456789',
+ content_length => 10000,
+ on_done => \&cmp_content_length,
+ );
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/necho.pl?count=10000&text=0123456789',
+ content_length => 100000,
+ on_done => \&cmp_content_length,
+ );
+ add_request(
+ ctx => \%args,
+ path => '/modules/h2/necho.pl?count=100000&text=0123456789',
+ content_length => 1000000,
+ on_done => \&cmp_content_length,
+ );
+ }
+ else {
+ skip "skipping test as mod_cgi not available" foreach(1..1);
+ }
+
+ connect_and_do( ctx => \%args );
+}
+
+do_suite( 'scheme' => 'http', 'host' => $host, 'port' => $port );
+
+
+if ($alpn_available||1) {
+ do_suite( 'scheme' => 'https', 'host' => $shost, 'port' => $sport );
+}
+else {
+ skip "skipping https tests as ALPN is not available" foreach(1..$num_suite);
+}
+