Skip to content

Unify Url class to never have leading / in the path #6532

Open
@antkmsft

Description

@antkmsft

There's this

void AppendPath(const std::string& encodedPath)
{
if (!m_encodedPath.empty() && m_encodedPath.back() != '/')
{
m_encodedPath += '/';
}
m_encodedPath += encodedPath;
}

and this

if (!m_encodedPath.empty())
{
if (!relative)
{
if (m_encodedPath[0] != '/')
{
url += "/";
}
}

and also this

if (*urlIter == '/')
{
++urlIter;
auto const pathIter = std::find(urlIter, url.end(), '?');

and then this

if (!m_httpProxy.HasValue() || request.GetUrl().GetScheme() == "https")
{
url = "/" + request.GetUrl().GetRelativeUrl();
}
else
{
url = request.GetUrl().GetAbsoluteUrl();
}

Which, if you do

Url url("http://www.microsoft.com");
url.AppendPath("/path");

will make no difference when you call url.GetAbsoluteUrl(), but should you call GetRelativeUrl(), will have the leading slash. It will result in GET //path HTTP 1.1 instead of GET /path HTTP 1.1 when using curl transport.
WinHTTP apparently corrects for this, so the bug becomes platform-specific. Servers don't like the //, and may return 404 (FWIW, typespec's Spector test server does, and I think it won't be alone).

What I think we should do, is fix inside the Url::AppendPath() - add if (existingPath.empty() && pathThatWeReAboutToAdd.startsWith('/')) { pathThatWeReAboutToAdd.dropLeading('/'); }
This will be in line with #5187, making the approach consistent in a case when the existing path was empty. ALso, this will be consistent with the Url::Url(std::string) constructor which does parsing and drops the / before parsing path.

Because otherwise, why would it be ok to

Url url("http://www.microsoft.com/existingPath/");
// always safe to have leading '/' when appending
url.AppendPath("/newPath"); // GetRelativeUrl() => "existingPath/newPath"

but not

Url url("http://www.microsoft.com/");
// suddenly NOT safe to have leading '/' when appending ?!
url.AppendPath("/newPath"); // GetRelativeUrl() => "/newPath", should be "newPath"

cc @LarryOsterman, if maybe I am missing something, and you have another thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Azure.CoreClientThis issue points to a problem in the data-plane of the library.needs-team-attentionWorkflow: This issue needs attention from Azure service team or SDK team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions