https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112017-10-31T15:44:48ZRuby Issue Tracking SystemRuby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676492017-10-31T15:44:48Zdgames (Dax Games)
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/67649/diff?detail_id=46717">diff</a>)</li></ul> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676502017-10-31T15:56:30Zdgames (Dax Games)
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/67650/diff?detail_id=46718">diff</a>)</li></ul> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676512017-10-31T15:59:20Zdgames (Dax Games)
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/67651/diff?detail_id=46719">diff</a>)</li></ul> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676522017-10-31T16:00:37Zdgames (Dax Games)
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/67652/diff?detail_id=46720">diff</a>)</li></ul> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676532017-10-31T16:02:40Zdgames (Dax Games)
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/67653/diff?detail_id=46721">diff</a>)</li></ul> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676542017-10-31T16:04:06Zdgames (Dax Games)
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/67654/diff?detail_id=46722">diff</a>)</li></ul> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676552017-10-31T21:15:28Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>From my understanding of the HTTP specs that define the Authorization header, there's no standards-compatible way to send multiple Authorization header fields in a single message. So I don't think it can be called Ruby's bug.</p>
<p>According to <a href="https://stackoverflow.com/questions/29282578/multiple-http-authorization-headers" class="external">this Stack Overflow question</a>, servers that require multiple Authorization fields apparently might accept a flattened, comma-separated list (which is the inline representation for any other standard multi-valued header (aside from cookies)).</p>
<p>Have you tried: <code>request["authorization"] = "Bearer #{pf_token}, #{ck_token}"</code> ?</p> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676572017-11-01T03:22:27Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/67657/diff?detail_id=46724">diff</a>)</li><li><strong>Status</strong> changed from <i>Open</i> to <i>Third Party's Issue</i></li></ul><p><a href="https://tools.ietf.org/html/rfc7230#section-3.2.2" class="external">https://tools.ietf.org/html/rfc7230#section-3.2.2</a></p>
<blockquote>
<p>A sender MUST NOT generate multiple header fields with the same field<br>
name in a message unless either the entire field value for that<br>
header field is defined as a comma-separated list [i.e., #(values)]<br>
or the header field is a well-known exception (as noted below).</p>
</blockquote>
<p>If that server doesn't accept comma-separated list but requires multiple headers, it seems a bug of the server.</p> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676582017-11-01T06:12:45Znaruse (Yui NARUSE)naruse@airemix.jp
<ul></ul><p><a href="https://fetch.spec.whatwg.org/" class="external">https://fetch.spec.whatwg.org/</a> also denies multiple Authorization header.<br>
Please fix your server or RFC/WHATWG spec.</p> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676652017-11-01T16:07:11Zdgames (Dax Games)
<ul></ul><p>Thanks all for the responses.</p>
<p>Unfortunately I do not have the capability to ''fix ' the server and a header similar to the header resulting from my 2nd and 3rd failed examples works in a nodejs sample app but not in Ruby. Where the header is defined as a hash:</p>
<pre><code class="javascript syntaxhl" data-language="javascript"><span class="nx">header</span> <span class="o">=</span> <span class="p">{</span>
<span class="dl">'</span><span class="s1">authorization</span><span class="dl">'</span> <span class="o">=></span> <span class="p">[</span><span class="dl">"</span><span class="s2">Bearer #{pf_token}</span><span class="dl">"</span><span class="p">,</span> <span class="dl">"</span><span class="s2">#{ck_token}</span><span class="dl">"</span><span class="p">],</span>
<span class="dl">'</span><span class="s1">oauth_clientid</span><span class="dl">'</span> <span class="o">=></span> <span class="nx">pf_credentials</span><span class="p">[</span><span class="dl">'</span><span class="s1">client_id</span><span class="dl">'</span><span class="p">],</span>
<span class="dl">'</span><span class="s1">content-type</span><span class="dl">'</span> <span class="o">=></span> <span class="dl">'</span><span class="s1">application/json</span><span class="dl">'</span>
<span class="p">}</span>
</code></pre>
<a name="Working-NodeJS-Sample"></a>
<h1 >Working NodeJS Sample<a href="#Working-NodeJS-Sample" class="wiki-anchor">¶</a></h1>
<pre><code class="javascript syntaxhl" data-language="javascript"> <span class="kd">let</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{</span>
<span class="na">method</span><span class="p">:</span> <span class="dl">'</span><span class="s1">GET</span><span class="dl">'</span><span class="p">,</span>
<span class="na">url</span><span class="p">:</span> <span class="dl">'</span><span class="s1">https://xxxxxxx/v1/PasswordVault/WebServices/PIMServices.svc/Safes</span><span class="dl">'</span><span class="p">,</span>
<span class="na">qs</span><span class="p">:</span>
<span class="p">{</span>
<span class="na">client_id</span><span class="p">:</span> <span class="dl">'</span><span class="s1">ClientId1</span><span class="dl">'</span><span class="p">,</span>
<span class="na">client_secret</span><span class="p">:</span> <span class="dl">'</span><span class="s1">ClientSecret1</span><span class="dl">'</span><span class="p">,</span>
<span class="na">grant_type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">client_credentials</span><span class="dl">'</span><span class="p">,</span>
<span class="na">scope</span><span class="p">:</span> <span class="dl">'</span><span class="s1">api</span><span class="dl">'</span>
<span class="p">},</span>
<span class="na">headers</span><span class="p">:</span>
<span class="p">{</span>
<span class="dl">'</span><span class="s1">Authorization</span><span class="dl">'</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">Bearer </span><span class="dl">'</span> <span class="o">+</span> <span class="nx">pftoken</span><span class="p">,</span> <span class="nx">cktoken</span><span class="p">],</span>
<span class="dl">'</span><span class="s1">oauth_clientid</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">clientid1</span><span class="dl">'</span><span class="p">,</span>
<span class="dl">'</span><span class="s1">content-type</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">application/json</span><span class="dl">'</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">headers</span><span class="p">);</span>
<span class="nf">request</span><span class="p">(</span><span class="nx">options</span><span class="p">,</span> <span class="nf">function </span><span class="p">(</span><span class="nx">error</span><span class="p">,</span> <span class="nx">response</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">reject</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span>
<span class="p">}</span>
<span class="nf">resolve</span><span class="p">(</span><span class="nx">body</span><span class="p">);</span>
<span class="p">});</span>
</code></pre>
<p>So this leads me to believe the server is not the issue.</p>
<p>This was my main concern, wondering if there is some issue with the way ruby is dealing with it?</p>
<p>I will try the comma separated string. I think I already did that but will try again.</p> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676672017-11-01T17:52:37Zdgames (Dax Games)
<ul></ul><p>I found the code that is actually causing the issue I was wrong before. The actual code is in: <code>class Net::HTTPGenericRequest</code></p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">def</span> <span class="nf">write_header</span><span class="p">(</span><span class="n">sock</span><span class="p">,</span> <span class="n">ver</span><span class="p">,</span> <span class="n">path</span><span class="p">)</span>
<span class="n">reqline</span> <span class="o">=</span> <span class="s2">"</span><span class="si">#{</span><span class="vi">@method</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">path</span><span class="si">}</span><span class="s2"> HTTP/</span><span class="si">#{</span><span class="n">ver</span><span class="si">}</span><span class="s2">"</span>
<span class="k">if</span> <span class="sr">/[\r\n]/</span> <span class="o">=~</span> <span class="n">reqline</span>
<span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">,</span> <span class="s2">"A Request-Line must not contain CR or LF"</span>
<span class="k">end</span>
<span class="n">buf</span> <span class="o">=</span> <span class="s2">""</span>
<span class="n">buf</span> <span class="o"><<</span> <span class="n">reqline</span> <span class="o"><<</span> <span class="s2">"</span><span class="se">\r\n</span><span class="s2">"</span>
<span class="n">each_capitalized</span> <span class="k">do</span> <span class="o">|</span><span class="n">k</span><span class="p">,</span><span class="n">v</span><span class="o">|</span>
<span class="n">buf</span> <span class="o"><<</span> <span class="s2">"</span><span class="si">#{</span><span class="n">k</span><span class="si">}</span><span class="s2">: </span><span class="si">#{</span><span class="n">v</span><span class="si">}</span><span class="se">\r\n</span><span class="s2">"</span>
<span class="k">end</span>
<span class="n">buf</span> <span class="o"><<</span> <span class="s2">"</span><span class="se">\r\n</span><span class="s2">"</span>
<span class="n">sock</span><span class="p">.</span><span class="nf">write</span> <span class="n">buf</span>
<span class="k">end</span>
</code></pre>
<p>I think this code is overly critical of '\r\n' since it is actually erroring out on what is valid to separate header elements. The method itself is using this same separator.</p> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676692017-11-02T00:56:56Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>dgames (Dax Games) wrote:</p>
<blockquote>
<p>Thanks all for the responses.</p>
<p>Unfortunately I do not have the capability to ''fix ' the server and a header similar to the header resulting from my 2nd and 3rd failed examples works in a nodejs sample app but not in Ruby.</p>
</blockquote>
<p>You should report it to the server's administrators.<br>
As far as the standard specs prohibit the duplicate header, we can't change the correct behavior and violate the standards.<br>
And it sounds that node.js has the bug.</p> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676702017-11-02T03:57:19Zphluid61 (Matthew Kerwin)matthew@kerwin.net.au
<ul></ul><p>dgames (Dax Games) wrote:</p>
<blockquote>
<p>I think this code is overly critical of '\r\n' since it is actually erroring out on what is valid to separate header elements. The method itself is using this same separator.</p>
</blockquote>
<p>That's like saying you should allow quotation marks in a string, because you're hacking the string to actually be two strings. It bans the "\r\n" characters specifically because they're separators, they can't be part of the <em>value</em>.</p>
<p>I think perhaps what you'd like to request, instead, is the ability to define the way multiple header fields with the same name are sent in a HTTP message. Here's a straw-man idea:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">h1</span><span class="p">.</span><span class="nf">always_concatenate!</span>
<span class="n">h1</span><span class="p">[</span><span class="s1">'foo'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'bar, baz'</span>
<span class="n">h1</span><span class="p">[</span><span class="s1">'foo'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'qux'</span>
<span class="c1"># =></span>
<span class="c1">#</span>
<span class="c1"># Foo: bar, baz, qux</span>
<span class="c1">#</span>
<span class="n">h2</span><span class="p">.</span><span class="nf">never_concatenate!</span>
<span class="n">h2</span><span class="p">[</span><span class="s1">'foo'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'bar, baz'</span>
<span class="n">h2</span><span class="p">[</span><span class="s1">'foo'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'qux'</span>
<span class="c1"># =></span>
<span class="c1">#</span>
<span class="c1"># Foo: bar, baz</span>
<span class="c1"># Foo: qux</span>
<span class="c1">#</span>
</code></pre>
<p>That is definitely a separate feature request, though.</p> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676732017-11-02T12:34:46Zdgames (Dax Games)
<ul></ul><p>nobu (Nobuyoshi Nakada) wrote:</p>
<blockquote>
<p>As far as the standard specs prohibit the duplicate header, we can't change the correct behavior and violate the standards.<br>
And it sounds that node.js has the bug.</p>
</blockquote>
<p>Node is passing a single header with an array of values as Ruby tries to do in the failing code samples but Node works Ruby fails. They are both trying to do the same thing one fails one doesn't.</p>
<p>For now I just overloaded the methods I need to behave the way I need them to behave and I have it working.</p> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676742017-11-02T14:01:43Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>dgames (Dax Games) wrote:</p>
<blockquote>
<p>nobu (Nobuyoshi Nakada) wrote:</p>
<blockquote>
<p>As far as the standard specs prohibit the duplicate header, we can't change the correct behavior and violate the standards.<br>
And it sounds that node.js has the bug.</p>
</blockquote>
<p>Node is passing a single header with an array of values as Ruby tries to do in the failing code samples but Node works Ruby fails. They are both trying to do the same thing one fails one doesn't.</p>
</blockquote>
<p>When what must fail don't fail, we call it a bug.</p> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676752017-11-02T14:35:32Zdgames (Dax Games)
<ul></ul><p>nobu (Nobuyoshi Nakada) wrote:</p>
<blockquote>
<p>When what must fail don't fail, we call it a bug.</p>
</blockquote>
<p>I'm sorry I do not understand. Maybe I wasn't clear, Node is doing EXACTLY what you say Ruby should do and works where Ruby fails when it does EXACTLY what you say it should do.</p>
<p>I am not arguing with you I am just trying to get a clear understanding of why Ruby does not work when using the 'correct' header based on the RFC using multiple auth methods in an array on a URI that works with Node using the 'correct' header based on the RFC using multiple auth methods in an array on the very same URI.</p> Ruby master - Bug #14071: HTTP Header requiring dual authorization fails with 'header field value cannot include CR/LF'https://bugs.ruby-lang.org/issues/14071?journal_id=676792017-11-03T01:00:59Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>dgames (Dax Games) wrote:</p>
<blockquote>
<p>I'm sorry I do not understand. Maybe I wasn't clear, Node is doing EXACTLY what you say Ruby should do and works where Ruby fails when it does EXACTLY what you say it should do.</p>
</blockquote>
<p>What is sent by NodeJS in that case?</p>