Remove regex usage from std.net.curl

This commit is contained in:
Dennis Korpel 2023-12-24 17:51:05 +01:00
parent f41348cda4
commit 096dee19e0

View file

@ -2419,8 +2419,8 @@ struct HTTP
@system @property void onReceiveHeader(void delegate(in char[] key,
in char[] value) callback)
{
import std.algorithm.searching : startsWith;
import std.regex : regex, match;
import std.algorithm.searching : findSplit, startsWith;
import std.string : indexOf, chomp;
import std.uni : toLower;
// Wrap incoming callback in order to separate http status line from
@ -2447,21 +2447,18 @@ struct HTTP
return;
}
// Normal http header
auto m = match(cast(char[]) header, regex("(.*?): (.*)$"));
auto fieldName = m.captures[1].toLower().idup;
auto m = header.findSplit(": ");
auto fieldName = m[0].toLower();
auto fieldContent = m[2].chomp;
if (fieldName == "content-type")
{
auto mct = match(cast(char[]) m.captures[2],
regex("charset=([^;]*)", "i"));
if (!mct.empty && mct.captures.length > 1)
charset = mct.captures[1].idup;
auto io = indexOf(fieldContent, "charset=", No.caseSensitive);
if (io != -1)
charset = fieldContent[io + "charset=".length .. $].findSplit(";")[0].idup;
}
if (!m.empty && callback !is null)
callback(fieldName, m.captures[2]);
headersIn[fieldName] = m.captures[2].idup;
if (!m[1].empty && callback !is null)
callback(fieldName, fieldContent);
headersIn[fieldName] = fieldContent.idup;
}
catch (UTFException e)
{
@ -2479,20 +2476,27 @@ struct HTTP
/// Parse status line, as received from / generated by cURL.
private static bool parseStatusLine(const char[] header, out StatusLine status) @safe
{
import std.conv : to;
import std.regex : regex, match;
import std.algorithm.searching : findSplit, startsWith;
import std.conv : to, ConvException;
const m = match(header, regex(r"^HTTP/(\d+)(?:\.(\d+))? (\d+)(?: (.*))?$"));
if (m.empty)
return false; // Invalid status line
else
if (!header.startsWith("HTTP/"))
return false;
try
{
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;
const m = header["HTTP/".length .. $].findSplit(" ");
const v = m[0].findSplit(".");
status.majorVersion = to!ushort(v[0]);
status.minorVersion = v[1].length ? to!ushort(v[2]) : 0;
const s2 = m[2].findSplit(" ");
status.code = to!ushort(s2[0]);
status.reason = s2[2].idup;
return true;
}
catch (ConvException e)
{
return false;
}
}
@safe unittest
@ -2505,6 +2509,12 @@ struct HTTP
// The HTTP2 protocol is binary; cURL generates this fake text header.
assert(parseStatusLine("HTTP/2 200", status)
&& status == StatusLine(2, 0, 200, null));
assert(!parseStatusLine("HTTP/2", status));
assert(!parseStatusLine("HTTP/2 -1", status));
assert(!parseStatusLine("HTTP/2 200", status));
assert(!parseStatusLine("HTTP/2.X 200", status));
assert(!parseStatusLine("HTTP|2 200", status));
}
/** Time condition enumeration as an alias of $(REF CurlTimeCond, etc,c,curl)