Remove support for specifying only ports in IServerAddresses #197

This commit is contained in:
John Luo 2016-07-13 17:10:12 -07:00
Родитель 26ed532df5
Коммит 07b078d4e3
5 изменённых файлов: 167 добавлений и 28 удалений

Просмотреть файл

@ -1,7 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClient", "samples\TestClient\TestClient.csproj", "{8B828433-B333-4C19-96AE-00BFFF9D8841}"
EndProject
@ -32,6 +31,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "HotAddSample", "samples\HotAddSample\HotAddSample.xproj", "{8BFA392A-8B67-4454-916B-67C545EDFAEF}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Net.Http.Server.Tests", "test\Microsoft.Net.Http.Server.Tests\Microsoft.Net.Http.Server.Tests.xproj", "{E837249E-E666-4DF2-AFC3-7A4D70234F9F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -134,6 +135,18 @@ Global
{8BFA392A-8B67-4454-916B-67C545EDFAEF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{8BFA392A-8B67-4454-916B-67C545EDFAEF}.Release|x86.ActiveCfg = Release|Any CPU
{8BFA392A-8B67-4454-916B-67C545EDFAEF}.Release|x86.Build.0 = Release|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Debug|x86.ActiveCfg = Debug|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Debug|x86.Build.0 = Debug|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Release|Any CPU.Build.0 = Release|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Release|x86.ActiveCfg = Release|Any CPU
{E837249E-E666-4DF2-AFC3-7A4D70234F9F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -148,5 +161,6 @@ Global
{B9F45F9D-D206-47F0-8E5F-54CE2F0BDF92} = {99D5E5F3-88F5-4CCF-8D8C-717C8925DF09}
{DCB6E0B1-223D-44E6-8696-4767E5B6E6A1} = {E183C826-1360-4DFF-9994-F33CED5C8525}
{8BFA392A-8B67-4454-916B-67C545EDFAEF} = {3A1E31E3-2794-4CA3-B8E2-253E96BDE514}
{E837249E-E666-4DF2-AFC3-7A4D70234F9F} = {E183C826-1360-4DFF-9994-F33CED5C8525}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -117,49 +117,50 @@ namespace Microsoft.Net.Http.Server
string host = null;
int? port = null;
string path = null;
string whole = prefix ?? string.Empty;
var whole = prefix ?? string.Empty;
int delimiterStart1 = whole.IndexOf("://", StringComparison.Ordinal);
if (delimiterStart1 < 0)
var schemeDelimiterEnd = whole.IndexOf("://", StringComparison.Ordinal);
if (schemeDelimiterEnd < 0)
{
int aPort;
if (int.TryParse(whole, NumberStyles.None, CultureInfo.InvariantCulture, out aPort))
{
return UrlPrefix.Create("http", "localhost", aPort, "/");
}
throw new FormatException("Invalid prefix, missing scheme separator: " + prefix);
}
int delimiterEnd1 = delimiterStart1 + "://".Length;
var hostDelimiterStart = schemeDelimiterEnd + "://".Length;
int delimiterStart3 = whole.IndexOf("/", delimiterEnd1, StringComparison.Ordinal);
if (delimiterStart3 < 0)
var pathDelimiterStart = whole.IndexOf("/", hostDelimiterStart, StringComparison.Ordinal);
if (pathDelimiterStart < 0)
{
delimiterStart3 = whole.Length;
pathDelimiterStart = whole.Length;
}
int delimiterStart2 = whole.LastIndexOf(":", delimiterStart3 - 1, delimiterStart3 - delimiterEnd1, StringComparison.Ordinal);
int delimiterEnd2 = delimiterStart2 + ":".Length;
if (delimiterStart2 < 0)
var hostDelimiterEnd = whole.LastIndexOf(":", pathDelimiterStart - 1, pathDelimiterStart - hostDelimiterStart, StringComparison.Ordinal);
if (hostDelimiterEnd < 0)
{
delimiterStart2 = delimiterStart3;
delimiterEnd2 = delimiterStart3;
hostDelimiterEnd = pathDelimiterStart;
}
scheme = whole.Substring(0, delimiterStart1);
string portString = whole.Substring(delimiterEnd2, delimiterStart3 - delimiterEnd2);
scheme = whole.Substring(0, schemeDelimiterEnd);
var portString = whole.Substring(hostDelimiterEnd, pathDelimiterStart - hostDelimiterEnd); // The leading ":" is included
int portValue;
if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portValue))
if (!string.IsNullOrEmpty(portString))
{
host = whole.Substring(delimiterEnd1, delimiterStart2 - delimiterEnd1);
port = portValue;
var portValueString = portString.Substring(1); // Trim the leading ":"
if (int.TryParse(portValueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portValue))
{
host = whole.Substring(hostDelimiterStart, hostDelimiterEnd - hostDelimiterStart);
port = portValue;
}
else
{
// This means a port was specified but was invalid or empty.
throw new FormatException("Invalid prefix, invalid port speficification: " + prefix);
}
}
else
{
host = whole.Substring(delimiterEnd1, delimiterStart3 - delimiterEnd1);
host = whole.Substring(hostDelimiterStart, pathDelimiterStart - hostDelimiterStart);
}
path = whole.Substring(delimiterStart3);
path = whole.Substring(pathDelimiterStart);
return UrlPrefix.Create(scheme, host, port, path);
return Create(scheme, host, port, path);
}
public bool IsHttps { get; private set; }

