From 65725c52b8170cbafa48551e952ce11ec0104bef Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 11 Jun 2024 14:03:11 +0200 Subject: [PATCH] Fix compatibility with Rack 3.1 Fix: https://github.com/Shopify/pitchfork/issues/128 --- .github/workflows/ci.yml | 17 +- .gitignore | 1 + Gemfile | 3 + Gemfile.lock | 34 -- ext/pitchfork_http/pitchfork_http.c | 514 +++++++++------------------ ext/pitchfork_http/pitchfork_http.rl | 18 +- lib/pitchfork/chunked.rb | 4 +- test/integration/test_http_basic.rb | 23 ++ test/unit/test_http_parser_ng.rb | 17 +- test/unit/test_request.rb | 4 +- 10 files changed, 226 insertions(+), 409 deletions(-) delete mode 100644 Gemfile.lock diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33d93f92..b28603e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: ruby: - name: Ruby ${{ matrix.ruby }} ${{ matrix.rubyopt }} + name: Ruby ${{ matrix.ruby }} / Rack ${{ matrix.rack }} ${{ matrix.rubyopt }} timeout-minutes: 15 strategy: fail-fast: false @@ -12,15 +12,24 @@ jobs: os: ["ubuntu-latest"] ruby: ["ruby-head", "3.3", "3.2", "3.1", "3.0", "2.7", "2.6"] rubyopt: [""] + rack: ["~> 3.1"] include: - ruby: "3.3" rubyopt: "--enable-frozen-string-literal" + rack: "~> 3.1" + - ruby: "3.3" + rack: "~> 3.0.0" + - ruby: "3.3" + rack: "~> 2.0" + env: + RACK_VERSION: "${{ matrix.rack }}" + RUBYOPT: "${{ matrix.rubyopt }}" runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v4 - - name: Set up Ruby + - name: Set up Ruby ${{ matrix.ruby }} uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} @@ -29,5 +38,5 @@ jobs: - name: Install packages run: sudo apt-get install -y ragel socat netcat - - name: Tests ${{ matrix.rubyopt }} - run: RUBYOPT="${{ matrix.rubyopt }}" bundle exec rake + - name: Tests Rack ${{ matrix.rack }} ${{ matrix.rubyopt }} + run: bundle exec rake diff --git a/.gitignore b/.gitignore index 79a67251..c5f8da3a 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ pkg/ /LATEST /*_1 test/integration/trash/ +Gemfile.lock diff --git a/Gemfile b/Gemfile index 8e5ad1c9..df9ecfba 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,9 @@ source "https://rubygems.org" gem 'minitest' gem 'rake' gem 'rake-compiler' +if ENV["RACK_VERSION"] + gem "rack", ENV["RACK_VERSION"] +end group :benchmark do gem "puma" diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 71d1ead6..00000000 --- a/Gemfile.lock +++ /dev/null @@ -1,34 +0,0 @@ -PATH - remote: . - specs: - pitchfork (0.14.0) - logger - rack (>= 2.0) - -GEM - remote: https://rubygems.org/ - specs: - logger (1.6.0) - minitest (5.22.2) - nio4r (2.7.0) - puma (6.4.2) - nio4r (~> 2.0) - rack (3.0.11) - rake (13.0.6) - rake-compiler (1.2.1) - rake - -PLATFORMS - aarch64-linux - arm64-darwin - x86_64-linux - -DEPENDENCIES - minitest - pitchfork! - puma - rake - rake-compiler - -BUNDLED WITH - 2.3.27 diff --git a/ext/pitchfork_http/pitchfork_http.c b/ext/pitchfork_http/pitchfork_http.c index 3e826953..f35b53ab 100644 --- a/ext/pitchfork_http/pitchfork_http.c +++ b/ext/pitchfork_http/pitchfork_http.c @@ -315,7 +315,7 @@ static void write_value(VALUE self, struct http_parser *hp, /** Machine **/ -#line 422 "pitchfork_http.rl" +#line 416 "pitchfork_http.rl" /** Data **/ @@ -331,7 +331,7 @@ static const int http_parser_en_Trailers = 114; static const int http_parser_en_main = 1; -#line 426 "pitchfork_http.rl" +#line 420 "pitchfork_http.rl" static void http_parser_init(struct http_parser *hp) { @@ -349,7 +349,7 @@ static void http_parser_init(struct http_parser *hp) cs = http_parser_start; } -#line 438 "pitchfork_http.rl" +#line 432 "pitchfork_http.rl" hp->cs = cs; } @@ -477,39 +477,38 @@ case 4: tr8: #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st5; tr42: #line 318 "pitchfork_http.rl" {MARK(mark, p); } -#line 347 "pitchfork_http.rl" +#line 336 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT); - rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + VALUE str = rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + if (STR_CSTR_EQ(str, "*")) { + VALUE str = rb_str_new("*", 1); + rb_hash_aset(hp->env, g_path_info, str); + rb_hash_aset(hp->env, g_request_path, str); + } } goto st5; tr45: -#line 347 "pitchfork_http.rl" +#line 336 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT); - rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + VALUE str = rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + if (STR_CSTR_EQ(str, "*")) { + VALUE str = rb_str_new("*", 1); + rb_hash_aset(hp->env, g_path_info, str); + rb_hash_aset(hp->env, g_request_path, str); + } } goto st5; tr49: -#line 357 "pitchfork_http.rl" +#line 351 "pitchfork_http.rl" { VALUE val; @@ -522,74 +521,41 @@ case 4: } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st5; tr55: -#line 351 "pitchfork_http.rl" +#line 345 "pitchfork_http.rl" {MARK(start.query, p); } -#line 352 "pitchfork_http.rl" +#line 346 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING); rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p)); } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st5; tr59: -#line 352 "pitchfork_http.rl" +#line 346 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING); rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p)); } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st5; st5: if ( ++p == pe ) goto _test_eof5; case 5: -#line 593 "pitchfork_http.c" +#line 559 "pitchfork_http.c" if ( (*p) == 72 ) goto tr10; goto st0; @@ -601,7 +567,7 @@ case 5: if ( ++p == pe ) goto _test_eof6; case 6: -#line 605 "pitchfork_http.c" +#line 571 "pitchfork_http.c" if ( (*p) == 84 ) goto st7; goto st0; @@ -661,7 +627,7 @@ case 13: goto st13; goto st0; tr18: -#line 356 "pitchfork_http.rl" +#line 350 "pitchfork_http.rl" { http_version(hp, PTR_TO(mark), LEN(mark, p)); } goto st14; tr26: @@ -688,7 +654,7 @@ case 13: if ( ++p == pe ) goto _test_eof14; case 14: -#line 692 "pitchfork_http.c" +#line 658 "pitchfork_http.c" switch( (*p) ) { case 9: goto st15; case 10: goto tr21; @@ -724,7 +690,7 @@ case 14: if ( ++p == pe ) goto _test_eof15; case 15: -#line 728 "pitchfork_http.c" +#line 694 "pitchfork_http.c" switch( (*p) ) { case 9: goto tr25; case 10: goto tr26; @@ -743,7 +709,7 @@ case 15: if ( ++p == pe ) goto _test_eof16; case 16: -#line 747 "pitchfork_http.c" +#line 713 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr29; case 13: goto tr30; @@ -756,7 +722,7 @@ case 16: goto st0; goto st16; tr19: -#line 356 "pitchfork_http.rl" +#line 350 "pitchfork_http.rl" { http_version(hp, PTR_TO(mark), LEN(mark, p)); } goto st17; tr27: @@ -783,12 +749,12 @@ case 16: if ( ++p == pe ) goto _test_eof17; case 17: -#line 787 "pitchfork_http.c" +#line 753 "pitchfork_http.c" if ( (*p) == 10 ) goto st14; goto st0; tr21: -#line 372 "pitchfork_http.rl" +#line 366 "pitchfork_http.rl" { finalize_header(hp); @@ -811,21 +777,10 @@ case 17: tr104: #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } -#line 372 "pitchfork_http.rl" +#line 366 "pitchfork_http.rl" { finalize_header(hp); @@ -848,12 +803,17 @@ case 17: tr108: #line 318 "pitchfork_http.rl" {MARK(mark, p); } -#line 347 "pitchfork_http.rl" +#line 336 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT); - rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + VALUE str = rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + if (STR_CSTR_EQ(str, "*")) { + VALUE str = rb_str_new("*", 1); + rb_hash_aset(hp->env, g_path_info, str); + rb_hash_aset(hp->env, g_request_path, str); + } } -#line 372 "pitchfork_http.rl" +#line 366 "pitchfork_http.rl" { finalize_header(hp); @@ -874,12 +834,17 @@ case 17: } goto st122; tr112: -#line 347 "pitchfork_http.rl" +#line 336 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT); - rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + VALUE str = rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + if (STR_CSTR_EQ(str, "*")) { + VALUE str = rb_str_new("*", 1); + rb_hash_aset(hp->env, g_path_info, str); + rb_hash_aset(hp->env, g_request_path, str); + } } -#line 372 "pitchfork_http.rl" +#line 366 "pitchfork_http.rl" { finalize_header(hp); @@ -900,7 +865,7 @@ case 17: } goto st122; tr117: -#line 357 "pitchfork_http.rl" +#line 351 "pitchfork_http.rl" { VALUE val; @@ -913,21 +878,10 @@ case 17: } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } -#line 372 "pitchfork_http.rl" +#line 366 "pitchfork_http.rl" { finalize_header(hp); @@ -948,30 +902,19 @@ case 17: } goto st122; tr124: -#line 351 "pitchfork_http.rl" +#line 345 "pitchfork_http.rl" {MARK(start.query, p); } -#line 352 "pitchfork_http.rl" +#line 346 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING); rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p)); } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } -#line 372 "pitchfork_http.rl" +#line 366 "pitchfork_http.rl" { finalize_header(hp); @@ -992,28 +935,17 @@ case 17: } goto st122; tr129: -#line 352 "pitchfork_http.rl" +#line 346 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING); rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p)); } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } -#line 372 "pitchfork_http.rl" +#line 366 "pitchfork_http.rl" { finalize_header(hp); @@ -1037,44 +969,43 @@ case 17: if ( ++p == pe ) goto _test_eof122; case 122: -#line 1041 "pitchfork_http.c" +#line 973 "pitchfork_http.c" goto st0; tr105: #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st18; tr109: #line 318 "pitchfork_http.rl" {MARK(mark, p); } -#line 347 "pitchfork_http.rl" +#line 336 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT); - rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + VALUE str = rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + if (STR_CSTR_EQ(str, "*")) { + VALUE str = rb_str_new("*", 1); + rb_hash_aset(hp->env, g_path_info, str); + rb_hash_aset(hp->env, g_request_path, str); + } } goto st18; tr113: -#line 347 "pitchfork_http.rl" +#line 336 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(mark, p), FRAGMENT); - rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + VALUE str = rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, p)); + if (STR_CSTR_EQ(str, "*")) { + VALUE str = rb_str_new("*", 1); + rb_hash_aset(hp->env, g_path_info, str); + rb_hash_aset(hp->env, g_request_path, str); + } } goto st18; tr118: -#line 357 "pitchfork_http.rl" +#line 351 "pitchfork_http.rl" { VALUE val; @@ -1087,74 +1018,41 @@ case 122: } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st18; tr125: -#line 351 "pitchfork_http.rl" +#line 345 "pitchfork_http.rl" {MARK(start.query, p); } -#line 352 "pitchfork_http.rl" +#line 346 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING); rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p)); } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st18; tr130: -#line 352 "pitchfork_http.rl" +#line 346 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING); rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p)); } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st18; st18: if ( ++p == pe ) goto _test_eof18; case 18: -#line 1158 "pitchfork_http.c" +#line 1056 "pitchfork_http.c" if ( (*p) == 10 ) goto tr21; goto st0; @@ -1172,7 +1070,7 @@ case 18: if ( ++p == pe ) goto _test_eof19; case 19: -#line 1176 "pitchfork_http.c" +#line 1074 "pitchfork_http.c" switch( (*p) ) { case 33: goto tr32; case 58: goto tr33; @@ -1209,7 +1107,7 @@ case 19: if ( ++p == pe ) goto _test_eof20; case 20: -#line 1213 "pitchfork_http.c" +#line 1111 "pitchfork_http.c" switch( (*p) ) { case 9: goto tr35; case 10: goto tr36; @@ -1228,7 +1126,7 @@ case 20: if ( ++p == pe ) goto _test_eof21; case 21: -#line 1232 "pitchfork_http.c" +#line 1130 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr39; case 13: goto tr40; @@ -1243,23 +1141,12 @@ case 21: tr9: #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st22; tr50: -#line 357 "pitchfork_http.rl" +#line 351 "pitchfork_http.rl" { VALUE val; @@ -1272,74 +1159,41 @@ case 21: } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st22; tr56: -#line 351 "pitchfork_http.rl" +#line 345 "pitchfork_http.rl" {MARK(start.query, p); } -#line 352 "pitchfork_http.rl" +#line 346 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING); rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p)); } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st22; tr60: -#line 352 "pitchfork_http.rl" +#line 346 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING); rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p)); } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st22; st22: if ( ++p == pe ) goto _test_eof22; case 22: -#line 1343 "pitchfork_http.c" +#line 1197 "pitchfork_http.c" switch( (*p) ) { case 32: goto tr42; case 35: goto st0; @@ -1357,7 +1211,7 @@ case 22: if ( ++p == pe ) goto _test_eof23; case 23: -#line 1361 "pitchfork_http.c" +#line 1215 "pitchfork_http.c" switch( (*p) ) { case 32: goto tr45; case 35: goto st0; @@ -1375,7 +1229,7 @@ case 23: if ( ++p == pe ) goto _test_eof24; case 24: -#line 1379 "pitchfork_http.c" +#line 1233 "pitchfork_http.c" if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st25; @@ -1412,7 +1266,7 @@ case 25: if ( ++p == pe ) goto _test_eof26; case 26: -#line 1416 "pitchfork_http.c" +#line 1270 "pitchfork_http.c" switch( (*p) ) { case 32: goto tr49; case 35: goto tr50; @@ -1450,7 +1304,7 @@ case 28: goto st26; goto st0; tr52: -#line 357 "pitchfork_http.rl" +#line 351 "pitchfork_http.rl" { VALUE val; @@ -1466,7 +1320,7 @@ case 28: if ( ++p == pe ) goto _test_eof29; case 29: -#line 1470 "pitchfork_http.c" +#line 1324 "pitchfork_http.c" switch( (*p) ) { case 32: goto tr55; case 35: goto tr56; @@ -1477,14 +1331,14 @@ case 29: goto st0; goto tr54; tr54: -#line 351 "pitchfork_http.rl" +#line 345 "pitchfork_http.rl" {MARK(start.query, p); } goto st30; st30: if ( ++p == pe ) goto _test_eof30; case 30: -#line 1488 "pitchfork_http.c" +#line 1342 "pitchfork_http.c" switch( (*p) ) { case 32: goto tr59; case 35: goto tr60; @@ -1495,14 +1349,14 @@ case 30: goto st0; goto st30; tr57: -#line 351 "pitchfork_http.rl" +#line 345 "pitchfork_http.rl" {MARK(start.query, p); } goto st31; st31: if ( ++p == pe ) goto _test_eof31; case 31: -#line 1506 "pitchfork_http.c" +#line 1360 "pitchfork_http.c" if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st32; @@ -1535,7 +1389,7 @@ case 32: if ( ++p == pe ) goto _test_eof33; case 33: -#line 1539 "pitchfork_http.c" +#line 1393 "pitchfork_http.c" switch( (*p) ) { case 84: goto tr63; case 116: goto tr63; @@ -1549,7 +1403,7 @@ case 33: if ( ++p == pe ) goto _test_eof34; case 34: -#line 1553 "pitchfork_http.c" +#line 1407 "pitchfork_http.c" switch( (*p) ) { case 84: goto tr64; case 116: goto tr64; @@ -1563,7 +1417,7 @@ case 34: if ( ++p == pe ) goto _test_eof35; case 35: -#line 1567 "pitchfork_http.c" +#line 1421 "pitchfork_http.c" switch( (*p) ) { case 80: goto tr65; case 112: goto tr65; @@ -1577,7 +1431,7 @@ case 35: if ( ++p == pe ) goto _test_eof36; case 36: -#line 1581 "pitchfork_http.c" +#line 1435 "pitchfork_http.c" switch( (*p) ) { case 58: goto tr66; case 83: goto tr67; @@ -1594,7 +1448,7 @@ case 36: if ( ++p == pe ) goto _test_eof37; case 37: -#line 1598 "pitchfork_http.c" +#line 1452 "pitchfork_http.c" if ( (*p) == 47 ) goto st38; goto st0; @@ -1689,7 +1543,7 @@ case 42: if ( ++p == pe ) goto _test_eof43; case 43: -#line 1693 "pitchfork_http.c" +#line 1547 "pitchfork_http.c" switch( (*p) ) { case 37: goto st41; case 47: goto tr76; @@ -1748,7 +1602,7 @@ case 44: if ( ++p == pe ) goto _test_eof45; case 45: -#line 1752 "pitchfork_http.c" +#line 1606 "pitchfork_http.c" switch( (*p) ) { case 37: goto st41; case 47: goto st0; @@ -1833,7 +1687,7 @@ case 47: if ( ++p == pe ) goto _test_eof48; case 48: -#line 1837 "pitchfork_http.c" +#line 1691 "pitchfork_http.c" if ( (*p) == 58 ) goto tr66; goto st0; @@ -2356,7 +2210,7 @@ case 67: if ( ++p == pe ) goto _test_eof68; case 68: -#line 2360 "pitchfork_http.c" +#line 2214 "pitchfork_http.c" switch( (*p) ) { case 32: goto tr3; case 33: goto st49; @@ -2447,7 +2301,7 @@ case 70: if ( ++p == pe ) goto _test_eof71; case 71: -#line 2451 "pitchfork_http.c" +#line 2305 "pitchfork_http.c" switch( (*p) ) { case 42: goto tr101; case 47: goto tr102; @@ -2463,7 +2317,7 @@ case 71: if ( ++p == pe ) goto _test_eof72; case 72: -#line 2467 "pitchfork_http.c" +#line 2321 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr104; case 13: goto tr105; @@ -2474,23 +2328,12 @@ case 72: tr106: #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st73; tr119: -#line 357 "pitchfork_http.rl" +#line 351 "pitchfork_http.rl" { VALUE val; @@ -2503,74 +2346,41 @@ case 72: } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st73; tr126: -#line 351 "pitchfork_http.rl" +#line 345 "pitchfork_http.rl" {MARK(start.query, p); } -#line 352 "pitchfork_http.rl" +#line 346 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING); rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p)); } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st73; tr131: -#line 352 "pitchfork_http.rl" +#line 346 "pitchfork_http.rl" { VALIDATE_MAX_URI_LENGTH(LEN(start.query, p), QUERY_STRING); rb_hash_aset(hp->env, g_query_string, STR_NEW(start.query, p)); } #line 332 "pitchfork_http.rl" { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, p), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ - if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); - rb_hash_aset(hp->env, g_path_info, str); - rb_hash_aset(hp->env, g_request_path, str); - } + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, p)); } goto st73; st73: if ( ++p == pe ) goto _test_eof73; case 73: -#line 2574 "pitchfork_http.c" +#line 2384 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr108; case 13: goto tr109; @@ -2590,7 +2400,7 @@ case 73: if ( ++p == pe ) goto _test_eof74; case 74: -#line 2594 "pitchfork_http.c" +#line 2404 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr112; case 13: goto tr113; @@ -2610,7 +2420,7 @@ case 74: if ( ++p == pe ) goto _test_eof75; case 75: -#line 2614 "pitchfork_http.c" +#line 2424 "pitchfork_http.c" if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st76; @@ -2647,7 +2457,7 @@ case 76: if ( ++p == pe ) goto _test_eof77; case 77: -#line 2651 "pitchfork_http.c" +#line 2461 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr117; case 13: goto tr118; @@ -2687,7 +2497,7 @@ case 79: goto st77; goto st0; tr121: -#line 357 "pitchfork_http.rl" +#line 351 "pitchfork_http.rl" { VALUE val; @@ -2703,7 +2513,7 @@ case 79: if ( ++p == pe ) goto _test_eof80; case 80: -#line 2707 "pitchfork_http.c" +#line 2517 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr124; case 13: goto tr125; @@ -2716,14 +2526,14 @@ case 80: goto st0; goto tr123; tr123: -#line 351 "pitchfork_http.rl" +#line 345 "pitchfork_http.rl" {MARK(start.query, p); } goto st81; st81: if ( ++p == pe ) goto _test_eof81; case 81: -#line 2727 "pitchfork_http.c" +#line 2537 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr129; case 13: goto tr130; @@ -2736,14 +2546,14 @@ case 81: goto st0; goto st81; tr127: -#line 351 "pitchfork_http.rl" +#line 345 "pitchfork_http.rl" {MARK(start.query, p); } goto st82; st82: if ( ++p == pe ) goto _test_eof82; case 82: -#line 2747 "pitchfork_http.c" +#line 2557 "pitchfork_http.c" if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st83; @@ -2776,7 +2586,7 @@ case 83: if ( ++p == pe ) goto _test_eof84; case 84: -#line 2780 "pitchfork_http.c" +#line 2590 "pitchfork_http.c" switch( (*p) ) { case 84: goto tr134; case 116: goto tr134; @@ -2790,7 +2600,7 @@ case 84: if ( ++p == pe ) goto _test_eof85; case 85: -#line 2794 "pitchfork_http.c" +#line 2604 "pitchfork_http.c" switch( (*p) ) { case 84: goto tr135; case 116: goto tr135; @@ -2804,7 +2614,7 @@ case 85: if ( ++p == pe ) goto _test_eof86; case 86: -#line 2808 "pitchfork_http.c" +#line 2618 "pitchfork_http.c" switch( (*p) ) { case 80: goto tr136; case 112: goto tr136; @@ -2818,7 +2628,7 @@ case 86: if ( ++p == pe ) goto _test_eof87; case 87: -#line 2822 "pitchfork_http.c" +#line 2632 "pitchfork_http.c" switch( (*p) ) { case 58: goto tr137; case 83: goto tr138; @@ -2835,7 +2645,7 @@ case 87: if ( ++p == pe ) goto _test_eof88; case 88: -#line 2839 "pitchfork_http.c" +#line 2649 "pitchfork_http.c" if ( (*p) == 47 ) goto st89; goto st0; @@ -2930,7 +2740,7 @@ case 93: if ( ++p == pe ) goto _test_eof94; case 94: -#line 2934 "pitchfork_http.c" +#line 2744 "pitchfork_http.c" switch( (*p) ) { case 37: goto st92; case 47: goto tr147; @@ -2989,7 +2799,7 @@ case 95: if ( ++p == pe ) goto _test_eof96; case 96: -#line 2993 "pitchfork_http.c" +#line 2803 "pitchfork_http.c" switch( (*p) ) { case 37: goto st92; case 47: goto st0; @@ -3074,7 +2884,7 @@ case 98: if ( ++p == pe ) goto _test_eof99; case 99: -#line 3078 "pitchfork_http.c" +#line 2888 "pitchfork_http.c" if ( (*p) == 58 ) goto tr137; goto st0; @@ -3094,7 +2904,7 @@ case 100: goto tr152; goto st0; tr151: -#line 367 "pitchfork_http.rl" +#line 361 "pitchfork_http.rl" { hp->len.chunk = step_incr(hp->len.chunk, (*p), 16); if (hp->len.chunk < 0) @@ -3105,7 +2915,7 @@ case 100: if ( ++p == pe ) goto _test_eof101; case 101: -#line 3109 "pitchfork_http.c" +#line 2919 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr153; case 13: goto st102; @@ -3122,7 +2932,7 @@ case 101: goto tr152; goto st0; tr153: -#line 396 "pitchfork_http.rl" +#line 390 "pitchfork_http.rl" { HP_FL_SET(hp, INTRAILER); cs = http_parser_en_Trailers; @@ -3135,7 +2945,7 @@ case 101: if ( ++p == pe ) goto _test_eof123; case 123: -#line 3139 "pitchfork_http.c" +#line 2949 "pitchfork_http.c" goto st0; st102: if ( ++p == pe ) @@ -3145,7 +2955,7 @@ case 102: goto tr153; goto st0; tr152: -#line 367 "pitchfork_http.rl" +#line 361 "pitchfork_http.rl" { hp->len.chunk = step_incr(hp->len.chunk, (*p), 16); if (hp->len.chunk < 0) @@ -3156,7 +2966,7 @@ case 102: if ( ++p == pe ) goto _test_eof103; case 103: -#line 3160 "pitchfork_http.c" +#line 2970 "pitchfork_http.c" switch( (*p) ) { case 10: goto st104; case 13: goto st107; @@ -3177,7 +2987,7 @@ case 103: case 104: goto tr159; tr159: -#line 404 "pitchfork_http.rl" +#line 398 "pitchfork_http.rl" { skip_chunk_data_hack: { size_t nr = MIN((size_t)hp->len.chunk, REMAINING); @@ -3199,7 +3009,7 @@ case 104: if ( ++p == pe ) goto _test_eof105; case 105: -#line 3203 "pitchfork_http.c" +#line 3013 "pitchfork_http.c" switch( (*p) ) { case 10: goto st100; case 13: goto st106; @@ -3429,7 +3239,7 @@ case 113: if ( ++p == pe ) goto _test_eof114; case 114: -#line 3433 "pitchfork_http.c" +#line 3243 "pitchfork_http.c" switch( (*p) ) { case 9: goto st115; case 10: goto tr167; @@ -3465,7 +3275,7 @@ case 114: if ( ++p == pe ) goto _test_eof115; case 115: -#line 3469 "pitchfork_http.c" +#line 3279 "pitchfork_http.c" switch( (*p) ) { case 9: goto tr171; case 10: goto tr172; @@ -3484,7 +3294,7 @@ case 115: if ( ++p == pe ) goto _test_eof116; case 116: -#line 3488 "pitchfork_http.c" +#line 3298 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr175; case 13: goto tr176; @@ -3520,12 +3330,12 @@ case 116: if ( ++p == pe ) goto _test_eof117; case 117: -#line 3524 "pitchfork_http.c" +#line 3334 "pitchfork_http.c" if ( (*p) == 10 ) goto st114; goto st0; tr167: -#line 391 "pitchfork_http.rl" +#line 385 "pitchfork_http.rl" { cs = http_parser_first_final; goto post_exec; @@ -3535,7 +3345,7 @@ case 117: if ( ++p == pe ) goto _test_eof124; case 124: -#line 3539 "pitchfork_http.c" +#line 3349 "pitchfork_http.c" goto st0; st118: if ( ++p == pe ) @@ -3558,7 +3368,7 @@ case 118: if ( ++p == pe ) goto _test_eof119; case 119: -#line 3562 "pitchfork_http.c" +#line 3372 "pitchfork_http.c" switch( (*p) ) { case 33: goto tr178; case 58: goto tr179; @@ -3595,7 +3405,7 @@ case 119: if ( ++p == pe ) goto _test_eof120; case 120: -#line 3599 "pitchfork_http.c" +#line 3409 "pitchfork_http.c" switch( (*p) ) { case 9: goto tr181; case 10: goto tr182; @@ -3614,7 +3424,7 @@ case 120: if ( ++p == pe ) goto _test_eof121; case 121: -#line 3618 "pitchfork_http.c" +#line 3428 "pitchfork_http.c" switch( (*p) ) { case 10: goto tr185; case 13: goto tr186; @@ -3755,7 +3565,7 @@ case 121: _out: {} } -#line 465 "pitchfork_http.rl" +#line 459 "pitchfork_http.rl" post_exec: /* "_out:" also goes here */ if (hp->cs != http_parser_error) hp->cs = cs; diff --git a/ext/pitchfork_http/pitchfork_http.rl b/ext/pitchfork_http/pitchfork_http.rl index a66308c8..297f679d 100644 --- a/ext/pitchfork_http/pitchfork_http.rl +++ b/ext/pitchfork_http/pitchfork_http.rl @@ -330,24 +330,18 @@ static void write_value(VALUE self, struct http_parser *hp, } action host { rb_hash_aset(hp->env, g_http_host, STR_NEW(mark, fpc)); } action request_uri { - VALUE str; - VALIDATE_MAX_URI_LENGTH(LEN(mark, fpc), REQUEST_URI); - str = rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, fpc)); - /* - * "OPTIONS * HTTP/1.1\r\n" is a valid request, but we can't have '*' - * in REQUEST_PATH or PATH_INFO or else Rack::Lint will complain - */ + rb_hash_aset(hp->env, g_request_uri, STR_NEW(mark, fpc)); + } + action fragment { + VALIDATE_MAX_URI_LENGTH(LEN(mark, fpc), FRAGMENT); + VALUE str = rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, fpc)); if (STR_CSTR_EQ(str, "*")) { - str = rb_str_new(NULL, 0); + VALUE str = rb_str_new("*", 1); rb_hash_aset(hp->env, g_path_info, str); rb_hash_aset(hp->env, g_request_path, str); } } - action fragment { - VALIDATE_MAX_URI_LENGTH(LEN(mark, fpc), FRAGMENT); - rb_hash_aset(hp->env, g_fragment, STR_NEW(mark, fpc)); - } action start_query {MARK(start.query, fpc); } action query_string { VALIDATE_MAX_URI_LENGTH(LEN(start.query, fpc), QUERY_STRING); diff --git a/lib/pitchfork/chunked.rb b/lib/pitchfork/chunked.rb index 20bbb6e8..34d65f28 100644 --- a/lib/pitchfork/chunked.rb +++ b/lib/pitchfork/chunked.rb @@ -107,9 +107,9 @@ def call(env) if chunkable_version?(env[Rack::SERVER_PROTOCOL]) && !STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) && !headers[Rack::CONTENT_LENGTH] && - !headers[Rack::TRANSFER_ENCODING] + !headers["transfer-encoding"] - headers[Rack::TRANSFER_ENCODING] = 'chunked' + headers["transfer-encoding"] = 'chunked' if headers['trailer'] response[2] = TrailerBody.new(body) else diff --git a/test/integration/test_http_basic.rb b/test/integration/test_http_basic.rb index d42c67aa..6acf1fa1 100644 --- a/test/integration/test_http_basic.rb +++ b/test/integration/test_http_basic.rb @@ -26,6 +26,28 @@ def test_http_basic assert_clean_shutdown(pid) end + def test_options_wildcard + addr, port = unused_port + + pid = spawn_server(app: File.join(ROOT, "test/integration/env.ru"), config: <<~CONFIG) + listen "#{addr}:#{port}" + CONFIG + + # Basic HTTP GET + assert_healthy("http://#{addr}:#{port}") + + # OPTIONS * HTTP/1.1 + Socket.tcp(addr, port) do |sock| + sock.print("OPTIONS * HTTP/1.1\r\n\r\n") + sock.close_write + result = sock.read + + assert_equal "HTTP/1.1 200 OK", result.lines.first.strip + end + + assert_clean_shutdown(pid) + end + def test_chunked_encoding addr, port = unused_port @@ -37,6 +59,7 @@ def test_chunked_encoding assert_healthy("http://#{addr}:#{port}") response = Net::HTTP.get_response(URI("http://#{addr}:#{port}")) + assert_instance_of Net::HTTPOK, response assert_equal "chunked", response["transfer-encoding"] assert_clean_shutdown(pid) diff --git a/test/unit/test_http_parser_ng.rb b/test/unit/test_http_parser_ng.rb index d30079f8..7770d725 100644 --- a/test/unit/test_http_parser_ng.rb +++ b/test/unit/test_http_parser_ng.rb @@ -522,21 +522,32 @@ def test_path_info_semicolon "/1;a=b" => { qs => "", pi => "/1;a=b" }, "/1;a=b?" => { qs => "", pi => "/1;a=b" }, "/1?a=b;c=d&e=f" => { qs => "a=b;c=d&e=f", pi => "/1" }, - "*" => { qs => "", pi => "" }, - }.each do |uri,expect| + }.each do |uri, expect| assert_equal req, @parser.headers(req.clear, str % [ uri ]) req = req.dup @parser.clear assert_equal uri, req["REQUEST_URI"], "REQUEST_URI mismatch" assert_equal expect[qs], req[qs], "#{qs} mismatch" assert_equal expect[pi], req[pi], "#{pi} mismatch" - next if uri == "*" uri = URI.parse("http://example.com#{uri}") assert_equal uri.query.to_s, req[qs], "#{qs} mismatch URI.parse disagrees" assert_equal uri.path, req[pi], "#{pi} mismatch URI.parse disagrees" end end + def test_path_info_option_wildcard + req = {} + uri = "*" + str = "OPTIONS %s HTTP/1.1\r\nHost: example.com\r\n\r\n" + assert_equal req, @parser.headers(req, str % [ uri ]) + req = req.dup + @parser.clear + + assert_equal uri, req["REQUEST_URI"], "REQUEST_URI mismatch" + assert_equal "", req["QUERY_STRING"], "QUERY_STRING mismatch" + assert_nil req["PATH_INFO"], "PATH_INFO mismatch" + end + def test_path_info_semicolon_absolute qs = "QUERY_STRING" pi = "PATH_INFO" diff --git a/test/unit/test_request.rb b/test/unit/test_request.rb index 1ac5cbd9..80af356c 100644 --- a/test/unit/test_request.rb +++ b/test/unit/test_request.rb @@ -28,8 +28,8 @@ def test_options client = MockRequest.new("OPTIONS * HTTP/1.1\r\n" \ "Host: foo\r\n\r\n") env = @request.read(client) - assert_equal '', env['REQUEST_PATH'] - assert_equal '', env['PATH_INFO'] + assert_nil env['REQUEST_PATH'] + assert_nil env['PATH_INFO'] assert_equal '*', env['REQUEST_URI'] assert_kind_of Array, @lint.call(env) end