Skip to content

Commit

Permalink
fix: Xrefmap baseUrl problem reported at dotnet#9866 (dotnet#9869)
Browse files Browse the repository at this point in the history
fix: xrefmap baseurl problems
  • Loading branch information
filzrev authored and p-kostov committed Jun 28, 2024
1 parent 1c5c51c commit 76a3efb
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 28 deletions.
10 changes: 0 additions & 10 deletions src/Docfx.Build/XRefMaps/XRefArchiveBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,6 @@ private async Task<string> DownloadCoreAsync(Uri uri, XRefArchive xa)
return null;
}

// If BaseUrl is not set. Use xrefmap file download url as basePath.
if (string.IsNullOrEmpty(map.BaseUrl))
{
var baseUrl = uri.GetLeftPart(UriPartial.Path);
baseUrl = baseUrl.Substring(0, baseUrl.LastIndexOf('/') + 1);
map.BaseUrl = baseUrl;
map.UpdateHref(new Uri(baseUrl)); // Update hrefs from relative to absolute url.
map.HrefUpdated = null; // Don't save this flag for downloaded XRefMap.
}

// Enforce XRefMap's references are sorted by uid.
// Note:
// Sort is not needed if `map.Sorted == true`.
Expand Down
32 changes: 15 additions & 17 deletions src/Docfx.Build/XRefMaps/XRefMapDownloader.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using System.Net;
using Docfx.Common;

Expand Down Expand Up @@ -152,33 +154,29 @@ protected static async Task<XRefMap> DownloadFromWebAsync(Uri uri)
case ".json":
{
using var sr = new StreamReader(stream, bufferSize: 81920); // Default :1024 byte
return JsonUtility.Deserialize<XRefMap>(sr);
var xrefMap = JsonUtility.Deserialize<XRefMap>(sr);
xrefMap.BaseUrl = ResolveBaseUrl(xrefMap, uri);
return xrefMap;
}
case ".yml":
default:
{
using var sr = new StreamReader(stream, bufferSize: 81920); // Default :1024 byte
return YamlUtility.Deserialize<XRefMap>(sr);
var xrefMap = YamlUtility.Deserialize<XRefMap>(sr);
xrefMap.BaseUrl = ResolveBaseUrl(xrefMap, uri);
return xrefMap;
}
}
}

public static void UpdateHref(XRefMap map, Uri uri)
private static string ResolveBaseUrl(XRefMap map, Uri uri)
{
if (!string.IsNullOrEmpty(map.BaseUrl))
{
if (!Uri.TryCreate(map.BaseUrl, UriKind.Absolute, out Uri baseUri))
{
throw new InvalidDataException($"Xref map file (from {uri.AbsoluteUri}) has an invalid base url: {map.BaseUrl}.");
}
map.UpdateHref(baseUri);
return;
}
if (uri.Scheme == "http" || uri.Scheme == "https")
{
map.UpdateHref(uri);
return;
}
throw new InvalidDataException($"Xref map file (from {uri.AbsoluteUri}) missing base url.");
return map.BaseUrl;

// If downloaded xrefmap has no baseUrl.
// Use xrefmap file download url as basePath.
var baseUrl = uri.GetLeftPart(UriPartial.Path);
return baseUrl.Substring(0, baseUrl.LastIndexOf('/') + 1);
}
}
54 changes: 54 additions & 0 deletions test/Docfx.Build.Tests/XRefMapDownloaderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,58 @@ public async Task ReadLocalXRefMapJsonFileTest()
xrefMap.Should().NotBeNull();
xrefMap.References.Should().HaveCount(1);
}

/// <summary>
/// XrefmapDownloader test for xrefmap that has no baseUrl and href is defined by relative path.
/// </summary>
[Fact(Skip = "Has dependency to external site content.")]
public async Task ReadRemoteXRefMapYamlFileTest1()
{
// Arrange
var path = "https://horizongir.github.io/ZedGraph/xrefmap.yml";

XRefMapDownloader downloader = new XRefMapDownloader();
var xrefMap = await downloader.DownloadAsync(new Uri(path)) as XRefMap;

// Assert
xrefMap.Sorted.Should().BeTrue();
xrefMap.HrefUpdated.Should().BeNull();

// If baseUrl is not exists. Set download URL is set automatically.
xrefMap.BaseUrl.Should().Be("https://horizongir.github.io/ZedGraph/");

// Test relative URL is preserved.
xrefMap.References[0].Href.Should().Be("api/ZedGraph.html");
xrefMap.References[0].Href = "https://horizongir.github.io/ZedGraph/api/ZedGraph.html";
xrefMap.BaseUrl = "http://localhost";

// Test url is resolved as absolute URL.
var reader = xrefMap.GetReader();
reader.Find("ZedGraph").Href.Should().Be("https://horizongir.github.io/ZedGraph/api/ZedGraph.html");
}

/// <summary>
/// XrefmapDownloader test for xrefmap that has no baseUrl, and href is defined by absolute path.
/// </summary>
[Fact(Skip = "Has dependency to external site content.")]
public async Task ReadRemoteXRefMapJsonFileTest2()
{
// Arrange
var path = "https://normanderwan.github.io/UnityXrefMaps/xrefmap.yml";

XRefMapDownloader downloader = new XRefMapDownloader();
var xrefMap = await downloader.DownloadAsync(new Uri(path)) as XRefMap;

// Assert
xrefMap.Sorted.Should().BeTrue();
xrefMap.HrefUpdated.Should().BeNull();

// If baseUrl is not exists. XrefMap download URL is set automatically.
xrefMap.BaseUrl.Should().Be("https://normanderwan.github.io/UnityXrefMaps/");

// If href is absolute URL. baseURL is ignored.
var xrefSpec = xrefMap.References[0];
xrefSpec.Href.Should().Be("https://docs.unity3d.com/ScriptReference/index.html");
xrefMap.GetReader().Find(xrefSpec.Uid).Href.Should().Be("https://docs.unity3d.com/ScriptReference/index.html");
}
}
1 change: 0 additions & 1 deletion test/docfx.Tests/Api.verified.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,6 @@ public XRefMapDownloader(string baseFolder = null, System.Collections.Generic.IR
protected virtual System.Threading.Tasks.Task<Docfx.Build.Engine.IXRefContainer> DownloadBySchemeAsync(System.Uri uri) { }
protected static Docfx.Build.Engine.IXRefContainer DownloadFromLocal(System.Uri uri) { }
protected static System.Threading.Tasks.Task<Docfx.Build.Engine.XRefMap> DownloadFromWebAsync(System.Uri uri) { }
public static void UpdateHref(Docfx.Build.Engine.XRefMap map, System.Uri uri) { }
}
public sealed class XRefMapReader : Docfx.Build.Engine.XRefRedirectionReader
{
Expand Down

0 comments on commit 76a3efb

Please sign in to comment.