O URI.resolve do Java é incompatível com o RFC 3986 quando o URI relativo contém um caminho vazio?
Eu acredito que a definição e implementação do método URI.resolve do Java é incompatível comSeção 5.2.2 da RFC 3986. Entendo que a API Java define como esse método funciona e, se fosse alterado agora, quebraria os aplicativos existentes, mas minha pergunta é a seguinte:Alguém pode confirmar meu entendimento de que esse método é incompatível com o RFC 3986?
Estou usando o exemplo desta pergunta:java.net.URI resolvido apenas com a string de consulta, que vou copiar aqui:
Estou tentando criar URIs usando o JDK java.net.URI. Eu quero acrescentar a um objeto URI absoluto, uma consulta (em String). No exemplo:
URI base = new URI("http://example.com/something/more/long");
String queryString = "query=http://local:282/rand&action=aaaa";
URI query = new URI(null, null, null, queryString, null);
URI result = base.resolve(query);
Teoria (ou o que penso) é que a resolução deve retornar:
http://example.com/something/more/long?query=http://local:282/rand&action=aaaa
Mas o que eu consegui é:
http://example.com/something/more/?query=http://local:282/rand&action=aaaa
Meu entendimento deSeção 5.2.2 da RFC 3986 é que, se o caminho do URI relativo estiver vazio, o caminho inteiro do URI base deverá ser usado:
if (R.path == "") then
T.path = Base.path;
if defined(R.query) then
T.query = R.query;
else
T.query = Base.query;
endif;
e somente se um caminho for especificado é o caminho relativo a ser mesclado com o caminho base:
else
if (R.path starts-with "/") then
T.path = remove_dot_segments(R.path);
else
T.path = merge(Base.path, R.path);
T.path = remove_dot_segments(T.path);
endif;
T.query = R.query;
endif;
mas a implementação Java sempre faz a mesclagem, mesmo se o caminho estiver vazio:
String cp = (child.path == null) ? "" : child.path;
if ((cp.length() > 0) && (cp.charAt(0) == '/')) {
// 5.2 (5): Child path is absolute
ru.path = child.path;
} else {
// 5.2 (6): Resolve relative path
ru.path = resolvePath(base.path, cp, base.isAbsolute());
}
Se minha leitura estiver correta, para obter esse comportamento do pseudocódigo da RFC, você poderia colocar um ponto como o caminho no URI relativo, antes da string de consulta, que da minha experiência usando URIs relativos como links em páginas da Web é o que eu esperaria :
transform(Base="http://example.com/something/more/long", R=".?query")
=> T="http://example.com/something/more/?query"
Mas eu esperaria, em uma página da web, que um link na página "http://example.com/something/more/long"to"? query "iria para"http://example.com/something/more/long?query", não "http://example.com/something/more/?query"- em outras palavras, consistente com o RFC, mas não com a implementação do Java.
Minha leitura do RFC está correta e o método Java é inconsistente, ou estou faltando alguma coisa?