Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
52060f3d
Commit
52060f3d
authored
Sep 04, 2015
by
Quinton Hoole
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #13554 from brendandburns/godep
Update go-restful
parents
e188ea6a
535c509d
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
268 additions
and
49 deletions
+268
-49
Godeps.json
Godeps/Godeps.json
+2
-2
CHANGES.md
.../_workspace/src/github.com/emicklei/go-restful/CHANGES.md
+5
-0
README.md
...s/_workspace/src/github.com/emicklei/go-restful/README.md
+1
-1
compress.go
..._workspace/src/github.com/emicklei/go-restful/compress.go
+6
-8
compress_test.go
...space/src/github.com/emicklei/go-restful/compress_test.go
+74
-0
compressor_pools.go
...ce/src/github.com/emicklei/go-restful/compressor_pools.go
+63
-0
container.go
...workspace/src/github.com/emicklei/go-restful/container.go
+34
-4
parameter.go
...workspace/src/github.com/emicklei/go-restful/parameter.go
+7
-1
request.go
.../_workspace/src/github.com/emicklei/go-restful/request.go
+31
-11
response.go
..._workspace/src/github.com/emicklei/go-restful/response.go
+23
-7
response_test.go
...space/src/github.com/emicklei/go-restful/response_test.go
+14
-14
swagger_webservice.go
...hub.com/emicklei/go-restful/swagger/swagger_webservice.go
+8
-1
No files found.
Godeps/Godeps.json
View file @
52060f3d
...
@@ -215,8 +215,8 @@
...
@@ -215,8 +215,8 @@
},
},
{
{
"ImportPath"
:
"github.com/emicklei/go-restful"
,
"ImportPath"
:
"github.com/emicklei/go-restful"
,
"Comment"
:
"v1.1.3-
76-gbfd6ff2
"
,
"Comment"
:
"v1.1.3-
98-g1f9a0ee
"
,
"Rev"
:
"
bfd6ff29d2961031cec64346a92bae4cde96c868
"
"Rev"
:
"
1f9a0ee00ff93717a275e15b30cf7df356255877
"
},
},
{
{
"ImportPath"
:
"github.com/evanphx/json-patch"
,
"ImportPath"
:
"github.com/evanphx/json-patch"
,
...
...
Godeps/_workspace/src/github.com/emicklei/go-restful/CHANGES.md
View file @
52060f3d
Change history of go-restful
Change history of go-restful
=
=
2015-08-06
-
add support for reading entities from compressed request content
-
use sync.Pool for compressors of http response and request body
-
add Description to Parameter for documentation in Swagger UI
2015-03-20
2015-03-20
-
add configurable logging
-
add configurable logging
...
...
Godeps/_workspace/src/github.com/emicklei/go-restful/README.md
View file @
52060f3d
...
@@ -47,7 +47,7 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo
...
@@ -47,7 +47,7 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo
-
Filters for intercepting the request
→
response flow on Service or Route level
-
Filters for intercepting the request
→
response flow on Service or Route level
-
Request-scoped variables using attributes
-
Request-scoped variables using attributes
-
Containers for WebServices on different HTTP endpoints
-
Containers for WebServices on different HTTP endpoints
-
Content encoding (gzip,deflate) of re
sponse
s
-
Content encoding (gzip,deflate) of re
quest and response payload
s
-
Automatic responses on OPTIONS (using a filter)
-
Automatic responses on OPTIONS (using a filter)
-
Automatic CORS request handling (using a filter)
-
Automatic CORS request handling (using a filter)
-
API declaration for Swagger UI (see swagger package)
-
API declaration for Swagger UI (see swagger package)
...
...
Godeps/_workspace/src/github.com/emicklei/go-restful/compress.go
View file @
52060f3d
...
@@ -73,15 +73,13 @@ func NewCompressingResponseWriter(httpWriter http.ResponseWriter, encoding strin
...
@@ -73,15 +73,13 @@ func NewCompressingResponseWriter(httpWriter http.ResponseWriter, encoding strin
c
.
writer
=
httpWriter
c
.
writer
=
httpWriter
var
err
error
var
err
error
if
ENCODING_GZIP
==
encoding
{
if
ENCODING_GZIP
==
encoding
{
c
.
compressor
,
err
=
gzip
.
NewWriterLevel
(
httpWriter
,
gzip
.
BestSpeed
)
w
:=
GzipWriterPool
.
Get
()
.
(
*
gzip
.
Writer
)
if
err
!=
nil
{
w
.
Reset
(
httpWriter
)
return
nil
,
err
c
.
compressor
=
w
}
}
else
if
ENCODING_DEFLATE
==
encoding
{
}
else
if
ENCODING_DEFLATE
==
encoding
{
c
.
compressor
,
err
=
zlib
.
NewWriterLevel
(
httpWriter
,
zlib
.
BestSpeed
)
w
:=
ZlibWriterPool
.
Get
()
.
(
*
zlib
.
Writer
)
if
err
!=
nil
{
w
.
Reset
(
httpWriter
)
return
nil
,
err
c
.
compressor
=
w
}
}
else
{
}
else
{
return
nil
,
errors
.
New
(
"Unknown encoding:"
+
encoding
)
return
nil
,
errors
.
New
(
"Unknown encoding:"
+
encoding
)
}
}
...
...
Godeps/_workspace/src/github.com/emicklei/go-restful/compress_test.go
View file @
52060f3d
package
restful
package
restful
import
(
import
(
"bytes"
"compress/gzip"
"compress/zlib"
"io"
"io/ioutil"
"net/http"
"net/http"
"net/http/httptest"
"net/http/httptest"
"testing"
"testing"
)
)
// go test -v -test.run TestGzip ...restful
func
TestGzip
(
t
*
testing
.
T
)
{
func
TestGzip
(
t
*
testing
.
T
)
{
EnableContentEncoding
=
true
EnableContentEncoding
=
true
httpRequest
,
_
:=
http
.
NewRequest
(
"GET"
,
"/test"
,
nil
)
httpRequest
,
_
:=
http
.
NewRequest
(
"GET"
,
"/test"
,
nil
)
...
@@ -27,6 +33,17 @@ func TestGzip(t *testing.T) {
...
@@ -27,6 +33,17 @@ func TestGzip(t *testing.T) {
if
httpWriter
.
Header
()
.
Get
(
"Content-Encoding"
)
!=
"gzip"
{
if
httpWriter
.
Header
()
.
Get
(
"Content-Encoding"
)
!=
"gzip"
{
t
.
Fatal
(
"Missing gzip header"
)
t
.
Fatal
(
"Missing gzip header"
)
}
}
reader
,
err
:=
gzip
.
NewReader
(
httpWriter
.
Body
)
if
err
!=
nil
{
t
.
Fatal
(
err
.
Error
())
}
data
,
err
:=
ioutil
.
ReadAll
(
reader
)
if
err
!=
nil
{
t
.
Fatal
(
err
.
Error
())
}
if
got
,
want
:=
string
(
data
),
"Hello World"
;
got
!=
want
{
t
.
Errorf
(
"got %v want %v"
,
got
,
want
)
}
}
}
func
TestDeflate
(
t
*
testing
.
T
)
{
func
TestDeflate
(
t
*
testing
.
T
)
{
...
@@ -50,4 +67,61 @@ func TestDeflate(t *testing.T) {
...
@@ -50,4 +67,61 @@ func TestDeflate(t *testing.T) {
if
httpWriter
.
Header
()
.
Get
(
"Content-Encoding"
)
!=
"deflate"
{
if
httpWriter
.
Header
()
.
Get
(
"Content-Encoding"
)
!=
"deflate"
{
t
.
Fatal
(
"Missing deflate header"
)
t
.
Fatal
(
"Missing deflate header"
)
}
}
reader
,
err
:=
zlib
.
NewReader
(
httpWriter
.
Body
)
if
err
!=
nil
{
t
.
Fatal
(
err
.
Error
())
}
data
,
err
:=
ioutil
.
ReadAll
(
reader
)
if
err
!=
nil
{
t
.
Fatal
(
err
.
Error
())
}
if
got
,
want
:=
string
(
data
),
"Hello World"
;
got
!=
want
{
t
.
Errorf
(
"got %v want %v"
,
got
,
want
)
}
}
func
TestGzipDecompressRequestBody
(
t
*
testing
.
T
)
{
b
:=
new
(
bytes
.
Buffer
)
w
:=
newGzipWriter
()
w
.
Reset
(
b
)
io
.
WriteString
(
w
,
`{"msg":"hi"}`
)
w
.
Flush
()
w
.
Close
()
req
:=
new
(
Request
)
httpRequest
,
_
:=
http
.
NewRequest
(
"GET"
,
"/"
,
bytes
.
NewReader
(
b
.
Bytes
()))
httpRequest
.
Header
.
Set
(
"Content-Type"
,
"application/json"
)
httpRequest
.
Header
.
Set
(
"Content-Encoding"
,
"gzip"
)
req
.
Request
=
httpRequest
doCacheReadEntityBytes
=
false
doc
:=
make
(
map
[
string
]
interface
{})
req
.
ReadEntity
(
&
doc
)
if
got
,
want
:=
doc
[
"msg"
],
"hi"
;
got
!=
want
{
t
.
Errorf
(
"got %v want %v"
,
got
,
want
)
}
}
func
TestZlibDecompressRequestBody
(
t
*
testing
.
T
)
{
b
:=
new
(
bytes
.
Buffer
)
w
:=
newZlibWriter
()
w
.
Reset
(
b
)
io
.
WriteString
(
w
,
`{"msg":"hi"}`
)
w
.
Flush
()
w
.
Close
()
req
:=
new
(
Request
)
httpRequest
,
_
:=
http
.
NewRequest
(
"GET"
,
"/"
,
bytes
.
NewReader
(
b
.
Bytes
()))
httpRequest
.
Header
.
Set
(
"Content-Type"
,
"application/json"
)
httpRequest
.
Header
.
Set
(
"Content-Encoding"
,
"deflate"
)
req
.
Request
=
httpRequest
doCacheReadEntityBytes
=
false
doc
:=
make
(
map
[
string
]
interface
{})
req
.
ReadEntity
(
&
doc
)
if
got
,
want
:=
doc
[
"msg"
],
"hi"
;
got
!=
want
{
t
.
Errorf
(
"got %v want %v"
,
got
,
want
)
}
}
}
Godeps/_workspace/src/github.com/emicklei/go-restful/compressor_pools.go
0 → 100644
View file @
52060f3d
package
restful
import
(
"bytes"
"compress/gzip"
"compress/zlib"
"sync"
)
// GzipWriterPool is used to get reusable zippers.
// The Get() result must be type asserted to *gzip.Writer.
var
GzipWriterPool
=
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
return
newGzipWriter
()
},
}
func
newGzipWriter
()
*
gzip
.
Writer
{
// create with an empty bytes writer; it will be replaced before using the gzipWriter
writer
,
err
:=
gzip
.
NewWriterLevel
(
new
(
bytes
.
Buffer
),
gzip
.
BestSpeed
)
if
err
!=
nil
{
panic
(
err
.
Error
())
}
return
writer
}
// GzipReaderPool is used to get reusable zippers.
// The Get() result must be type asserted to *gzip.Reader.
var
GzipReaderPool
=
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
return
newGzipReader
()
},
}
func
newGzipReader
()
*
gzip
.
Reader
{
// create with an empty reader (but with GZIP header); it will be replaced before using the gzipReader
w
:=
GzipWriterPool
.
Get
()
.
(
*
gzip
.
Writer
)
b
:=
new
(
bytes
.
Buffer
)
w
.
Reset
(
b
)
w
.
Flush
()
w
.
Close
()
reader
,
err
:=
gzip
.
NewReader
(
bytes
.
NewReader
(
b
.
Bytes
()))
if
err
!=
nil
{
panic
(
err
.
Error
())
}
return
reader
}
// ZlibWriterPool is used to get reusable zippers.
// The Get() result must be type asserted to *zlib.Writer.
var
ZlibWriterPool
=
&
sync
.
Pool
{
New
:
func
()
interface
{}
{
return
newZlibWriter
()
},
}
func
newZlibWriter
()
*
zlib
.
Writer
{
writer
,
err
:=
zlib
.
NewWriterLevel
(
new
(
bytes
.
Buffer
),
gzip
.
BestSpeed
)
if
err
!=
nil
{
panic
(
err
.
Error
())
}
return
writer
}
Godeps/_workspace/src/github.com/emicklei/go-restful/container.go
View file @
52060f3d
...
@@ -11,6 +11,7 @@ import (
...
@@ -11,6 +11,7 @@ import (
"os"
"os"
"runtime"
"runtime"
"strings"
"strings"
"sync"
"github.com/emicklei/go-restful/log"
"github.com/emicklei/go-restful/log"
)
)
...
@@ -18,6 +19,7 @@ import (
...
@@ -18,6 +19,7 @@ import (
// Container holds a collection of WebServices and a http.ServeMux to dispatch http requests.
// Container holds a collection of WebServices and a http.ServeMux to dispatch http requests.
// The requests are further dispatched to routes of WebServices using a RouteSelector
// The requests are further dispatched to routes of WebServices using a RouteSelector
type
Container
struct
{
type
Container
struct
{
webServicesLock
sync
.
RWMutex
webServices
[]
*
WebService
webServices
[]
*
WebService
ServeMux
*
http
.
ServeMux
ServeMux
*
http
.
ServeMux
isRegisteredOnRoot
bool
isRegisteredOnRoot
bool
...
@@ -83,6 +85,8 @@ func (c *Container) EnableContentEncoding(enabled bool) {
...
@@ -83,6 +85,8 @@ func (c *Container) EnableContentEncoding(enabled bool) {
// Add a WebService to the Container. It will detect duplicate root paths and panic in that case.
// Add a WebService to the Container. It will detect duplicate root paths and panic in that case.
func
(
c
*
Container
)
Add
(
service
*
WebService
)
*
Container
{
func
(
c
*
Container
)
Add
(
service
*
WebService
)
*
Container
{
c
.
webServicesLock
.
Lock
()
defer
c
.
webServicesLock
.
Unlock
()
// If registered on root then no additional specific mapping is needed
// If registered on root then no additional specific mapping is needed
if
!
c
.
isRegisteredOnRoot
{
if
!
c
.
isRegisteredOnRoot
{
pattern
:=
c
.
fixedPrefixPath
(
service
.
RootPath
())
pattern
:=
c
.
fixedPrefixPath
(
service
.
RootPath
())
...
@@ -122,6 +126,19 @@ func (c *Container) Add(service *WebService) *Container {
...
@@ -122,6 +126,19 @@ func (c *Container) Add(service *WebService) *Container {
return
c
return
c
}
}
func
(
c
*
Container
)
Remove
(
ws
*
WebService
)
error
{
c
.
webServicesLock
.
Lock
()
defer
c
.
webServicesLock
.
Unlock
()
newServices
:=
[]
*
WebService
{}
for
ix
:=
range
c
.
webServices
{
if
c
.
webServices
[
ix
]
.
rootPath
!=
ws
.
rootPath
{
newServices
=
append
(
newServices
,
c
.
webServices
[
ix
])
}
}
c
.
webServices
=
newServices
return
nil
}
// logStackOnRecover is the default RecoverHandleFunction and is called
// logStackOnRecover is the default RecoverHandleFunction and is called
// when DoNotRecover is false and the recoverHandleFunc is not set for the container.
// when DoNotRecover is false and the recoverHandleFunc is not set for the container.
// Default implementation logs the stacktrace and writes the stacktrace on the response.
// Default implementation logs the stacktrace and writes the stacktrace on the response.
...
@@ -190,9 +207,16 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R
...
@@ -190,9 +207,16 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R
}
}
}
}
// Find best match Route ; err is non nil if no match was found
// Find best match Route ; err is non nil if no match was found
webService
,
route
,
err
:=
c
.
router
.
SelectRoute
(
var
webService
*
WebService
c
.
webServices
,
var
route
*
Route
httpRequest
)
var
err
error
func
()
{
c
.
webServicesLock
.
RLock
()
defer
c
.
webServicesLock
.
RUnlock
()
webService
,
route
,
err
=
c
.
router
.
SelectRoute
(
c
.
webServices
,
httpRequest
)
}()
if
err
!=
nil
{
if
err
!=
nil
{
// a non-200 response has already been written
// a non-200 response has already been written
// run container filters anyway ; they should not touch the response...
// run container filters anyway ; they should not touch the response...
...
@@ -272,7 +296,13 @@ func (c *Container) Filter(filter FilterFunction) {
...
@@ -272,7 +296,13 @@ func (c *Container) Filter(filter FilterFunction) {
// RegisteredWebServices returns the collections of added WebServices
// RegisteredWebServices returns the collections of added WebServices
func
(
c
Container
)
RegisteredWebServices
()
[]
*
WebService
{
func
(
c
Container
)
RegisteredWebServices
()
[]
*
WebService
{
return
c
.
webServices
c
.
webServicesLock
.
RLock
()
defer
c
.
webServicesLock
.
RUnlock
()
result
:=
make
([]
*
WebService
,
len
(
c
.
webServices
))
for
ix
:=
range
c
.
webServices
{
result
[
ix
]
=
c
.
webServices
[
ix
]
}
return
result
}
}
// computeAllowedMethods returns a list of HTTP methods that are valid for a Request
// computeAllowedMethods returns a list of HTTP methods that are valid for a Request
...
...
Godeps/_workspace/src/github.com/emicklei/go-restful/parameter.go
View file @
52060f3d
...
@@ -95,8 +95,14 @@ func (p *Parameter) DataType(typeName string) *Parameter {
...
@@ -95,8 +95,14 @@ func (p *Parameter) DataType(typeName string) *Parameter {
return
p
return
p
}
}
// DefaultValue sets the default value field and return
w
the receiver
// DefaultValue sets the default value field and return
s
the receiver
func
(
p
*
Parameter
)
DefaultValue
(
stringRepresentation
string
)
*
Parameter
{
func
(
p
*
Parameter
)
DefaultValue
(
stringRepresentation
string
)
*
Parameter
{
p
.
data
.
DefaultValue
=
stringRepresentation
p
.
data
.
DefaultValue
=
stringRepresentation
return
p
return
p
}
}
// Description sets the description value field and returns the receiver
func
(
p
*
Parameter
)
Description
(
doc
string
)
*
Parameter
{
p
.
data
.
Description
=
doc
return
p
}
Godeps/_workspace/src/github.com/emicklei/go-restful/request.go
View file @
52060f3d
...
@@ -6,6 +6,8 @@ package restful
...
@@ -6,6 +6,8 @@ package restful
import
(
import
(
"bytes"
"bytes"
"compress/gzip"
"compress/zlib"
"encoding/json"
"encoding/json"
"encoding/xml"
"encoding/xml"
"io"
"io"
...
@@ -82,15 +84,17 @@ func (r *Request) HeaderParameter(name string) string {
...
@@ -82,15 +84,17 @@ func (r *Request) HeaderParameter(name string) string {
// ReadEntity checks the Accept header and reads the content into the entityPointer
// ReadEntity checks the Accept header and reads the content into the entityPointer
// May be called multiple times in the request-response flow
// May be called multiple times in the request-response flow
func
(
r
*
Request
)
ReadEntity
(
entityPointer
interface
{})
(
err
error
)
{
func
(
r
*
Request
)
ReadEntity
(
entityPointer
interface
{})
(
err
error
)
{
defer
r
.
Request
.
Body
.
Close
()
contentType
:=
r
.
Request
.
Header
.
Get
(
HEADER_ContentType
)
contentType
:=
r
.
Request
.
Header
.
Get
(
HEADER_ContentType
)
contentEncoding
:=
r
.
Request
.
Header
.
Get
(
HEADER_ContentEncoding
)
if
doCacheReadEntityBytes
{
if
doCacheReadEntityBytes
{
return
r
.
cachingReadEntity
(
contentType
,
entityPointer
)
return
r
.
cachingReadEntity
(
contentType
,
contentEncoding
,
entityPointer
)
}
}
// unmarshall directly from request Body
// unmarshall directly from request Body
return
r
.
decodeEntity
(
r
.
Request
.
Body
,
contentType
,
entityPointer
)
return
r
.
decodeEntity
(
r
.
Request
.
Body
,
contentType
,
contentEncoding
,
entityPointer
)
}
}
func
(
r
*
Request
)
cachingReadEntity
(
contentType
string
,
entityPointer
interface
{})
(
err
error
)
{
func
(
r
*
Request
)
cachingReadEntity
(
contentType
string
,
contentEncoding
string
,
entityPointer
interface
{})
(
err
error
)
{
var
buffer
[]
byte
var
buffer
[]
byte
if
r
.
bodyContent
!=
nil
{
if
r
.
bodyContent
!=
nil
{
buffer
=
*
r
.
bodyContent
buffer
=
*
r
.
bodyContent
...
@@ -101,22 +105,38 @@ func (r *Request) cachingReadEntity(contentType string, entityPointer interface{
...
@@ -101,22 +105,38 @@ func (r *Request) cachingReadEntity(contentType string, entityPointer interface{
}
}
r
.
bodyContent
=
&
buffer
r
.
bodyContent
=
&
buffer
}
}
return
r
.
decodeEntity
(
bytes
.
NewReader
(
buffer
),
contentType
,
entityPointer
)
return
r
.
decodeEntity
(
bytes
.
NewReader
(
buffer
),
contentType
,
contentEncoding
,
entityPointer
)
}
}
func
(
r
*
Request
)
decodeEntity
(
reader
io
.
Reader
,
contentType
string
,
entityPointer
interface
{})
(
err
error
)
{
func
(
r
*
Request
)
decodeEntity
(
reader
io
.
Reader
,
contentType
string
,
contentEncoding
string
,
entityPointer
interface
{})
(
err
error
)
{
if
strings
.
Contains
(
contentType
,
MIME_XML
)
{
entityReader
:=
reader
return
xml
.
NewDecoder
(
reader
)
.
Decode
(
entityPointer
)
// check if the request body needs decompression
if
ENCODING_GZIP
==
contentEncoding
{
gzipReader
:=
GzipReaderPool
.
Get
()
.
(
*
gzip
.
Reader
)
gzipReader
.
Reset
(
reader
)
entityReader
=
gzipReader
}
else
if
ENCODING_DEFLATE
==
contentEncoding
{
zlibReader
,
err
:=
zlib
.
NewReader
(
reader
)
if
err
!=
nil
{
return
err
}
entityReader
=
zlibReader
}
}
// decode JSON
if
strings
.
Contains
(
contentType
,
MIME_JSON
)
||
MIME_JSON
==
defaultRequestContentType
{
if
strings
.
Contains
(
contentType
,
MIME_JSON
)
||
MIME_JSON
==
defaultRequestContentType
{
decoder
:=
json
.
NewDecoder
(
r
eader
)
decoder
:=
json
.
NewDecoder
(
entityR
eader
)
decoder
.
UseNumber
()
decoder
.
UseNumber
()
return
decoder
.
Decode
(
entityPointer
)
return
decoder
.
Decode
(
entityPointer
)
}
}
if
MIME_XML
==
defaultRequestContentType
{
return
xml
.
NewDecoder
(
reader
)
.
Decode
(
entityPointer
)
// decode XML
if
strings
.
Contains
(
contentType
,
MIME_XML
)
||
MIME_XML
==
defaultRequestContentType
{
return
xml
.
NewDecoder
(
entityReader
)
.
Decode
(
entityPointer
)
}
}
return
NewError
(
400
,
"Unable to unmarshal content of type:"
+
contentType
)
return
NewError
(
http
.
StatusBadRequest
,
"Unable to unmarshal content of type:"
+
contentType
)
}
}
// SetAttribute adds or replaces the attribute with the given value.
// SetAttribute adds or replaces the attribute with the given value.
...
...
Godeps/_workspace/src/github.com/emicklei/go-restful/response.go
View file @
52060f3d
...
@@ -28,11 +28,12 @@ type Response struct {
...
@@ -28,11 +28,12 @@ type Response struct {
statusCode
int
// HTTP status code that has been written explicity (if zero then net/http has written 200)
statusCode
int
// HTTP status code that has been written explicity (if zero then net/http has written 200)
contentLength
int
// number of bytes written for the response body
contentLength
int
// number of bytes written for the response body
prettyPrint
bool
// controls the indentation feature of XML and JSON serialization. It is initialized using var PrettyPrintResponses.
prettyPrint
bool
// controls the indentation feature of XML and JSON serialization. It is initialized using var PrettyPrintResponses.
err
error
// err property is kept when WriteError is called
}
}
// Creates a new response based on a http ResponseWriter.
// Creates a new response based on a http ResponseWriter.
func
NewResponse
(
httpWriter
http
.
ResponseWriter
)
*
Response
{
func
NewResponse
(
httpWriter
http
.
ResponseWriter
)
*
Response
{
return
&
Response
{
httpWriter
,
""
,
[]
string
{},
http
.
StatusOK
,
0
,
PrettyPrintResponses
}
// empty content-types
return
&
Response
{
httpWriter
,
""
,
[]
string
{},
http
.
StatusOK
,
0
,
PrettyPrintResponses
,
nil
}
// empty content-types
}
}
// If Accept header matching fails, fall back to this type, otherwise
// If Accept header matching fails, fall back to this type, otherwise
...
@@ -182,6 +183,7 @@ func (r *Response) WriteJson(value interface{}, contentType string) error {
...
@@ -182,6 +183,7 @@ func (r *Response) WriteJson(value interface{}, contentType string) error {
// WriteError write the http status and the error string on the response.
// WriteError write the http status and the error string on the response.
func
(
r
*
Response
)
WriteError
(
httpStatus
int
,
err
error
)
error
{
func
(
r
*
Response
)
WriteError
(
httpStatus
int
,
err
error
)
error
{
r
.
err
=
err
return
r
.
WriteErrorString
(
httpStatus
,
err
.
Error
())
return
r
.
WriteErrorString
(
httpStatus
,
err
.
Error
())
}
}
...
@@ -203,21 +205,30 @@ func (r *Response) WriteErrorString(status int, errorReason string) error {
...
@@ -203,21 +205,30 @@ func (r *Response) WriteErrorString(status int, errorReason string) error {
// WriteHeader is overridden to remember the Status Code that has been written.
// WriteHeader is overridden to remember the Status Code that has been written.
// Note that using this method, the status value is only written when
// Note that using this method, the status value is only written when
// - calling WriteEntity,
// calling WriteEntity,
// - or directly calling WriteAsXml or WriteAsJson,
// or directly calling WriteAsXml or WriteAsJson,
// - or if the status is one for which no response is allowed (i.e.,
// or if the status is one for which no response is allowed:
// 204 (http.StatusNoContent) or 304 (http.StatusNotModified))
//
// 202 = http.StatusAccepted
// 204 = http.StatusNoContent
// 206 = http.StatusPartialContent
// 304 = http.StatusNotModified
//
// If this behavior does not fit your need then you can write to the underlying response, such as:
// response.ResponseWriter.WriteHeader(http.StatusAccepted)
func
(
r
*
Response
)
WriteHeader
(
httpStatus
int
)
{
func
(
r
*
Response
)
WriteHeader
(
httpStatus
int
)
{
r
.
statusCode
=
httpStatus
r
.
statusCode
=
httpStatus
// if 20
1,204
,304 then WriteEntity will not be called so we need to pass this code
// if 20
2,204,206
,304 then WriteEntity will not be called so we need to pass this code
if
http
.
StatusNoContent
==
httpStatus
||
if
http
.
StatusNoContent
==
httpStatus
||
http
.
StatusNotModified
==
httpStatus
||
http
.
StatusNotModified
==
httpStatus
||
http
.
StatusPartialContent
==
httpStatus
{
http
.
StatusPartialContent
==
httpStatus
||
http
.
StatusAccepted
==
httpStatus
{
r
.
ResponseWriter
.
WriteHeader
(
httpStatus
)
r
.
ResponseWriter
.
WriteHeader
(
httpStatus
)
}
}
}
}
// StatusCode returns the code that has been written using WriteHeader.
// StatusCode returns the code that has been written using WriteHeader.
// If WriteHeader, WriteEntity or WriteAsXml has not been called (yet) then return 200 OK.
func
(
r
Response
)
StatusCode
()
int
{
func
(
r
Response
)
StatusCode
()
int
{
if
0
==
r
.
statusCode
{
if
0
==
r
.
statusCode
{
// no status code has been written yet; assume OK
// no status code has been written yet; assume OK
...
@@ -245,3 +256,8 @@ func (r Response) ContentLength() int {
...
@@ -245,3 +256,8 @@ func (r Response) ContentLength() int {
func
(
r
Response
)
CloseNotify
()
<-
chan
bool
{
func
(
r
Response
)
CloseNotify
()
<-
chan
bool
{
return
r
.
ResponseWriter
.
(
http
.
CloseNotifier
)
.
CloseNotify
()
return
r
.
ResponseWriter
.
(
http
.
CloseNotifier
)
.
CloseNotify
()
}
}
// Error returns the err created by WriteError
func
(
r
Response
)
Error
()
error
{
return
r
.
err
}
Godeps/_workspace/src/github.com/emicklei/go-restful/response_test.go
View file @
52060f3d
...
@@ -9,7 +9,7 @@ import (
...
@@ -9,7 +9,7 @@ import (
func
TestWriteHeader
(
t
*
testing
.
T
)
{
func
TestWriteHeader
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
,
nil
}
resp
.
WriteHeader
(
123
)
resp
.
WriteHeader
(
123
)
if
resp
.
StatusCode
()
!=
123
{
if
resp
.
StatusCode
()
!=
123
{
t
.
Errorf
(
"Unexpected status code:%d"
,
resp
.
StatusCode
())
t
.
Errorf
(
"Unexpected status code:%d"
,
resp
.
StatusCode
())
...
@@ -18,7 +18,7 @@ func TestWriteHeader(t *testing.T) {
...
@@ -18,7 +18,7 @@ func TestWriteHeader(t *testing.T) {
func
TestNoWriteHeader
(
t
*
testing
.
T
)
{
func
TestNoWriteHeader
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
,
nil
}
if
resp
.
StatusCode
()
!=
http
.
StatusOK
{
if
resp
.
StatusCode
()
!=
http
.
StatusOK
{
t
.
Errorf
(
"Unexpected status code:%d"
,
resp
.
StatusCode
())
t
.
Errorf
(
"Unexpected status code:%d"
,
resp
.
StatusCode
())
}
}
...
@@ -31,7 +31,7 @@ type food struct {
...
@@ -31,7 +31,7 @@ type food struct {
// go test -v -test.run TestMeasureContentLengthXml ...restful
// go test -v -test.run TestMeasureContentLengthXml ...restful
func
TestMeasureContentLengthXml
(
t
*
testing
.
T
)
{
func
TestMeasureContentLengthXml
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
,
nil
}
resp
.
WriteAsXml
(
food
{
"apple"
})
resp
.
WriteAsXml
(
food
{
"apple"
})
if
resp
.
ContentLength
()
!=
76
{
if
resp
.
ContentLength
()
!=
76
{
t
.
Errorf
(
"Incorrect measured length:%d"
,
resp
.
ContentLength
())
t
.
Errorf
(
"Incorrect measured length:%d"
,
resp
.
ContentLength
())
...
@@ -41,7 +41,7 @@ func TestMeasureContentLengthXml(t *testing.T) {
...
@@ -41,7 +41,7 @@ func TestMeasureContentLengthXml(t *testing.T) {
// go test -v -test.run TestMeasureContentLengthJson ...restful
// go test -v -test.run TestMeasureContentLengthJson ...restful
func
TestMeasureContentLengthJson
(
t
*
testing
.
T
)
{
func
TestMeasureContentLengthJson
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
,
nil
}
resp
.
WriteAsJson
(
food
{
"apple"
})
resp
.
WriteAsJson
(
food
{
"apple"
})
if
resp
.
ContentLength
()
!=
22
{
if
resp
.
ContentLength
()
!=
22
{
t
.
Errorf
(
"Incorrect measured length:%d"
,
resp
.
ContentLength
())
t
.
Errorf
(
"Incorrect measured length:%d"
,
resp
.
ContentLength
())
...
@@ -51,7 +51,7 @@ func TestMeasureContentLengthJson(t *testing.T) {
...
@@ -51,7 +51,7 @@ func TestMeasureContentLengthJson(t *testing.T) {
// go test -v -test.run TestMeasureContentLengthJsonNotPretty ...restful
// go test -v -test.run TestMeasureContentLengthJsonNotPretty ...restful
func
TestMeasureContentLengthJsonNotPretty
(
t
*
testing
.
T
)
{
func
TestMeasureContentLengthJsonNotPretty
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
false
}
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
false
,
nil
}
resp
.
WriteAsJson
(
food
{
"apple"
})
resp
.
WriteAsJson
(
food
{
"apple"
})
if
resp
.
ContentLength
()
!=
16
{
if
resp
.
ContentLength
()
!=
16
{
t
.
Errorf
(
"Incorrect measured length:%d"
,
resp
.
ContentLength
())
t
.
Errorf
(
"Incorrect measured length:%d"
,
resp
.
ContentLength
())
...
@@ -61,7 +61,7 @@ func TestMeasureContentLengthJsonNotPretty(t *testing.T) {
...
@@ -61,7 +61,7 @@ func TestMeasureContentLengthJsonNotPretty(t *testing.T) {
// go test -v -test.run TestMeasureContentLengthWriteErrorString ...restful
// go test -v -test.run TestMeasureContentLengthWriteErrorString ...restful
func
TestMeasureContentLengthWriteErrorString
(
t
*
testing
.
T
)
{
func
TestMeasureContentLengthWriteErrorString
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
,
nil
}
resp
.
WriteErrorString
(
404
,
"Invalid"
)
resp
.
WriteErrorString
(
404
,
"Invalid"
)
if
resp
.
ContentLength
()
!=
len
(
"Invalid"
)
{
if
resp
.
ContentLength
()
!=
len
(
"Invalid"
)
{
t
.
Errorf
(
"Incorrect measured length:%d"
,
resp
.
ContentLength
())
t
.
Errorf
(
"Incorrect measured length:%d"
,
resp
.
ContentLength
())
...
@@ -79,7 +79,7 @@ func TestStatusIsPassedToResponse(t *testing.T) {
...
@@ -79,7 +79,7 @@ func TestStatusIsPassedToResponse(t *testing.T) {
{
write
:
400
,
read
:
200
},
{
write
:
400
,
read
:
200
},
}
{
}
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"*/*"
,
[]
string
{
"*/*"
},
0
,
0
,
true
,
nil
}
resp
.
WriteHeader
(
each
.
write
)
resp
.
WriteHeader
(
each
.
write
)
if
got
,
want
:=
httpWriter
.
Code
,
each
.
read
;
got
!=
want
{
if
got
,
want
:=
httpWriter
.
Code
,
each
.
read
;
got
!=
want
{
t
.
Error
(
"got %v want %v"
,
got
,
want
)
t
.
Error
(
"got %v want %v"
,
got
,
want
)
...
@@ -90,7 +90,7 @@ func TestStatusIsPassedToResponse(t *testing.T) {
...
@@ -90,7 +90,7 @@ func TestStatusIsPassedToResponse(t *testing.T) {
// go test -v -test.run TestStatusCreatedAndContentTypeJson_Issue54 ...restful
// go test -v -test.run TestStatusCreatedAndContentTypeJson_Issue54 ...restful
func
TestStatusCreatedAndContentTypeJson_Issue54
(
t
*
testing
.
T
)
{
func
TestStatusCreatedAndContentTypeJson_Issue54
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
resp
:=
Response
{
httpWriter
,
"application/json"
,
[]
string
{
"application/json"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"application/json"
,
[]
string
{
"application/json"
},
0
,
0
,
true
,
nil
}
resp
.
WriteHeader
(
201
)
resp
.
WriteHeader
(
201
)
resp
.
WriteAsJson
(
food
{
"Juicy"
})
resp
.
WriteAsJson
(
food
{
"Juicy"
})
if
httpWriter
.
HeaderMap
.
Get
(
"Content-Type"
)
!=
"application/json"
{
if
httpWriter
.
HeaderMap
.
Get
(
"Content-Type"
)
!=
"application/json"
{
...
@@ -112,7 +112,7 @@ func (e errorOnWriteRecorder) Write(bytes []byte) (int, error) {
...
@@ -112,7 +112,7 @@ func (e errorOnWriteRecorder) Write(bytes []byte) (int, error) {
// go test -v -test.run TestLastWriteErrorCaught ...restful
// go test -v -test.run TestLastWriteErrorCaught ...restful
func
TestLastWriteErrorCaught
(
t
*
testing
.
T
)
{
func
TestLastWriteErrorCaught
(
t
*
testing
.
T
)
{
httpWriter
:=
errorOnWriteRecorder
{
httptest
.
NewRecorder
()}
httpWriter
:=
errorOnWriteRecorder
{
httptest
.
NewRecorder
()}
resp
:=
Response
{
httpWriter
,
"application/json"
,
[]
string
{
"application/json"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"application/json"
,
[]
string
{
"application/json"
},
0
,
0
,
true
,
nil
}
err
:=
resp
.
WriteAsJson
(
food
{
"Juicy"
})
err
:=
resp
.
WriteAsJson
(
food
{
"Juicy"
})
if
err
.
Error
()
!=
"fail"
{
if
err
.
Error
()
!=
"fail"
{
t
.
Errorf
(
"Unexpected error message:%v"
,
err
)
t
.
Errorf
(
"Unexpected error message:%v"
,
err
)
...
@@ -123,7 +123,7 @@ func TestLastWriteErrorCaught(t *testing.T) {
...
@@ -123,7 +123,7 @@ func TestLastWriteErrorCaught(t *testing.T) {
func
TestAcceptStarStar_Issue83
(
t
*
testing
.
T
)
{
func
TestAcceptStarStar_Issue83
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
// Accept Produces
// Accept Produces
resp
:=
Response
{
httpWriter
,
"application/bogus,*/*;q=0.8"
,
[]
string
{
"application/json"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"application/bogus,*/*;q=0.8"
,
[]
string
{
"application/json"
},
0
,
0
,
true
,
nil
}
resp
.
WriteEntity
(
food
{
"Juicy"
})
resp
.
WriteEntity
(
food
{
"Juicy"
})
ct
:=
httpWriter
.
Header
()
.
Get
(
"Content-Type"
)
ct
:=
httpWriter
.
Header
()
.
Get
(
"Content-Type"
)
if
"application/json"
!=
ct
{
if
"application/json"
!=
ct
{
...
@@ -135,7 +135,7 @@ func TestAcceptStarStar_Issue83(t *testing.T) {
...
@@ -135,7 +135,7 @@ func TestAcceptStarStar_Issue83(t *testing.T) {
func
TestAcceptSkipStarStar_Issue83
(
t
*
testing
.
T
)
{
func
TestAcceptSkipStarStar_Issue83
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
// Accept Produces
// Accept Produces
resp
:=
Response
{
httpWriter
,
" application/xml ,*/* ; q=0.8"
,
[]
string
{
"application/json"
,
"application/xml"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
" application/xml ,*/* ; q=0.8"
,
[]
string
{
"application/json"
,
"application/xml"
},
0
,
0
,
true
,
nil
}
resp
.
WriteEntity
(
food
{
"Juicy"
})
resp
.
WriteEntity
(
food
{
"Juicy"
})
ct
:=
httpWriter
.
Header
()
.
Get
(
"Content-Type"
)
ct
:=
httpWriter
.
Header
()
.
Get
(
"Content-Type"
)
if
"application/xml"
!=
ct
{
if
"application/xml"
!=
ct
{
...
@@ -147,7 +147,7 @@ func TestAcceptSkipStarStar_Issue83(t *testing.T) {
...
@@ -147,7 +147,7 @@ func TestAcceptSkipStarStar_Issue83(t *testing.T) {
func
TestAcceptXmlBeforeStarStar_Issue83
(
t
*
testing
.
T
)
{
func
TestAcceptXmlBeforeStarStar_Issue83
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
// Accept Produces
// Accept Produces
resp
:=
Response
{
httpWriter
,
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
,
[]
string
{
"application/json"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
,
[]
string
{
"application/json"
},
0
,
0
,
true
,
nil
}
resp
.
WriteEntity
(
food
{
"Juicy"
})
resp
.
WriteEntity
(
food
{
"Juicy"
})
ct
:=
httpWriter
.
Header
()
.
Get
(
"Content-Type"
)
ct
:=
httpWriter
.
Header
()
.
Get
(
"Content-Type"
)
if
"application/json"
!=
ct
{
if
"application/json"
!=
ct
{
...
@@ -158,7 +158,7 @@ func TestAcceptXmlBeforeStarStar_Issue83(t *testing.T) {
...
@@ -158,7 +158,7 @@ func TestAcceptXmlBeforeStarStar_Issue83(t *testing.T) {
// go test -v -test.run TestWriteHeaderNoContent_Issue124 ...restful
// go test -v -test.run TestWriteHeaderNoContent_Issue124 ...restful
func
TestWriteHeaderNoContent_Issue124
(
t
*
testing
.
T
)
{
func
TestWriteHeaderNoContent_Issue124
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
resp
:=
Response
{
httpWriter
,
"text/plain"
,
[]
string
{
"text/plain"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"text/plain"
,
[]
string
{
"text/plain"
},
0
,
0
,
true
,
nil
}
resp
.
WriteHeader
(
http
.
StatusNoContent
)
resp
.
WriteHeader
(
http
.
StatusNoContent
)
if
httpWriter
.
Code
!=
http
.
StatusNoContent
{
if
httpWriter
.
Code
!=
http
.
StatusNoContent
{
t
.
Errorf
(
"got %d want %d"
,
httpWriter
.
Code
,
http
.
StatusNoContent
)
t
.
Errorf
(
"got %d want %d"
,
httpWriter
.
Code
,
http
.
StatusNoContent
)
...
@@ -168,7 +168,7 @@ func TestWriteHeaderNoContent_Issue124(t *testing.T) {
...
@@ -168,7 +168,7 @@ func TestWriteHeaderNoContent_Issue124(t *testing.T) {
// go test -v -test.run TestStatusCreatedAndContentTypeJson_Issue163 ...restful
// go test -v -test.run TestStatusCreatedAndContentTypeJson_Issue163 ...restful
func
TestStatusCreatedAndContentTypeJson_Issue163
(
t
*
testing
.
T
)
{
func
TestStatusCreatedAndContentTypeJson_Issue163
(
t
*
testing
.
T
)
{
httpWriter
:=
httptest
.
NewRecorder
()
httpWriter
:=
httptest
.
NewRecorder
()
resp
:=
Response
{
httpWriter
,
"application/json"
,
[]
string
{
"application/json"
},
0
,
0
,
true
}
resp
:=
Response
{
httpWriter
,
"application/json"
,
[]
string
{
"application/json"
},
0
,
0
,
true
,
nil
}
resp
.
WriteHeader
(
http
.
StatusNotModified
)
resp
.
WriteHeader
(
http
.
StatusNotModified
)
if
httpWriter
.
Code
!=
http
.
StatusNotModified
{
if
httpWriter
.
Code
!=
http
.
StatusNotModified
{
t
.
Errorf
(
"Got %d want %d"
,
httpWriter
.
Code
,
http
.
StatusNotModified
)
t
.
Errorf
(
"Got %d want %d"
,
httpWriter
.
Code
,
http
.
StatusNotModified
)
...
...
Godeps/_workspace/src/github.com/emicklei/go-restful/swagger/swagger_webservice.go
View file @
52060f3d
...
@@ -173,7 +173,14 @@ func (sws SwaggerService) getDeclarations(req *restful.Request, resp *restful.Re
...
@@ -173,7 +173,14 @@ func (sws SwaggerService) getDeclarations(req *restful.Request, resp *restful.Re
}
else
{
}
else
{
host
=
hostvalues
[
0
]
host
=
hostvalues
[
0
]
}
}
(
&
decl
)
.
BasePath
=
fmt
.
Sprintf
(
"http://%s"
,
host
)
// inspect Referer for the scheme (http vs https)
scheme
:=
"http"
if
referer
:=
req
.
Request
.
Header
[
"Referer"
];
len
(
referer
)
>
0
{
if
strings
.
HasPrefix
(
referer
[
0
],
"https"
)
{
scheme
=
"https"
}
}
(
&
decl
)
.
BasePath
=
fmt
.
Sprintf
(
"%s://%s"
,
scheme
,
host
)
}
}
resp
.
WriteAsJson
(
decl
)
resp
.
WriteAsJson
(
decl
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment