Skip to content

Commit

Permalink
Merge pull request #8869 from dkorpel/std-net-remove-regex
Browse files Browse the repository at this point in the history
Remove regex usage from std.net.curl
  • Loading branch information
dkorpel authored Dec 30, 2023
2 parents 713ac80 + 096dee1 commit e84acb7
Showing 1 changed file with 34 additions and 24 deletions.
58 changes: 34 additions & 24 deletions std/net/curl.d
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
{
Expand All @@ -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
Expand All @@ -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)
Expand Down

0 comments on commit e84acb7

Please sign in to comment.