Fix parsing error on raw urls without path. (#406)

This commit is contained in:
Justin Kotalik 2017-11-15 14:05:21 -08:00 committed by GitHub
parent cfd974337d
commit 848e3c5cda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 1 deletions

View File

@ -2,11 +2,14 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
namespace Microsoft.AspNetCore.HttpSys.Internal
{
internal static class RawUrlHelper
{
private static readonly byte[] _forwardSlashPath = Encoding.ASCII.GetBytes("/");
/// <summary>
/// Find the segment of the URI byte array which represents the path.
/// </summary>
@ -39,7 +42,8 @@ namespace Microsoft.AspNetCore.HttpSys.Internal
if (pathStartIndex == -1)
{
// e.g. for request lines like: 'GET http://myserver' (no final '/')
pathStartIndex = raw.Length;
// At this point we can return a path with a slash.
return new ArraySegment<byte>(_forwardSlashPath);
}
}
else

View File

@ -114,6 +114,23 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
}
}
[ConditionalFact]
public async Task Request_FullUriInRequestLine_ParsesPath()
{
string root;
using (var server = Utilities.CreateHttpServerReturnRoot("/", out root))
{
// Send a HTTP request with the request line:
// GET http://localhost:5001 HTTP/1.1
var responseTask = SendSocketRequestAsync(root, root);
var context = await server.AcceptAsync(Utilities.DefaultTimeout);
Assert.Equal("/", context.Request.Path);
Assert.Equal("", context.Request.PathBase);
Assert.Equal(root, context.Request.RawUrl);
Assert.False(root.EndsWith("/")); // make sure root doesn't have a trailing slash
}
}
[ConditionalFact]
public async Task Request_OptionsStar_EmptyPath()
{

View File

@ -259,6 +259,42 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
[ConditionalFact]
public async Task Request_FullUriInRequestLine_ParsesPath()
{
using (var server = Utilities.CreateHttpServerReturnRoot("/", out var root, httpContext =>
{
var requestInfo = httpContext.Features.Get<IHttpRequestFeature>();
Assert.Equal("/", requestInfo.Path);
Assert.Equal("", requestInfo.PathBase);
return Task.CompletedTask;
}))
{
// Send a HTTP request with the request line:
// GET http://localhost:5001 HTTP/1.1
var response = await SendSocketRequestAsync(root, root);
var responseStatusCode = response.Substring(9); // Skip "HTTP/1.1 "
Assert.Equal(StatusCodes.Status200OK.ToString(), responseStatusCode);
}
}
[ConditionalFact]
public async Task Request_FullUriInRequestLineWithSlashesInQuery_BlockedByHttpSys()
{
using (var server = Utilities.CreateHttpServerReturnRoot("/", out var root, httpContext =>
{
return Task.CompletedTask;
}))
{
// Send a HTTP request with the request line:
// GET http://localhost:5001?query=value/1/2 HTTP/1.1
// Should return a 400 as it is a client error
var response = await SendSocketRequestAsync(root, root + "?query=value/1/2");
var responseStatusCode = response.Substring(9); // Skip "HTTP/1.1 "
Assert.Equal(StatusCodes.Status400BadRequest.ToString(), responseStatusCode);
}
}
[ConditionalTheory]
// The test server defines these prefixes: "/", "/11", "/2/3", "/2", "/11/2"
[InlineData("/", "", "/")]