diff --git a/examples/import-mapping/samepackage/server.gen.go b/examples/import-mapping/samepackage/server.gen.go index f0dd6d85bf..4b40b2cb7d 100644 --- a/examples/import-mapping/samepackage/server.gen.go +++ b/examples/import-mapping/samepackage/server.gen.go @@ -236,6 +236,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/examples/minimal-server/iris/api/ping.gen.go b/examples/minimal-server/iris/api/ping.gen.go index 3ef88437f7..8f92a5327d 100644 --- a/examples/minimal-server/iris/api/ping.gen.go +++ b/examples/minimal-server/iris/api/ping.gen.go @@ -47,6 +47,9 @@ func RegisterHandlers(router *iris.Application, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) { + for _, m := range options.Middlewares { + router.Use(m) + } wrapper := ServerInterfaceWrapper{ Handler: si, diff --git a/examples/petstore-expanded/iris/api/petstore-server.gen.go b/examples/petstore-expanded/iris/api/petstore-server.gen.go index 9846a1b10e..9c200a97a0 100644 --- a/examples/petstore-expanded/iris/api/petstore-server.gen.go +++ b/examples/petstore-expanded/iris/api/petstore-server.gen.go @@ -173,6 +173,9 @@ func RegisterHandlers(router *iris.Application, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) { + for _, m := range options.Middlewares { + router.Use(m) + } wrapper := ServerInterfaceWrapper{ Handler: si, diff --git a/examples/petstore-expanded/strict/api/petstore-server.gen.go b/examples/petstore-expanded/strict/api/petstore-server.gen.go index 52ff32f095..2b1a1a05a9 100644 --- a/examples/petstore-expanded/strict/api/petstore-server.gen.go +++ b/examples/petstore-expanded/strict/api/petstore-server.gen.go @@ -543,6 +543,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/examples/streaming/stdhttp/sse/streaming.gen.go b/examples/streaming/stdhttp/sse/streaming.gen.go index 01e0792dfc..d75ba2b5c9 100644 --- a/examples/streaming/stdhttp/sse/streaming.gen.go +++ b/examples/streaming/stdhttp/sse/streaming.gen.go @@ -252,6 +252,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/aggregates/oneof/union.gen.go b/internal/test/aggregates/oneof/union.gen.go index 999e294d74..8daaa3ee7a 100644 --- a/internal/test/aggregates/oneof/union.gen.go +++ b/internal/test/aggregates/oneof/union.gen.go @@ -341,6 +341,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/bodies/content_types/text_and_json/text_and_json.gen.go b/internal/test/bodies/content_types/text_and_json/text_and_json.gen.go index 15a62ab57e..76143f5ab5 100644 --- a/internal/test/bodies/content_types/text_and_json/text_and_json.gen.go +++ b/internal/test/bodies/content_types/text_and_json/text_and_json.gen.go @@ -483,6 +483,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/bodies/responses/headers/headers.gen.go b/internal/test/bodies/responses/headers/headers.gen.go index d0587d2d14..3d0004f5d3 100644 --- a/internal/test/bodies/responses/headers/headers.gen.go +++ b/internal/test/bodies/responses/headers/headers.gen.go @@ -214,6 +214,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/events/webhooks/fiberv3/config.yaml b/internal/test/events/webhooks/fiberv3/config.yaml new file mode 100644 index 0000000000..edbb32d14a --- /dev/null +++ b/internal/test/events/webhooks/fiberv3/config.yaml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=../../../../../configuration-schema.json +package: fiberv3 +generate: + models: true + client: true + fiber-v3-server: true +output-options: + skip-prune: true +output: webhooks.gen.go diff --git a/internal/test/events/webhooks/fiberv3/doc.go b/internal/test/events/webhooks/fiberv3/doc.go new file mode 100644 index 0000000000..06d15da29d --- /dev/null +++ b/internal/test/events/webhooks/fiberv3/doc.go @@ -0,0 +1,6 @@ +// Package webhooks_fiberv3 verifies that the fiber-v3-server flag +// emits a compilable WebhookReceiverInterface with fiber v3's +// (c fiber.Ctx) error signature. Compile-time assertion only. +package fiberv3 + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml ../spec.yaml diff --git a/internal/test/events/webhooks/fiberv3/webhooks.gen.go b/internal/test/events/webhooks/fiberv3/webhooks.gen.go new file mode 100644 index 0000000000..01e1b443a3 --- /dev/null +++ b/internal/test/events/webhooks/fiberv3/webhooks.gen.go @@ -0,0 +1,348 @@ +// Package fiberv3 provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. +package fiberv3 + +import ( + "bytes" + "context" + "encoding/json" + "io" + "net/http" + "net/url" + "strings" + + "github.com/gofiber/fiber/v3" +) + +// Defines values for PetStatusEventStatus. +const ( + Available PetStatusEventStatus = "available" + Pending PetStatusEventStatus = "pending" + Sold PetStatusEventStatus = "sold" +) + +// Valid indicates whether the value is a known member of the PetStatusEventStatus enum. +func (e PetStatusEventStatus) Valid() bool { + switch e { + case Available: + return true + case Pending: + return true + case Sold: + return true + default: + return false + } +} + +// PetStatusEvent defines model for PetStatusEvent. +type PetStatusEvent struct { + Id string `json:"id"` + Status PetStatusEventStatus `json:"status"` +} + +// PetStatusEventStatus defines model for PetStatusEvent.Status. +type PetStatusEventStatus string + +// PetStatusChangedJSONRequestBody defines body for PetStatusChanged for application/json ContentType. +type PetStatusChangedJSONRequestBody = PetStatusEvent + +// RequestEditorFn is the function signature for the RequestEditor callback function +type RequestEditorFn func(ctx context.Context, req *http.Request) error + +// Doer performs HTTP requests. +// +// The standard http.Client implements this interface. +type HttpRequestDoer interface { + Do(req *http.Request) (*http.Response, error) +} + +// Client which conforms to the OpenAPI3 specification for this service. +type Client struct { + // The endpoint of the server conforming to this interface, with scheme, + // https://api.deepmap.com for example. This can contain a path relative + // to the server, such as https://api.deepmap.com/dev-test, and all the + // paths in the swagger spec will be appended to the server. + Server string + + // Doer for performing requests, typically a *http.Client with any + // customized settings, such as certificate chains. + Client HttpRequestDoer + + // A list of callbacks for modifying requests which are generated before sending over + // the network. + RequestEditors []RequestEditorFn +} + +// ClientOption allows setting custom parameters during construction +type ClientOption func(*Client) error + +// Creates a new Client, with reasonable defaults +func NewClient(server string, opts ...ClientOption) (*Client, error) { + // create a client with sane default values + client := Client{ + Server: server, + } + // mutate client and add all optional params + for _, o := range opts { + if err := o(&client); err != nil { + return nil, err + } + } + // ensure the server URL always has a trailing slash + if !strings.HasSuffix(client.Server, "/") { + client.Server += "/" + } + // create httpClient, if not already present + if client.Client == nil { + client.Client = &http.Client{} + } + return &client, nil +} + +// WithHTTPClient allows overriding the default Doer, which is +// automatically created using http.Client. This is useful for tests. +func WithHTTPClient(doer HttpRequestDoer) ClientOption { + return func(c *Client) error { + c.Client = doer + return nil + } +} + +// WithRequestEditorFn allows setting up a callback function, which will be +// called right before sending the request. This can be used to mutate the request. +func WithRequestEditorFn(fn RequestEditorFn) ClientOption { + return func(c *Client) error { + c.RequestEditors = append(c.RequestEditors, fn) + return nil + } +} + +// The interface specification for the client above. +type ClientInterface interface { +} + +func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { + for _, r := range c.RequestEditors { + if err := r(ctx, req); err != nil { + return err + } + } + for _, r := range additionalEditors { + if err := r(ctx, req); err != nil { + return err + } + } + return nil +} + +// ClientWithResponses builds on ClientInterface to offer response payloads +type ClientWithResponses struct { + ClientInterface +} + +// NewClientWithResponses creates a new ClientWithResponses, which wraps +// Client with return type handling +func NewClientWithResponses(server string, opts ...ClientOption) (*ClientWithResponses, error) { + client, err := NewClient(server, opts...) + if err != nil { + return nil, err + } + return &ClientWithResponses{client}, nil +} + +// WithBaseURL overrides the baseURL. +func WithBaseURL(baseURL string) ClientOption { + return func(c *Client) error { + newBaseURL, err := url.Parse(baseURL) + if err != nil { + return err + } + c.Server = newBaseURL.String() + return nil + } +} + +// ClientWithResponsesInterface is the interface specification for the client with responses above. +type ClientWithResponsesInterface interface { +} + +// WebhookInitiator sends OpenAPI 3.1 webhook requests to target URLs. +// Modeled on the generated Client, but with no stored Server -- the full +// target URL is provided per-call by the caller (typically discovered +// from a subscription registration). +type WebhookInitiator struct { + // Doer for performing requests, typically a *http.Client with any + // customized settings, such as certificate chains. + Client HttpRequestDoer + + // A list of callbacks for modifying requests which are generated before sending over + // the network. + RequestEditors []RequestEditorFn +} + +// WebhookInitiatorOption allows setting custom parameters during construction. +type WebhookInitiatorOption func(*WebhookInitiator) error + +// NewWebhookInitiator creates a new WebhookInitiator with reasonable defaults. +func NewWebhookInitiator(opts ...WebhookInitiatorOption) (*WebhookInitiator, error) { + initiator := WebhookInitiator{} + for _, o := range opts { + if err := o(&initiator); err != nil { + return nil, err + } + } + if initiator.Client == nil { + initiator.Client = &http.Client{} + } + return &initiator, nil +} + +// WithWebhookHTTPClient allows overriding the default Doer, which is +// automatically created using http.Client. This is useful for tests. +func WithWebhookHTTPClient(doer HttpRequestDoer) WebhookInitiatorOption { + return func(p *WebhookInitiator) error { + p.Client = doer + return nil + } +} + +// WithWebhookRequestEditorFn allows setting up a callback function, which +// will be called right before sending the webhook request. This can be +// used to mutate the request, e.g. to add signature headers. +func WithWebhookRequestEditorFn(fn RequestEditorFn) WebhookInitiatorOption { + return func(p *WebhookInitiator) error { + p.RequestEditors = append(p.RequestEditors, fn) + return nil + } +} + +func (p *WebhookInitiator) applyWebhookEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { + for _, r := range p.RequestEditors { + if err := r(ctx, req); err != nil { + return err + } + } + for _, r := range additionalEditors { + if err := r(ctx, req); err != nil { + return err + } + } + return nil +} + +// WebhookInitiatorInterface is the interface specification for the webhook initiator. +type WebhookInitiatorInterface interface { + // PetStatusChangedWithBody fires the petStatusChanged webhook with any body + PetStatusChangedWithBody(ctx context.Context, targetURL string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PetStatusChanged(ctx context.Context, targetURL string, body PetStatusChangedJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) +} + +func (p *WebhookInitiator) PetStatusChangedWithBody(ctx context.Context, targetURL string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPetStatusChangedWebhookRequestWithBody(targetURL, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := p.applyWebhookEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return p.Client.Do(req) +} + +func (p *WebhookInitiator) PetStatusChanged(ctx context.Context, targetURL string, body PetStatusChangedJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPetStatusChangedWebhookRequest(targetURL, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := p.applyWebhookEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return p.Client.Do(req) +} + +// NewPetStatusChangedWebhookRequest builds a application/json POST request for the petStatusChanged webhook +func NewPetStatusChangedWebhookRequest(targetURL string, body PetStatusChangedJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPetStatusChangedWebhookRequestWithBody(targetURL, "application/json", bodyReader) +} + +// NewPetStatusChangedWebhookRequestWithBody builds a POST request for the petStatusChanged webhook with any body +func NewPetStatusChangedWebhookRequestWithBody(targetURL string, contentType string, body io.Reader) (*http.Request, error) { + var err error + _ = err + + reqURL, err := url.Parse(targetURL) + if err != nil { + return nil, err + } + + req, err := http.NewRequest(http.MethodPost, reqURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + +// ServerInterface represents all server handlers. +type ServerInterface interface { +} + +// ServerInterfaceWrapper converts contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface + HandlerMiddlewares []HandlerMiddlewareFunc +} + +type MiddlewareFunc fiber.Handler +type HandlerMiddlewareFunc func(c fiber.Ctx, next fiber.Handler) error + +// FiberServerOptions provides options for the Fiber server. +type FiberServerOptions struct { + BaseURL string + Middlewares []MiddlewareFunc + HandlerMiddlewares []HandlerMiddlewareFunc +} + +// RegisterHandlers creates http.Handler with routing matching OpenAPI spec. +func RegisterHandlers(router fiber.Router, si ServerInterface) { + RegisterHandlersWithOptions(router, si, FiberServerOptions{}) +} + +// RegisterHandlersWithOptions creates http.Handler with additional options +func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, options FiberServerOptions) { + +} + +// WebhookReceiverInterface represents handlers for receiving inbound +// webhook requests. Each webhook becomes a Handle*Webhook +// method that the implementation fills in. The caller mounts the per- +// webhook fiber.Handler returned by {Op}WebhookHandler at +// whatever URL path they advertise to senders. +type WebhookReceiverInterface interface { + // Notifies subscribers that a pet's status changed. + // HandlePetStatusChangedWebhook handles the POST webhook for petStatusChanged. + HandlePetStatusChangedWebhook(c fiber.Ctx) error +} + +// PetStatusChangedWebhookHandler returns the fiber.Handler for the petStatusChanged webhook. +// Mount this at the URL path advertised to webhook senders. Errors +// during parameter binding are returned via fiber.NewError so fiber's +// error chain reports them as 400. Per-handler middleware is not +// generated here; use fiber.App.Use() for engine-level middleware. +func PetStatusChangedWebhookHandler(si WebhookReceiverInterface) fiber.Handler { + return func(c fiber.Ctx) error { + return si.HandlePetStatusChangedWebhook(c) + } +} diff --git a/internal/test/events/webhooks/iris/webhooks.gen.go b/internal/test/events/webhooks/iris/webhooks.gen.go index 2be7989803..a7008cdfe3 100644 --- a/internal/test/events/webhooks/iris/webhooks.gen.go +++ b/internal/test/events/webhooks/iris/webhooks.gen.go @@ -319,6 +319,9 @@ func RegisterHandlers(router *iris.Application, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) { + for _, m := range options.Middlewares { + router.Use(m) + } router.Build() } diff --git a/internal/test/go.mod b/internal/test/go.mod index 5fbe0b6847..ebc09a69b0 100644 --- a/internal/test/go.mod +++ b/internal/test/go.mod @@ -9,6 +9,7 @@ require ( github.com/gin-gonic/gin v1.12.0 github.com/go-chi/chi/v5 v5.2.5 github.com/gofiber/fiber/v2 v2.52.13 + github.com/gofiber/fiber/v3 v3.4.0 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 github.com/kataras/iris/v12 v12.2.11 @@ -29,7 +30,7 @@ require ( github.com/CloudyKit/jet/v6 v6.3.2 // indirect github.com/Joker/jade v1.1.3 // indirect github.com/Shopify/goreferrer v0.0.0-20250617153402-88c1d9a79b05 // indirect - github.com/andybalholm/brotli v1.2.1 // indirect + github.com/andybalholm/brotli v1.2.2 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/bytedance/gopkg v0.1.4 // indirect @@ -50,6 +51,8 @@ require ( github.com/go-playground/validator/v10 v10.30.2 // indirect github.com/goccy/go-json v0.10.6 // indirect github.com/goccy/go-yaml v1.19.2 // indirect + github.com/gofiber/schema v1.8.0 // indirect + github.com/gofiber/utils/v2 v2.1.1 // indirect github.com/golang/snappy v1.0.0 // indirect github.com/gomarkdown/markdown v0.0.0-20260417124207-7d523f7318df // indirect github.com/gorilla/css v1.0.1 // indirect @@ -61,13 +64,13 @@ require ( github.com/kataras/pio v0.0.13 // indirect github.com/kataras/sitemap v0.0.6 // indirect github.com/kataras/tunnel v0.0.4 // indirect - github.com/klauspost/compress v1.18.6 // indirect + github.com/klauspost/compress v1.19.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/labstack/gommon v0.5.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/mailgun/raymond/v2 v2.0.48 // indirect github.com/mailru/easyjson v0.9.2 // indirect - github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-colorable v0.1.15 // indirect github.com/mattn/go-isatty v0.0.22 // indirect github.com/mattn/go-runewidth v0.0.23 // indirect github.com/microcosm-cc/bluemonday v1.0.27 // indirect @@ -76,6 +79,7 @@ require ( github.com/oasdiff/yaml v0.1.0 // indirect github.com/oasdiff/yaml3 v0.0.13 // indirect github.com/pelletier/go-toml/v2 v2.3.0 // indirect + github.com/philhofer/fwd v1.2.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/quic-go/qpack v0.6.0 // indirect github.com/quic-go/quic-go v0.59.0 // indirect @@ -88,10 +92,11 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/tdewolff/minify/v2 v2.24.13 // indirect github.com/tdewolff/parse/v2 v2.8.12 // indirect + github.com/tinylib/msgp v1.6.4 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.3.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.70.0 // indirect + github.com/valyala/fasthttp v1.72.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect diff --git a/internal/test/go.sum b/internal/test/go.sum index 40976f71ca..68164a3ebe 100644 --- a/internal/test/go.sum +++ b/internal/test/go.sum @@ -14,8 +14,8 @@ github.com/Shopify/goreferrer v0.0.0-20250617153402-88c1d9a79b05 h1:dG7/gLroJGht github.com/Shopify/goreferrer v0.0.0-20250617153402-88c1d9a79b05/go.mod h1:NYezi6wtnJtBm5btoprXc5SvAdqH0XTXWnUup0MptAI= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/andybalholm/brotli v1.2.1 h1:R+f5xP285VArJDRgowrfb9DqL18yVK0gKAW/F+eTWro= -github.com/andybalholm/brotli v1.2.1/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= +github.com/andybalholm/brotli v1.2.2 h1:HzTuoo2ErYQqf5qvcJInB8uvqSVxRttzkFexPWtnceM= +github.com/andybalholm/brotli v1.2.2/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= @@ -53,6 +53,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fxamacker/cbor/v2 v2.9.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78= +github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM= github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= github.com/getkin/kin-openapi v0.140.0 h1:JFn675aXRFjyiZKa/BFWploGldQlI0gobp4J5k0EZ2g= @@ -86,6 +88,12 @@ github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/gofiber/fiber/v2 v2.52.13 h1:TOKP64iqC9b5P49VrBW5tHhUOvDyrtJ0xePEfzJbCbk= github.com/gofiber/fiber/v2 v2.52.13/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= +github.com/gofiber/fiber/v3 v3.4.0 h1:F0aND4vwZF7dR7cbvSwFQQEpBU902XHKWxrLsFBkVqw= +github.com/gofiber/fiber/v3 v3.4.0/go.mod h1:nAhJfdxUIJJph2tPWPmqWf8QDIN2iiqQiQf3lENZpdk= +github.com/gofiber/schema v1.8.0 h1:NGsC9toPHmj8Xg4KpznuXBzNmHG6V5YV0tXKpKMcmis= +github.com/gofiber/schema v1.8.0/go.mod h1:lmbXPQ8hvzXSLkdS2DS7pb4kpunC2Roh7Sj3HMjGfzA= +github.com/gofiber/utils/v2 v2.1.1 h1:kGnoGjwEnFW6w0x45W+kLlmMJvqBGkuUA4oMWKn/T/I= +github.com/gofiber/utils/v2 v2.1.1/go.mod h1:DdOgEVwQTi8cou/AKWPqhXOR4fHGRVhA/rEWL3IXG7Q= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -142,8 +150,8 @@ github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= -github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= -github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ= +github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -165,8 +173,8 @@ github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqA github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= github.com/mailru/easyjson v0.9.2 h1:dX8U45hQsZpxd80nLvDGihsQ/OxlvTkVUXH2r/8cb2M= github.com/mailru/easyjson v0.9.2/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= -github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY= +github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4= github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw= @@ -209,6 +217,8 @@ github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pelletier/go-toml/v2 v2.3.0 h1:k59bC/lIZREW0/iVaQR8nDHxVq8OVlIzYCOJf421CaM= github.com/pelletier/go-toml/v2 v2.3.0/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= +github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -228,6 +238,8 @@ github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiy github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shamaton/msgpack/v3 v3.1.2 h1:d5gWAIyMU4M0WgDjz6IFSCuXJUA2dFwRHBpDclE8CLw= +github.com/shamaton/msgpack/v3 v3.1.2/go.mod h1:DcQG8jrdrQCIxr3HlMYkiXdMhK+KfN2CitkyzsQV4uc= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= @@ -259,14 +271,16 @@ github.com/tdewolff/parse/v2 v2.8.12/go.mod h1:Hwlni2tiVNKyzR1o6nUs4FOF07URA+JLB github.com/tdewolff/test v1.0.11/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= github.com/tdewolff/test v1.0.12 h1:7F21DqIajswxuche0geHdrUZRCWE4oko4b7bcmkkrxk= github.com/tdewolff/test v1.0.12/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= +github.com/tinylib/msgp v1.6.4 h1:mOwYbyYDLPj35mkA2BjjYejgJk9BuHxDdvRnb6v2ZcQ= +github.com/tinylib/msgp v1.6.4/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY= github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.70.0 h1:LAhMGcWk13QZWm85+eg8ZBNbrq5mnkWFGbHMUJHIdXA= -github.com/valyala/fasthttp v1.70.0/go.mod h1:oDZEHHkJ/Buyklg6uURmYs19442zFSnCIfX3j1FY3pE= +github.com/valyala/fasthttp v1.72.0 h1:R7kYdoWhn1ye1fVpP+cDHDJwYm3NkwLliwgzJ/Abg7M= +github.com/valyala/fasthttp v1.72.0/go.mod h1:zsbLTYqcpIktdQytlVBwIjY9La5d6bs990nBxWg8efk= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= @@ -275,6 +289,8 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= diff --git a/internal/test/parameters/roundtrip/chi/gen/server.gen.go b/internal/test/parameters/roundtrip/chi/gen/server.gen.go index a32748c70d..82513e7f2f 100644 --- a/internal/test/parameters/roundtrip/chi/gen/server.gen.go +++ b/internal/test/parameters/roundtrip/chi/gen/server.gen.go @@ -605,6 +605,21 @@ func (siw *ServerInterfaceWrapper) GetHeader(w http.ResponseWriter, r *http.Requ } + // ------------- Optional header parameter "X-Pass-Through" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Pass-Through")]; found { + var XPassThrough string + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Pass-Through", Count: n}) + return + } + + XPassThrough = valueList[0] + + params.XPassThrough = &XPassThrough + + } + // ------------- Optional header parameter "1-Starting-With-Number" ------------- if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { var N1StartingWithNumber string @@ -1568,28 +1583,28 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", - "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", - "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", - "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", - "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", - "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", - "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", - "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", - "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", - "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", - "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", - "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", - "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", - "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", - "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", - "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", - "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", - "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", - "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", - "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", - "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", - "R4QvCIXkLvk3AAD//w==", + "3FpNb+M2E/4rAt/3VMiWne1JPQXbbZuim6R1gC0Q5MBI44hbSeSSdDaB4f9ekJQsiZL1YUv56C2xhjPP", + "POQzFIfaooAmjKaQSoH8LeIgGE0F6H9WJGEx/JX9pH4JaCohlepPCU/SYzEmqfpPBBEkWP/+zAD5SEhO", + "0ge02+1cFIIIOGGS0BT56NwR2q+Tx3Lo/VcIJFKmxo+O/pEqq6cr89DfIsYpAy6JAXcRlqKRVMIDcLRz", + "0YU4DxMDKnt4T2kMOFUPC2f/57BGPvqfV+TvZcG9qwIPh28bwiFE/m0+2FWhizh3FbdVjGvChbzECTQQ", + "4yJO46YHVlRt5ZZc3WlOSbqmanBMAsgmJ9WB0OeLG+VdEqncoxsQ0lkBfwSOXPQIXJhpWM4X84UypAxS", + "zAjy0Yf5Yr5ELmJYRhq/l823yc/bMsxxslNPHkCnq5LFal7VbKBfQX4sD9CuOE5AAhfIv62sH8xYTAI9", + "2PsqqLWK2qanujAyNpCvYSM3p0FHRmUuJd/A7s6trvGzxeJQvL2dZwlhp2N6AaX/EGhnQ1vUaKgKgnGS", + "EEkelSE8sZiGgPw1jgVkiQW5mzw15JaoWlOeYGlE8OEMuTVN7NxeERU9BwLCyRGzKKGDOcfPfcPiSlgi", + "IRG94u9/MdEa8NRgtPE9HYw9LTQXTC9eaAVQv1Jmh65HbKPguIhTyb2aSWAMCg4bMwgoqpOgnjlCYi5J", + "+uB8JzJy0k1yr0tlo5elqBBhl267uoSwxptYHlthIN2YpdZYYD6lm+RaFRbRVWGu84cmReXWecTxBkSe", + "57cN8OfSCtOuZXSdFdEiY/UE+bfLxcI9Wyzu3B7FoF5yfzTcVGaCOvlqyZKPAIfA28rrb8bi1PIa5W6y", + "5P+eXZeGTFpoW0LPPmW14UVKbx3IubJuBvFihfgAqlcux3VUpjY1kzVFdT6E4N0V6XoimaM8IQvg0YeO", + "lKaz31dXl3mRcZ17uklDBwtHRuBw/N0xWJzMx2GBYiFmNxGnm4fomB3F9ricrTLr2Rcio9llbv1iu0yM", + "7yHO1q7Wl7ed64r6Q+ur/h/2sHohblJPn7f0cfTtIiGf9RlIZ4jGfPcvc5afjoaSduiQNAZrfcT/Uvzs", + "t7ThFJU34glY6rGkJqbokjYJr5uf6rgWdsrbxn9Ievv8q+IbQFyn+k5h7k3Ir6a7bnb66O0UXl5VcAmW", + "nDxZeiNhezX6XBt0TCki4eRCM9lNR9heaIMYO36P66BsmMKmJqcktZ8G8XPSBtdB0QCxTcZPbX8jYQ9y", + "Rtjd3rPi6pvbMNZO2Nreh+qqcutBzWn72pvWGcNCZMfRPhc014V56/XMgJP2q1y+6IblzwCsuHs7lHLJ", + "qqNVGAKw9t6P1ScNjeujNWO1TYqFEhaYxz7uZ8zFShEQthH3Z9WygzzBcABOmJs7rZ09i0cx1hVLwaCG", + "U4Bv6M0SdixcNj5chaaEdmyl/EJ50jnV2qhjlnt1k+3bhPHpUkPRwG6yherFQPXrKtucTX/HZ0UcI+A+", + "1a6LDzvbaa602yQ8WkCrY2zHab8wfOX+uwX2uDtSy8nAK9ITKpv5jqh6wOjRYFzVhr3dzrVJEU3GWuXL", + "ngG0vZ3e9dQMlc4a3W/Xq8aRr968nowj+3jfl6F3076enrn+39atmga+iQb2ZCwdIb4W1b1HmWX77hci", + "I3Mz7G2XPaioDZvwsL+c+LSvGNbfrxrcGx4jH0VSMt/zso9XJQg5V2fmBLM5Jmh3t/s3AAD//w==", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/test/parameters/roundtrip/chi/gen/types.gen.go b/internal/test/parameters/roundtrip/chi/gen/types.gen.go index cf9e959422..d0ea47a200 100644 --- a/internal/test/parameters/roundtrip/chi/gen/types.gen.go +++ b/internal/test/parameters/roundtrip/chi/gen/types.gen.go @@ -93,6 +93,9 @@ type GetHeaderParams struct { // XComplexObject complex object XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + // XPassThrough non-JSON content, bound as the raw header string + XPassThrough *string `json:"X-Pass-Through,omitempty"` + // N1StartingWithNumber name starting with number N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` } diff --git a/internal/test/parameters/roundtrip/client/gen/client.gen.go b/internal/test/parameters/roundtrip/client/gen/client.gen.go index 77de438c5c..4db51cf2c5 100644 --- a/internal/test/parameters/roundtrip/client/gen/client.gen.go +++ b/internal/test/parameters/roundtrip/client/gen/client.gen.go @@ -105,6 +105,9 @@ type GetHeaderParams struct { // XComplexObject complex object XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + // XPassThrough non-JSON content, bound as the raw header string + XPassThrough *string `json:"X-Pass-Through,omitempty"` + // N1StartingWithNumber name starting with number N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` } @@ -1007,15 +1010,23 @@ func NewGetHeaderRequest(server string, params *GetHeaderParams) (*http.Request, req.Header.Set("X-Complex-Object", headerParam6) } - if params.N1StartingWithNumber != nil { + if params.XPassThrough != nil { var headerParam7 string - headerParam7, err = runtime.StyleParamWithOptions("simple", false, "1-Starting-With-Number", *params.N1StartingWithNumber, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "string", Format: ""}) + headerParam7 = *params.XPassThrough + + req.Header.Set("X-Pass-Through", headerParam7) + } + + if params.N1StartingWithNumber != nil { + var headerParam8 string + + headerParam8, err = runtime.StyleParamWithOptions("simple", false, "1-Starting-With-Number", *params.N1StartingWithNumber, runtime.StyleParamOptions{ParamLocation: runtime.ParamLocationHeader, Type: "string", Format: ""}) if err != nil { return nil, err } - req.Header.Set("1-Starting-With-Number", headerParam7) + req.Header.Set("1-Starting-With-Number", headerParam8) } } diff --git a/internal/test/parameters/roundtrip/echo/gen/server.gen.go b/internal/test/parameters/roundtrip/echo/gen/server.gen.go index f55c138151..54e8ffbe9b 100644 --- a/internal/test/parameters/roundtrip/echo/gen/server.gen.go +++ b/internal/test/parameters/roundtrip/echo/gen/server.gen.go @@ -361,6 +361,18 @@ func (w *ServerInterfaceWrapper) GetHeader(ctx echo.Context) error { params.XComplexObject = &XComplexObject } + // ------------- Optional header parameter "X-Pass-Through" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Pass-Through")]; found { + var XPassThrough string + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Pass-Through, got %d", n)) + } + + XPassThrough = valueList[0] + + params.XPassThrough = &XPassThrough + } // ------------- Optional header parameter "1-Starting-With-Number" ------------- if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { var N1StartingWithNumber string @@ -901,28 +913,28 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", - "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", - "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", - "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", - "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", - "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", - "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", - "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", - "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", - "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", - "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", - "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", - "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", - "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", - "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", - "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", - "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", - "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", - "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", - "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", - "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", - "R4QvCIXkLvk3AAD//w==", + "3FpNb+M2E/4rAt/3VMiWne1JPQXbbZuim6R1gC0Q5MBI44hbSeSSdDaB4f9ekJQsiZL1YUv56C2xhjPP", + "POQzFIfaooAmjKaQSoH8LeIgGE0F6H9WJGEx/JX9pH4JaCohlepPCU/SYzEmqfpPBBEkWP/+zAD5SEhO", + "0ge02+1cFIIIOGGS0BT56NwR2q+Tx3Lo/VcIJFKmxo+O/pEqq6cr89DfIsYpAy6JAXcRlqKRVMIDcLRz", + "0YU4DxMDKnt4T2kMOFUPC2f/57BGPvqfV+TvZcG9qwIPh28bwiFE/m0+2FWhizh3FbdVjGvChbzECTQQ", + "4yJO46YHVlRt5ZZc3WlOSbqmanBMAsgmJ9WB0OeLG+VdEqncoxsQ0lkBfwSOXPQIXJhpWM4X84UypAxS", + "zAjy0Yf5Yr5ELmJYRhq/l823yc/bMsxxslNPHkCnq5LFal7VbKBfQX4sD9CuOE5AAhfIv62sH8xYTAI9", + "2PsqqLWK2qanujAyNpCvYSM3p0FHRmUuJd/A7s6trvGzxeJQvL2dZwlhp2N6AaX/EGhnQ1vUaKgKgnGS", + "EEkelSE8sZiGgPw1jgVkiQW5mzw15JaoWlOeYGlE8OEMuTVN7NxeERU9BwLCyRGzKKGDOcfPfcPiSlgi", + "IRG94u9/MdEa8NRgtPE9HYw9LTQXTC9eaAVQv1Jmh65HbKPguIhTyb2aSWAMCg4bMwgoqpOgnjlCYi5J", + "+uB8JzJy0k1yr0tlo5elqBBhl267uoSwxptYHlthIN2YpdZYYD6lm+RaFRbRVWGu84cmReXWecTxBkSe", + "57cN8OfSCtOuZXSdFdEiY/UE+bfLxcI9Wyzu3B7FoF5yfzTcVGaCOvlqyZKPAIfA28rrb8bi1PIa5W6y", + "5P+eXZeGTFpoW0LPPmW14UVKbx3IubJuBvFihfgAqlcux3VUpjY1kzVFdT6E4N0V6XoimaM8IQvg0YeO", + "lKaz31dXl3mRcZ17uklDBwtHRuBw/N0xWJzMx2GBYiFmNxGnm4fomB3F9ricrTLr2Rcio9llbv1iu0yM", + "7yHO1q7Wl7ed64r6Q+ur/h/2sHohblJPn7f0cfTtIiGf9RlIZ4jGfPcvc5afjoaSduiQNAZrfcT/Uvzs", + "t7ThFJU34glY6rGkJqbokjYJr5uf6rgWdsrbxn9Ievv8q+IbQFyn+k5h7k3Ir6a7bnb66O0UXl5VcAmW", + "nDxZeiNhezX6XBt0TCki4eRCM9lNR9heaIMYO36P66BsmMKmJqcktZ8G8XPSBtdB0QCxTcZPbX8jYQ9y", + "Rtjd3rPi6pvbMNZO2Nreh+qqcutBzWn72pvWGcNCZMfRPhc014V56/XMgJP2q1y+6IblzwCsuHs7lHLJ", + "qqNVGAKw9t6P1ScNjeujNWO1TYqFEhaYxz7uZ8zFShEQthH3Z9WygzzBcABOmJs7rZ09i0cx1hVLwaCG", + "U4Bv6M0SdixcNj5chaaEdmyl/EJ50jnV2qhjlnt1k+3bhPHpUkPRwG6yherFQPXrKtucTX/HZ0UcI+A+", + "1a6LDzvbaa602yQ8WkCrY2zHab8wfOX+uwX2uDtSy8nAK9ITKpv5jqh6wOjRYFzVhr3dzrVJEU3GWuXL", + "ngG0vZ3e9dQMlc4a3W/Xq8aRr968nowj+3jfl6F3076enrn+39atmga+iQb2ZCwdIb4W1b1HmWX77hci", + "I3Mz7G2XPaioDZvwsL+c+LSvGNbfrxrcGx4jH0VSMt/zso9XJQg5V2fmBLM5Jmh3t/s3AAD//w==", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/test/parameters/roundtrip/echo/gen/types.gen.go b/internal/test/parameters/roundtrip/echo/gen/types.gen.go index 043be6dba0..2a902d51cc 100644 --- a/internal/test/parameters/roundtrip/echo/gen/types.gen.go +++ b/internal/test/parameters/roundtrip/echo/gen/types.gen.go @@ -93,6 +93,9 @@ type GetHeaderParams struct { // XComplexObject complex object XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + // XPassThrough non-JSON content, bound as the raw header string + XPassThrough *string `json:"X-Pass-Through,omitempty"` + // N1StartingWithNumber name starting with number N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` } diff --git a/internal/test/parameters/roundtrip/echov5/gen/server.gen.go b/internal/test/parameters/roundtrip/echov5/gen/server.gen.go index 30bebc6b46..dd0d3a30f3 100644 --- a/internal/test/parameters/roundtrip/echov5/gen/server.gen.go +++ b/internal/test/parameters/roundtrip/echov5/gen/server.gen.go @@ -361,6 +361,18 @@ func (w *ServerInterfaceWrapper) GetHeader(ctx *echo.Context) error { params.XComplexObject = &XComplexObject } + // ------------- Optional header parameter "X-Pass-Through" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Pass-Through")]; found { + var XPassThrough string + n := len(valueList) + if n != 1 { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for X-Pass-Through, got %d", n)) + } + + XPassThrough = valueList[0] + + params.XPassThrough = &XPassThrough + } // ------------- Optional header parameter "1-Starting-With-Number" ------------- if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { var N1StartingWithNumber string @@ -901,28 +913,28 @@ func RegisterHandlersWithOptions(router EchoRouter, si ServerInterface, options // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", - "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", - "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", - "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", - "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", - "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", - "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", - "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", - "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", - "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", - "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", - "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", - "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", - "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", - "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", - "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", - "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", - "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", - "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", - "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", - "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", - "R4QvCIXkLvk3AAD//w==", + "3FpNb+M2E/4rAt/3VMiWne1JPQXbbZuim6R1gC0Q5MBI44hbSeSSdDaB4f9ekJQsiZL1YUv56C2xhjPP", + "POQzFIfaooAmjKaQSoH8LeIgGE0F6H9WJGEx/JX9pH4JaCohlepPCU/SYzEmqfpPBBEkWP/+zAD5SEhO", + "0ge02+1cFIIIOGGS0BT56NwR2q+Tx3Lo/VcIJFKmxo+O/pEqq6cr89DfIsYpAy6JAXcRlqKRVMIDcLRz", + "0YU4DxMDKnt4T2kMOFUPC2f/57BGPvqfV+TvZcG9qwIPh28bwiFE/m0+2FWhizh3FbdVjGvChbzECTQQ", + "4yJO46YHVlRt5ZZc3WlOSbqmanBMAsgmJ9WB0OeLG+VdEqncoxsQ0lkBfwSOXPQIXJhpWM4X84UypAxS", + "zAjy0Yf5Yr5ELmJYRhq/l823yc/bMsxxslNPHkCnq5LFal7VbKBfQX4sD9CuOE5AAhfIv62sH8xYTAI9", + "2PsqqLWK2qanujAyNpCvYSM3p0FHRmUuJd/A7s6trvGzxeJQvL2dZwlhp2N6AaX/EGhnQ1vUaKgKgnGS", + "EEkelSE8sZiGgPw1jgVkiQW5mzw15JaoWlOeYGlE8OEMuTVN7NxeERU9BwLCyRGzKKGDOcfPfcPiSlgi", + "IRG94u9/MdEa8NRgtPE9HYw9LTQXTC9eaAVQv1Jmh65HbKPguIhTyb2aSWAMCg4bMwgoqpOgnjlCYi5J", + "+uB8JzJy0k1yr0tlo5elqBBhl267uoSwxptYHlthIN2YpdZYYD6lm+RaFRbRVWGu84cmReXWecTxBkSe", + "57cN8OfSCtOuZXSdFdEiY/UE+bfLxcI9Wyzu3B7FoF5yfzTcVGaCOvlqyZKPAIfA28rrb8bi1PIa5W6y", + "5P+eXZeGTFpoW0LPPmW14UVKbx3IubJuBvFihfgAqlcux3VUpjY1kzVFdT6E4N0V6XoimaM8IQvg0YeO", + "lKaz31dXl3mRcZ17uklDBwtHRuBw/N0xWJzMx2GBYiFmNxGnm4fomB3F9ricrTLr2Rcio9llbv1iu0yM", + "7yHO1q7Wl7ed64r6Q+ur/h/2sHohblJPn7f0cfTtIiGf9RlIZ4jGfPcvc5afjoaSduiQNAZrfcT/Uvzs", + "t7ThFJU34glY6rGkJqbokjYJr5uf6rgWdsrbxn9Ievv8q+IbQFyn+k5h7k3Ir6a7bnb66O0UXl5VcAmW", + "nDxZeiNhezX6XBt0TCki4eRCM9lNR9heaIMYO36P66BsmMKmJqcktZ8G8XPSBtdB0QCxTcZPbX8jYQ9y", + "Rtjd3rPi6pvbMNZO2Nreh+qqcutBzWn72pvWGcNCZMfRPhc014V56/XMgJP2q1y+6IblzwCsuHs7lHLJ", + "qqNVGAKw9t6P1ScNjeujNWO1TYqFEhaYxz7uZ8zFShEQthH3Z9WygzzBcABOmJs7rZ09i0cx1hVLwaCG", + "U4Bv6M0SdixcNj5chaaEdmyl/EJ50jnV2qhjlnt1k+3bhPHpUkPRwG6yherFQPXrKtucTX/HZ0UcI+A+", + "1a6LDzvbaa602yQ8WkCrY2zHab8wfOX+uwX2uDtSy8nAK9ITKpv5jqh6wOjRYFzVhr3dzrVJEU3GWuXL", + "ngG0vZ3e9dQMlc4a3W/Xq8aRr968nowj+3jfl6F3076enrn+39atmga+iQb2ZCwdIb4W1b1HmWX77hci", + "I3Mz7G2XPaioDZvwsL+c+LSvGNbfrxrcGx4jH0VSMt/zso9XJQg5V2fmBLM5Jmh3t/s3AAD//w==", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/test/parameters/roundtrip/echov5/gen/types.gen.go b/internal/test/parameters/roundtrip/echov5/gen/types.gen.go index f9ac88c94a..2ff655c92a 100644 --- a/internal/test/parameters/roundtrip/echov5/gen/types.gen.go +++ b/internal/test/parameters/roundtrip/echov5/gen/types.gen.go @@ -93,6 +93,9 @@ type GetHeaderParams struct { // XComplexObject complex object XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + // XPassThrough non-JSON content, bound as the raw header string + XPassThrough *string `json:"X-Pass-Through,omitempty"` + // N1StartingWithNumber name starting with number N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` } diff --git a/internal/test/parameters/roundtrip/fiber/gen/server.gen.go b/internal/test/parameters/roundtrip/fiber/gen/server.gen.go index 0557bc8fab..71a6febb8c 100644 --- a/internal/test/parameters/roundtrip/fiber/gen/server.gen.go +++ b/internal/test/parameters/roundtrip/fiber/gen/server.gen.go @@ -458,6 +458,20 @@ func (siw *ServerInterfaceWrapper) GetHeader(c *fiber.Ctx) error { } + // ------------- Optional header parameter "X-Pass-Through" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Pass-Through")]; found { + var XPassThrough string + n := len(valueList) + if n != 1 { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Too many values for ParamName X-Pass-Through, 1 is required, but %d found", n)) + } + + XPassThrough = valueList[0] + + params.XPassThrough = &XPassThrough + + } + // ------------- Optional header parameter "1-Starting-With-Number" ------------- if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { var N1StartingWithNumber string @@ -1335,28 +1349,28 @@ func RegisterHandlersWithOptions(router fiber.Router, si ServerInterface, option // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", - "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", - "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", - "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", - "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", - "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", - "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", - "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", - "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", - "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", - "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", - "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", - "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", - "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", - "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", - "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", - "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", - "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", - "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", - "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", - "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", - "R4QvCIXkLvk3AAD//w==", + "3FpNb+M2E/4rAt/3VMiWne1JPQXbbZuim6R1gC0Q5MBI44hbSeSSdDaB4f9ekJQsiZL1YUv56C2xhjPP", + "POQzFIfaooAmjKaQSoH8LeIgGE0F6H9WJGEx/JX9pH4JaCohlepPCU/SYzEmqfpPBBEkWP/+zAD5SEhO", + "0ge02+1cFIIIOGGS0BT56NwR2q+Tx3Lo/VcIJFKmxo+O/pEqq6cr89DfIsYpAy6JAXcRlqKRVMIDcLRz", + "0YU4DxMDKnt4T2kMOFUPC2f/57BGPvqfV+TvZcG9qwIPh28bwiFE/m0+2FWhizh3FbdVjGvChbzECTQQ", + "4yJO46YHVlRt5ZZc3WlOSbqmanBMAsgmJ9WB0OeLG+VdEqncoxsQ0lkBfwSOXPQIXJhpWM4X84UypAxS", + "zAjy0Yf5Yr5ELmJYRhq/l823yc/bMsxxslNPHkCnq5LFal7VbKBfQX4sD9CuOE5AAhfIv62sH8xYTAI9", + "2PsqqLWK2qanujAyNpCvYSM3p0FHRmUuJd/A7s6trvGzxeJQvL2dZwlhp2N6AaX/EGhnQ1vUaKgKgnGS", + "EEkelSE8sZiGgPw1jgVkiQW5mzw15JaoWlOeYGlE8OEMuTVN7NxeERU9BwLCyRGzKKGDOcfPfcPiSlgi", + "IRG94u9/MdEa8NRgtPE9HYw9LTQXTC9eaAVQv1Jmh65HbKPguIhTyb2aSWAMCg4bMwgoqpOgnjlCYi5J", + "+uB8JzJy0k1yr0tlo5elqBBhl267uoSwxptYHlthIN2YpdZYYD6lm+RaFRbRVWGu84cmReXWecTxBkSe", + "57cN8OfSCtOuZXSdFdEiY/UE+bfLxcI9Wyzu3B7FoF5yfzTcVGaCOvlqyZKPAIfA28rrb8bi1PIa5W6y", + "5P+eXZeGTFpoW0LPPmW14UVKbx3IubJuBvFihfgAqlcux3VUpjY1kzVFdT6E4N0V6XoimaM8IQvg0YeO", + "lKaz31dXl3mRcZ17uklDBwtHRuBw/N0xWJzMx2GBYiFmNxGnm4fomB3F9ricrTLr2Rcio9llbv1iu0yM", + "7yHO1q7Wl7ed64r6Q+ur/h/2sHohblJPn7f0cfTtIiGf9RlIZ4jGfPcvc5afjoaSduiQNAZrfcT/Uvzs", + "t7ThFJU34glY6rGkJqbokjYJr5uf6rgWdsrbxn9Ievv8q+IbQFyn+k5h7k3Ir6a7bnb66O0UXl5VcAmW", + "nDxZeiNhezX6XBt0TCki4eRCM9lNR9heaIMYO36P66BsmMKmJqcktZ8G8XPSBtdB0QCxTcZPbX8jYQ9y", + "Rtjd3rPi6pvbMNZO2Nreh+qqcutBzWn72pvWGcNCZMfRPhc014V56/XMgJP2q1y+6IblzwCsuHs7lHLJ", + "qqNVGAKw9t6P1ScNjeujNWO1TYqFEhaYxz7uZ8zFShEQthH3Z9WygzzBcABOmJs7rZ09i0cx1hVLwaCG", + "U4Bv6M0SdixcNj5chaaEdmyl/EJ50jnV2qhjlnt1k+3bhPHpUkPRwG6yherFQPXrKtucTX/HZ0UcI+A+", + "1a6LDzvbaa602yQ8WkCrY2zHab8wfOX+uwX2uDtSy8nAK9ITKpv5jqh6wOjRYFzVhr3dzrVJEU3GWuXL", + "ngG0vZ3e9dQMlc4a3W/Xq8aRr968nowj+3jfl6F3076enrn+39atmga+iQb2ZCwdIb4W1b1HmWX77hci", + "I3Mz7G2XPaioDZvwsL+c+LSvGNbfrxrcGx4jH0VSMt/zso9XJQg5V2fmBLM5Jmh3t/s3AAD//w==", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/test/parameters/roundtrip/fiber/gen/types.gen.go b/internal/test/parameters/roundtrip/fiber/gen/types.gen.go index c7b09599fb..64f4da2026 100644 --- a/internal/test/parameters/roundtrip/fiber/gen/types.gen.go +++ b/internal/test/parameters/roundtrip/fiber/gen/types.gen.go @@ -93,6 +93,9 @@ type GetHeaderParams struct { // XComplexObject complex object XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + // XPassThrough non-JSON content, bound as the raw header string + XPassThrough *string `json:"X-Pass-Through,omitempty"` + // N1StartingWithNumber name starting with number N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` } diff --git a/internal/test/parameters/roundtrip/gin/gen/server.gen.go b/internal/test/parameters/roundtrip/gin/gen/server.gen.go index 5bf8e4232f..1168b72053 100644 --- a/internal/test/parameters/roundtrip/gin/gen/server.gen.go +++ b/internal/test/parameters/roundtrip/gin/gen/server.gen.go @@ -456,6 +456,21 @@ func (siw *ServerInterfaceWrapper) GetHeader(c *gin.Context) { } + // ------------- Optional header parameter "X-Pass-Through" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Pass-Through")]; found { + var XPassThrough string + n := len(valueList) + if n != 1 { + siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-Pass-Through, got %d", n), http.StatusBadRequest) + return + } + + XPassThrough = valueList[0] + + params.XPassThrough = &XPassThrough + + } + // ------------- Optional header parameter "1-Starting-With-Number" ------------- if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { var N1StartingWithNumber string @@ -1198,28 +1213,28 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", - "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", - "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", - "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", - "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", - "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", - "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", - "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", - "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", - "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", - "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", - "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", - "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", - "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", - "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", - "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", - "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", - "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", - "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", - "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", - "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", - "R4QvCIXkLvk3AAD//w==", + "3FpNb+M2E/4rAt/3VMiWne1JPQXbbZuim6R1gC0Q5MBI44hbSeSSdDaB4f9ekJQsiZL1YUv56C2xhjPP", + "POQzFIfaooAmjKaQSoH8LeIgGE0F6H9WJGEx/JX9pH4JaCohlepPCU/SYzEmqfpPBBEkWP/+zAD5SEhO", + "0ge02+1cFIIIOGGS0BT56NwR2q+Tx3Lo/VcIJFKmxo+O/pEqq6cr89DfIsYpAy6JAXcRlqKRVMIDcLRz", + "0YU4DxMDKnt4T2kMOFUPC2f/57BGPvqfV+TvZcG9qwIPh28bwiFE/m0+2FWhizh3FbdVjGvChbzECTQQ", + "4yJO46YHVlRt5ZZc3WlOSbqmanBMAsgmJ9WB0OeLG+VdEqncoxsQ0lkBfwSOXPQIXJhpWM4X84UypAxS", + "zAjy0Yf5Yr5ELmJYRhq/l823yc/bMsxxslNPHkCnq5LFal7VbKBfQX4sD9CuOE5AAhfIv62sH8xYTAI9", + "2PsqqLWK2qanujAyNpCvYSM3p0FHRmUuJd/A7s6trvGzxeJQvL2dZwlhp2N6AaX/EGhnQ1vUaKgKgnGS", + "EEkelSE8sZiGgPw1jgVkiQW5mzw15JaoWlOeYGlE8OEMuTVN7NxeERU9BwLCyRGzKKGDOcfPfcPiSlgi", + "IRG94u9/MdEa8NRgtPE9HYw9LTQXTC9eaAVQv1Jmh65HbKPguIhTyb2aSWAMCg4bMwgoqpOgnjlCYi5J", + "+uB8JzJy0k1yr0tlo5elqBBhl267uoSwxptYHlthIN2YpdZYYD6lm+RaFRbRVWGu84cmReXWecTxBkSe", + "57cN8OfSCtOuZXSdFdEiY/UE+bfLxcI9Wyzu3B7FoF5yfzTcVGaCOvlqyZKPAIfA28rrb8bi1PIa5W6y", + "5P+eXZeGTFpoW0LPPmW14UVKbx3IubJuBvFihfgAqlcux3VUpjY1kzVFdT6E4N0V6XoimaM8IQvg0YeO", + "lKaz31dXl3mRcZ17uklDBwtHRuBw/N0xWJzMx2GBYiFmNxGnm4fomB3F9ricrTLr2Rcio9llbv1iu0yM", + "7yHO1q7Wl7ed64r6Q+ur/h/2sHohblJPn7f0cfTtIiGf9RlIZ4jGfPcvc5afjoaSduiQNAZrfcT/Uvzs", + "t7ThFJU34glY6rGkJqbokjYJr5uf6rgWdsrbxn9Ievv8q+IbQFyn+k5h7k3Ir6a7bnb66O0UXl5VcAmW", + "nDxZeiNhezX6XBt0TCki4eRCM9lNR9heaIMYO36P66BsmMKmJqcktZ8G8XPSBtdB0QCxTcZPbX8jYQ9y", + "Rtjd3rPi6pvbMNZO2Nreh+qqcutBzWn72pvWGcNCZMfRPhc014V56/XMgJP2q1y+6IblzwCsuHs7lHLJ", + "qqNVGAKw9t6P1ScNjeujNWO1TYqFEhaYxz7uZ8zFShEQthH3Z9WygzzBcABOmJs7rZ09i0cx1hVLwaCG", + "U4Bv6M0SdixcNj5chaaEdmyl/EJ50jnV2qhjlnt1k+3bhPHpUkPRwG6yherFQPXrKtucTX/HZ0UcI+A+", + "1a6LDzvbaa602yQ8WkCrY2zHab8wfOX+uwX2uDtSy8nAK9ITKpv5jqh6wOjRYFzVhr3dzrVJEU3GWuXL", + "ngG0vZ3e9dQMlc4a3W/Xq8aRr968nowj+3jfl6F3076enrn+39atmga+iQb2ZCwdIb4W1b1HmWX77hci", + "I3Mz7G2XPaioDZvwsL+c+LSvGNbfrxrcGx4jH0VSMt/zso9XJQg5V2fmBLM5Jmh3t/s3AAD//w==", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/test/parameters/roundtrip/gin/gen/types.gen.go b/internal/test/parameters/roundtrip/gin/gen/types.gen.go index e73bcb5083..d070fe992d 100644 --- a/internal/test/parameters/roundtrip/gin/gen/types.gen.go +++ b/internal/test/parameters/roundtrip/gin/gen/types.gen.go @@ -93,6 +93,9 @@ type GetHeaderParams struct { // XComplexObject complex object XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + // XPassThrough non-JSON content, bound as the raw header string + XPassThrough *string `json:"X-Pass-Through,omitempty"` + // N1StartingWithNumber name starting with number N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` } diff --git a/internal/test/parameters/roundtrip/gorilla/gen/server.gen.go b/internal/test/parameters/roundtrip/gorilla/gen/server.gen.go index 489209ea0a..69cd221f85 100644 --- a/internal/test/parameters/roundtrip/gorilla/gen/server.gen.go +++ b/internal/test/parameters/roundtrip/gorilla/gen/server.gen.go @@ -466,6 +466,21 @@ func (siw *ServerInterfaceWrapper) GetHeader(w http.ResponseWriter, r *http.Requ } + // ------------- Optional header parameter "X-Pass-Through" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Pass-Through")]; found { + var XPassThrough string + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Pass-Through", Count: n}) + return + } + + XPassThrough = valueList[0] + + params.XPassThrough = &XPassThrough + + } + // ------------- Optional header parameter "1-Starting-With-Number" ------------- if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { var N1StartingWithNumber string @@ -1401,28 +1416,28 @@ func HandlerWithOptions(si ServerInterface, options GorillaServerOptions) http.H // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", - "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", - "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", - "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", - "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", - "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", - "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", - "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", - "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", - "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", - "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", - "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", - "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", - "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", - "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", - "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", - "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", - "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", - "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", - "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", - "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", - "R4QvCIXkLvk3AAD//w==", + "3FpNb+M2E/4rAt/3VMiWne1JPQXbbZuim6R1gC0Q5MBI44hbSeSSdDaB4f9ekJQsiZL1YUv56C2xhjPP", + "POQzFIfaooAmjKaQSoH8LeIgGE0F6H9WJGEx/JX9pH4JaCohlepPCU/SYzEmqfpPBBEkWP/+zAD5SEhO", + "0ge02+1cFIIIOGGS0BT56NwR2q+Tx3Lo/VcIJFKmxo+O/pEqq6cr89DfIsYpAy6JAXcRlqKRVMIDcLRz", + "0YU4DxMDKnt4T2kMOFUPC2f/57BGPvqfV+TvZcG9qwIPh28bwiFE/m0+2FWhizh3FbdVjGvChbzECTQQ", + "4yJO46YHVlRt5ZZc3WlOSbqmanBMAsgmJ9WB0OeLG+VdEqncoxsQ0lkBfwSOXPQIXJhpWM4X84UypAxS", + "zAjy0Yf5Yr5ELmJYRhq/l823yc/bMsxxslNPHkCnq5LFal7VbKBfQX4sD9CuOE5AAhfIv62sH8xYTAI9", + "2PsqqLWK2qanujAyNpCvYSM3p0FHRmUuJd/A7s6trvGzxeJQvL2dZwlhp2N6AaX/EGhnQ1vUaKgKgnGS", + "EEkelSE8sZiGgPw1jgVkiQW5mzw15JaoWlOeYGlE8OEMuTVN7NxeERU9BwLCyRGzKKGDOcfPfcPiSlgi", + "IRG94u9/MdEa8NRgtPE9HYw9LTQXTC9eaAVQv1Jmh65HbKPguIhTyb2aSWAMCg4bMwgoqpOgnjlCYi5J", + "+uB8JzJy0k1yr0tlo5elqBBhl267uoSwxptYHlthIN2YpdZYYD6lm+RaFRbRVWGu84cmReXWecTxBkSe", + "57cN8OfSCtOuZXSdFdEiY/UE+bfLxcI9Wyzu3B7FoF5yfzTcVGaCOvlqyZKPAIfA28rrb8bi1PIa5W6y", + "5P+eXZeGTFpoW0LPPmW14UVKbx3IubJuBvFihfgAqlcux3VUpjY1kzVFdT6E4N0V6XoimaM8IQvg0YeO", + "lKaz31dXl3mRcZ17uklDBwtHRuBw/N0xWJzMx2GBYiFmNxGnm4fomB3F9ricrTLr2Rcio9llbv1iu0yM", + "7yHO1q7Wl7ed64r6Q+ur/h/2sHohblJPn7f0cfTtIiGf9RlIZ4jGfPcvc5afjoaSduiQNAZrfcT/Uvzs", + "t7ThFJU34glY6rGkJqbokjYJr5uf6rgWdsrbxn9Ievv8q+IbQFyn+k5h7k3Ir6a7bnb66O0UXl5VcAmW", + "nDxZeiNhezX6XBt0TCki4eRCM9lNR9heaIMYO36P66BsmMKmJqcktZ8G8XPSBtdB0QCxTcZPbX8jYQ9y", + "Rtjd3rPi6pvbMNZO2Nreh+qqcutBzWn72pvWGcNCZMfRPhc014V56/XMgJP2q1y+6IblzwCsuHs7lHLJ", + "qqNVGAKw9t6P1ScNjeujNWO1TYqFEhaYxz7uZ8zFShEQthH3Z9WygzzBcABOmJs7rZ09i0cx1hVLwaCG", + "U4Bv6M0SdixcNj5chaaEdmyl/EJ50jnV2qhjlnt1k+3bhPHpUkPRwG6yherFQPXrKtucTX/HZ0UcI+A+", + "1a6LDzvbaa602yQ8WkCrY2zHab8wfOX+uwX2uDtSy8nAK9ITKpv5jqh6wOjRYFzVhr3dzrVJEU3GWuXL", + "ngG0vZ3e9dQMlc4a3W/Xq8aRr968nowj+3jfl6F3076enrn+39atmga+iQb2ZCwdIb4W1b1HmWX77hci", + "I3Mz7G2XPaioDZvwsL+c+LSvGNbfrxrcGx4jH0VSMt/zso9XJQg5V2fmBLM5Jmh3t/s3AAD//w==", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/test/parameters/roundtrip/gorilla/gen/types.gen.go b/internal/test/parameters/roundtrip/gorilla/gen/types.gen.go index b7a27e4096..4dc13fdcd7 100644 --- a/internal/test/parameters/roundtrip/gorilla/gen/types.gen.go +++ b/internal/test/parameters/roundtrip/gorilla/gen/types.gen.go @@ -93,6 +93,9 @@ type GetHeaderParams struct { // XComplexObject complex object XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + // XPassThrough non-JSON content, bound as the raw header string + XPassThrough *string `json:"X-Pass-Through,omitempty"` + // N1StartingWithNumber name starting with number N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` } diff --git a/internal/test/parameters/roundtrip/iris/gen/server.gen.go b/internal/test/parameters/roundtrip/iris/gen/server.gen.go index 2da66aeedf..3671a78e34 100644 --- a/internal/test/parameters/roundtrip/iris/gen/server.gen.go +++ b/internal/test/parameters/roundtrip/iris/gen/server.gen.go @@ -419,6 +419,20 @@ func (w *ServerInterfaceWrapper) GetHeader(ctx iris.Context) { params.XComplexObject = &XComplexObject } + // ------------- Optional header parameter "X-Pass-Through" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Pass-Through")]; found { + var XPassThrough string + n := len(valueList) + if n != 1 { + ctx.StatusCode(http.StatusBadRequest) + ctx.Writef("Expected one value for X-Pass-Through, got %d", n) + return + } + + XPassThrough = valueList[0] + + params.XPassThrough = &XPassThrough + } // ------------- Optional header parameter "1-Starting-With-Number" ------------- if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { var N1StartingWithNumber string @@ -996,6 +1010,9 @@ func RegisterHandlers(router *iris.Application, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) { + for _, m := range options.Middlewares { + router.Use(m) + } wrapper := ServerInterfaceWrapper{ Handler: si, @@ -1037,28 +1054,28 @@ func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, o // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", - "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", - "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", - "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", - "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", - "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", - "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", - "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", - "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", - "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", - "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", - "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", - "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", - "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", - "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", - "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", - "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", - "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", - "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", - "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", - "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", - "R4QvCIXkLvk3AAD//w==", + "3FpNb+M2E/4rAt/3VMiWne1JPQXbbZuim6R1gC0Q5MBI44hbSeSSdDaB4f9ekJQsiZL1YUv56C2xhjPP", + "POQzFIfaooAmjKaQSoH8LeIgGE0F6H9WJGEx/JX9pH4JaCohlepPCU/SYzEmqfpPBBEkWP/+zAD5SEhO", + "0ge02+1cFIIIOGGS0BT56NwR2q+Tx3Lo/VcIJFKmxo+O/pEqq6cr89DfIsYpAy6JAXcRlqKRVMIDcLRz", + "0YU4DxMDKnt4T2kMOFUPC2f/57BGPvqfV+TvZcG9qwIPh28bwiFE/m0+2FWhizh3FbdVjGvChbzECTQQ", + "4yJO46YHVlRt5ZZc3WlOSbqmanBMAsgmJ9WB0OeLG+VdEqncoxsQ0lkBfwSOXPQIXJhpWM4X84UypAxS", + "zAjy0Yf5Yr5ELmJYRhq/l823yc/bMsxxslNPHkCnq5LFal7VbKBfQX4sD9CuOE5AAhfIv62sH8xYTAI9", + "2PsqqLWK2qanujAyNpCvYSM3p0FHRmUuJd/A7s6trvGzxeJQvL2dZwlhp2N6AaX/EGhnQ1vUaKgKgnGS", + "EEkelSE8sZiGgPw1jgVkiQW5mzw15JaoWlOeYGlE8OEMuTVN7NxeERU9BwLCyRGzKKGDOcfPfcPiSlgi", + "IRG94u9/MdEa8NRgtPE9HYw9LTQXTC9eaAVQv1Jmh65HbKPguIhTyb2aSWAMCg4bMwgoqpOgnjlCYi5J", + "+uB8JzJy0k1yr0tlo5elqBBhl267uoSwxptYHlthIN2YpdZYYD6lm+RaFRbRVWGu84cmReXWecTxBkSe", + "57cN8OfSCtOuZXSdFdEiY/UE+bfLxcI9Wyzu3B7FoF5yfzTcVGaCOvlqyZKPAIfA28rrb8bi1PIa5W6y", + "5P+eXZeGTFpoW0LPPmW14UVKbx3IubJuBvFihfgAqlcux3VUpjY1kzVFdT6E4N0V6XoimaM8IQvg0YeO", + "lKaz31dXl3mRcZ17uklDBwtHRuBw/N0xWJzMx2GBYiFmNxGnm4fomB3F9ricrTLr2Rcio9llbv1iu0yM", + "7yHO1q7Wl7ed64r6Q+ur/h/2sHohblJPn7f0cfTtIiGf9RlIZ4jGfPcvc5afjoaSduiQNAZrfcT/Uvzs", + "t7ThFJU34glY6rGkJqbokjYJr5uf6rgWdsrbxn9Ievv8q+IbQFyn+k5h7k3Ir6a7bnb66O0UXl5VcAmW", + "nDxZeiNhezX6XBt0TCki4eRCM9lNR9heaIMYO36P66BsmMKmJqcktZ8G8XPSBtdB0QCxTcZPbX8jYQ9y", + "Rtjd3rPi6pvbMNZO2Nreh+qqcutBzWn72pvWGcNCZMfRPhc014V56/XMgJP2q1y+6IblzwCsuHs7lHLJ", + "qqNVGAKw9t6P1ScNjeujNWO1TYqFEhaYxz7uZ8zFShEQthH3Z9WygzzBcABOmJs7rZ09i0cx1hVLwaCG", + "U4Bv6M0SdixcNj5chaaEdmyl/EJ50jnV2qhjlnt1k+3bhPHpUkPRwG6yherFQPXrKtucTX/HZ0UcI+A+", + "1a6LDzvbaa602yQ8WkCrY2zHab8wfOX+uwX2uDtSy8nAK9ITKpv5jqh6wOjRYFzVhr3dzrVJEU3GWuXL", + "ngG0vZ3e9dQMlc4a3W/Xq8aRr968nowj+3jfl6F3076enrn+39atmga+iQb2ZCwdIb4W1b1HmWX77hci", + "I3Mz7G2XPaioDZvwsL+c+LSvGNbfrxrcGx4jH0VSMt/zso9XJQg5V2fmBLM5Jmh3t/s3AAD//w==", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/test/parameters/roundtrip/iris/gen/types.gen.go b/internal/test/parameters/roundtrip/iris/gen/types.gen.go index b075b62ba0..4795859510 100644 --- a/internal/test/parameters/roundtrip/iris/gen/types.gen.go +++ b/internal/test/parameters/roundtrip/iris/gen/types.gen.go @@ -93,6 +93,9 @@ type GetHeaderParams struct { // XComplexObject complex object XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + // XPassThrough non-JSON content, bound as the raw header string + XPassThrough *string `json:"X-Pass-Through,omitempty"` + // N1StartingWithNumber name starting with number N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` } diff --git a/internal/test/parameters/roundtrip/param_roundtrip_test.go b/internal/test/parameters/roundtrip/param_roundtrip_test.go index aa027feed8..d836fb46f9 100644 --- a/internal/test/parameters/roundtrip/param_roundtrip_test.go +++ b/internal/test/parameters/roundtrip/param_roundtrip_test.go @@ -440,6 +440,7 @@ func testImpl(t *testing.T, handler http.Handler) { expectedObject2 := paramclient.Object{FirstName: "Marcin", Role: "annoyed_at_swagger"} var expectedPrimitive2 int32 = 100 var expectedN1s = "111" + var expectedPassThrough = "raw header value" t.Run("all params at once", func(t *testing.T) { params := paramclient.GetHeaderParams{ @@ -450,6 +451,7 @@ func testImpl(t *testing.T, handler http.Handler) { XObjectExploded: &expectedObject, XObject: &expectedObject2, XComplexObject: &expectedComplexObject, + XPassThrough: &expectedPassThrough, N1StartingWithNumber: &expectedN1s, } req, err := paramclient.NewGetHeaderRequest(server, ¶ms) @@ -488,6 +490,19 @@ func testImpl(t *testing.T, handler http.Handler) { require.NotNil(t, got.XObject) assert.Equal(t, expectedObject, *got.XObject) }) + + // Regression: pass-through (non-JSON content) header params used to be + // clobbered with the zero value by the wrapper templates' trailing + // assignment, so the handler always saw "". + t.Run("pass-through only", func(t *testing.T) { + params := paramclient.GetHeaderParams{XPassThrough: &expectedPassThrough} + req, err := paramclient.NewGetHeaderRequest(server, ¶ms) + require.NoError(t, err) + var got paramclient.GetHeaderParams + doRoundTrip(t, req, &got) + require.NotNil(t, got.XPassThrough) + assert.Equal(t, expectedPassThrough, *got.XPassThrough) + }) }) // ========================================================================= diff --git a/internal/test/parameters/roundtrip/parameters.yaml b/internal/test/parameters/roundtrip/parameters.yaml index 7c09631965..8e77ecc4a8 100644 --- a/internal/test/parameters/roundtrip/parameters.yaml +++ b/internal/test/parameters/roundtrip/parameters.yaml @@ -509,6 +509,14 @@ paths: application/json: schema: $ref: "#/components/schemas/ComplexObject" + - name: X-Pass-Through + description: non-JSON content, bound as the raw header string + in: header + required: false + content: + text/plain: + schema: + type: string - name: 1-Starting-With-Number description: name starting with number in: header diff --git a/internal/test/parameters/roundtrip/stdhttp/gen/server.gen.go b/internal/test/parameters/roundtrip/stdhttp/gen/server.gen.go index eda0976432..e1dab89be5 100644 --- a/internal/test/parameters/roundtrip/stdhttp/gen/server.gen.go +++ b/internal/test/parameters/roundtrip/stdhttp/gen/server.gen.go @@ -467,6 +467,21 @@ func (siw *ServerInterfaceWrapper) GetHeader(w http.ResponseWriter, r *http.Requ } + // ------------- Optional header parameter "X-Pass-Through" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("X-Pass-Through")]; found { + var XPassThrough string + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "X-Pass-Through", Count: n}) + return + } + + XPassThrough = valueList[0] + + params.XPassThrough = &XPassThrough + + } + // ------------- Optional header parameter "1-Starting-With-Number" ------------- if valueList, found := headers[http.CanonicalHeaderKey("1-Starting-With-Number")]; found { var N1StartingWithNumber string @@ -1383,28 +1398,28 @@ func HandlerWithOptions(si ServerInterface, options StdHTTPServerOptions) http.H // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "3FpLb+M2F/0rwv2+VaFYdqYrdRVMp22ATiatA0yBIAtGuo44lUQOSacJDP33gpRkPa2HLeXRXWJd3sch", - "z6F4qR14LOIsxlhJcHcgUHIWSzT/rGnEQ/wz+0n/4rFYYaz0nwqflMNDQmP9n/QCjIj5/ZkjuCCVoPED", - "JElig4/SE5QrymJw4cKSxq+Vx7LY/Tf0FGjT1I+J/pFpq6cv6UN3B1wwjkLRNLlLvxSNxgofUEBiw6W8", - "8KM0qezhPWMhklg/LJz9X+AGXPifU9TvZMGdL0U+Ar9vqUAf3Nt8sK1DF3HuKm6rOW6okOqKRNgCjA2C", - "hW0PalGNlV1ydWcwpfGG6cEh9TCbnNgEgs+XN9q7okq7hxuUylqjeEQBNjyikOk0rBbLxVIbMo4x4RRc", - "+LBYLlZgAycqMPk72Xyn9Tk7TgSJEv3kAU25ulii51XPBvyK6mN5gHElSIQKhQT3trJ+COch9cxg55tk", - "tVXUNT3VhZGhAa5JG+wcBhMZylgqscXkzq6u8fPl8lC8vZ1TI0JiYjoeY39T7EbDWDRgqBKCCxpRRR+1", - "IT7xkPkI7oaEErPCvNxNXhrYJag2TEREpST4cA52gxOJPSiihudAQDw5YhbFt4gQ5HloWFIJSxVGclD8", - "/S9ptJZ8Gml04T1fGntYWE6YQbiwSkLDpKweuhmxC4LjIs5F92olXmpQYNhagcegCYJ+ZklFhKLxg/UP", - "VYEVb6N7I5WtXlayAkRduuvq4uOGbEN1rMJgvE2XWqvAfIq30bUWFtmnMNf5w7RE7dZ6JOEWZV7n9y2K", - "59IKM65VcJ2JaFGxfgLu7Wq5tM+Xyzt7gBg0JffHFJvKTDArXy1Z8QESH0WXvP6WWpwqr0HuJiv+r7Pr", - "0pBZhbYj9NmnTBteRHqbiVxo6/YkXkyID2T1ynLczCrVpnaw5lDnQxm8O5FuFpI5ygs6QrLrPldn68z6", - "7CtVwdlVbv1iMh6SewyzxWEWsLNbGMn6ofNd+vf6sKbStS3PIa/B0xDIBqmezSHDVAhTvlyXMcuPH2NB", - "O3QKmQK1Iex6KXz2e8Z4iMo73QwoDVhSM0N0xdqI149PdVwHOmVd/g9Rb19/lXwjgOtl3ynIvQn6NXjX", - "j84Qvp2Cy6sSLiJK0Kca36jfrUafG4OOkSLqz060tLr5ANsTbRRix+9xPZCNY9jc4JSo9tMofE7a4Hog", - "GkG22fBp7G/UHwDOBLvbe2Zcc3Mbh9oJW9v7YF2VbgOgOW1fe9M840TKm0Cw7UMw5AbkujDvvP8YcX/2", - "KrcbpiP4MyIvLrcOlVyy6unF+Yi8u7lSa0T6qeujOVPrSxQLxS9ynvq4nyEXakag3wXcH1XLHvAkJx5a", - "fm5udbbOajjKqe4wCgRNOkXyLc1Pyo9Nl0+frs6mlO3UTPmFiah3qo1RzywPatfW2/XTw6WHwsh2bS2r", - "F0tqWNu2jtn8l2i1iFME3Jfad7NQr3aeO+MuCk8W0Mr2wgNxum/kXrnBXUv2uEvImpORd5AnKFv6oU71", - "gDGgwbhuDHu7neu0RJgNtcqnMyNgezu967kRKp01+t+u160jX715PRtG9eP9UITeTft6fuSGf7y2bhv4", - "JhrYs6F0BPk6WPceaZbtu1+pCtKbYWe3GgBFY9iMh/3VzKd9jbD5QDTNeytCcCFQiruOk30dqlCqhT4z", - "R4QvCIXkLvk3AAD//w==", + "3FpNb+M2E/4rAt/3VMiWne1JPQXbbZuim6R1gC0Q5MBI44hbSeSSdDaB4f9ekJQsiZL1YUv56C2xhjPP", + "POQzFIfaooAmjKaQSoH8LeIgGE0F6H9WJGEx/JX9pH4JaCohlepPCU/SYzEmqfpPBBEkWP/+zAD5SEhO", + "0ge02+1cFIIIOGGS0BT56NwR2q+Tx3Lo/VcIJFKmxo+O/pEqq6cr89DfIsYpAy6JAXcRlqKRVMIDcLRz", + "0YU4DxMDKnt4T2kMOFUPC2f/57BGPvqfV+TvZcG9qwIPh28bwiFE/m0+2FWhizh3FbdVjGvChbzECTQQ", + "4yJO46YHVlRt5ZZc3WlOSbqmanBMAsgmJ9WB0OeLG+VdEqncoxsQ0lkBfwSOXPQIXJhpWM4X84UypAxS", + "zAjy0Yf5Yr5ELmJYRhq/l823yc/bMsxxslNPHkCnq5LFal7VbKBfQX4sD9CuOE5AAhfIv62sH8xYTAI9", + "2PsqqLWK2qanujAyNpCvYSM3p0FHRmUuJd/A7s6trvGzxeJQvL2dZwlhp2N6AaX/EGhnQ1vUaKgKgnGS", + "EEkelSE8sZiGgPw1jgVkiQW5mzw15JaoWlOeYGlE8OEMuTVN7NxeERU9BwLCyRGzKKGDOcfPfcPiSlgi", + "IRG94u9/MdEa8NRgtPE9HYw9LTQXTC9eaAVQv1Jmh65HbKPguIhTyb2aSWAMCg4bMwgoqpOgnjlCYi5J", + "+uB8JzJy0k1yr0tlo5elqBBhl267uoSwxptYHlthIN2YpdZYYD6lm+RaFRbRVWGu84cmReXWecTxBkSe", + "57cN8OfSCtOuZXSdFdEiY/UE+bfLxcI9Wyzu3B7FoF5yfzTcVGaCOvlqyZKPAIfA28rrb8bi1PIa5W6y", + "5P+eXZeGTFpoW0LPPmW14UVKbx3IubJuBvFihfgAqlcux3VUpjY1kzVFdT6E4N0V6XoimaM8IQvg0YeO", + "lKaz31dXl3mRcZ17uklDBwtHRuBw/N0xWJzMx2GBYiFmNxGnm4fomB3F9ricrTLr2Rcio9llbv1iu0yM", + "7yHO1q7Wl7ed64r6Q+ur/h/2sHohblJPn7f0cfTtIiGf9RlIZ4jGfPcvc5afjoaSduiQNAZrfcT/Uvzs", + "t7ThFJU34glY6rGkJqbokjYJr5uf6rgWdsrbxn9Ievv8q+IbQFyn+k5h7k3Ir6a7bnb66O0UXl5VcAmW", + "nDxZeiNhezX6XBt0TCki4eRCM9lNR9heaIMYO36P66BsmMKmJqcktZ8G8XPSBtdB0QCxTcZPbX8jYQ9y", + "Rtjd3rPi6pvbMNZO2Nreh+qqcutBzWn72pvWGcNCZMfRPhc014V56/XMgJP2q1y+6IblzwCsuHs7lHLJ", + "qqNVGAKw9t6P1ScNjeujNWO1TYqFEhaYxz7uZ8zFShEQthH3Z9WygzzBcABOmJs7rZ09i0cx1hVLwaCG", + "U4Bv6M0SdixcNj5chaaEdmyl/EJ50jnV2qhjlnt1k+3bhPHpUkPRwG6yherFQPXrKtucTX/HZ0UcI+A+", + "1a6LDzvbaa602yQ8WkCrY2zHab8wfOX+uwX2uDtSy8nAK9ITKpv5jqh6wOjRYFzVhr3dzrVJEU3GWuXL", + "ngG0vZ3e9dQMlc4a3W/Xq8aRr968nowj+3jfl6F3076enrn+39atmga+iQb2ZCwdIb4W1b1HmWX77hci", + "I3Mz7G2XPaioDZvwsL+c+LSvGNbfrxrcGx4jH0VSMt/zso9XJQg5V2fmBLM5Jmh3t/s3AAD//w==", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/test/parameters/roundtrip/stdhttp/gen/types.gen.go b/internal/test/parameters/roundtrip/stdhttp/gen/types.gen.go index 132c9c3499..e203ec106c 100644 --- a/internal/test/parameters/roundtrip/stdhttp/gen/types.gen.go +++ b/internal/test/parameters/roundtrip/stdhttp/gen/types.gen.go @@ -93,6 +93,9 @@ type GetHeaderParams struct { // XComplexObject complex object XComplexObject *ComplexObject `json:"X-Complex-Object,omitempty"` + // XPassThrough non-JSON content, bound as the raw header string + XPassThrough *string `json:"X-Pass-Through,omitempty"` + // N1StartingWithNumber name starting with number N1StartingWithNumber *string `json:"1-Starting-With-Number,omitempty"` } diff --git a/internal/test/references/external/path_item_refs/bionicle/bionicle.gen.go b/internal/test/references/external/path_item_refs/bionicle/bionicle.gen.go index cc9d332eae..fe26501dc6 100644 --- a/internal/test/references/external/path_item_refs/bionicle/bionicle.gen.go +++ b/internal/test/references/external/path_item_refs/bionicle/bionicle.gen.go @@ -293,6 +293,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/references/external/path_item_refs/common/common.gen.go b/internal/test/references/external/path_item_refs/common/common.gen.go index 91da73aeb9..ffbf011010 100644 --- a/internal/test/references/external/path_item_refs/common/common.gen.go +++ b/internal/test/references/external/path_item_refs/common/common.gen.go @@ -171,6 +171,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/references/external/path_item_refs/fooservice/fooservice.gen.go b/internal/test/references/external/path_item_refs/fooservice/fooservice.gen.go index fa95a0dcee..37e19cf679 100644 --- a/internal/test/references/external/path_item_refs/fooservice/fooservice.gen.go +++ b/internal/test/references/external/path_item_refs/fooservice/fooservice.gen.go @@ -253,6 +253,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/references/external/path_item_response_qualification/gen/spec_base/issue.gen.go b/internal/test/references/external/path_item_response_qualification/gen/spec_base/issue.gen.go index c36883c4e2..f3c56a9c1b 100644 --- a/internal/test/references/external/path_item_response_qualification/gen/spec_base/issue.gen.go +++ b/internal/test/references/external/path_item_response_qualification/gen/spec_base/issue.gen.go @@ -649,6 +649,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/references/external/path_item_response_qualification/gen/spec_ext/issue.gen.go b/internal/test/references/external/path_item_response_qualification/gen/spec_ext/issue.gen.go index 18d5045500..db4a685356 100644 --- a/internal/test/references/external/path_item_response_qualification/gen/spec_ext/issue.gen.go +++ b/internal/test/references/external/path_item_response_qualification/gen/spec_ext/issue.gen.go @@ -173,6 +173,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/references/external/removed_ref/gen/spec_base/issue.gen.go b/internal/test/references/external/removed_ref/gen/spec_base/issue.gen.go index 6d31cc8043..3268820f34 100644 --- a/internal/test/references/external/removed_ref/gen/spec_base/issue.gen.go +++ b/internal/test/references/external/removed_ref/gen/spec_base/issue.gen.go @@ -287,6 +287,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/references/external/removed_ref/gen/spec_ext/issue.gen.go b/internal/test/references/external/removed_ref/gen/spec_ext/issue.gen.go index b7809cd969..058e91a802 100644 --- a/internal/test/references/external/removed_ref/gen/spec_ext/issue.gen.go +++ b/internal/test/references/external/removed_ref/gen/spec_ext/issue.gen.go @@ -185,6 +185,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/references/multipackage/default_response/gen/api/api.gen.go b/internal/test/references/multipackage/default_response/gen/api/api.gen.go index 43b8c3239c..3807ae73cb 100644 --- a/internal/test/references/multipackage/default_response/gen/api/api.gen.go +++ b/internal/test/references/multipackage/default_response/gen/api/api.gen.go @@ -254,6 +254,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/references/multipackage/response_cast/gen/spec_base/issue.gen.go b/internal/test/references/multipackage/response_cast/gen/spec_base/issue.gen.go index 95fefde7d0..94baaa8c59 100644 --- a/internal/test/references/multipackage/response_cast/gen/spec_base/issue.gen.go +++ b/internal/test/references/multipackage/response_cast/gen/spec_base/issue.gen.go @@ -237,6 +237,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/references/multipackage/response_cast/gen/spec_other/issue.gen.go b/internal/test/references/multipackage/response_cast/gen/spec_other/issue.gen.go index 79deccb92b..1840d9f1c9 100644 --- a/internal/test/references/multipackage/response_cast/gen/spec_other/issue.gen.go +++ b/internal/test/references/multipackage/response_cast/gen/spec_other/issue.gen.go @@ -229,6 +229,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/schemas/deprecated/deprecated.gen.go b/internal/test/schemas/deprecated/deprecated.gen.go index 51b76c4577..26bade4661 100644 --- a/internal/test/schemas/deprecated/deprecated.gen.go +++ b/internal/test/schemas/deprecated/deprecated.gen.go @@ -1975,6 +1975,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/schemas/objects/objects.gen.go b/internal/test/schemas/objects/objects.gen.go index 7f621e9795..dea233f151 100644 --- a/internal/test/schemas/objects/objects.gen.go +++ b/internal/test/schemas/objects/objects.gen.go @@ -935,6 +935,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/servers/middleware/iris/config.yaml b/internal/test/servers/middleware/iris/config.yaml new file mode 100644 index 0000000000..be1895acbd --- /dev/null +++ b/internal/test/servers/middleware/iris/config.yaml @@ -0,0 +1,6 @@ +# yaml-language-server: $schema=../../../../../configuration-schema.json +package: serversmiddlewareiris +generate: + iris-server: true + models: true +output: middleware.gen.go diff --git a/internal/test/servers/middleware/iris/doc.go b/internal/test/servers/middleware/iris/doc.go new file mode 100644 index 0000000000..7908ac6728 --- /dev/null +++ b/internal/test/servers/middleware/iris/doc.go @@ -0,0 +1,3 @@ +package serversmiddlewareiris + +//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml diff --git a/internal/test/servers/middleware/iris/main_test.go b/internal/test/servers/middleware/iris/main_test.go new file mode 100644 index 0000000000..a9e19caf00 --- /dev/null +++ b/internal/test/servers/middleware/iris/main_test.go @@ -0,0 +1,41 @@ +package serversmiddlewareiris + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/kataras/iris/v12" + "github.com/stretchr/testify/assert" +) + +type impl struct{} + +// (GET /test) +func (i *impl) Test(ctx iris.Context) { + ctx.StatusCode(http.StatusOK) +} + +// IrisServerOptions.Middlewares used to be silently ignored by +// RegisterHandlersWithOptions; this asserts they actually run. +func TestMiddlewaresAreApplied(t *testing.T) { + server := &impl{} + + calls := 0 + app := iris.New() + RegisterHandlersWithOptions(app, server, IrisServerOptions{ + Middlewares: []MiddlewareFunc{ + func(ctx iris.Context) { + calls++ + ctx.Next() + }, + }, + }) + + req := httptest.NewRequest(http.MethodGet, "/test", nil) + rec := httptest.NewRecorder() + app.ServeHTTP(rec, req) + + assert.Equal(t, http.StatusOK, rec.Code) + assert.Equal(t, 1, calls) +} diff --git a/internal/test/servers/middleware/iris/middleware.gen.go b/internal/test/servers/middleware/iris/middleware.gen.go new file mode 100644 index 0000000000..8086e994ae --- /dev/null +++ b/internal/test/servers/middleware/iris/middleware.gen.go @@ -0,0 +1,55 @@ +// Package serversmiddlewareiris provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.0.0-00010101000000-000000000000 DO NOT EDIT. +package serversmiddlewareiris + +import ( + "github.com/kataras/iris/v12" +) + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (GET /test) + Test(ctx iris.Context) +} + +// ServerInterfaceWrapper converts echo contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface +} + +type MiddlewareFunc iris.Handler + +// Test converts iris context to params. +func (w *ServerInterfaceWrapper) Test(ctx iris.Context) { + + // Invoke the callback with all the unmarshaled arguments + w.Handler.Test(ctx) +} + +// IrisServerOption is the option for iris server +type IrisServerOptions struct { + BaseURL string + Middlewares []MiddlewareFunc +} + +// RegisterHandlers creates http.Handler with routing matching OpenAPI spec. +func RegisterHandlers(router *iris.Application, si ServerInterface) { + RegisterHandlersWithOptions(router, si, IrisServerOptions{}) +} + +// RegisterHandlersWithOptions creates http.Handler with additional options +func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) { + for _, m := range options.Middlewares { + router.Use(m) + } + + wrapper := ServerInterfaceWrapper{ + Handler: si, + } + + router.Get(options.BaseURL+"/test", wrapper.Test) + + router.Build() +} diff --git a/internal/test/servers/middleware/iris/spec.yaml b/internal/test/servers/middleware/iris/spec.yaml new file mode 100644 index 0000000000..a5c46d2869 --- /dev/null +++ b/internal/test/servers/middleware/iris/spec.yaml @@ -0,0 +1,11 @@ +openapi: "3.0.1" +info: + title: Iris middleware test + version: 1.0.0 +paths: + /test: + get: + operationId: test + responses: + 200: + description: good diff --git a/internal/test/servers/routers/smoke/chi/out.gen.go b/internal/test/servers/routers/smoke/chi/out.gen.go index 29b13ef98f..09e3483a14 100644 --- a/internal/test/servers/routers/smoke/chi/out.gen.go +++ b/internal/test/servers/routers/smoke/chi/out.gen.go @@ -377,6 +377,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/servers/routers/smoke/fiber/out.gen.go b/internal/test/servers/routers/smoke/fiber/out.gen.go index d2867215ad..03c0d82173 100644 --- a/internal/test/servers/routers/smoke/fiber/out.gen.go +++ b/internal/test/servers/routers/smoke/fiber/out.gen.go @@ -261,10 +261,10 @@ func (sh *strictHandler) GetGetMultibody(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(GetGetMultibodyResponseObject); ok { if err := validResponse.VisitGetGetMultibodyResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -286,10 +286,10 @@ func (sh *strictHandler) GetObject(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(GetObjectResponseObject); ok { if err := validResponse.VisitGetObjectResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -334,10 +334,10 @@ func (sh *strictHandler) PostPostMultibody(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(PostPostMultibodyResponseObject); ok { if err := validResponse.VisitPostPostMultibodyResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -368,10 +368,10 @@ func (sh *strictHandler) PostPostObject(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(PostPostObjectResponseObject); ok { if err := validResponse.VisitPostPostObjectResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) diff --git a/internal/test/servers/routers/smoke/gorilla/out.gen.go b/internal/test/servers/routers/smoke/gorilla/out.gen.go index 254b183a01..985d886e6e 100644 --- a/internal/test/servers/routers/smoke/gorilla/out.gen.go +++ b/internal/test/servers/routers/smoke/gorilla/out.gen.go @@ -348,6 +348,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/servers/routers/smoke/iris/out.gen.go b/internal/test/servers/routers/smoke/iris/out.gen.go index d57447cbae..9d5e46bb0b 100644 --- a/internal/test/servers/routers/smoke/iris/out.gen.go +++ b/internal/test/servers/routers/smoke/iris/out.gen.go @@ -6,6 +6,7 @@ package iris import ( "context" "errors" + "fmt" "io" "net/http" "strings" @@ -95,6 +96,9 @@ func RegisterHandlers(router *iris.Application, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) { + for _, m := range options.Middlewares { + router.Use(m) + } wrapper := ServerInterfaceWrapper{ Handler: si, @@ -208,15 +212,15 @@ func (sh *strictHandler) GetGetMultibody(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(GetGetMultibodyResponseObject); ok { if err := validResponse.VisitGetGetMultibodyResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -235,15 +239,15 @@ func (sh *strictHandler) GetObject(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(GetObjectResponseObject); ok { if err := validResponse.VisitGetObjectResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -287,15 +291,15 @@ func (sh *strictHandler) PostPostMultibody(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(PostPostMultibodyResponseObject); ok { if err := validResponse.VisitPostPostMultibodyResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -324,15 +328,15 @@ func (sh *strictHandler) PostPostObject(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(PostPostObjectResponseObject); ok { if err := validResponse.VisitPostPostObjectResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } diff --git a/internal/test/servers/routers/smoke/std-http/out.gen.go b/internal/test/servers/routers/smoke/std-http/out.gen.go index 4fc5ab39c0..d4f928d3dc 100644 --- a/internal/test/servers/routers/smoke/std-http/out.gen.go +++ b/internal/test/servers/routers/smoke/std-http/out.gen.go @@ -352,6 +352,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/servers/strict/buffering/serversstrictbuffering.gen.go b/internal/test/servers/strict/buffering/serversstrictbuffering.gen.go index a6400da7ae..b17dd30580 100644 --- a/internal/test/servers/strict/buffering/serversstrictbuffering.gen.go +++ b/internal/test/servers/strict/buffering/serversstrictbuffering.gen.go @@ -424,6 +424,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/servers/strict/chi/server.gen.go b/internal/test/servers/strict/chi/server.gen.go index aff67e9c59..87dbbca6ab 100644 --- a/internal/test/servers/strict/chi/server.gen.go +++ b/internal/test/servers/strict/chi/server.gen.go @@ -1402,6 +1402,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/servers/strict/fiber/fiber_strict_test.go b/internal/test/servers/strict/fiber/fiber_strict_test.go index d47e8aebfc..054ac50cdc 100644 --- a/internal/test/servers/strict/fiber/fiber_strict_test.go +++ b/internal/test/servers/strict/fiber/fiber_strict_test.go @@ -2,7 +2,9 @@ package api import ( "bytes" + "context" "encoding/json" + "errors" "io" "mime" "mime/multipart" @@ -28,6 +30,26 @@ func TestFiberServer(t *testing.T) { testImpl(t, adaptor.FiberApp(r)) } +type erroringServer struct{ StrictServer } + +func (erroringServer) JSONExample(ctx context.Context, request JSONExampleRequestObject) (JSONExampleResponseObject, error) { + return nil, errors.New("handler failure") +} + +// Errors returned by strict handlers used to be wrapped in +// fiber.NewError(StatusBadRequest, ...); they must reach fiber's error +// chain untouched, where the default handler reports them as 500. +func TestFiberHandlerErrorIsServerError(t *testing.T) { + strictHandler := NewStrictHandler(erroringServer{}, nil) + r := fiber.New() + RegisterHandlers(r, strictHandler) + + value := "123" + requestBody := clientAPI.Example{Value: &value} + rr := testutil.NewRequest().Post("/json").WithJsonBody(requestBody).GoWithHTTPHandler(t, adaptor.FiberApp(r)).Recorder + assert.Equal(t, http.StatusInternalServerError, rr.Code) +} + func testImpl(t *testing.T, handler http.Handler) { t.Run("JSONExample", func(t *testing.T) { value := "123" diff --git a/internal/test/servers/strict/fiber/server.gen.go b/internal/test/servers/strict/fiber/server.gen.go index e66757304e..19532d2dbd 100644 --- a/internal/test/servers/strict/fiber/server.gen.go +++ b/internal/test/servers/strict/fiber/server.gen.go @@ -385,8 +385,7 @@ func (siw *ServerInterfaceWrapper) HeadersExample(c *fiber.Ctx) error { params.Header1 = Header1 } else { - err = fmt.Errorf("Header parameter header1 is required, but not found: %w", err) - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return fiber.NewError(fiber.StatusBadRequest, "Header parameter header1 is required, but not found") } // ------------- Optional header parameter "header2" ------------- @@ -1231,10 +1230,10 @@ func (sh *strictHandler) JSONExample(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(JSONExampleResponseObject); ok { if err := validResponse.VisitJSONExampleResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1258,10 +1257,10 @@ func (sh *strictHandler) MultipartExample(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(MultipartExampleResponseObject); ok { if err := validResponse.VisitMultipartExampleResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1291,10 +1290,10 @@ func (sh *strictHandler) MultipartRelatedExample(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(MultipartRelatedExampleResponseObject); ok { if err := validResponse.VisitMultipartRelatedExampleResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1348,10 +1347,10 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(MultipleRequestAndResponseTypesResponseObject); ok { if err := validResponse.VisitMultipleRequestAndResponseTypesResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1373,10 +1372,10 @@ func (sh *strictHandler) NoContentHeaders(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(NoContentHeadersResponseObject); ok { if err := validResponse.VisitNoContentHeadersResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1404,10 +1403,10 @@ func (sh *strictHandler) RequiredJSONBody(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(RequiredJSONBodyResponseObject); ok { if err := validResponse.VisitRequiredJSONBodyResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1433,10 +1432,10 @@ func (sh *strictHandler) RequiredTextBody(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(RequiredTextBodyResponseObject); ok { if err := validResponse.VisitRequiredTextBodyResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1460,10 +1459,10 @@ func (sh *strictHandler) ReservedGoKeywordParameters(ctx *fiber.Ctx, pType strin response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(ReservedGoKeywordParametersResponseObject); ok { if err := validResponse.VisitReservedGoKeywordParametersResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1494,10 +1493,10 @@ func (sh *strictHandler) ReusableResponses(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(ReusableResponsesResponseObject); ok { if err := validResponse.VisitReusableResponsesResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1530,10 +1529,10 @@ func (sh *strictHandler) SameNameParamAndBodyProperty(ctx *fiber.Ctx, name strin response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(SameNameParamAndBodyPropertyResponseObject); ok { if err := validResponse.VisitSameNameParamAndBodyPropertyResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1561,10 +1560,10 @@ func (sh *strictHandler) TextExample(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(TextExampleResponseObject); ok { if err := validResponse.VisitTextExampleResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1588,10 +1587,10 @@ func (sh *strictHandler) UnknownExample(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(UnknownExampleResponseObject); ok { if err := validResponse.VisitUnknownExampleResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1617,10 +1616,10 @@ func (sh *strictHandler) UnspecifiedContentType(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(UnspecifiedContentTypeResponseObject); ok { if err := validResponse.VisitUnspecifiedContentTypeResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1648,10 +1647,10 @@ func (sh *strictHandler) URLEncodedExample(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(URLEncodedExampleResponseObject); ok { if err := validResponse.VisitURLEncodedExampleResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1684,10 +1683,10 @@ func (sh *strictHandler) HeadersExample(ctx *fiber.Ctx, params HeadersExamplePar response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(HeadersExampleResponseObject); ok { if err := validResponse.VisitHeadersExampleResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) @@ -1718,10 +1717,10 @@ func (sh *strictHandler) UnionExample(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(UnionExampleResponseObject); ok { if err := validResponse.VisitUnionExampleResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) diff --git a/internal/test/servers/strict/gorilla/server.gen.go b/internal/test/servers/strict/gorilla/server.gen.go index f9ef3f7f3b..d5d7c8412c 100644 --- a/internal/test/servers/strict/gorilla/server.gen.go +++ b/internal/test/servers/strict/gorilla/server.gen.go @@ -1301,6 +1301,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/internal/test/servers/strict/iris/iris_strict_test.go b/internal/test/servers/strict/iris/iris_strict_test.go new file mode 100644 index 0000000000..203c4a5ff8 --- /dev/null +++ b/internal/test/servers/strict/iris/iris_strict_test.go @@ -0,0 +1,33 @@ +package api + +import ( + "context" + "errors" + "net/http" + "testing" + + "github.com/kataras/iris/v12" + "github.com/stretchr/testify/assert" + + clientAPI "github.com/oapi-codegen/oapi-codegen/v2/internal/test/servers/strict/client" + "github.com/oapi-codegen/testutil" +) + +type erroringServer struct{ StrictServer } + +func (erroringServer) JSONExample(ctx context.Context, request JSONExampleRequestObject) (JSONExampleResponseObject, error) { + return nil, errors.New("handler failure") +} + +// Errors returned by strict handlers used to be reported via +// ctx.StopWithError(StatusBadRequest, ...); they are server-side +// failures and must be reported as 500. +func TestIrisHandlerErrorIsServerError(t *testing.T) { + app := iris.New() + RegisterHandlers(app, NewStrictHandler(erroringServer{}, nil)) + + value := "123" + requestBody := clientAPI.Example{Value: &value} + rr := testutil.NewRequest().Post("/json").WithJsonBody(requestBody).GoWithHTTPHandler(t, app).Recorder + assert.Equal(t, http.StatusInternalServerError, rr.Code) +} diff --git a/internal/test/servers/strict/iris/server.gen.go b/internal/test/servers/strict/iris/server.gen.go index ca61a49060..e6aefeeb23 100644 --- a/internal/test/servers/strict/iris/server.gen.go +++ b/internal/test/servers/strict/iris/server.gen.go @@ -283,6 +283,9 @@ func RegisterHandlers(router *iris.Application, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) { + for _, m := range options.Middlewares { + router.Use(m) + } wrapper := ServerInterfaceWrapper{ Handler: si, @@ -1044,15 +1047,15 @@ func (sh *strictHandler) JSONExample(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(JSONExampleResponseObject); ok { if err := validResponse.VisitJSONExampleResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1078,15 +1081,15 @@ func (sh *strictHandler) MultipartExample(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(MultipartExampleResponseObject); ok { if err := validResponse.VisitMultipartExampleResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1115,15 +1118,15 @@ func (sh *strictHandler) MultipartRelatedExample(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(MultipartRelatedExampleResponseObject); ok { if err := validResponse.VisitMultipartRelatedExampleResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1189,15 +1192,15 @@ func (sh *strictHandler) MultipleRequestAndResponseTypes(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(MultipleRequestAndResponseTypesResponseObject); ok { if err := validResponse.VisitMultipleRequestAndResponseTypesResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1216,15 +1219,15 @@ func (sh *strictHandler) NoContentHeaders(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(NoContentHeadersResponseObject); ok { if err := validResponse.VisitNoContentHeadersResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1250,15 +1253,15 @@ func (sh *strictHandler) RequiredJSONBody(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(RequiredJSONBodyResponseObject); ok { if err := validResponse.VisitRequiredJSONBodyResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1285,15 +1288,15 @@ func (sh *strictHandler) RequiredTextBody(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(RequiredTextBodyResponseObject); ok { if err := validResponse.VisitRequiredTextBodyResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1314,15 +1317,15 @@ func (sh *strictHandler) ReservedGoKeywordParameters(ctx iris.Context, pType str response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(ReservedGoKeywordParametersResponseObject); ok { if err := validResponse.VisitReservedGoKeywordParametersResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1351,15 +1354,15 @@ func (sh *strictHandler) ReusableResponses(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(ReusableResponsesResponseObject); ok { if err := validResponse.VisitReusableResponsesResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1390,15 +1393,15 @@ func (sh *strictHandler) SameNameParamAndBodyProperty(ctx iris.Context, name str response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(SameNameParamAndBodyPropertyResponseObject); ok { if err := validResponse.VisitSameNameParamAndBodyPropertyResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1427,15 +1430,15 @@ func (sh *strictHandler) TextExample(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(TextExampleResponseObject); ok { if err := validResponse.VisitTextExampleResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1456,15 +1459,15 @@ func (sh *strictHandler) UnknownExample(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(UnknownExampleResponseObject); ok { if err := validResponse.VisitUnknownExampleResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1487,15 +1490,15 @@ func (sh *strictHandler) UnspecifiedContentType(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(UnspecifiedContentTypeResponseObject); ok { if err := validResponse.VisitUnspecifiedContentTypeResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1525,15 +1528,15 @@ func (sh *strictHandler) URLEncodedExample(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(URLEncodedExampleResponseObject); ok { if err := validResponse.VisitURLEncodedExampleResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1564,15 +1567,15 @@ func (sh *strictHandler) HeadersExample(ctx iris.Context, params HeadersExampleP response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(HeadersExampleResponseObject); ok { if err := validResponse.VisitHeadersExampleResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } @@ -1601,15 +1604,15 @@ func (sh *strictHandler) UnionExample(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(UnionExampleResponseObject); ok { if err := validResponse.VisitUnionExampleResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } diff --git a/internal/test/servers/strict/multicontent/fiber/serversstrictmulticontentfiber.gen.go b/internal/test/servers/strict/multicontent/fiber/serversstrictmulticontentfiber.gen.go index 215b87e819..2383875c28 100644 --- a/internal/test/servers/strict/multicontent/fiber/serversstrictmulticontentfiber.gen.go +++ b/internal/test/servers/strict/multicontent/fiber/serversstrictmulticontentfiber.gen.go @@ -425,10 +425,10 @@ func (sh *strictHandler) Test(ctx *fiber.Ctx) error { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.(TestResponseObject); ok { if err := validResponse.VisitTestResponse(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) diff --git a/internal/test/servers/strict/multicontent/iris/serversstrictmulticontentiris.gen.go b/internal/test/servers/strict/multicontent/iris/serversstrictmulticontentiris.gen.go index 30c51c90ed..ccaec9ff4f 100644 --- a/internal/test/servers/strict/multicontent/iris/serversstrictmulticontentiris.gen.go +++ b/internal/test/servers/strict/multicontent/iris/serversstrictmulticontentiris.gen.go @@ -331,6 +331,9 @@ func RegisterHandlers(router *iris.Application, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) { + for _, m := range options.Middlewares { + router.Use(m) + } wrapper := ServerInterfaceWrapper{ Handler: si, @@ -408,15 +411,15 @@ func (sh *strictHandler) Test(ctx iris.Context) { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.(TestResponseObject); ok { if err := validResponse.VisitTestResponse(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } } diff --git a/internal/test/servers/strict/stdhttp/server.gen.go b/internal/test/servers/strict/stdhttp/server.gen.go index a390586d49..62e17e8718 100644 --- a/internal/test/servers/strict/stdhttp/server.gen.go +++ b/internal/test/servers/strict/stdhttp/server.gen.go @@ -1294,6 +1294,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go index 092e2e1b69..ea29b723ee 100644 --- a/pkg/codegen/codegen.go +++ b/pkg/codegen/codegen.go @@ -557,6 +557,15 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { } } + // Webhook receiver (fiber v3) -- (c fiber.Ctx) error signature. + var fiberV3WebhookReceiverOut string + if opts.Generate.FiberV3Server && len(webhookOps) > 0 { + fiberV3WebhookReceiverOut, err = GenerateFiberV3Receiver(t, "Webhook", webhookOps) + if err != nil { + return "", fmt.Errorf("error generating fiber v3 webhook receiver: %w", err) + } + } + // Webhook receiver (iris) -- (ctx iris.Context) signature. var irisWebhookReceiverOut string if opts.Generate.IrisServer && len(webhookOps) > 0 { @@ -642,6 +651,15 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { } } + // Callback receiver (fiber v3). + var fiberV3CallbackReceiverOut string + if opts.Generate.FiberV3Server && len(callbackOps) > 0 { + fiberV3CallbackReceiverOut, err = GenerateFiberV3Receiver(t, "Callback", callbackOps) + if err != nil { + return "", fmt.Errorf("error generating fiber v3 callback receiver: %w", err) + } + } + // Callback receiver (iris). var irisCallbackReceiverOut string if opts.Generate.IrisServer && len(callbackOps) > 0 { @@ -816,6 +834,18 @@ func Generate(spec *openapi3.T, opts Configuration) (string, error) { if err != nil { return "", fmt.Errorf("error writing server path handlers: %w", err) } + if fiberV3WebhookReceiverOut != "" { + _, err = w.WriteString(fiberV3WebhookReceiverOut) + if err != nil { + return "", fmt.Errorf("error writing fiber v3 webhook receiver: %w", err) + } + } + if fiberV3CallbackReceiverOut != "" { + _, err = w.WriteString(fiberV3CallbackReceiverOut) + if err != nil { + return "", fmt.Errorf("error writing fiber v3 callback receiver: %w", err) + } + } } if opts.Generate.GinServer { diff --git a/pkg/codegen/operations.go b/pkg/codegen/operations.go index af64daf8f5..2235c5ceb9 100644 --- a/pkg/codegen/operations.go +++ b/pkg/codegen/operations.go @@ -2029,6 +2029,14 @@ func GenerateFiberReceiver(t *template.Template, prefix string, ops []OperationD return GenerateTemplates([]string{"fiber/fiber-receiver.tmpl"}, t, NewReceiverTemplateData(prefix, ops)) } +// GenerateFiberV3Receiver renders the fiber (v3) receiver template. +// Same shape as v2 but with `fiber.Ctx` (interface, by value) -- the +// only API difference between fiber v2 and v3 that affects the +// receiver. +func GenerateFiberV3Receiver(t *template.Template, prefix string, ops []OperationDefinition) (string, error) { + return GenerateTemplates([]string{"fiber-v3/fiber-receiver.tmpl"}, t, NewReceiverTemplateData(prefix, ops)) +} + // GenerateIrisReceiver renders the iris receiver template. Iris's // handler shape is `(ctx iris.Context)` (no error return); binding // errors set ctx.StatusCode(400) plus ctx.WriteString and return. diff --git a/pkg/codegen/templates/chi/chi-middleware.tmpl b/pkg/codegen/templates/chi/chi-middleware.tmpl index b8392427f9..651e389d83 100644 --- a/pkg/codegen/templates/chi/chi-middleware.tmpl +++ b/pkg/codegen/templates/chi/chi-middleware.tmpl @@ -104,7 +104,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ } {{if .IsPassThrough}} - params.{{.GoName}} = {{if .HasOptionalPointer }}&{{end}}valueList[0] + {{.GoName}} = valueList[0] {{end}} {{if .IsJson}} diff --git a/pkg/codegen/templates/echo/echo-wrappers.tmpl b/pkg/codegen/templates/echo/echo-wrappers.tmpl index 7d19c91d58..7766928cab 100644 --- a/pkg/codegen/templates/echo/echo-wrappers.tmpl +++ b/pkg/codegen/templates/echo/echo-wrappers.tmpl @@ -72,7 +72,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for {{.ParamName}}, got %d", n)) } {{if .IsPassThrough}} - params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}valueList[0] + {{.GoName}} = valueList[0] {{end}} {{if .IsJson}} err = json.Unmarshal([]byte(valueList[0]), &{{.GoName}}) diff --git a/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl b/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl index 8fcab2c66c..9f8142ee09 100644 --- a/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl +++ b/pkg/codegen/templates/echo/v5/echo-wrappers.tmpl @@ -72,7 +72,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx *echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Expected one value for {{.ParamName}}, got %d", n)) } {{if .IsPassThrough}} - params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}valueList[0] + {{.GoName}} = valueList[0] {{end}} {{if .IsJson}} err = json.Unmarshal([]byte(valueList[0]), &{{.GoName}}) diff --git a/pkg/codegen/templates/fiber-v3/fiber-middleware.tmpl b/pkg/codegen/templates/fiber-v3/fiber-middleware.tmpl index 39cfdd7084..042a15802b 100644 --- a/pkg/codegen/templates/fiber-v3/fiber-middleware.tmpl +++ b/pkg/codegen/templates/fiber-v3/fiber-middleware.tmpl @@ -47,9 +47,11 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c fiber.Ctx) error { {{end}} +{{if opts.Compatibility.EnableAuthScopesOnContext -}} {{range .SecurityDefinitions}} c.RequestCtx().SetUserValue(({{.ProviderName | sanitizeGoIdentity | ucFirst}}Scopes), {{toStringArray .Scopes}}) {{end}} +{{- end}} {{if .RequiresParamObject}} // Parameter object where we will unmarshal all parameters from the context @@ -84,9 +86,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c fiber.Ctx) error { params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}value {{end}} }{{if .Required}} else { - err = fmt.Errorf("Query argument {{.ParamName}} is required, but not found") - c.Status(fiber.StatusBadRequest).JSON(err) - return err + return fiber.NewError(fiber.StatusBadRequest, "Query argument {{.ParamName}} is required, but not found") }{{end}} {{end}} {{if .IsStyled}} @@ -109,7 +109,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c fiber.Ctx) error { } {{if .IsPassThrough}} - params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}valueList[0] + {{.GoName}} = valueList[0] {{end}} {{if .IsJson}} @@ -129,8 +129,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c fiber.Ctx) error { params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}{{.GoName}} } {{if .Required}}else { - err = fmt.Errorf("Header parameter {{.ParamName}} is required, but not found: %w", err) - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return fiber.NewError(fiber.StatusBadRequest, "Header parameter {{.ParamName}} is required, but not found") }{{end}} {{end}} diff --git a/pkg/codegen/templates/fiber-v3/fiber-receiver.tmpl b/pkg/codegen/templates/fiber-v3/fiber-receiver.tmpl new file mode 100644 index 0000000000..f28d2bdf42 --- /dev/null +++ b/pkg/codegen/templates/fiber-v3/fiber-receiver.tmpl @@ -0,0 +1,100 @@ +// {{.Prefix}}ReceiverInterface represents handlers for receiving inbound +// {{.PrefixLower}} requests. Each {{.PrefixLower}} becomes a Handle*{{.Prefix}} +// method that the implementation fills in. The caller mounts the per- +// {{.PrefixLower}} fiber.Handler returned by {Op}{{.Prefix}}Handler at +// whatever URL path they advertise to senders. +type {{.Prefix}}ReceiverInterface interface { +{{range .Operations -}} +{{.SummaryAsComment ""}} +// Handle{{.OperationId}}{{$.Prefix}} handles the {{.Method}} {{$.PrefixLower}} for {{.SourceName}}. +Handle{{.OperationId}}{{$.Prefix}}(c fiber.Ctx{{if .RequiresParamObject}}, params {{.OperationId}}Params{{end}}) error +{{end}} +} + +{{range .Operations -}} +{{$opid := .OperationId -}} +{{$srcName := .SourceName -}} +// {{$opid}}{{$.Prefix}}Handler returns the fiber.Handler for the {{$srcName}} {{$.PrefixLower}}. +// Mount this at the URL path advertised to {{$.PrefixLower}} senders. Errors +// during parameter binding are returned via fiber.NewError so fiber's +// error chain reports them as 400. Per-handler middleware is not +// generated here; use fiber.App.Use() for engine-level middleware. +func {{$opid}}{{$.Prefix}}Handler(si {{$.Prefix}}ReceiverInterface) fiber.Handler { + return func(c fiber.Ctx) error { +{{- if .RequiresParamObject}} + var err error + _ = err + + // Parameter object where we will unmarshal all parameters from the context. + var params {{$opid}}Params +{{if .QueryParams}} + var query url.Values + query, err = url.ParseQuery(string(c.Request().URI().QueryString())) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for query string: %w", err).Error()) + } +{{end}} +{{range $paramIdx, $param := .QueryParams}} + // ------------- {{if .Required}}Required{{else}}Optional{{end}} query parameter "{{.ParamName}}" ------------- + {{if .IsStyled}} + err = runtime.BindQueryParameterWithOptions("{{.Style}}", {{.Explode}}, {{.Required}}, "{{.ParamName}}", query, ¶ms.{{.GoName}}, runtime.BindQueryParameterOptions{Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %w", err).Error()) + } + {{else}} + if paramValue := c.Query("{{.ParamName}}"); paramValue != "" { + {{if .IsPassThrough}} + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}paramValue + {{end}} + {{if .IsJson}} + var value {{.TypeDef}} + err = json.Unmarshal([]byte(paramValue), &value) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unmarshaling parameter '{{.ParamName}}' as JSON: %w", err).Error()) + } + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}value + {{end}} + }{{if .Required}} else { + return fiber.NewError(fiber.StatusBadRequest, "Query argument {{.ParamName}} is required, but not found") + }{{end}} + {{end}} +{{end}} +{{if .HeaderParams}} + headers := c.GetReqHeaders() +{{range $paramIdx, $param := .HeaderParams}} + // ------------- {{if .Required}}Required{{else}}Optional{{end}} header parameter "{{.ParamName}}" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("{{.ParamName}}")]; found { + var {{.GoName}} {{.TypeDef}} + n := len(valueList) + if n != 1 { + return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Too many values for header {{.ParamName}}, 1 is required, but %d found", n)) + } + {{if .IsPassThrough}} + {{.GoName}} = valueList[0] + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}{{.GoName}} + {{end}} + {{if .IsJson}} + err = json.Unmarshal([]byte(valueList[0]), &{{.GoName}}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Error unmarshaling parameter '{{.ParamName}}' as JSON: %w", err).Error()) + } + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}{{.GoName}} + {{end}} + {{if .IsStyled}} + err = runtime.BindStyledParameterWithOptions("{{.Style}}", "{{.ParamName}}", valueList[0], &{{.GoName}}, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: {{.Explode}}, Required: {{.Required}}, Type: "{{.SchemaType}}", Format: "{{.SchemaFormat}}"}) + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, fmt.Errorf("Invalid format for parameter {{.ParamName}}: %w", err).Error()) + } + params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}{{.GoName}} + {{end}} + }{{if .Required}} else { + return fiber.NewError(fiber.StatusBadRequest, "Header parameter {{.ParamName}} is required, but not found") + }{{end}} +{{end}} +{{end}} +{{- end}} + return si.Handle{{$opid}}{{$.Prefix}}(c{{if .RequiresParamObject}}, params{{end}}) + } +} + +{{end}} diff --git a/pkg/codegen/templates/fiber/fiber-middleware.tmpl b/pkg/codegen/templates/fiber/fiber-middleware.tmpl index 533996e73d..9766d074fc 100644 --- a/pkg/codegen/templates/fiber/fiber-middleware.tmpl +++ b/pkg/codegen/templates/fiber/fiber-middleware.tmpl @@ -86,9 +86,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}value {{end}} }{{if .Required}} else { - err = fmt.Errorf("Query argument {{.ParamName}} is required, but not found") - c.Status(fiber.StatusBadRequest).JSON(err) - return err + return fiber.NewError(fiber.StatusBadRequest, "Query argument {{.ParamName}} is required, but not found") }{{end}} {{end}} {{if .IsStyled}} @@ -111,7 +109,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { } {{if .IsPassThrough}} - params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}valueList[0] + {{.GoName}} = valueList[0] {{end}} {{if .IsJson}} @@ -131,8 +129,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *fiber.Ctx) error { params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}{{.GoName}} } {{if .Required}}else { - err = fmt.Errorf("Header parameter {{.ParamName}} is required, but not found: %w", err) - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return fiber.NewError(fiber.StatusBadRequest, "Header parameter {{.ParamName}} is required, but not found") }{{end}} {{end}} diff --git a/pkg/codegen/templates/gin/gin-wrappers.tmpl b/pkg/codegen/templates/gin/gin-wrappers.tmpl index b768c67a95..a100342a42 100644 --- a/pkg/codegen/templates/gin/gin-wrappers.tmpl +++ b/pkg/codegen/templates/gin/gin-wrappers.tmpl @@ -99,7 +99,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(c *gin.Context) { } {{if .IsPassThrough}} - params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}valueList[0] + {{.GoName}} = valueList[0] {{end}} {{if .IsJson}} diff --git a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl index 2ef4b852e1..916eb9bde8 100644 --- a/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl +++ b/pkg/codegen/templates/gorilla/gorilla-middleware.tmpl @@ -104,7 +104,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ } {{if .IsPassThrough}} - params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}valueList[0] + {{.GoName}} = valueList[0] {{end}} {{if .IsJson}} diff --git a/pkg/codegen/templates/iris/iris-handler.tmpl b/pkg/codegen/templates/iris/iris-handler.tmpl index f2fb56e442..795cf4f10a 100644 --- a/pkg/codegen/templates/iris/iris-handler.tmpl +++ b/pkg/codegen/templates/iris/iris-handler.tmpl @@ -12,6 +12,10 @@ func RegisterHandlers(router *iris.Application, si ServerInterface) { // RegisterHandlersWithOptions creates http.Handler with additional options func RegisterHandlersWithOptions(router *iris.Application, si ServerInterface, options IrisServerOptions) { + for _, m := range options.Middlewares { + router.Use(m) + } + {{if .}} wrapper := ServerInterfaceWrapper{ Handler: si, diff --git a/pkg/codegen/templates/iris/iris-middleware.tmpl b/pkg/codegen/templates/iris/iris-middleware.tmpl index 46eddccaa2..daf41466d8 100644 --- a/pkg/codegen/templates/iris/iris-middleware.tmpl +++ b/pkg/codegen/templates/iris/iris-middleware.tmpl @@ -90,7 +90,7 @@ func (w *ServerInterfaceWrapper) {{.OperationId}} (ctx iris.Context) { return } {{if .IsPassThrough}} - params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}valueList[0] + {{.GoName}} = valueList[0] {{end}} {{if .IsJson}} err = json.Unmarshal([]byte(valueList[0]), &{{.GoName}}) diff --git a/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl b/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl index 65c62cacb0..b9d0a2a5ad 100644 --- a/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl +++ b/pkg/codegen/templates/stdhttp/std-http-middleware.tmpl @@ -104,7 +104,7 @@ func (siw *ServerInterfaceWrapper) {{$opid}}(w http.ResponseWriter, r *http.Requ } {{if .IsPassThrough}} - params.{{.GoName}} = {{if .HasOptionalPointer}}&{{end}}valueList[0] + {{.GoName}} = valueList[0] {{end}} {{if .IsJson}} diff --git a/pkg/codegen/templates/strict/strict-fiber-v3.tmpl b/pkg/codegen/templates/strict/strict-fiber-v3.tmpl index 6ef8f3874f..d4f1542586 100644 --- a/pkg/codegen/templates/strict/strict-fiber-v3.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber-v3.tmpl @@ -78,10 +78,10 @@ type strictHandler struct { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.({{$opid | ucFirst}}ResponseObject); ok { if err := validResponse.Visit{{$opid}}Response(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) diff --git a/pkg/codegen/templates/strict/strict-fiber.tmpl b/pkg/codegen/templates/strict/strict-fiber.tmpl index 0bdc9af82d..2bd4e6bf7a 100644 --- a/pkg/codegen/templates/strict/strict-fiber.tmpl +++ b/pkg/codegen/templates/strict/strict-fiber.tmpl @@ -90,10 +90,10 @@ type strictHandler struct { response, err := handler(ctx, request) if err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } else if validResponse, ok := response.({{$opid | ucFirst}}ResponseObject); ok { if err := validResponse.Visit{{$opid}}Response(ctx); err != nil { - return fiber.NewError(fiber.StatusBadRequest, err.Error()) + return err } } else if response != nil { return fmt.Errorf("unexpected response type: %T", response) diff --git a/pkg/codegen/templates/strict/strict-http.tmpl b/pkg/codegen/templates/strict/strict-http.tmpl index 062e5459e4..8e6166cc99 100644 --- a/pkg/codegen/templates/strict/strict-http.tmpl +++ b/pkg/codegen/templates/strict/strict-http.tmpl @@ -18,6 +18,16 @@ func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareF } func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + if options.RequestErrorHandlerFunc == nil { + options.RequestErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + if options.ResponseErrorHandlerFunc == nil { + options.ResponseErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + } return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} } diff --git a/pkg/codegen/templates/strict/strict-iris.tmpl b/pkg/codegen/templates/strict/strict-iris.tmpl index 5195c251b0..404db7e234 100644 --- a/pkg/codegen/templates/strict/strict-iris.tmpl +++ b/pkg/codegen/templates/strict/strict-iris.tmpl @@ -107,15 +107,15 @@ type strictHandler struct { response, err := handler(ctx, request) if err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } else if validResponse, ok := response.({{$opid | ucFirst}}ResponseObject); ok { if err := validResponse.Visit{{$opid}}Response(ctx); err != nil { - ctx.StopWithError(http.StatusBadRequest, err) + ctx.StopWithError(http.StatusInternalServerError, err) return } } else if response != nil { - ctx.Writef("Unexpected response type: %T", response) + ctx.StopWithError(http.StatusInternalServerError, fmt.Errorf("unexpected response type: %T", response)) return } }