From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-3.9 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 2A9F2211B3; Sat, 1 Dec 2018 14:00:36 +0000 (UTC) Date: Sat, 1 Dec 2018 14:00:35 +0000 From: Eric Wong To: kcar-public@bogomips.org Subject: [PATCH] request: set env["FRAGMENT"] for WebDAV litmus test Message-ID: <20181201140035.5brfoi3tj6snni6a@dcvr> References: <20170420021543.7222-1-e@80x24.org> <20170420021543.7222-2-e@80x24.org> <20170523212520.GA11848@starla> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20170523212520.GA11848@starla> List-Id: This is because some people implement WebDAV, and the litmus[1] test needs DELETE to fail if there is a fragment in the request. --- Eric Wong wrote: > Eric Wong wrote: > > + # lets not waste cycles setting fragment in the request, > > + # valid clients do not send it, but we will just silently ignore it. > > + Fragment = ( uchar | reserved )*; > > Damnit, we can't do this and must set env["FRAGMENT"] :< > > This is because some people may implement WebDAV in Rack, and > the litmus test needs DELETE to fail if there is a fragment > in the request. > > And there may be other things, which rely on it, too. ext/kcar/kcar.rl | 13 ++++++++++--- ext/kcar/kcar_http_common.rl | 2 +- test/test_request_parser.rb | 4 ++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/ext/kcar/kcar.rl b/ext/kcar/kcar.rl index 9d04dd8..32b29d5 100644 --- a/ext/kcar/kcar.rl +++ b/ext/kcar/kcar.rl @@ -19,7 +19,7 @@ static VALUE g_rack_url_scheme, g_80, g_443, g_http, g_https, g_HTTP_HOST, g_HTTP_CONNECTION, g_HTTP_TRAILER, g_HTTP_TRANSFER_ENCODING, g_HTTP_VERSION, - g_CONTENT_LENGTH, g_CONTENT_TYPE, + g_CONTENT_LENGTH, g_CONTENT_TYPE, g_FRAGMENT, g_PATH_INFO, g_QUERY_STRING, g_REQUEST_METHOD, g_REQUEST_PATH, g_REQUEST_URI, g_SERVER_NAME, g_SERVER_PORT, g_SERVER_PROTOCOL; @@ -50,7 +50,6 @@ DEF_MAX_LENGTH(FIELD_NAME, 256); DEF_MAX_LENGTH(FIELD_VALUE, 80 * 1024); DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32))); DEF_MAX_LENGTH(REQUEST_URI, 1024 * 15); -DEF_MAX_LENGTH(FRAGMENT, 1024); /* just in case (stolen from Mongrel) */ DEF_MAX_LENGTH(REQUEST_PATH, 4096); /* common PATH_MAX on modern systems */ DEF_MAX_LENGTH(QUERY_STRING, (1024 * 10)); @@ -272,6 +271,13 @@ request_host(struct http_parser *hp, VALUE env, const char *ptr, size_t len) hp->v.host = val; } +static void +set_fragment(VALUE env, const char *ptr, size_t len) +{ + VALUE val = rb_str_new(ptr, len); + rb_hash_aset(env, g_FRAGMENT, val); +} + static void request_uri(VALUE env, const char *ptr, size_t len) { @@ -608,7 +614,7 @@ static void write_value(struct http_parser *hp, VALUE hdr, action url_scheme { url_scheme(hp, hdr, PTR_TO(mark), LEN(mark, fpc)); } action host { request_host(hp, hdr, PTR_TO(mark), LEN(mark, fpc)); } action request_uri { request_uri(hdr, PTR_TO(mark), LEN(mark, fpc)); } - + action fragment { set_fragment(hdr, PTR_TO(mark), LEN(mark, fpc)); } action start_query { MARK(start.query, fpc); } action query_string { query_string(hp, hdr, PTR_TO(start.query), LEN(start.query, fpc)); @@ -1126,6 +1132,7 @@ void Init_kcar_ext(void) rb_global_variable(&globals); C(globals, g_CONTENT_LENGTH, "CONTENT_LENGTH"); C(globals, g_CONTENT_TYPE, "CONTENT_TYPE"); + C(globals, g_FRAGMENT, "FRAGMENT"); C(globals, g_HTTP_HOST, "HTTP_HOST"); C(globals, g_HTTP_CONNECTION, "HTTP_CONNECTION"); C(globals, g_HTTP_TRAILER, "HTTP_TRAILER"); diff --git a/ext/kcar/kcar_http_common.rl b/ext/kcar/kcar_http_common.rl index 0c596bc..897ba85 100644 --- a/ext/kcar/kcar_http_common.rl +++ b/ext/kcar/kcar_http_common.rl @@ -45,7 +45,7 @@ # lets not waste cycles setting fragment in the request, # valid clients do not send it, but we will just silently ignore it. - Fragment = ( uchar | reserved )*; + Fragment = ( uchar | reserved )* >mark %fragment; Method = (token){1,20} >mark %request_method; GetOnly = "GET" >mark %request_method; diff --git a/test/test_request_parser.rb b/test/test_request_parser.rb index 895a948..9ed4b51 100644 --- a/test/test_request_parser.rb +++ b/test/test_request_parser.rb @@ -594,7 +594,7 @@ class TestRequestParser < Test::Unit::TestCase s = "#{m} /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n" req = @hp.request(@env, s) assert_equal '/forums/1/topics/2375?page=1', req['REQUEST_URI'] - assert_nil req['FRAGMENT'] + assert_equal 'posts-17408', req['FRAGMENT'] assert_equal 'page=1', req['QUERY_STRING'] assert_equal "", s assert_equal m, req['REQUEST_METHOD'] @@ -606,7 +606,7 @@ class TestRequestParser < Test::Unit::TestCase get = "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n" req = @hp.request(@env, get) assert_equal '/forums/1/topics/2375?page=1', req['REQUEST_URI'] - assert_nil req['FRAGMENT'] + assert_equal 'posts-17408', req['FRAGMENT'] assert_equal 'page=1', req['QUERY_STRING'] assert_equal '', get end