unicorn Ruby/Rack server user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
From: Mishael A Sibiryakov <death@junki.org>
To: unicorn-public@bogomips.org
Subject: [PATCH] Add some tolerance (RFC2616 sec. 19.3)
Date: Thu, 20 Oct 2016 12:05:32 +0300	[thread overview]
Message-ID: <1476954332.1736.156.camel@junki.org> (raw)

Hi all.

We're implementing client certificate authentication with nginx and

Nginx configured in the following way:

proxy_set_header X-SSL-Client-Cert $ssl_client_cert;

When client submits certificate and nginx passes it to the unicorn,
unicorn responds with 400 (Bad Request). This caused because nginx
doesn't use "\r\n" they using just "\n" and multilne headers is failed
to parse (I've added test).

Accorording to RFC2616 section 19.3:

"The line terminator for message-header fields is the sequence CRLF.
However, we recommend that applications, when parsing such headers,
recognize a single LF as a line terminator and ignore the leading CR."

CRLF changed to ("\r\n" | "\n")

Github commit https://github.com/uno4ki/unicorn/commit/ed127b66e162aaf1

PS: Googling "nginx unicorn ssl_client_cert" shows the problem. 

 ext/unicorn_http/unicorn_http_common.rl |  2 +-
 test/unit/test_http_parser.rb           | 16 ++++++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/ext/unicorn_http/unicorn_http_common.rl
index cc1d455..507e570 100644
--- a/ext/unicorn_http/unicorn_http_common.rl
+++ b/ext/unicorn_http/unicorn_http_common.rl
@@ -4,7 +4,7 @@
 # line endings
-  CRLF = "\r\n";
+  CRLF = ("\r\n" | "\n");
 # character types
   CTL = (cntrl | 127);
diff --git a/test/unit/test_http_parser.rb
index c72f7f2..4b1a16e 100644
--- a/test/unit/test_http_parser.rb
+++ b/test/unit/test_http_parser.rb
@@ -230,6 +230,22 @@ def test_nasty_pound_header
     assert_equal expect, req['HTTP_X_SSL_BULLSHIT']
+  def test_multiline_header_0d0a
+    parser = HttpParser.new
+    parser.buf << "GET / HTTP/1.0\r\nX-Multiline-Header: foo
bar\r\n\tcha cha\r\n\tzha zha\r\n\r\n"
+    req = parser.env
+    assert_equal req, parser.parse
+    assert_equal 'foo bar cha cha zha zha',
+  end
+  def test_multiline_header_0a
+    parser = HttpParser.new
+    parser.buf << "GET / HTTP/1.0\nX-Multiline-Header: foo bar\n\tcha
cha\n\tzha zha\n\n"
+    req = parser.env
+    assert_equal req, parser.parse
+    assert_equal 'foo bar cha cha zha zha',
+  end
   def test_continuation_eats_leading_spaces
     parser = HttpParser.new
     header = "GET / HTTP/1.1\r\n" \

             reply	other threads:[~2016-10-20  9:05 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-20  9:05 Mishael A Sibiryakov [this message]
2016-10-20 17:55 ` [PATCH] Add some tolerance (RFC2616 sec. 19.3) Eric Wong
2016-10-20 20:25   ` Mishael A Sibiryakov
2016-10-20 20:50     ` Eric Wong
2016-10-20 21:03       ` Mishael A Sibiryakov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

  List information: https://yhbt.net/unicorn/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1476954332.1736.156.camel@junki.org \
    --to=death@junki.org \
    --cc=unicorn-public@bogomips.org \


* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox


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).