GithubHelp home page GithubHelp logo

runtime's Introduction

runtime Build Status codecov

Slack Status license Go Reference Go Report Card

go OpenAPI toolkit runtime

The runtime component for use in code generation or as untyped usage.

runtime's People

Contributors

akutz avatar anfernee avatar bcomnes avatar casualjim avatar deborggraever avatar dependabot[bot] avatar ederavilaprado avatar elakito avatar equanox avatar fredbi avatar galaxie avatar glendc avatar ifraixedes avatar jkawamoto avatar josephwoodward avatar jsilland avatar kenjones-cisco avatar keramix avatar kunde21 avatar kzys avatar makarandnsd avatar moenning avatar mstoykov avatar nan0tube avatar stoyanr avatar thomdixon avatar vadskye avatar wahabmk avatar youyuanwu avatar zeitlinger avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

runtime's Issues

Set* does not show up in request when called in ClientAuthInfoWriter

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.

Content-Type header set for empty responses.

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.

Meet error when get the latest version

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)

Add support for reading client certificate and key from memory

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.

Question about not having a method for getting all response headers

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

Boolean to enable SSL Insecure

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

Are there any other reasons to use Gorilla context a part of the historical ones?

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!

Enhancement: Simple swagger validation HTTP middleware

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.
  • At the moment it uses an internal routableUntypedAPI, which wraps around untyped.API and calls runtime.OperationHandler for each request after validation.
  • It also uses other functions of untyped.API for content negotiation, etc.
  • OperationHandler accepts body parameter, read from request, and returns a response object, which is then written into http response

With 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

  • create a new method in Context NewRoutableProxyContext.
  • reuse untyped.API to allow to specify consumers, producers, authenticators
    • question, why can't consumers and producers be read from swagger spec?
  • reuse internal 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 succeeds

Caveats (at least the ones I thought about)

  • in order to validate request body, it has to be read, which makes it unavailable in subsequent http handlers. One possible way to solve it, is to copy it and reset on the request when passing it to the proxy handler. Depending on the size of the body, this could consume too much memory.
  • response validation is no longer possible
  • any others ????

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.

use context instead of "golang.org/x/net/context"

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"

runtime.ClientRequest and multiple values for a parameter usage

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

There is no way to return extra arguments in the Content-Type header

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.

client timeout is 0

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?

Path not found error : trailing slash url

Problem statement

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.

[Question] How to extend/customize Authorization function?

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.

Trailing slash removed from root requests

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:

  • r.pathPatterm is "/"
  • basePath is "/myservice"

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:

  1. Remove && r.pathPattern != "/" - not sure what this is trying to achieve
  2. Swap out path.Join for something that is URL aware (e.g. as suggested by https://stackoverflow.com/questions/34668012/combine-url-paths-with-path-join)

Runtime/client doesn't properly handle escaped path params

The 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?

Typo on line 185 of router.go?

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

Generated client doesn't have "text/html" consumer

go-swagger generated client is unable to work with "text/html" responses because there is no in consumers list

runtime/client/runtime.go

Lines 207 to 215 in 563d495

// TODO: actually infer this stuff from the spec
rt.Consumers = map[string]runtime.Consumer{
runtime.JSONMime: runtime.JSONConsumer(),
runtime.XMLMime: runtime.XMLConsumer(),
runtime.TextMime: runtime.TextConsumer(),
runtime.DefaultMime: runtime.ByteStreamConsumer(),
}
rt.Producers = map[string]runtime.Producer{
runtime.JSONMime: runtime.JSONProducer(),

Enable reading Method, Path & Body from AuthenticateRequest()

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?

JSON producer adds newline character to the end of JSON body

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...

skarmavbild 2016-11-11 kl 13 14 57
skarmavbild 2016-11-11 kl 13 14 30

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

formData handling generates an invalid request when property consumes is multipart/form-data

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

Checking consumptions of all requests breaks code

if _, ok := r.Producers[cmt]; !ok && cmt != runtime.MultipartFormMime {

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 ?

Question : is it possible to use this library to validate API request/responses

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.

Request using a file attachment may lead to panic

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)
}

Allow registering the fallback consumer to read response

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

File doesn't implement io.Reader

Problem statement

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.

Swagger specification

https://github.com/robbert229/swagger-download-file-bug/blob/master/swagger.yaml

Steps to reproduce - ( after each get you will need to repost )

  1. clone the repository && run the application
  2. open up swagger ui and load the locally hosted spec.
  3. upload a file ( via POST /file )
  4. attempt to download said file ( via GET /file )

https://github.com/robbert229/swagger-download-file-bug

Environment

swagger version: Master
go version: go1.7.5 linux/amd64
OS: linux ( archlinux )

client should just have an option to build from an http.Client

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:

  • Transport http.RoundTripper
  • Jar http.CookieJar
  • DefaultAuthentication runtime.ClientAuthInfoWriter (this is really just a Transport.)
  • clientOnce *sync.Once

end result: could simplify the usage of the runtime client and provide helper methods for doing all the things that are currently being done.

Read APIError response body

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:

return readResponse.ReadResponse(response{res}, cons)

type APIError struct {
OperationName string
Response interface{}
Code int
}

Problem is, that this embedded response body is closed via a defer in go-openapi/runtime/client/runtime.go.Submit():

defer res.Body.Close()

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.

Static list of consumers / producers?

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?

Sending form data in 'chuncked' Transfer-Encoding

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.

Make file parameter accepting arbitrary io.Reader, not just os.File

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

fileParam.txt

Enhancement: specify TLS CA certificate without file

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.

Explicit dependencies in vendor tree

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.

Support closing streams in ByteStreamProducer

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
                }

Runtime Client: Can't inspect swagger error response body unless DEBUG flag is `True`

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 ?

Bugs / Lint errors

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 builder
  • middleware/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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.