kcar RubyGem user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
* [PATCH] request: set env["FRAGMENT"] for WebDAV litmus test
       [not found]   ` <20170523212520.GA11848@starla>
@ 2018-12-01 14:00     ` Eric Wong
  0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2018-12-01 14:00 UTC (permalink / raw)
  To: kcar-public

This is because some people implement WebDAV, and the litmus[1]
test needs DELETE to fail if there is a fragment in the request.

<http://www.webdav.org/neon/litmus/>
---

  Eric Wong <e@80x24.org> wrote:
  > Eric Wong <e@80x24.org> 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.  <http://www.webdav.org/neon/litmus/>
  > 
  > 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

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2018-12-01 14:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20170420021543.7222-1-e@80x24.org>
     [not found] ` <20170420021543.7222-2-e@80x24.org>
     [not found]   ` <20170523212520.GA11848@starla>
2018-12-01 14:00     ` [PATCH] request: set env["FRAGMENT"] for WebDAV litmus test Eric Wong

Code repositories for project(s) associated with this public inbox

	https://yhbt.net/kcar.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).