diff --git a/datamodel/document_config.go b/datamodel/document_config.go index 4efe85c..a833293 100644 --- a/datamodel/document_config.go +++ b/datamodel/document_config.go @@ -3,7 +3,10 @@ package datamodel -import "net/url" +import ( + "net/http" + "net/url" +) // DocumentConfiguration is used to configure the document creation process. It was added in v0.6.0 to allow // for more fine-grained control over controls and new features. @@ -15,6 +18,10 @@ type DocumentConfiguration struct { // Schema must be set to "http/https". BaseURL *url.URL + // RemoteDocumentGetter is a function that will be used to retrieve remote documents. If not set, the default + // remote document getter will be used. + RemoteDocumentGetter func(url string) (*http.Response, error) + // If resolving locally, the BasePath will be the root from which relative references will be resolved from. // It's usually the location of the root specification. BasePath string // set the Base Path for resolving relative references if the spec is exploded. diff --git a/datamodel/low/v2/swagger.go b/datamodel/low/v2/swagger.go index 305f9bb..79e39a0 100644 --- a/datamodel/low/v2/swagger.go +++ b/datamodel/low/v2/swagger.go @@ -143,9 +143,10 @@ func createDocument(info *datamodel.SpecInfo, config *datamodel.DocumentConfigur // build an index idx := index.NewSpecIndexWithConfig(info.RootNode, &index.SpecIndexConfig{ - BaseURL: config.BaseURL, - AllowRemoteLookup: config.AllowRemoteReferences, - AllowFileLookup: config.AllowFileReferences, + BaseURL: config.BaseURL, + RemoteDocumentGetter: config.RemoteDocumentGetter, + AllowRemoteLookup: config.AllowRemoteReferences, + AllowFileLookup: config.AllowFileReferences, }) doc.Index = idx doc.SpecInfo = info diff --git a/datamodel/low/v3/create_document.go b/datamodel/low/v3/create_document.go index f8465fe..5a6990b 100644 --- a/datamodel/low/v3/create_document.go +++ b/datamodel/low/v3/create_document.go @@ -48,11 +48,12 @@ func createDocument(info *datamodel.SpecInfo, config *datamodel.DocumentConfigur } // build an index idx := index.NewSpecIndexWithConfig(info.RootNode, &index.SpecIndexConfig{ - BaseURL: config.BaseURL, - BasePath: cwd, - AllowFileLookup: config.AllowFileReferences, - AllowRemoteLookup: config.AllowRemoteReferences, - AvoidBuildIndex: config.AvoidIndexBuild, + BaseURL: config.BaseURL, + RemoteDocumentGetter: config.RemoteDocumentGetter, + BasePath: cwd, + AllowFileLookup: config.AllowFileReferences, + AllowRemoteLookup: config.AllowRemoteReferences, + AvoidBuildIndex: config.AvoidIndexBuild, }) doc.Index = idx diff --git a/index/find_component.go b/index/find_component.go index 50e2473..f09dfa8 100644 --- a/index/find_component.go +++ b/index/find_component.go @@ -5,9 +5,6 @@ package index import ( "fmt" - "github.com/pb33f/libopenapi/utils" - "github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath" - "gopkg.in/yaml.v3" "io/ioutil" "net/http" "net/url" @@ -15,6 +12,10 @@ import ( "path/filepath" "strings" "time" + + "github.com/pb33f/libopenapi/utils" + "github.com/vmware-labs/yaml-jsonpath/pkg/yamlpath" + "gopkg.in/yaml.v3" ) // FindComponent will locate a component by its reference, returns nil if nothing is found. @@ -87,8 +88,10 @@ func (index *SpecIndex) FindComponent(componentId string, parent *yaml.Node) *Re var httpClient = &http.Client{Timeout: time.Duration(60) * time.Second} -func getRemoteDoc(u string, d chan []byte, e chan error) { - resp, err := httpClient.Get(u) +type RemoteDocumentGetter = func(url string) (*http.Response, error) + +func getRemoteDoc(g RemoteDocumentGetter, u string, d chan []byte, e chan error) { + resp, err := g(u) if err != nil { e <- err close(e) @@ -121,7 +124,11 @@ func (index *SpecIndex) lookupRemoteReference(ref string) (*yaml.Node, *yaml.Nod go func(uri string) { bc := make(chan []byte) ec := make(chan error) - go getRemoteDoc(uri, bc, ec) + var getter RemoteDocumentGetter = httpClient.Get + if index.config != nil && index.config.RemoteDocumentGetter != nil { + getter = index.config.RemoteDocumentGetter + } + go getRemoteDoc(getter, uri, bc, ec) select { case v := <-bc: body = v diff --git a/index/index_model.go b/index/index_model.go index a1e6a83..4a859dd 100644 --- a/index/index_model.go +++ b/index/index_model.go @@ -4,12 +4,13 @@ package index import ( - "golang.org/x/sync/syncmap" - "gopkg.in/yaml.v3" "net/http" "net/url" "os" "sync" + + "golang.org/x/sync/syncmap" + "gopkg.in/yaml.v3" ) // Constants used to determine if resolving is local, file based or remote file based. @@ -60,6 +61,10 @@ type SpecIndexConfig struct { // More details on relative references can be found in issue #73: https://github.com/pb33f/libopenapi/issues/73 BaseURL *url.URL // set the Base URL for resolving relative references if the spec is exploded. + // If resolving remotely, the RemoteDocumentGetter will be used to fetch the remote document. + // If not set, the default http client will be used. + RemoteDocumentGetter func(url string) (*http.Response, error) + // If resolving locally, the BasePath will be the root from which relative references will be resolved from BasePath string // set the Base Path for resolving relative references if the spec is exploded.