@@ -261,21 +261,34 @@ public static String resolve(String baseUri, String pathToResolve) {
261261 }
262262 try {
263263 URI uri = new URI (baseUri );
264+ // URI#resolve drops base scheme for opaque URIs, https://github.com/jsonld-java/jsonld-java/issues/232
265+ if (uri .isOpaque ()) {
266+ String basePath = uri .getPath () != null ? uri .getPath () : uri .getSchemeSpecificPart ();
267+ // Drop the last segment, see https://tools.ietf.org/html/rfc3986#section-5.2.3 (2nd bullet point)
268+ basePath = basePath .contains ("/" ) ? basePath .substring (0 , basePath .lastIndexOf ('/' ) + 1 ) : "" ;
269+ return new URI (uri .getScheme (), basePath + pathToResolve , null ).toString ();
270+ }
271+ // "a base URI [...] does not allow a fragment" (https://tools.ietf.org/html/rfc3986#section-4.3)
272+ uri = new URI (uri .getScheme (), uri .getAuthority (), uri .getPath (), uri .getQuery (), null );
264273 // query string parsing
265274 if (pathToResolve .startsWith ("?" )) {
266- // drop fragment from uri if it has one
267- if (uri .getFragment () != null ) {
268- uri = new URI (uri .getScheme (), uri .getAuthority (), uri .getPath (), null , null );
269- }
270- // add query to the end manually (as URI.resolve does it wrong)
275+ // drop query, https://tools.ietf.org/html/rfc3986#section-5.2.2: T.query = R.query;
276+ uri = new URI (uri .getScheme (), uri .getAuthority (), uri .getPath (), null , null );
277+ // add query to the end manually (as URI#resolve does it wrong)
278+ return uri .toString () + pathToResolve ;
279+ } else if (pathToResolve .startsWith ("#" )) {
280+ // add fragment to the end manually (as URI#resolve does it wrong)
271281 return uri .toString () + pathToResolve ;
272282 }
273-
283+ // ensure a slash between the authority and the path of a URL
284+ if (uri .getSchemeSpecificPart ().startsWith ("//" ) && !uri .getSchemeSpecificPart ().matches ("//.*/.*" )) {
285+ uri = new URI (uri + "/" );
286+ }
274287 uri = uri .resolve (pathToResolve );
275288 // java doesn't discard unnecessary dot segments
276289 String path = uri .getPath ();
277290 if (path != null ) {
278- path = JsonLdUrl .removeDotSegments (uri . getPath () , true );
291+ path = JsonLdUrl .removeDotSegments (path , true );
279292 }
280293 return new URI (uri .getScheme (), uri .getAuthority (), path , uri .getQuery (),
281294 uri .getFragment ()).toString ();
0 commit comments