Skip to content

Commit af7811e

Browse files
committed
Updated V2 writer to output relative server Urls
1 parent 409e039 commit af7811e

File tree

2 files changed

+117
-9
lines changed

2 files changed

+117
-9
lines changed

src/Microsoft.OpenApi/Models/OpenApiDocument.cs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -232,17 +232,33 @@ private static void WriteHostInfoV2(IOpenApiWriter writer, IList<OpenApiServer>
232232

233233
// Divide the URL in the Url property into host and basePath required in OpenAPI V2
234234
// The Url property cannotcontain path templating to be valid for V2 serialization.
235-
var firstServerUrl = new Uri(firstServer.Url);
235+
var firstServerUrl = new Uri(firstServer.Url, UriKind.RelativeOrAbsolute);
236236

237237
// host
238-
writer.WriteProperty(
239-
OpenApiConstants.Host,
240-
firstServerUrl.GetComponents(UriComponents.Host | UriComponents.Port, UriFormat.SafeUnescaped));
241-
242-
// basePath
243-
if (firstServerUrl.AbsolutePath != "/")
238+
if (firstServerUrl.IsAbsoluteUri)
239+
{
240+
writer.WriteProperty(
241+
OpenApiConstants.Host,
242+
firstServerUrl.GetComponents(UriComponents.Host | UriComponents.Port, UriFormat.SafeUnescaped));
243+
244+
// basePath
245+
if (firstServerUrl.AbsolutePath != "/")
246+
{
247+
writer.WriteProperty(OpenApiConstants.BasePath, firstServerUrl.AbsolutePath);
248+
}
249+
} else
244250
{
245-
writer.WriteProperty(OpenApiConstants.BasePath, firstServerUrl.AbsolutePath);
251+
var relativeUrl = firstServerUrl.OriginalString;
252+
if (relativeUrl.StartsWith("//"))
253+
{
254+
var pathPosition = relativeUrl.IndexOf('/', 3);
255+
writer.WriteProperty(OpenApiConstants.Host, relativeUrl.Substring(0, pathPosition));
256+
relativeUrl = relativeUrl.Substring(pathPosition);
257+
}
258+
if (!String.IsNullOrEmpty(relativeUrl) && relativeUrl != "/")
259+
{
260+
writer.WriteProperty(OpenApiConstants.BasePath, relativeUrl);
261+
}
246262
}
247263

248264
// Consider all schemes of the URLs in the server list that have the same
@@ -260,7 +276,7 @@ private static void WriteHostInfoV2(IOpenApiWriter writer, IList<OpenApiServer>
260276
UriComponents.Host | UriComponents.Port | UriComponents.Path,
261277
UriFormat.SafeUnescaped,
262278
StringComparison.OrdinalIgnoreCase) ==
263-
0)
279+
0 && u.IsAbsoluteUri)
264280
.Select(u => u.Scheme)
265281
.Distinct()
266282
.ToList();

test/Microsoft.OpenApi.Tests/Models/OpenApiDocumentTests.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2552,5 +2552,97 @@ public void SerializeDocumentWithReferenceButNoComponents()
25522552
// Assert
25532553
Assert.NotEmpty(actual);
25542554
}
2555+
2556+
[Fact]
2557+
public void SerializeRelativePathAsV2JsonWorks()
2558+
{
2559+
// Arrange
2560+
var expected =
2561+
@"swagger: '2.0'
2562+
info:
2563+
version: 1.0.0
2564+
basePath: /server1
2565+
paths: { }";
2566+
var doc = new OpenApiDocument()
2567+
{
2568+
Info = new OpenApiInfo() { Version = "1.0.0" },
2569+
Servers = new List<OpenApiServer>() {
2570+
new OpenApiServer()
2571+
{
2572+
Url = "/server1"
2573+
}
2574+
}
2575+
};
2576+
2577+
// Act
2578+
var actual = doc.SerializeAsYaml(OpenApiSpecVersion.OpenApi2_0);
2579+
2580+
// Assert
2581+
actual = actual.MakeLineBreaksEnvironmentNeutral();
2582+
expected = expected.MakeLineBreaksEnvironmentNeutral();
2583+
actual.Should().Be(expected);
2584+
}
2585+
2586+
[Fact]
2587+
public void SerializeRelativePathWithHostAsV2JsonWorks()
2588+
{
2589+
// Arrange
2590+
var expected =
2591+
@"swagger: '2.0'
2592+
info:
2593+
version: 1.0.0
2594+
host: //example.org
2595+
basePath: /server1
2596+
paths: { }";
2597+
var doc = new OpenApiDocument()
2598+
{
2599+
Info = new OpenApiInfo() { Version = "1.0.0" },
2600+
Servers = new List<OpenApiServer>() {
2601+
new OpenApiServer()
2602+
{
2603+
Url = "//example.org/server1"
2604+
}
2605+
}
2606+
};
2607+
2608+
// Act
2609+
var actual = doc.SerializeAsYaml(OpenApiSpecVersion.OpenApi2_0);
2610+
2611+
// Assert
2612+
actual = actual.MakeLineBreaksEnvironmentNeutral();
2613+
expected = expected.MakeLineBreaksEnvironmentNeutral();
2614+
actual.Should().Be(expected);
2615+
}
2616+
2617+
[Fact]
2618+
public void SerializeRelativeRootPathWithHostAsV2JsonWorks()
2619+
{
2620+
// Arrange
2621+
var expected =
2622+
@"swagger: '2.0'
2623+
info:
2624+
version: 1.0.0
2625+
host: //example.org
2626+
paths: { }";
2627+
var doc = new OpenApiDocument()
2628+
{
2629+
Info = new OpenApiInfo() { Version = "1.0.0" },
2630+
Servers = new List<OpenApiServer>() {
2631+
new OpenApiServer()
2632+
{
2633+
Url = "//example.org/"
2634+
}
2635+
}
2636+
};
2637+
2638+
// Act
2639+
var actual = doc.SerializeAsYaml(OpenApiSpecVersion.OpenApi2_0);
2640+
2641+
// Assert
2642+
actual = actual.MakeLineBreaksEnvironmentNeutral();
2643+
expected = expected.MakeLineBreaksEnvironmentNeutral();
2644+
actual.Should().Be(expected);
2645+
}
2646+
25552647
}
25562648
}

0 commit comments

Comments
 (0)