Skip to content

Commit 6de7a6b

Browse files
committed
Recognize path parameters in path segment fragments #39
1 parent a52193a commit 6de7a6b

File tree

3 files changed

+75
-3
lines changed

3 files changed

+75
-3
lines changed

fixtures/bugs/39/swagger.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
swagger: "2.0"
2+
info:
3+
version: "1.0.0"
4+
title: "fragment-param test"
5+
schemes:
6+
- http
7+
basePath: /service
8+
paths:
9+
/foo/bar{fragment}.{subfragment}:
10+
get:
11+
description: "lookup foo with bar*.*, where * is some string"
12+
parameters:
13+
- name: "fragment"
14+
in: "path"
15+
type: string
16+
required: true
17+
description: "this fragment header parameter is not recognized by codegen"
18+
- name: "subfragment"
19+
in: "path"
20+
type: string
21+
required: true
22+
description: "this subfragment header parameter is not recognized by codegen"
23+
produces:
24+
- text/plain
25+
responses:
26+
'200':
27+
description: "Successful"
28+
schema:
29+
type: string
30+
'400':
31+
description: "Bad request"
32+

spec.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -532,8 +532,15 @@ func (s *SpecValidator) validateParameters() *Result {
532532
}
533533
var fromPath []string
534534
for _, i := range params {
535-
fromPath = append(fromPath, knowns[i])
536-
knowns[i] = "!"
535+
knownsi := knowns[i]
536+
iparams := extractPathParams(knownsi)
537+
if len(iparams) > 0 {
538+
fromPath = append(fromPath, iparams...)
539+
for _, iparam := range iparams {
540+
knownsi = strings.Replace(knownsi, iparam, "!", 1)
541+
}
542+
knowns[i] = knownsi
543+
}
537544
}
538545
knownPath := strings.Join(knowns, "/")
539546
if orig, ok := knownPaths[knownPath]; ok {
@@ -609,13 +616,30 @@ func (s *SpecValidator) validateParameters() *Result {
609616
func parsePath(path string) (segments []string, params []int) {
610617
for i, p := range strings.Split(path, "/") {
611618
segments = append(segments, p)
612-
if len(p) > 0 && p[0] == '{' && p[len(p)-1] == '}' {
619+
if d0 := strings.Index(p, "{"); d0 >= 0 && d0 < strings.Index(p, "}") {
613620
params = append(params, i)
614621
}
615622
}
616623
return
617624
}
618625

626+
func extractPathParams(segment string) (params []string) {
627+
for {
628+
d0 := strings.IndexByte(segment, '{')
629+
if d0 < 0 {
630+
break
631+
}
632+
d1 := strings.IndexByte(segment[d0:], '}')
633+
if d1 > 0 {
634+
params = append(params, segment[d0:d0+d1+1])
635+
} else {
636+
break
637+
}
638+
segment = segment[d1:]
639+
}
640+
return params
641+
}
642+
619643
func (s *SpecValidator) validateReferencesValid() *Result {
620644
// each reference must point to a valid object
621645
res := new(Result)

spec_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,22 @@ func TestIssue18(t *testing.T) {
205205
}
206206
}
207207

208+
// check if a fragment path parameter is recognized
209+
func TestIssue39(t *testing.T) {
210+
fp := filepath.Join("fixtures", "bugs", "39", "swagger.yml")
211+
212+
// as swagger spec
213+
doc, err := loads.Spec(fp)
214+
if assert.NoError(t, err) {
215+
validator := NewSpecValidator(doc.Schema(), strfmt.Default)
216+
res, _ := validator.Validate(doc)
217+
for _, e := range res.Errors {
218+
log.Println(e)
219+
}
220+
assert.True(t, res.IsValid())
221+
}
222+
}
223+
208224
func TestValidateDuplicatePropertyNames(t *testing.T) {
209225
// simple allOf
210226
doc, err := loads.Spec(filepath.Join("fixtures", "validation", "duplicateprops.json"))

0 commit comments

Comments
 (0)