mirror of
https://github.com/dlang/phobos.git
synced 2025-04-28 06:00:35 +03:00
Fix Issue 19367 - std.net.curl does not understand HTTP/2 status lines
This commit is contained in:
parent
969b4e7bf8
commit
1d4cfe3d88
1 changed files with 32 additions and 12 deletions
|
@ -2385,7 +2385,6 @@ struct HTTP
|
||||||
in char[] value) callback)
|
in char[] value) callback)
|
||||||
{
|
{
|
||||||
import std.algorithm.searching : startsWith;
|
import std.algorithm.searching : startsWith;
|
||||||
import std.conv : to;
|
|
||||||
import std.regex : regex, match;
|
import std.regex : regex, match;
|
||||||
import std.uni : toLower;
|
import std.uni : toLower;
|
||||||
|
|
||||||
|
@ -2405,18 +2404,8 @@ struct HTTP
|
||||||
if (header.startsWith("HTTP/"))
|
if (header.startsWith("HTTP/"))
|
||||||
{
|
{
|
||||||
headersIn.clear();
|
headersIn.clear();
|
||||||
|
if (parseStatusLine(header, status))
|
||||||
const m = match(header, regex(r"^HTTP/(\d+)\.(\d+) (\d+) (.*)$"));
|
|
||||||
if (m.empty)
|
|
||||||
{
|
{
|
||||||
// Invalid status line
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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)
|
if (onReceiveStatusLine != null)
|
||||||
onReceiveStatusLine(status);
|
onReceiveStatusLine(status);
|
||||||
}
|
}
|
||||||
|
@ -2452,6 +2441,37 @@ struct HTTP
|
||||||
private RefCounted!Impl p;
|
private RefCounted!Impl p;
|
||||||
import etc.c.curl : CurlTimeCond;
|
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)
|
/** 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)
|
$(HTTP www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25, _RFC2616 Section 14.25)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue