The runtime component for use in code generation or as untyped usage.
go-openapi / runtime Goto Github PK
View Code? Open in Web Editor NEWopenapi runtime interfaces
License: Apache License 2.0
openapi runtime interfaces
License: Apache License 2.0
Because most of the request is build before calling ClientAuthInfoWriter in buildHttp any changes to the query, body or path are not actually reflected in the final request that is sent. Changes to headers appear to be okay :).
As per the Specification at least query parameters should be changeable from inside ClietnAuthInfoWriter, as in APIKeyAuth.
Unfortunately my tries at fixing produce way too much changes IMO and I still have not figured out if changing the body should be possible from inside ClientAuthInfoWriter and how to make everything in httpBuild work with it.
I've bumped into a minor problem with a go-swagger
generated apiserver when it comes to empty responses (e.g. DELETE requests). The problem is that a Content-Type: application/json
response header is always set even for empty responses.
This is a problem at least for the jquery ajax client with tries to parse the empty body as json and fails.
Here a related issue on stack overflow I found:
simphony/simphony-remote#184
golang/go#20784
Searching a bit it seems to me its not clearly defined if a Content-Type for an empty response is valid or not but it seems questionable at least:
https://stackoverflow.com/questions/40614416/is-empty-body-correct-if-content-type-is-application-json
https://stackoverflow.com/questions/15032932/what-should-the-content-type-be-for-a-4xx-error-without-a-body
In general I think its not really useful to set a Content-Type if the response body is empty.
I tried to come up with a simple fix for this but realised that this seems to be a bit more work and probably requires an api change because right now its not possible for the Context.Respond
method to know if the given middleware.Responder
will write some payload to the http.ResponseWriter
. It would somehow need to know this in advance to decide if the Content-Type
header should be set or not.
I'm willing to work on a PR but wanted to illicit some feedback if and how to proceed on this.
As the title.
The error messages is:
go-openapi/runtime/client/request.go:101: undefined: url.PathEscape
go-openapi/runtime/client/request.go:202: req.GetBody undefined (type *http.Request has no field or method GetBody)
Currently, the runtime.TLSClientOptions
struct accepts only file paths to the client certificate and key. The pull request I will submit shortly adds support for reading from a *x509.Certificate
and crypto.PrivateKey
.
This is useful if your data is stored in a different format or if the key is encrypted.
After the above mentioned commit, go-swagger server code generations start to fail with error: *XyzAPI does not implement middleware.RoutableAPI (missing Authorizer method)
Hi,
The runtime ClientResponse API has a method for reading known headers but no method for reading/listing unknown headers.
https://github.com/go-openapi/runtime/blob/master/client_response.go#L24-L29
If one is using the runtime library with a specific swagger file and as the application level headers are all known a priori, those headers can be read using GetHeader(name). But if one uses the runtime library to dynamically invoke a service, the unknown response headers cannot be read at the moment.
Therefore, I am wondering if not providing a method for reading all the response headers in ClientResponse API is intentional based on the swagger usage or there may be a room for a change.
I am not asking for a change but I just would like to know about the decision taken and whether there have been a similar usage request from someone else.
Thanks.
regards, aki
Hello,
Looking for reference to bypass the following error: "x509: certificate signed by unknown authority".
Perhaps we should be able to define insecure option somewhere in the transport.
Sincerely,
Victor da Costa
I'm wondering why Gorilla context is used than the standard context package or the old golang.org/x/net/context
.
I guess that these sources were created before the existence of the official context package, so the Gorilla context was a great solution, however are there any other reasons or I'm wrong in my guess?
Thanks!
As mentioned in #44 I would like to submit a PR to make it easy to create a simple validation middleware for HTTP requests, which can be used with any mux library.
Before I start with the implementation, I wanted to share some ideas and run them past you, to make sure I am moving into the right direction.
Current State (simplified)
Context
requires a RoutableAPI
object to find an appropriate handler for each request.routableUntypedAPI
, which wraps around untyped.API
and calls runtime.OperationHandler
for each request after validation.untyped.API
for content negotiation, etc.OperationHandler
accepts body
parameter, read from request, and returns a response object, which is then written into http responseWith this implementation there is currently no easy way to bypass OperationHandlers
, i.e. consumers of the library are forced to use untyped.API
to specify handlers for each path and method.
Implementation suggestion
Context
NewRoutableProxyContext
.untyped.API
to allow to specify consumers, producers, authenticators
routableUntypedAPI
struct, but add a new factory function newRoutableProxyAPI
, which will create http handlers for each operation/method, but instead of calling OperationHandler
, they will call a provided proxy http.Handler
, if validation succeedsCaveats (at least the ones I thought about)
As an alternative I could add a completely new implementation of RoutableAPI
without any references to untyped.API
. I am just not quite sure, if it is still required in other modules.
quick grep shows:
./vendor/github.com/go-openapi/runtime/client_operation.go:20: "golang.org/x/net/context"
./vendor/github.com/go-openapi/runtime/.travis.yml:12:- go get -u golang.org/x/net/context
./vendor/github.com/go-openapi/runtime/client/runtime.go:33: "golang.org/x/net/context"
Parameters such as query or form parameters allow multiple values per key and there are corresponding API in most web frameworks to retrieve those values, as in here
https://docs.oracle.com/javaee/7/api/javax/servlet/ServletRequest.html#getParameter-java.lang.String-
https://docs.oracle.com/javaee/7/api/javax/servlet/ServletRequest.html#getParameterValues-java.lang.String-
I observe below that runtime.ClientRequest's SetHeaderParam, SetQueryParam, and SetFormParam methods allow multiple values to be set.
https://github.com/go-openapi/runtime/blob/master/client_request.go#L39-L53
A query parameter with multiple values is correctly processed, but a form parameter seems to use only the first entry from the below code.
https://github.com/go-openapi/runtime/blob/master/client/request.go#L119-L126
So, my first question is, shouldn't we be handling multiple values here?
Another question is that SetFileParam takes a single value instead of taking optionally multiple values as in the other methods. Here, shouldn't we have a multivalue signature as in the other methdos?
I have a target service which expects multiple values for a file parameter, in other words, we expect multiple parts for the same name, as mentioned here.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#As_a_header_for_a_multipart_body
I would appreciate if you can provide me the answer to my questions.
regards, aki
Hello,
Due to security issues in JSON described in https://www.owasp.org/images/6/6a/OWASPLondon20161124_JSON_Hijacking_Gareth_Heyes.pdf I tried to modify a swagger file to enforce UTF-8 charset in the Content-Type HTTP header in server responses. Thus a revised version of the swagger file looks like the following:
swagger: "2.0"
info:
title: An API
description: API to do things
version: 2.0.0
consumes:
- application/json
produces:
- application/json; charset=utf-8
Due to the PR #go-swagger/go-swagger#1104 the go-swagger(version 0.12.0) generated server code uses only the main part of the header removing all extra arguments from it.
A Custom Producer is also unable to provide the header value with charset as it is called after rw.WriteHeader() call that freezes all HTTP headers.
Thus by the looks of it it seems the only place where this issue can be fixed is in NegotiateContentType function (https://github.com/go-openapi/runtime/blob/master/middleware/negotiate.go#L46) so it returns MIME type along with any other arguments as specified in the swagger file.
I can provide a PR with a change as described above but would like to hear a confirmation that is a right thing to do.
I was getting the error "context deadline exceeded" using a generated client. After some debugging, I discovered the default timeout is not affecting the call to Submit() in client/runtime.go
.
request.timeout is 0 in this line:
ctx, cancel := context.WithTimeout(pctx, request.timeout)
Setting a good timeout just before that line gets me past the error.
request.SetTimeout(30 * time.Second)
ctx, cancel := context.WithTimeout(pctx, request.timeout)
Am I just using the client wrong, or is this a bug?
When I specify endpoints ending with a slash in my swagger file, at runtime when trying to reach the same endpoint I get a {"code":404,"message":"path /trailingslashpath/ was not found"}
response.
It looks related to this: github.com/go-swagger/go-swagger/pull/292 but the problem does not come from the same code.
I don't know if this is an expected result or not.
The behavior is due to the DefaultRouter function. It calls the 'path.Join' function which removes any trailing slash except for the root path.
The result is that no handler seems to be registered.
Where i can find any documentation regarding middleware?
Any proper documentation is available anywhere?
Example, OAuth uses scope for Authorization, which maps to the url path.
But it is on a resource route level. The values of the parameters are not looked at. E.g.
If the access control needs to say prevent user to execute the http handler but only when the parameter values are of values X or Y, I probably need a custom plugin written.
But it looks like the current framework only supports url route level, just wonder if there are anything I missed looking at.
Given the example swagger:
swagger: '2.0'
basePath: "/myservice"
paths:
/:
get:
the following code in request.go doesnt create the correct path:
// create http request
var reinstateSlash bool
if r.pathPattern != "" && r.pathPattern != "/" && r.pathPattern[len(r.pathPattern)-1] == '/' {
reinstateSlash = true
}
urlPath := path.Join(basePath, r.pathPattern)
for k, v := range r.pathParams {
urlPath = strings.Replace(urlPath, "{"+k+"}", url.PathEscape(v), -1)
}
if reinstateSlash {
urlPath = urlPath + "/"
}
So in this example:
request.buildHTTP currently bins off the trailing slash to set the urlPath to: "/myservice" instead of the correct "/myservice/". Changing basePath to "/myservice/" doesnt make any difference.
Couple of options:
&& r.pathPattern != "/"
- not sure what this is trying to achieveThe runtime server path correctly unescapes any URL path params, but there currently seems to be a gap on the generated client side for escaping URL path params.
Parameters are not escaped before adding them to the URL in buildHTTP
.
As a stop gap, the caller of the client can path escape the path params when creating the generated Parameters object. However this also reveals a subtler issue with the net/url
and net/http
package in go
.
Here's a minimal example to show what happens
func main() {
pathParam := "needs/escape"
escaped := url.PathEscape(pathParam)
fmt.Println(escaped)
p, e := url.Parse(escaped)
if e != nil {
fmt.Println(e)
return
}
fmt.Println("URL Parse")
fmt.Println(p.Path)
fmt.Println(p.RawPath)
fmt.Println(p.EscapedPath())
p.Path = "basepath/" + p.Path
fmt.Println("URL w/ modified Path")
fmt.Println(p.Path)
fmt.Println(p.RawPath)
fmt.Println(p.EscapedPath())
p.RawPath = "basepath/" + p.RawPath
fmt.Println("URL w/ modified Path and RawPath")
fmt.Println(p.Path)
fmt.Println(p.RawPath)
fmt.Println(p.EscapedPath())
}
The corresponding output is
needs%2Fescape
URL Parse
needs/escape
needs%2Fescape
needs%2Fescape
URL w/ modified Path
basepath/needs/escape
needs%2Fescape
basepath/needs/escape
URL w/ modified Path and RawPath
basepath/needs/escape
basepath/needs%2Fescape
basepath/needs%2Fescape
In https://github.com/go-openapi/runtime/blob/master/client/runtime.go#L260, only the .Path
field of URL is modified, as a result, EscapedPath
doesn't return the proper path with the "/" encoded as "%2F" and the URL sent on the request is incorrect.
I wanted to get some feedback before submitting a PR. I think we can add something like
if req.URL.RawPath != "" {
req.URL.RawPath = strings.Join(r.BasePath, req.URL.RawPath)
}
and do this for the reinstateSlash part following it as well.
Alternatively, we can have basepath passed in to buildHTTP
so that the URL is properly formatted on Parse and we don't have to twiddle with it afterwards. Would that break any compatibility if the signature changes?
Lastly, should the runtime call url.PathEscape on each of the pathParams before replacing them in the path or leave that up to the caller?
As of today I get this error message when trying to build my code:
../../github.com/go-openapi/runtime/middleware/router.go:185: undefined: url.PathUnescape
The runtime is used to process HTTP Requests for HTTP Clients. Consumers are provided by the client operation. Right now the selection process is as simple, as selecting the first one available in the array of given consumers.
This could use some improvement.
Relevant TODO: https://github.com/go-openapi/runtime/blob/master/client/runtime.go#L231
go-swagger generated client is unable to work with "text/html" responses because there is no in consumers list
Lines 207 to 215 in 563d495
I am trying to generate api for OVH using go-swagger
generator. But I am facing challenge to add authentication. OVH api requires a X-Ovh-Signature
header for authentication. This header is a sha1 hash of METHOD
, PATH
, BODY
amount other things.
AuthenticateRequest()
method gets a ClientRequest which does not have access to these values. How can I achieve this?
Right now it is possible to have a null pointer reference in TextProducer in case the given data type is not one expected.
Reference: https://github.com/go-openapi/runtime/blob/master/text.go#L49
This should probably have a default case, which will return an error with some information about the type, Eg.:
default:
return fmt.Errorf("%v is not a supported data type", tped)
I've spent the last couple of hours debugging an issue we've run into where the hash of the request body sent (using go-swagger/go-openapi) isn't what it's supposed to be (using other common tools).
I've narrowed it down to the JSON producer, which adds a newline char at the end...
So I go and have a look at the unit tests. And they seem cheat by appending a newline char in the assert:
https://github.com/go-openapi/runtime/blob/master/json_test.go#L61
assert.Equal(t, consProdJSON+"\n", rw.Body.String())
What the...?
ping @casualjim
When using the swagger-ui, a single formData parameter is serialized as a multipart/form-data when the consumes parameter is set to multipart/form-data, as in
/foo:
post:
parameters:
- name: text
in: formData
type: string
produces:
- application/json
consumes:
- multipart/form-data
In contrast, in go-openapi, when there is no file parameter used, its serialziaion (in client/request#BuildHTTP) sets the content-type to multiplart/form-data but it does not use the multipart/form-data serialization (at https://github.com/go-openapi/runtime/blob/master/client/request.go#L109), resulting in an invalid http request.
I would like to have this behavior fixed and make the multipart serialization code also depend on the mediaType value.
I have a proposed fix (elakito@0d8f0ab) in my repo branch at https://github.com/elakito/runtime/tree/work
The branch also includes the patch (elakito@87dbbc7) to handle multiple values per form-parameter, which was mentioned in #68.
Please let me know if this change is okay and if so, how to proceed (sending a single PR or two PRs).
thanks.
regards, aki
Line 341 in 1bd9084
The code above is breaking code that has being working for probably close to two years and a half.
We have an internal api that has only consumes: "application/x-www-form-urlencoded". After upgrading runtime from 4812642 to current master this new check prevents a GET request to finish giving:
none of producers: map[application/json:0x7ddce0 application/xml:0x7deac0 text/plain:0x7de360 text/html:0x7de360 application/octet-stream:0x7dd470] registered. try application/x-www-form-urlencoded
Deleting just this lines fixes the problem at least as far as my tests pass
Am I doing something wrong is the code generation doing something wrong or is the check too strict ?
Hello,
I'm not raising an issue but asking for help/information.
I'm trying to use the go-openapi to write a http middleware that validates requests and responses for a ReST HTTP server. But I can't find which go-openapi component I should use, if any.
My application loads the swagger.json that defines my API. Now, I was wondering how to checks if http requests conform to the swagger.
Any clue ?
Thanks in advance for your help.
Regards, Stan.
I am seeing the following error and it seems that this may happen when a mime multipart is being created for the request and some IO error occurs during that time. This problem does not happen all the time because the error comes from the interaction between two go routines preparing for the mime multipart request.
2018/09/05 16:51:55 io: read/write on closed pipe
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x407583a]
goroutine 141 [running]:
io.copyBuffer(0x0, 0x0, 0xa0c1020, 0xc420d608e0, 0xc420dd2000, 0x8000, 0x8000, 0x5fd6aa0, 0x0, 0xa0c1020)
/usr/local/go/src/io/io.go:402 +0x21a
io.Copy(0x0, 0x0, 0xa0c1020, 0xc420d608e0, 0xc420d608e0, 0x0, 0x0)
/usr/local/go/src/io/io.go:362 +0x5a
github.com/go-openapi/runtime/client.(*request).buildHTTP.func1(0xc420d5d6b0, 0xc4200e8a70, 0xc420be3d80)
/dev/goworkspace/src/github.com/go-openapi/runtime/client/request.go:180 +0x3be
created by github.com/go-openapi/runtime/client.(*request).buildHTTP
/dev/goworkspace/src/github.com/go-openapi/runtime/client/request.go:151 +0x5ee
As seen in the stack trace, the error is triggered from this line
https://github.com/go-openapi/runtime/blob/master/client/request.go#L180
where the multipart part writing fails in the if-block above, but this line is executed although wrtr is nil in this case.
if _, err := io.Copy(wrtr, fi); err != nil {
I think we should replace this "if" to "else if" so that the copy is only called if the writer is available, which would look like this.
wrtr, err := mp.CreateFormFile(fn, filepath.Base(fi.Name()))
if err != nil {
pw.CloseWithError(err)
log.Println(err)
} else if _, err := io.Copy(wrtr, fi); err != nil {
pw.CloseWithError(err)
log.Println(err)
}
What should be useful is to use packages on which runtime package depends as vendored code. I would like to use glide as package manager.
Currently, if the content-type of the response doesn't match those registered consumers, the response is simply rejected with the error.
no consumer: ...
I would like to have an option of reading the response in this case and I would like to ask if we can treat the consumer registered for "/" to be used as the fallback consumer.
I have created a commit that shows the proposed change``
elakito@e7607f1
Could you comment on this proposal?
regards, aki
When we enable the debug mode, it uses the logging format defined in the standardLogger (https://github.com/go-openapi/runtime/blob/master/middleware/context.go#L35). It'd be great to reuse the Logger defined when configuring the runtime.
Is it possible to unify the logger format when debug is enabled? Or I am missing something
I want using runtime package to upload file (client side). Can I get sample codes about using multipart to file upload?
Thanks
I am reposting this from go-swagger/go-swagger#943
When you have a response with a type of file in your swagger spec the generated type is the File
interface found in this repository. File
doesn't implement io.Reader
and therefore cannot be produced by the application/octet-stream producer, meaning that you cannot actually return said type from your API.
https://github.com/robbert229/swagger-download-file-bug/blob/master/swagger.yaml
https://github.com/robbert229/swagger-download-file-bug
swagger version: Master
go version: go1.7.5 linux/amd64
OS: linux ( archlinux )
https://github.com/go-openapi/runtime/blob/master/client/runtime.go#L268 (1st of 2 locations)
This code uses formatting, and so blows up when the URL contains escaped characters, as they use %.
r.logger.Debugf(string(b) + "\n")
It should be this instead:
r.logger.Debugf("%s\n", string(b))
Per https://tools.ietf.org/html/rfc7231#section-5.3.2:
A request without any Accept header field implies that the user agent will accept any media type in response.
Currently, content negotiation will fall through to the default content type (usually ""
) in these cases when it should return the first offered, as it does for Accept: */*
.
type Runtime struct {
DefaultMediaType string
DefaultAuthentication runtime.ClientAuthInfoWriter
Consumers map[string]runtime.Consumer
Producers map[string]runtime.Producer
Transport http.RoundTripper
Jar http.CookieJar
//Spec *spec.Document
Host string
BasePath string
Formats strfmt.Registry
Debug bool
Context context.Context
clientOnce *sync.Once
client *http.Client
schemes []string
}
is harder to actually use than it needs to be. It takes a bunch of parameters to setup the http.Client meaning users have to jump through hoops to use it.
For example the authentication mechanism, we already have a great way for creating oauth2 clients in the
oauth2 library and creating a working http.Client. Instead of just creating the http.Client from there and
configuring the timeout as I desire I have to contort into go-openapi's model which in the end just creates an
http.Client anyways....
following fields could be stripped if http.Client was just accepted:
end result: could simplify the usage of the runtime client and provide helper methods for doing all the things that are currently being done.
I make a request via a client generated based on a swagger spec generated via the goswagger.io project with an invalid json property. The back-end returns a HTTP 422 with details in the response body. Reading the response body is crucial to debug the problem.
go-openapi/runtime/client/runtime.go.Submit()
calls readResponse.ReadResponse
which returns an APIError
with the response body embedded:
Line 422 in 231d787
Lines 55 to 59 in 231d787
Problem is, that this embedded response body is closed via a defer
in go-openapi/runtime/client/runtime.go.Submit()
:
Line 395 in 231d787
Thereby casting the error and reading the response body later on fails with http: read on closed response body
:
apiError, ok := err.(*runtime.APIError)
if !ok {
// handle
}
response, ok := apiError.Response.(runtime.ClientResponse)
if !ok {
// handle
}
body, err := ioutil.ReadAll(response.Body())
if err != nil {
// fails with "http: read on closed response body"
}
fmt.Println(string(body))
How can I access the APIError response body? Might it be possible to embed the body as a string inside the APIError? Let me know if you need more info.
Hello,
Trying to understand why my client (generated by go-swagger) would not accept the application/problem+json
media type I stumbled upon these hard coded values: https://github.com/go-openapi/runtime/blob/master/client/runtime.go#L137-L147
What are the reason for these?
They are used in Submit()
but shouldn't the values from the passed runtime.ClientOperation
struct be used instead e.i. runtime.ClientOperation.ProducesMediaTypes
and runtime.ClientOperation.ConsumesMediaTypes
?
I've run into dependency mismatches between go-openapi repos. It would be easier to avoid mismatches if they used semantic versioning.
Currently runtime's producers/consumers are statically set via a predefined list. While those defaults might not be bad, this could probably be done smarter, by inferring the information from the OpenAPI/Swagger2.0 Spec.
Relevant TODO: https://github.com/go-openapi/runtime/blob/master/client/runtime.go#L136
the old repo:
https://github.com/go-swagger/go-swagger/releases/tag/0.5.0
had prebuild binaries
QUESTION 1: Is there anything like this now?
QUESTION 2: What is the relationship between the go-swagger repo and the go-openapi repo?
QUESTION 3: How does one build and executable (either everything, or just the validator)?
QUESTION 4: How does one test the executable?
This issue is related to go-openapi/validate#39 about allowing path parameters to match a fragment within a path segment. As mentioned in PR go-openapi/validate#40, the runtime/middleware's router needs to be changed to extract these path parameters.
I am attaching a PR to this ticket.
When constructing client request with form data, the request.BuildHTTP() does not set the content length before writing form data as the body. This causes that a chunked transfer is declared, and corrupts the form data.
Hey guys,
Is this possible to allow more general interface for swagger file
type? I have a case when the file content I want to post is in-memory buffer. Storing it to disk just to be able to submit looks like an overhead. Attached a patch, not tested yet, it's just to describe my idea a little bit better.
Thanks,
--Vovan
If the path contains multiple parameters:
/{id}/something/{anotherId}
the regex to convert it {(.+)}
does work correctly. It should be non-inclusive
In a similar vein to #90, I will be submitting a PR to add support for reading the TLSClientOptions
CA certificate from memory, rather than a file.
E.g.
type TLSClientOptions struct {
// ...
CA string
LoadedCA *x509.Certificate
// ...
}
The Loaded
nomenclature feels ugly, but matches the route taken in #91.
We could make a breaking change to improve the terminology, as follows:
// comments removed for brevity
type TLSClientOptions struct {
CertificatePemFile string
Certificate *x509.Certificate
KeyPemFile string
Key crypto.PrivateKey
CAPemFile string
CA *x509.Certificate // <--- the addition from this issue/PR
ServerName string
InsecureSkipVerify bool
_ struct{}
}
It would also be nice to improve the logic so that the in-memory objects are used, when present, otherwise the files are loaded. Currently for the certificates and keys, either both are loaded from memory or both are loaded from disk.
I'll start work on a non-breaking change version of the above, but feedback here is very welcome on the idea of a more thorough refactoring.
It would be nice to explicit the dependencies of this package in a vendor tree, so one can build our generated code without the go-swagger package itself.
Hello,
I've been reworking an API to use go-swagger and stumbled across a few problems when implementing an endpoint that returns image/jpeg
. One issue was that I retrieve images from a remote server via HTTP and want to send them to the client without having to buffer them in memory. The normal way of doing that would be simply copying the io.Reader and using something like defer reader.Close()
to make sure that I don't leak resources.
However, with swagger (go-openapi) the actual response is only sent after my handler function is called, so the stream will be closed before a response can be returned to the client, leading to panic: http: read on closed response body
.
To work around this I modified the ByteStreamProducer
to check for io.Closer
and automatically close the stream. I realize this might be considered a breaking change, because it might require people to wrap their payloads with ioutil.NopCloser
. I can also see how this might not be a standard use case for swagger.
Either way, this is the code I added, in case you think this is useful:
diff --git a/vendor/github.com/go-openapi/runtime/bytestream.go b/vendor/github.com/go-openapi/runtime/bytestream.go
index dd8115f..73b2976 100644
--- a/vendor/github.com/go-openapi/runtime/bytestream.go
+++ b/vendor/github.com/go-openapi/runtime/bytestream.go
@@ -71,6 +71,9 @@ func ByteStreamProducer() Producer {
}
if rdr, ok := data.(io.Reader); ok {
+ if closer, ok := data.(io.Closer); ok {
+ defer closer.Close()
+ }
_, err := io.Copy(writer, rdr)
return err
}
Part of client code is like this
https://github.com/go-openapi/runtime/blob/master/client/runtime.go#L297
res, err := r.do(ctx, client, req) // make requests, by default follows 10 redirects before failing
if err != nil {
return nil, err
}
defer res.Body.Close()
if r.Debug {
b, err2 := httputil.DumpResponse(res, true)
if err2 != nil {
return nil, err2
}
r.logger.Debugf("%s\n", string(b))
}
With flag DEBUG=true
, ioutil.nopCloser
returned and consumer can unwrap ClientResponse.Body()
to check for validation error message like this "{\"code\":602,\"message\":\"name in body is required\"}"
.
For client in production environment and I don't want DEBUG
flag on, response body is closed, http.bodyEOFSignal
returned and can't do nothing to check for validation error.
Maybe there's option to retain response body or turn response body into ioutil.nopCloser
like httputil.DumpResponse
did ?
I ran gometalinter over the code base (sanity check for my own work) and found the following items to be resolved. Will look at fixing as part of separate PR.
client/auth_info.go:35:19:warning: error return value not checked (r.SetHeaderParam("Authorization", "Basic "+encoded)) (errcheck)
client/auth_info.go:44:19:warning: error return value not checked (r.SetQueryParam(name, value)) (errcheck)
client/auth_info.go:51:20:warning: error return value not checked (r.SetHeaderParam(name, value)) (errcheck)
client/auth_info.go:61:19:warning: error return value not checked (r.SetHeaderParam("Authorization", "Bearer "+token)) (errcheck)
client/runtime.go:217:2:warning: should replace loop with accept = append(accept, operation.ProducesMediaTypes...) (S1011) (megacheck)
middleware/context.go:78:2:warning: field formats is unused (U1000) (megacheck)
middleware/context.go:231:2:warning: const ctxAllowedMethods is unused (U1000) (megacheck)
; middleware/context.go:226:1:warning: ctxAllowedMethods is unused (deadcode)
middleware/context.go:236:2:warning: const ctxConsumer is unused (U1000) (megacheck)
; middleware/context.go:226:1:warning: ctxConsumer is unused (deadcode)
middleware/context.go:539:3:warning: ineffectual assignment to b (ineffassign)
NOTE: b is assigned to builder or if nil to a default value, but b is not used only buildermiddleware/header/header.go:49:18:warning: should use strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c)) instead (S1003) (megacheck)
middleware/header/header.go:50:6:warning: should use strings.ContainsRune(" \t\r\n", rune(c)) instead (S1003) (megacheck)
middleware/parameter.go:196::warning: declaration of "err" shadows declaration at middleware/parameter.go:177 (vetshadow)
middleware/parameter.go:201::warning: declaration of "err" shadows declaration at middleware/parameter.go:177 (vetshadow)
middleware/parameter.go:206::warning: declaration of "err" shadows declaration at middleware/parameter.go:177 (vetshadow)
middleware/parameter.go:215::warning: declaration of "err" shadows declaration at middleware/parameter.go:177 (vetshadow)
middleware/router.go:116:2:warning: field api is unused (U1000) (megacheck)
middleware/validation.go:28:1:warning: newValidation is unused (deadcode)
middleware/validation.go:59:6:warning: type untypedBinder is unused (U1000) (megacheck)
; middleware/validation.go:59:1:warning: untypedBinder is unused (deadcode)
middleware/validation.go:62:2:warning: 'if err != nil { return err }; return nil' can be simplified to 'return err' (S1013) (megacheck)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.