Fix some null warnings in HTTP parsing
MODIFY
WalletWasabi/Tor/Http/Helpers/HttpMessageHelper.cs
WalletWasabi/Tor/Http/Helpers/HttpMessageHelper.cs
@@ -57,12 +57,7 @@ namespace WalletWasabi.Tor.Http.Helpers
builder.Append(headers);
while (true)
{
- string header = await ReadCRLFLineAsync(stream, Encoding.ASCII, ctsToken).ConfigureAwait(false);
-
- if (header is null)
- {
- throw new FormatException("Malformed HTTP message: End of headers must be CRLF.");
- }
+ var header = await ReadCRLFLineAsync(stream, Encoding.ASCII, ctsToken).ConfigureAwait(false);
if (header.Length == 0)
{
@@ -124,7 +119,7 @@ namespace WalletWasabi.Tor.Http.Helpers
return bab.Length > 0
? bab.ToString(encoding)
- : null;
+ : throw new FormatException("There's no CRLF.");
}
public static byte[]? HandleGzipCompression(HttpContentHeaders contentHeaders, byte[]? decodedBodyArray)
@@ -189,7 +184,7 @@ namespace WalletWasabi.Tor.Http.Helpers
// transfer coding(Section 4.1) is the final encoding, the message
// body length is determined by reading and decoding the chunked
// data until the transfer coding indicates the data is complete.
- if (headerStruct?.ResponseHeaders is { } && headerStruct.ResponseHeaders.Contains("Transfer-Encoding"))
+ if (headerStruct?.ResponseHeaders?.Contains("Transfer-Encoding") is true)
{
// https://tools.ietf.org/html/rfc7230#section-4
// All transfer-coding names are case-insensitive
@@ -215,10 +210,8 @@ namespace WalletWasabi.Tor.Http.Helpers
// the recipient times out before the indicated number of octets are
// received, the recipient MUST consider the message to be
// incomplete and close the connection.
- if (headerStruct.ContentHeaders.Contains("Content-Length"))
+ if (headerStruct?.ContentHeaders?.Contains("Content-Length") is true && headerStruct.ContentHeaders.ContentLength is { } contentLength)
{
- long? contentLength = headerStruct.ContentHeaders?.ContentLength;
-
return await ReadBytesTillLengthAsync(stream, contentLength, ctsToken).ConfigureAwait(false);
}
@@ -237,7 +230,7 @@ namespace WalletWasabi.Tor.Http.Helpers
return await GetDecodedChunkedContentBytesAsync(stream, null, headerStruct, ctsToken).ConfigureAwait(false);
}
- private static async Task<byte[]> GetDecodedChunkedContentBytesAsync(Stream stream, HttpRequestContentHeaders requestHeaders, HttpResponseContentHeaders responseHeaders, CancellationToken ctsToken = default)
+ private static async Task<byte[]> GetDecodedChunkedContentBytesAsync(Stream stream, HttpRequestContentHeaders? requestHeaders, HttpResponseContentHeaders responseHeaders, CancellationToken ctsToken = default)
{
if (responseHeaders is null && requestHeaders is null)
{
@@ -287,6 +280,8 @@ namespace WalletWasabi.Tor.Http.Helpers
{
var chunkData = await ReadBytesTillLengthAsync(stream, chunkSize, ctsToken).ConfigureAwait(false);
string crlfLine = await ReadCRLFLineAsync(stream, Encoding.ASCII, ctsToken).ConfigureAwait(false);
+
+ // If more than a CRLF was read, then it's not an empty estring.
if (crlfLine.Length != 0)
{
throw new FormatException("Chunk does not end with CRLF.");
@@ -399,11 +394,13 @@ namespace WalletWasabi.Tor.Http.Helpers
// https://tools.ietf.org/html/rfc7230#section-4.1.1
// chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
var parts = firstChunkLine.Split(";", StringSplitOptions.RemoveEmptyEntries);
+
// https://tools.ietf.org/html/rfc7230#section-4.1
// The chunk-size field is a string of hex digits indicating the size of
// the chunk-data in octets.
- chunkSize = Convert.ToInt64(parts.First().Trim(), 16);
- chunkExtensions = parts.Skip(1);
+ var length = parts.Length;
+ chunkSize = length > 0 ? Convert.ToInt64(parts.First().Trim(), 16) : 0;
+ chunkExtensions = length > 1 ? parts.Skip(1) : Enumerable.Empty<string>();
}
private static async Task<byte[]> GetBytesTillEndAsync(Stream stream, CancellationToken ctsToken)
@@ -423,7 +420,7 @@ namespace WalletWasabi.Tor.Http.Helpers
}
}
- private static async Task<byte[]> ReadBytesTillLengthAsync(Stream stream, long? length, CancellationToken ctsToken)
+ private static async Task<byte[]> ReadBytesTillLengthAsync(Stream stream, long length, CancellationToken ctsToken)
{
try
{

Fix some null warnings in HTTP parsing