Open sidh opened 6 years ago
You don't strictly need to specify the Content-Type header.
I think it should work if you define your spec like:
swagger: "2.0"
info:
title: Test
version: 0.0.1
schemes:
- "http"
paths:
/test:
get:
produces:
- "application/octet-stream"
responses:
200:
description: 200 response
schema:
type: string
format: binary
When it comes to unknown mime types and not having producers or consumers, those are stored in a map on the client and you can add your own. They are not meant to be a complete list although we could/should probably add a few more.
https://github.com/go-openapi/runtime/blob/master/client/runtime.go#L140-L151
I need to specify correct content-type so web browser is able to pick it up as correct content and display/act accordingly.
What I guess I really need is a default consumer for generated client that if set, acts as a fallback option (most likely it will just act as a default ByteStreamConsumer). I need that since I cannot specify beforehand which content-types will be used.
Somewhere here: https://github.com/go-openapi/runtime/blob/master/client/runtime.go#L324-L327
See also #1284
This is still an on-going problem. Indeed, using application/octet-stream
is a solution, but there are cases much like the one OP described with images where we do want the client to behave like application/octet-stream
despite the specified content type.
As a temporary workaround, I modified the generated NewHTTPClientWithConfig
in the _client.go
file to include:
transport.Consumers["image/jpeg"] = runtime.ByteStreamConsumer()
transport.Consumers["image/png"] = runtime.ByteStreamConsumer()
transport.Consumers["image/webp"] = runtime.ByteStreamConsumer()
transport.Consumers["image/gif"] = runtime.ByteStreamConsumer()
Works without any problems :)
fwiw you can edit that in your own application code without modifying the generated code. You will just need to use a different constructor, there is a reason those fields are exported :)
here's an example where I build a client to actually reuse tcp connections and I've added a consumer in there too so you see where to do it.
func (c *clusterFlags) NewAPIClient() (*bhclient.BuildingHistory, error) {
clientTlsOpts, err := httptransport.TLSClientAuth(httptransport.TLSClientOptions{
CA: c.ClientCACertificate,
Certificate: c.ClientCertificate,
Key: c.ClientCertificateKey,
})
if err != nil {
return nil, fmt.Errorf("TLS config: %v", err)
}
transp := httptransport.KeepAliveTransport(&http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: clientTlsOpts,
})
schemes := bhclient.DefaultSchemes
bt := httptransport.New(c.JoinURI().Host, bhclient.DefaultBasePath, schemes)
// further configure go-swagger runtime.Transport
bt.Consumers["image/jpeg"] = runtime.ByteStreamConsumer()
bt.Transport = transp
return bhclient.New(bt, nil), nil
}
Problem statement
If some content type like "image/png" or "/" is specified in "produces" part schema, generated client does not accept those content types and errors out with 'no consumer: "image/png"'.
Specifically, we use a schema like the one below and respond to user requests with binary data and set content-type header manually based on mime-type of the data. It works fine if you access it from curl or web browser but errors in go-swagger generated client.
Swagger specification