@@ -29,16 +29,14 @@ type SwaggerLoader struct {
2929 // IsExternalRefsAllowed enables visiting other files
3030 IsExternalRefsAllowed bool
3131
32- // LoadSwaggerFromURIFunc allows overriding the swagger file/URL reading func
33- LoadSwaggerFromURIFunc func (loader * SwaggerLoader , url * url.URL ) (* Swagger , error )
34-
3532 // ReadFromURIFunc allows overriding the any file/URL reading func
3633 ReadFromURIFunc func (loader * SwaggerLoader , url * url.URL ) ([]byte , error )
3734
3835 Context context.Context
3936
40- visitedFiles map [string ]struct {}
41- visitedSwaggers map [string ]* Swagger
37+ visitedPathItemRefs map [string ]struct {}
38+
39+ visitedDocuments map [string ]* Swagger
4240
4341 visitedExample map [* Example ]struct {}
4442 visitedHeader map [* Header ]struct {}
@@ -55,22 +53,17 @@ func NewSwaggerLoader() *SwaggerLoader {
5553 return & SwaggerLoader {}
5654}
5755
58- func (swaggerLoader * SwaggerLoader ) reset () {
59- swaggerLoader .visitedFiles = make (map [string ]struct {})
60- swaggerLoader .visitedSwaggers = make (map [string ]* Swagger )
56+ func (swaggerLoader * SwaggerLoader ) resetVisitedPathItemRefs () {
57+ swaggerLoader .visitedPathItemRefs = make (map [string ]struct {})
6158}
6259
6360// LoadSwaggerFromURI loads a spec from a remote URL
6461func (swaggerLoader * SwaggerLoader ) LoadSwaggerFromURI (location * url.URL ) (* Swagger , error ) {
65- swaggerLoader .reset ()
62+ swaggerLoader .resetVisitedPathItemRefs ()
6663 return swaggerLoader .loadSwaggerFromURIInternal (location )
6764}
6865
6966func (swaggerLoader * SwaggerLoader ) loadSwaggerFromURIInternal (location * url.URL ) (* Swagger , error ) {
70- f := swaggerLoader .LoadSwaggerFromURIFunc
71- if f != nil {
72- return f (swaggerLoader , location )
73- }
7467 data , err := swaggerLoader .readURL (location )
7568 if err != nil {
7669 return nil , err
@@ -111,8 +104,7 @@ func (swaggerLoader *SwaggerLoader) loadSingleElementFromURI(ref string, rootPat
111104}
112105
113106func (swaggerLoader * SwaggerLoader ) readURL (location * url.URL ) ([]byte , error ) {
114- f := swaggerLoader .ReadFromURIFunc
115- if f != nil {
107+ if f := swaggerLoader .ReadFromURIFunc ; f != nil {
116108 return f (swaggerLoader , location )
117109 }
118110
@@ -121,36 +113,23 @@ func (swaggerLoader *SwaggerLoader) readURL(location *url.URL) ([]byte, error) {
121113 if err != nil {
122114 return nil , err
123115 }
124- data , err := ioutil .ReadAll (resp .Body )
125116 defer resp .Body .Close ()
126- if err != nil {
127- return nil , err
128- }
129- return data , nil
117+ return ioutil .ReadAll (resp .Body )
130118 }
131119 if location .Scheme != "" || location .Host != "" || location .RawQuery != "" {
132120 return nil , fmt .Errorf ("unsupported URI: %q" , location .String ())
133121 }
134- data , err := ioutil .ReadFile (location .Path )
135- if err != nil {
136- return nil , err
137- }
138- return data , nil
122+ return ioutil .ReadFile (location .Path )
139123}
140124
141125// LoadSwaggerFromFile loads a spec from a local file path
142126func (swaggerLoader * SwaggerLoader ) LoadSwaggerFromFile (path string ) (* Swagger , error ) {
143- swaggerLoader .reset ()
127+ swaggerLoader .resetVisitedPathItemRefs ()
144128 return swaggerLoader .loadSwaggerFromFileInternal (path )
145129}
146130
147131func (swaggerLoader * SwaggerLoader ) loadSwaggerFromFileInternal (path string ) (* Swagger , error ) {
148- f := swaggerLoader .LoadSwaggerFromURIFunc
149132 pathAsURL := & url.URL {Path : path }
150- if f != nil {
151- x , err := f (swaggerLoader , pathAsURL )
152- return x , err
153- }
154133 data , err := swaggerLoader .readURL (pathAsURL )
155134 if err != nil {
156135 return nil , err
@@ -160,33 +139,39 @@ func (swaggerLoader *SwaggerLoader) loadSwaggerFromFileInternal(path string) (*S
160139
161140// LoadSwaggerFromData loads a spec from a byte array
162141func (swaggerLoader * SwaggerLoader ) LoadSwaggerFromData (data []byte ) (* Swagger , error ) {
163- swaggerLoader .reset ()
142+ swaggerLoader .resetVisitedPathItemRefs ()
164143 return swaggerLoader .loadSwaggerFromDataInternal (data )
165144}
166145
167146func (swaggerLoader * SwaggerLoader ) loadSwaggerFromDataInternal (data []byte ) (* Swagger , error ) {
168- swagger := & Swagger {}
169- if err := yaml .Unmarshal (data , swagger ); err != nil {
147+ doc := & Swagger {}
148+ if err := yaml .Unmarshal (data , doc ); err != nil {
149+ return nil , err
150+ }
151+ if err := swaggerLoader .ResolveRefsIn (doc , nil ); err != nil {
170152 return nil , err
171153 }
172- return swagger , swaggerLoader . ResolveRefsIn ( swagger , nil )
154+ return doc , nil
173155}
174156
175157// LoadSwaggerFromDataWithPath takes the OpenApi spec data in bytes and a path where the resolver can find referred
176158// elements and returns a *Swagger with all resolved data or an error if unable to load data or resolve refs.
177159func (swaggerLoader * SwaggerLoader ) LoadSwaggerFromDataWithPath (data []byte , path * url.URL ) (* Swagger , error ) {
178- swaggerLoader .reset ()
160+ swaggerLoader .resetVisitedPathItemRefs ()
179161 return swaggerLoader .loadSwaggerFromDataWithPathInternal (data , path )
180162}
181163
182164func (swaggerLoader * SwaggerLoader ) loadSwaggerFromDataWithPathInternal (data []byte , path * url.URL ) (* Swagger , error ) {
183- visited , ok := swaggerLoader .visitedSwaggers [path .String ()]
184- if ok {
185- return visited , nil
165+ if swaggerLoader .visitedDocuments == nil {
166+ swaggerLoader .visitedDocuments = make (map [string ]* Swagger )
167+ }
168+ uri := path .String ()
169+ if doc , ok := swaggerLoader .visitedDocuments [uri ]; ok {
170+ return doc , nil
186171 }
187172
188173 swagger := & Swagger {}
189- swaggerLoader .visitedSwaggers [ path . String () ] = swagger
174+ swaggerLoader .visitedDocuments [ uri ] = swagger
190175
191176 if err := yaml .Unmarshal (data , swagger ); err != nil {
192177 return nil , err
@@ -200,32 +185,8 @@ func (swaggerLoader *SwaggerLoader) loadSwaggerFromDataWithPathInternal(data []b
200185
201186// ResolveRefsIn expands references if for instance spec was just unmarshalled
202187func (swaggerLoader * SwaggerLoader ) ResolveRefsIn (swagger * Swagger , path * url.URL ) (err error ) {
203- if swaggerLoader .visitedExample == nil {
204- swaggerLoader .visitedExample = make (map [* Example ]struct {})
205- }
206- if swaggerLoader .visitedHeader == nil {
207- swaggerLoader .visitedHeader = make (map [* Header ]struct {})
208- }
209- if swaggerLoader .visitedLink == nil {
210- swaggerLoader .visitedLink = make (map [* Link ]struct {})
211- }
212- if swaggerLoader .visitedParameter == nil {
213- swaggerLoader .visitedParameter = make (map [* Parameter ]struct {})
214- }
215- if swaggerLoader .visitedRequestBody == nil {
216- swaggerLoader .visitedRequestBody = make (map [* RequestBody ]struct {})
217- }
218- if swaggerLoader .visitedResponse == nil {
219- swaggerLoader .visitedResponse = make (map [* Response ]struct {})
220- }
221- if swaggerLoader .visitedSchema == nil {
222- swaggerLoader .visitedSchema = make (map [* Schema ]struct {})
223- }
224- if swaggerLoader .visitedSecurityScheme == nil {
225- swaggerLoader .visitedSecurityScheme = make (map [* SecurityScheme ]struct {})
226- }
227- if swaggerLoader .visitedFiles == nil {
228- swaggerLoader .reset ()
188+ if swaggerLoader .visitedPathItemRefs == nil {
189+ swaggerLoader .resetVisitedPathItemRefs ()
229190 }
230191
231192 // Visit all components
@@ -456,6 +417,9 @@ func (swaggerLoader *SwaggerLoader) resolveRefSwagger(swagger *Swagger, ref stri
456417
457418func (swaggerLoader * SwaggerLoader ) resolveHeaderRef (swagger * Swagger , component * HeaderRef , documentPath * url.URL ) error {
458419 if component != nil && component .Value != nil {
420+ if swaggerLoader .visitedHeader == nil {
421+ swaggerLoader .visitedHeader = make (map [* Header ]struct {})
422+ }
459423 if _ , ok := swaggerLoader .visitedHeader [component .Value ]; ok {
460424 return nil
461425 }
@@ -500,6 +464,9 @@ func (swaggerLoader *SwaggerLoader) resolveHeaderRef(swagger *Swagger, component
500464
501465func (swaggerLoader * SwaggerLoader ) resolveParameterRef (swagger * Swagger , component * ParameterRef , documentPath * url.URL ) error {
502466 if component != nil && component .Value != nil {
467+ if swaggerLoader .visitedParameter == nil {
468+ swaggerLoader .visitedParameter = make (map [* Parameter ]struct {})
469+ }
503470 if _ , ok := swaggerLoader .visitedParameter [component .Value ]; ok {
504471 return nil
505472 }
@@ -560,6 +527,9 @@ func (swaggerLoader *SwaggerLoader) resolveParameterRef(swagger *Swagger, compon
560527
561528func (swaggerLoader * SwaggerLoader ) resolveRequestBodyRef (swagger * Swagger , component * RequestBodyRef , documentPath * url.URL ) error {
562529 if component != nil && component .Value != nil {
530+ if swaggerLoader .visitedRequestBody == nil {
531+ swaggerLoader .visitedRequestBody = make (map [* RequestBody ]struct {})
532+ }
563533 if _ , ok := swaggerLoader .visitedRequestBody [component .Value ]; ok {
564534 return nil
565535 }
@@ -612,6 +582,9 @@ func (swaggerLoader *SwaggerLoader) resolveRequestBodyRef(swagger *Swagger, comp
612582
613583func (swaggerLoader * SwaggerLoader ) resolveResponseRef (swagger * Swagger , component * ResponseRef , documentPath * url.URL ) error {
614584 if component != nil && component .Value != nil {
585+ if swaggerLoader .visitedResponse == nil {
586+ swaggerLoader .visitedResponse = make (map [* Response ]struct {})
587+ }
615588 if _ , ok := swaggerLoader .visitedResponse [component .Value ]; ok {
616589 return nil
617590 }
@@ -683,6 +656,9 @@ func (swaggerLoader *SwaggerLoader) resolveResponseRef(swagger *Swagger, compone
683656
684657func (swaggerLoader * SwaggerLoader ) resolveSchemaRef (swagger * Swagger , component * SchemaRef , documentPath * url.URL ) error {
685658 if component != nil && component .Value != nil {
659+ if swaggerLoader .visitedSchema == nil {
660+ swaggerLoader .visitedSchema = make (map [* Schema ]struct {})
661+ }
686662 if _ , ok := swaggerLoader .visitedSchema [component .Value ]; ok {
687663 return nil
688664 }
@@ -766,6 +742,9 @@ func (swaggerLoader *SwaggerLoader) resolveSchemaRef(swagger *Swagger, component
766742
767743func (swaggerLoader * SwaggerLoader ) resolveSecuritySchemeRef (swagger * Swagger , component * SecuritySchemeRef , documentPath * url.URL ) error {
768744 if component != nil && component .Value != nil {
745+ if swaggerLoader .visitedSecurityScheme == nil {
746+ swaggerLoader .visitedSecurityScheme = make (map [* SecurityScheme ]struct {})
747+ }
769748 if _ , ok := swaggerLoader .visitedSecurityScheme [component .Value ]; ok {
770749 return nil
771750 }
@@ -801,6 +780,9 @@ func (swaggerLoader *SwaggerLoader) resolveSecuritySchemeRef(swagger *Swagger, c
801780
802781func (swaggerLoader * SwaggerLoader ) resolveExampleRef (swagger * Swagger , component * ExampleRef , documentPath * url.URL ) error {
803782 if component != nil && component .Value != nil {
783+ if swaggerLoader .visitedExample == nil {
784+ swaggerLoader .visitedExample = make (map [* Example ]struct {})
785+ }
804786 if _ , ok := swaggerLoader .visitedExample [component .Value ]; ok {
805787 return nil
806788 }
@@ -836,6 +818,9 @@ func (swaggerLoader *SwaggerLoader) resolveExampleRef(swagger *Swagger, componen
836818
837819func (swaggerLoader * SwaggerLoader ) resolveLinkRef (swagger * Swagger , component * LinkRef , documentPath * url.URL ) error {
838820 if component != nil && component .Value != nil {
821+ if swaggerLoader .visitedLink == nil {
822+ swaggerLoader .visitedLink = make (map [* Link ]struct {})
823+ }
839824 if _ , ok := swaggerLoader .visitedLink [component .Value ]; ok {
840825 return nil
841826 }
@@ -875,10 +860,10 @@ func (swaggerLoader *SwaggerLoader) resolvePathItemRef(swagger *Swagger, entrypo
875860 key = documentPath .EscapedPath ()
876861 }
877862 key += entrypoint
878- if _ , ok := swaggerLoader .visitedFiles [key ]; ok {
863+ if _ , ok := swaggerLoader .visitedPathItemRefs [key ]; ok {
879864 return nil
880865 }
881- swaggerLoader .visitedFiles [key ] = struct {}{}
866+ swaggerLoader .visitedPathItemRefs [key ] = struct {}{}
882867
883868 const prefix = "#/paths/"
884869 if pathItem == nil {
0 commit comments