Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 33 additions & 22 deletions src/Microsoft.OpenApi.Readers/V2/OpenApiDocumentDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,39 +149,19 @@ private static void MakeServers(IList<OpenApiServer> servers, ParsingContext con
{
Copy link
Contributor

@PerthCharern PerthCharern Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If schemes is set to an empty list, I think we should treat that in the same way as schemes being null, i.e. line 148 should be if (schemes != null && schemes.Count != 0)

Spec says:
If the schemes is not included, the default scheme to be used is the one used to access the Swagger definition itself.

The term "not included" is not really precisely defined, but I think it should also apply to an empty schemes list.

If we don't modify the if clause as above, we won't have any server when schemes is an empty list. When servers is an empty list, the V3 spec interprets it as a default url of /, which is something totally different.

foreach (var scheme in schemes)
{
if (String.IsNullOrEmpty(scheme))
{
host = "//" + host; // The double slash prefix creates a relative url where the scheme is defined by the BaseUrl
}

var uriBuilder = new UriBuilder(scheme, host)
{
Path = basePath
};

var server = new OpenApiServer
{
Url = uriBuilder.ToString()
Url = BuildUrl(scheme, host, basePath)
};

servers.Add(server);
}
}
else
{
if (!String.IsNullOrEmpty(host))
{
host = "//" + host; // The double slash prefix creates a relative url where the scheme is defined by the BaseUrl
}
var uriBuilder = new UriBuilder()
{
Scheme = null,
Host = host,
Path = basePath
};
var server = new OpenApiServer
{
Url = uriBuilder.ToString()
Url = BuildUrl(null, host, basePath)
};

servers.Add(server);
Expand All @@ -198,6 +178,37 @@ private static void MakeServers(IList<OpenApiServer> servers, ParsingContext con
}
}

private static string BuildUrl(string scheme, string host, string basePath)
{
if (String.IsNullOrEmpty(scheme) && !String.IsNullOrEmpty(host))
{
host = "//" + host; // The double slash prefix creates a relative url where the scheme is defined by the BaseUrl
}

int? port = null;

if (!String.IsNullOrEmpty(host) && host.Contains(":"))
{
var pieces = host.Split(':');
host = pieces.First();
port = int.Parse(pieces.Last());
}

var uriBuilder = new UriBuilder()
{
Scheme = scheme,
Host = host,
Path = basePath
};

if (port != null)
{
uriBuilder.Port = port.Value;
}

return uriBuilder.ToString();
}

public static OpenApiDocument LoadOpenApi(RootNode rootNode)
{
var openApidoc = new OpenApiDocument();
Expand Down
22 changes: 22 additions & 0 deletions test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,5 +235,27 @@ public void MultipleServers()
Assert.Equal("https://dev.bing.com/api", doc.Servers.Last().Url);
}

[Fact]
public void LocalHostWithCustomHost()
{
var input = @"
swagger: 2.0
info:
title: test
version: 1.0.0
host: localhost:23232
paths: {}
";
var reader = new OpenApiStringReader(new OpenApiReaderSettings()
{
BaseUrl = new Uri("https://bing.com")
});

var doc = reader.Read(input, out var diagnostic);

var server = doc.Servers.First();
Assert.Equal(1, doc.Servers.Count);
Assert.Equal("https://localhost:23232", server.Url);
}
}
}