Просмотреть файл

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>e837249e-e666-4df2-afc3-7a4d70234f9f</ProjectGuid>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

Просмотреть файл

@ -0,0 +1,85 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
using Xunit;
namespace Microsoft.Net.Http.Server
{
public class UrlPrefixTests
{
[Theory]
[InlineData("")]
[InlineData("5000")]
[InlineData("//noscheme")]
public void CreateThrowsForUrlsWithoutSchemeDelimiter(string url)
{
Assert.Throws<FormatException>(() => UrlPrefix.Create(url));
}
[Theory]
[InlineData("://emptyscheme")]
[InlineData("://")]
[InlineData("://:5000")]
public void CreateThrowsForUrlsWithEmptyScheme(string url)
{
Assert.Throws<ArgumentOutOfRangeException>(() => UrlPrefix.Create(url));
}
[Theory]
[InlineData("http://")]
[InlineData("http://:5000")]
[InlineData("http:///")]
[InlineData("http:///:5000")]
[InlineData("http:////")]
[InlineData("http:////:5000")]
public void CreateThrowsForUrlsWithoutHost(string url)
{
Assert.Throws<ArgumentNullException>(() => UrlPrefix.Create(url));
}
[Theory]
[InlineData("http://www.example.com:NOTAPORT")]
[InlineData("https://www.example.com:NOTAPORT")]
[InlineData("http://www.example.com:NOTAPORT/")]
[InlineData("http://foo:/tmp/weblistener-test.sock:5000/doesn't/matter")]
public void CreateThrowsForUrlsWithInvalidPorts(string url)
{
Assert.Throws<FormatException>(() => UrlPrefix.Create(url));
}
[Theory]
[InlineData("http://+", "http", "+", "80", "/", "http://+:80/")]
[InlineData("http://*", "http", "*", "80", "/", "http://*:80/")]
[InlineData("http://localhost", "http", "localhost", "80", "/", "http://localhost:80/")]
[InlineData("http://www.example.com", "http", "www.example.com", "80", "/", "http://www.example.com:80/")]
[InlineData("https://www.example.com", "https", "www.example.com", "443", "/", "https://www.example.com:443/")]
[InlineData("http://www.example.com/", "http", "www.example.com", "80", "/", "http://www.example.com:80/")]
[InlineData("http://www.example.com/foo?bar=baz", "http", "www.example.com", "80", "/foo?bar=baz/", "http://www.example.com:80/foo?bar=baz/")]
[InlineData("http://www.example.com:5000", "http", "www.example.com", "5000", "/", "http://www.example.com:5000/")]
[InlineData("https://www.example.com:5000", "https", "www.example.com", "5000", "/", "https://www.example.com:5000/")]
[InlineData("http://www.example.com:5000/", "http", "www.example.com", "5000", "/", "http://www.example.com:5000/")]
[InlineData("http://www.example.com/foo:bar", "http", "www.example.com", "80", "/foo:bar/", "http://www.example.com:80/foo:bar/")]
public void UrlsAreParsedCorrectly(string url, string scheme, string host, string port, string pathBase, string toString)
{
var urlPrefix = UrlPrefix.Create(url);
Assert.Equal(scheme, urlPrefix.Scheme);
Assert.Equal(host, urlPrefix.Host);
Assert.Equal(port, urlPrefix.Port);
Assert.Equal(pathBase, urlPrefix.Path);
Assert.Equal(toString ?? url, urlPrefix.ToString());
}
[Fact]
public void PathBaseIsNotNormalized()
{
var urlPrefix = UrlPrefix.Create("http://localhost:8080/p\u0041\u030Athbase");
Assert.False(urlPrefix.Path.IsNormalized(NormalizationForm.FormC));
Assert.Equal("/p\u0041\u030Athbase/", urlPrefix.Path);
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
{
"testRunner": "xunit",
"dependencies": {
"dotnet-test-xunit": "2.2.0-*",
"Microsoft.Net.Http.Server": "0.2.0-*",
"xunit": "2.2.0-*"
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.0-*",
"type": "platform"
}
}
},
"net451": { }
}
}