diff --git a/openapi3/loader.go b/openapi3/loader.go index 0b8d0e1cc..7a9e324d0 100644 --- a/openapi3/loader.go +++ b/openapi3/loader.go @@ -422,8 +422,35 @@ func (loader *Loader) documentPathForRecursiveRef(current *url.URL, resolvedRef if loader.rootDir == "" { return current } - return &url.URL{Path: path.Join(loader.rootDir, resolvedRef)} - + if resolvedRef == "" { + return current + } + var fragment string + relPath := resolvedRef + if idx := strings.IndexByte(relPath, '#'); idx >= 0 { + fragment = relPath[idx+1:] + relPath = relPath[:idx] + } + if relPath == "" { + return &url.URL{ + Path: current.Path, + Fragment: fragment, + } + } + respolvedPath := path.Join(loader.rootDir, relPath) + // Unfortunately `path.Join` remove last slash from result file. + // For example: + // ``` + // path.Join("foo/bar/", "") == "foo/bar" + // ``` + // In this workaround we try to restore last slash if needed. + if (resolvedRef == "" || strings.HasSuffix(resolvedRef, "/")) && !strings.HasSuffix(respolvedPath, "/") { + respolvedPath += "/" + } + return &url.URL{ + Path: respolvedPath, + Fragment: fragment, + } } func (loader *Loader) resolveRef(doc *T, ref string, path *url.URL) (*T, string, *url.URL, error) {