Skip to content

Commit

Permalink
Merge pull request #6752 from CyberShadow/pull-20181105-211026
Browse files Browse the repository at this point in the history
Fix Issue 19367 - std.net.curl does not understand HTTP/2 status lines
merged-on-behalf-of: Vladimir Panteleev <github@thecybershadow.net>
  • Loading branch information
dlang-bot authored Nov 8, 2018
2 parents 969b4e7 + 1d4cfe3 commit 014f33f
Showing 1 changed file with 32 additions and 12 deletions.
44 changes: 32 additions & 12 deletions std/net/curl.d
Original file line number Diff line number Diff line change
Expand Up @@ -2385,7 +2385,6 @@ struct HTTP
in char[] value) callback)
{
import std.algorithm.searching : startsWith;
import std.conv : to;
import std.regex : regex, match;
import std.uni : toLower;

Expand All @@ -2405,18 +2404,8 @@ struct HTTP
if (header.startsWith("HTTP/"))
{
headersIn.clear();

const m = match(header, regex(r"^HTTP/(\d+)\.(\d+) (\d+) (.*)$"));
if (m.empty)
{
// Invalid status line
}
else
if (parseStatusLine(header, status))
{
status.majorVersion = to!ushort(m.captures[1]);
status.minorVersion = to!ushort(m.captures[2]);
status.code = to!ushort(m.captures[3]);
status.reason = m.captures[4].idup;
if (onReceiveStatusLine != null)
onReceiveStatusLine(status);
}
Expand Down Expand Up @@ -2452,6 +2441,37 @@ struct HTTP
private RefCounted!Impl p;
import etc.c.curl : CurlTimeCond;

/// Parse status line, as received from / generated by cURL.
private static bool parseStatusLine(in char[] header, out StatusLine status) @safe
{
import std.conv : to;
import std.regex : regex, match;

const m = match(header, regex(r"^HTTP/(\d+)(?:\.(\d+))? (\d+)(?: (.*))?$"));
if (m.empty)
return false; // Invalid status line
else
{
status.majorVersion = to!ushort(m.captures[1]);
status.minorVersion = m.captures[2].length ? to!ushort(m.captures[2]) : 0;
status.code = to!ushort(m.captures[3]);
status.reason = m.captures[4].idup;
return true;
}
}

@safe unittest
{
StatusLine status;
assert(parseStatusLine("HTTP/1.1 200 OK", status)
&& status == StatusLine(1, 1, 200, "OK"));
assert(parseStatusLine("HTTP/1.0 304 Not Modified", status)
&& status == StatusLine(1, 0, 304, "Not Modified"));
// The HTTP2 protocol is binary; cURL generates this fake text header.
assert(parseStatusLine("HTTP/2 200", status)
&& status == StatusLine(2, 0, 200, null));
}

/** Time condition enumeration as an alias of $(REF CurlTimeCond, etc,c,curl)
$(HTTP www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25, _RFC2616 Section 14.25)
Expand Down

0 comments on commit 014f33f

Please sign in to comment.