Update all dependencies

Note: should we ditch vendoring?

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2025-09-29 10:20:26 +00:00 committed by Gabriel
parent 22fde8d30e
commit 0093393bc3
371 changed files with 91052 additions and 25816 deletions

View file

@ -1,62 +1,78 @@
linters-settings:
govet:
check-shadowing: true
golint:
min-confidence: 0
gocyclo:
min-complexity: 45
maligned:
suggest-new: true
dupl:
threshold: 200
goconst:
min-len: 2
min-occurrences: 3
version: "2"
linters:
enable-all: true
default: all
disable:
- nilerr # nilerr crashes on this repo
- maligned
- unparam
- lll
- gochecknoinits
- gochecknoglobals
- funlen
- godox
- gocognit
- whitespace
- wsl
- wrapcheck
- testpackage
- nlreturn
- gomnd
- exhaustivestruct
- goerr113
- errorlint
- nestif
- godot
- gofumpt
- paralleltest
- tparallel
- thelper
- ifshort
- exhaustruct
- varnamelen
- gci
- depguard
- errchkjson
- inamedparam
- nonamedreturns
- musttag
- ireturn
- forcetypeassert
- cyclop
# deprecated linters
- deadcode
- interfacer
- scopelint
- varcheck
- structcheck
- golint
- nosnakecase
- depguard
- err113 # disabled temporarily: there are just too many issues to address
- errchkjson
- errorlint
- exhaustruct
- forcetypeassert
- funlen
- gochecknoglobals
- gochecknoinits
- gocognit
- godot
- godox
- gomoddirectives # moved to mono-repo, multi-modules, so replace directives are needed
- gosmopolitan
- inamedparam
#- intrange # disabled while < go1.22
- ireturn
- lll
- musttag
- nestif
- nilerr # nilerr crashes on this repo
- nlreturn
- noinlineerr
- nonamedreturns
- paralleltest
- recvcheck
- testpackage
- thelper
- tparallel
- unparam
- varnamelen
- whitespace
- wrapcheck
- wsl
- wsl_v5
settings:
dupl:
threshold: 200
goconst:
min-len: 2
min-occurrences: 3
gocyclo:
min-complexity: 45
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- gofmt
- goimports
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
issues:
# Maximum issues count per one linter.
# Set to 0 to disable.
# Default: 50
max-issues-per-linter: 0
# Maximum count of issues with the same text.
# Set to 0 to disable.
# Default: 3
max-same-issues: 0

View file

@ -8,3 +8,32 @@
# go OpenAPI toolkit runtime
The runtime component for use in code generation or as untyped usage.
## Release notes
### v0.29.0 [draft, unpublished]
**New with this release**:
* upgraded to `go1.24` and modernized the code base accordingly
* updated all dependencies, and removed an noticable indirect dependency (e.g. `mailru/easyjson`)
* **breaking change** no longer imports `opentracing-go` (#365).
* the `WithOpentracing()` method now returns an opentelemetry transport
* for users who can't transition to opentelemetry, the previous behavior
of `WithOpentracing` delivering an opentracing transport is provided by a separate
module `github.com/go-openapi/runtime/client-middleware/opentracing`.
* removed direct dependency to `gopkg.in/yaml.v3`, in favor of `go.yaml.in/yaml/v3` (an indirect
test dependency to the older package is still around)
* technically, the repo has evolved to a mono-repo, multiple modules structures (2 go modules
published), with CI adapted accordingly
**What coming next?**
Moving forward, we want to :
* [ ] continue narrowing down the scope of dependencies:
* yaml support in an independent module
* introduce more up-to-date support for opentelemetry as a separate module that evolves
independently from the main package (to avoid breaking changes, the existing API
will remain maintained, but evolve at a slower pace than opentelemetry).
* [ ] fix a few known issues with some file upload requests (e.g. #286)

View file

@ -22,7 +22,7 @@ import (
"io"
"reflect"
"github.com/go-openapi/swag"
"github.com/go-openapi/swag/jsonutils"
)
func defaultCloser() error { return nil }
@ -206,7 +206,7 @@ func ByteStreamProducer(opts ...byteStreamOpt) Producer {
return err
case t.Kind() == reflect.Struct || t.Kind() == reflect.Slice:
b, err := swag.WriteJSON(data)
b, err := jsonutils.WriteJSON(data)
if err != nil {
return err
}

View file

@ -11,8 +11,7 @@ import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/propagation"
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
"go.opentelemetry.io/otel/semconv/v1.17.0/httpconv"
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
"go.opentelemetry.io/otel/trace"
)
@ -133,10 +132,13 @@ func (t *openTelemetryTransport) Submit(op *runtime.ClientOperation) (interface{
if span != nil {
statusCode := response.Code()
// NOTE: this is replaced by semconv.HTTPResponseStatusCode in semconv v1.21
span.SetAttributes(semconv.HTTPStatusCode(statusCode))
span.SetAttributes(semconv.HTTPResponseStatusCode(statusCode))
// NOTE: the conversion from HTTP status code to trace code is no longer available with
// semconv v1.21
span.SetStatus(httpconv.ServerStatus(statusCode))
const minHTTPStatusIsError = 400
if statusCode >= minHTTPStatusIsError {
span.SetStatus(codes.Error, http.StatusText(statusCode))
}
}
return reader.ReadResponse(response, consumer)
@ -173,7 +175,7 @@ func (t *openTelemetryTransport) newOpenTelemetrySpan(op *runtime.ClientOperatio
span.SetAttributes(
attribute.String("net.peer.name", t.host),
attribute.String(string(semconv.HTTPRouteKey), op.PathPattern),
attribute.String(string(semconv.HTTPMethodKey), op.Method),
attribute.String(string(semconv.HTTPRequestMethodKey), op.Method),
attribute.String("span.kind", trace.SpanKindClient.String()),
attribute.String("http.scheme", scheme),
)

View file

@ -1,99 +0,0 @@
package client
import (
"fmt"
"net/http"
"github.com/go-openapi/strfmt"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log"
"github.com/go-openapi/runtime"
)
type tracingTransport struct {
transport runtime.ClientTransport
host string
opts []opentracing.StartSpanOption
}
func newOpenTracingTransport(transport runtime.ClientTransport, host string, opts []opentracing.StartSpanOption,
) runtime.ClientTransport {
return &tracingTransport{
transport: transport,
host: host,
opts: opts,
}
}
func (t *tracingTransport) Submit(op *runtime.ClientOperation) (interface{}, error) {
if op.Context == nil {
return t.transport.Submit(op)
}
params := op.Params
reader := op.Reader
var span opentracing.Span
defer func() {
if span != nil {
span.Finish()
}
}()
op.Params = runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
span = createClientSpan(op, req.GetHeaderParams(), t.host, t.opts)
return params.WriteToRequest(req, reg)
})
op.Reader = runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
if span != nil {
code := response.Code()
ext.HTTPStatusCode.Set(span, uint16(code))
if code >= 400 {
ext.Error.Set(span, true)
}
}
return reader.ReadResponse(response, consumer)
})
submit, err := t.transport.Submit(op)
if err != nil && span != nil {
ext.Error.Set(span, true)
span.LogFields(log.Error(err))
}
return submit, err
}
func createClientSpan(op *runtime.ClientOperation, header http.Header, host string,
opts []opentracing.StartSpanOption) opentracing.Span {
ctx := op.Context
span := opentracing.SpanFromContext(ctx)
if span != nil {
opts = append(opts, ext.SpanKindRPCClient)
span, _ = opentracing.StartSpanFromContextWithTracer(
ctx, span.Tracer(), operationName(op), opts...)
ext.Component.Set(span, "go-openapi")
ext.PeerHostname.Set(span, host)
span.SetTag("http.path", op.PathPattern)
ext.HTTPMethod.Set(span, op.Method)
_ = span.Tracer().Inject(
span.Context(),
opentracing.HTTPHeaders,
opentracing.HTTPHeadersCarrier(header))
return span
}
return nil
}
func operationName(op *runtime.ClientOperation) string {
if op.ID != "" {
return op.ID
}
return fmt.Sprintf("%s_%s", op.Method, op.PathPattern)
}

View file

@ -30,23 +30,11 @@ import (
"strings"
"time"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
)
// NewRequest creates a new swagger http client request
func newRequest(method, pathPattern string, writer runtime.ClientRequestWriter) *request {
return &request{
pathPattern: pathPattern,
method: method,
writer: writer,
header: make(http.Header),
query: make(url.Values),
timeout: DefaultTimeout,
getBody: getRequestBuffer,
}
}
var _ runtime.ClientRequest = new(request) // ensure compliance to the interface
// Request represents a swagger client request.
//
@ -67,17 +55,149 @@ type request struct {
query url.Values
formFields url.Values
fileFields map[string][]runtime.NamedReadCloser
payload interface{}
payload any
timeout time.Duration
buf *bytes.Buffer
getBody func(r *request) []byte
}
var (
// ensure interface compliance
_ runtime.ClientRequest = new(request)
)
// NewRequest creates a new swagger http client request
func newRequest(method, pathPattern string, writer runtime.ClientRequestWriter) *request {
return &request{
pathPattern: pathPattern,
method: method,
writer: writer,
header: make(http.Header),
query: make(url.Values),
timeout: DefaultTimeout,
getBody: getRequestBuffer,
}
}
// BuildHTTP creates a new http request based on the data from the params
func (r *request) BuildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry) (*http.Request, error) {
return r.buildHTTP(mediaType, basePath, producers, registry, nil)
}
func (r *request) GetMethod() string {
return r.method
}
func (r *request) GetPath() string {
path := r.pathPattern
for k, v := range r.pathParams {
path = strings.ReplaceAll(path, "{"+k+"}", v)
}
return path
}
func (r *request) GetBody() []byte {
return r.getBody(r)
}
// SetHeaderParam adds a header param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetHeaderParam(name string, values ...string) error {
if r.header == nil {
r.header = make(http.Header)
}
r.header[http.CanonicalHeaderKey(name)] = values
return nil
}
// GetHeaderParams returns the all headers currently set for the request
func (r *request) GetHeaderParams() http.Header {
return r.header
}
// SetQueryParam adds a query param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetQueryParam(name string, values ...string) error {
if r.query == nil {
r.query = make(url.Values)
}
r.query[name] = values
return nil
}
// GetQueryParams returns a copy of all query params currently set for the request
func (r *request) GetQueryParams() url.Values {
var result = make(url.Values)
for key, value := range r.query {
result[key] = append([]string{}, value...)
}
return result
}
// SetFormParam adds a forn param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetFormParam(name string, values ...string) error {
if r.formFields == nil {
r.formFields = make(url.Values)
}
r.formFields[name] = values
return nil
}
// SetPathParam adds a path param to the request
func (r *request) SetPathParam(name string, value string) error {
if r.pathParams == nil {
r.pathParams = make(map[string]string)
}
r.pathParams[name] = value
return nil
}
// SetFileParam adds a file param to the request
func (r *request) SetFileParam(name string, files ...runtime.NamedReadCloser) error {
for _, file := range files {
if actualFile, ok := file.(*os.File); ok {
fi, err := os.Stat(actualFile.Name())
if err != nil {
return err
}
if fi.IsDir() {
return fmt.Errorf("%q is a directory, only files are supported", file.Name())
}
}
}
if r.fileFields == nil {
r.fileFields = make(map[string][]runtime.NamedReadCloser)
}
if r.formFields == nil {
r.formFields = make(url.Values)
}
r.fileFields[name] = files
return nil
}
func (r *request) GetFileParam() map[string][]runtime.NamedReadCloser {
return r.fileFields
}
// SetBodyParam sets a body parameter on the request.
// This does not yet serialze the object, this happens as late as possible.
func (r *request) SetBodyParam(payload any) error {
r.payload = payload
return nil
}
func (r *request) GetBodyParam() any {
return r.payload
}
// SetTimeout sets the timeout for a request
func (r *request) SetTimeout(timeout time.Duration) error {
r.timeout = timeout
return nil
}
func (r *request) isMultipart(mediaType string) bool {
if len(r.fileFields) > 0 {
@ -87,22 +207,6 @@ func (r *request) isMultipart(mediaType string) bool {
return runtime.MultipartFormMime == mediaType
}
// BuildHTTP creates a new http request based on the data from the params
func (r *request) BuildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry) (*http.Request, error) {
return r.buildHTTP(mediaType, basePath, producers, registry, nil)
}
func escapeQuotes(s string) string {
return strings.NewReplacer("\\", "\\\\", `"`, "\\\"").Replace(s)
}
func logClose(err error, pw *io.PipeWriter) {
log.Println(err)
closeErr := pw.CloseWithError(err)
if closeErr != nil {
log.Println(closeErr)
}
}
func (r *request) buildHTTP(mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter) (*http.Request, error) { //nolint:gocyclo,maintidx
// build the data
if err := r.writer.WriteToRequest(r, registry); err != nil {
@ -169,7 +273,8 @@ func (r *request) buildHTTP(mediaType, basePath string, producers map[string]run
fileContentType = p.ContentType()
} else {
// Need to read the data so that we can detect the content type
buf := make([]byte, 512)
const contentTypeBufferSize = 512
buf := make([]byte, contentTypeBufferSize)
size, err := fi.Read(buf)
if err != nil && err != io.EOF {
logClose(err, pw)
@ -348,27 +453,8 @@ DoneChoosingBodySource:
return req, nil
}
func mangleContentType(mediaType, boundary string) string {
if strings.ToLower(mediaType) == runtime.URLencodedFormMime {
return fmt.Sprintf("%s; boundary=%s", mediaType, boundary)
}
return "multipart/form-data; boundary=" + boundary
}
func (r *request) GetMethod() string {
return r.method
}
func (r *request) GetPath() string {
path := r.pathPattern
for k, v := range r.pathParams {
path = strings.ReplaceAll(path, "{"+k+"}", v)
}
return path
}
func (r *request) GetBody() []byte {
return r.getBody(r)
func escapeQuotes(s string) string {
return strings.NewReplacer("\\", "\\\\", `"`, "\\\"").Replace(s)
}
func getRequestBuffer(r *request) []byte {
@ -378,105 +464,17 @@ func getRequestBuffer(r *request) []byte {
return r.buf.Bytes()
}
// SetHeaderParam adds a header param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetHeaderParam(name string, values ...string) error {
if r.header == nil {
r.header = make(http.Header)
func logClose(err error, pw *io.PipeWriter) {
log.Println(err)
closeErr := pw.CloseWithError(err)
if closeErr != nil {
log.Println(closeErr)
}
r.header[http.CanonicalHeaderKey(name)] = values
return nil
}
// GetHeaderParams returns the all headers currently set for the request
func (r *request) GetHeaderParams() http.Header {
return r.header
}
// SetQueryParam adds a query param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetQueryParam(name string, values ...string) error {
if r.query == nil {
r.query = make(url.Values)
func mangleContentType(mediaType, boundary string) string {
if strings.ToLower(mediaType) == runtime.URLencodedFormMime {
return fmt.Sprintf("%s; boundary=%s", mediaType, boundary)
}
r.query[name] = values
return nil
}
// GetQueryParams returns a copy of all query params currently set for the request
func (r *request) GetQueryParams() url.Values {
var result = make(url.Values)
for key, value := range r.query {
result[key] = append([]string{}, value...)
}
return result
}
// SetFormParam adds a forn param to the request
// when there is only 1 value provided for the varargs, it will set it.
// when there are several values provided for the varargs it will add it (no overriding)
func (r *request) SetFormParam(name string, values ...string) error {
if r.formFields == nil {
r.formFields = make(url.Values)
}
r.formFields[name] = values
return nil
}
// SetPathParam adds a path param to the request
func (r *request) SetPathParam(name string, value string) error {
if r.pathParams == nil {
r.pathParams = make(map[string]string)
}
r.pathParams[name] = value
return nil
}
// SetFileParam adds a file param to the request
func (r *request) SetFileParam(name string, files ...runtime.NamedReadCloser) error {
for _, file := range files {
if actualFile, ok := file.(*os.File); ok {
fi, err := os.Stat(actualFile.Name())
if err != nil {
return err
}
if fi.IsDir() {
return fmt.Errorf("%q is a directory, only files are supported", file.Name())
}
}
}
if r.fileFields == nil {
r.fileFields = make(map[string][]runtime.NamedReadCloser)
}
if r.formFields == nil {
r.formFields = make(url.Values)
}
r.fileFields[name] = files
return nil
}
func (r *request) GetFileParam() map[string][]runtime.NamedReadCloser {
return r.fileFields
}
// SetBodyParam sets a body parameter on the request.
// This does not yet serialze the object, this happens as late as possible.
func (r *request) SetBodyParam(payload interface{}) error {
r.payload = payload
return nil
}
func (r *request) GetBodyParam() interface{} {
return r.payload
}
// SetTimeout sets the timeout for a request
func (r *request) SetTimeout(timeout time.Duration) error {
r.timeout = timeout
return nil
return "multipart/form-data; boundary=" + boundary
}

View file

@ -32,13 +32,11 @@ import (
"sync"
"time"
"github.com/go-openapi/strfmt"
"github.com/opentracing/opentracing-go"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/logger"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/runtime/yamlpc"
"github.com/go-openapi/strfmt"
)
const (
@ -46,6 +44,9 @@ const (
schemeHTTPS = "https"
)
// DefaultTimeout the default request timeout
var DefaultTimeout = 30 * time.Second
// TLSClientOptions to configure client authentication with mutual TLS
type TLSClientOptions struct {
// Certificate is the path to a PEM-encoded certificate to be used for
@ -193,13 +194,6 @@ func TLSClientAuth(opts TLSClientOptions) (*tls.Config, error) {
return cfg, nil
}
func basePool(pool *x509.CertPool) *x509.CertPool {
if pool == nil {
return x509.NewCertPool()
}
return pool
}
// TLSTransport creates a http client transport suitable for mutual tls auth
func TLSTransport(opts TLSClientOptions) (http.RoundTripper, error) {
cfg, err := TLSClientAuth(opts)
@ -219,9 +213,6 @@ func TLSClient(opts TLSClientOptions) (*http.Client, error) {
return &http.Client{Transport: transport}, nil
}
// DefaultTimeout the default request timeout
var DefaultTimeout = 30 * time.Second
// Runtime represents an API client that uses the transport
// to make http requests based on a swagger specification.
type Runtime struct {
@ -306,8 +297,33 @@ func NewWithClient(host, basePath string, schemes []string, client *http.Client)
// A new client span is created for each request.
// If the context of the client operation does not contain an active span, no span is created.
// The provided opts are applied to each spans - for example to add global tags.
func (r *Runtime) WithOpenTracing(opts ...opentracing.StartSpanOption) runtime.ClientTransport {
return newOpenTracingTransport(r, r.Host, opts)
//
// Deprecated: use [WithOpenTelemetry] instead, as opentracing is now archived and superseded by opentelemetry.
//
// # Deprecation notice
//
// The [Runtime.WithOpenTracing] method has been deprecated in favor of [Runtime.WithOpenTelemetry].
//
// The method is still around so programs calling it will still build. However, it will return
// an opentelemetry transport.
//
// If you have a strict requirement on using opentracing, you may still do so by importing
// module [github.com/go-openapi/runtime/client-middleware/opentracing] and using
// [github.com/go-openapi/runtime/client-middleware/opentracing.WithOpenTracing] with your
// usual opentracing options and opentracing-enabled transport.
//
// Passed options are ignored unless they are of type [OpenTelemetryOpt].
func (r *Runtime) WithOpenTracing(opts ...any) runtime.ClientTransport {
otelOpts := make([]OpenTelemetryOpt, 0, len(opts))
for _, o := range opts {
otelOpt, ok := o.(OpenTelemetryOpt)
if !ok {
continue
}
otelOpts = append(otelOpts, otelOpt)
}
return r.WithOpenTelemetry(otelOpts...)
}
// WithOpenTelemetry adds opentelemetry support to the provided runtime.
@ -318,42 +334,6 @@ func (r *Runtime) WithOpenTelemetry(opts ...OpenTelemetryOpt) runtime.ClientTran
return newOpenTelemetryTransport(r, r.Host, opts)
}
func (r *Runtime) pickScheme(schemes []string) string {
if v := r.selectScheme(r.schemes); v != "" {
return v
}
if v := r.selectScheme(schemes); v != "" {
return v
}
return schemeHTTP
}
func (r *Runtime) selectScheme(schemes []string) string {
schLen := len(schemes)
if schLen == 0 {
return ""
}
scheme := schemes[0]
// prefer https, but skip when not possible
if scheme != schemeHTTPS && schLen > 1 {
for _, sch := range schemes {
if sch == schemeHTTPS {
scheme = sch
break
}
}
}
return scheme
}
func transportOrDefault(left, right http.RoundTripper) http.RoundTripper {
if left == nil {
return right
}
return left
}
// EnableConnectionReuse drains the remaining body from a response
// so that go will reuse the TCP connections.
//
@ -376,57 +356,7 @@ func (r *Runtime) EnableConnectionReuse() {
)
}
// takes a client operation and creates equivalent http.Request
func (r *Runtime) createHttpRequest(operation *runtime.ClientOperation) (*request, *http.Request, error) { //nolint:revive,stylecheck
params, _, auth := operation.Params, operation.Reader, operation.AuthInfo
request := newRequest(operation.Method, operation.PathPattern, params)
var accept []string
accept = append(accept, operation.ProducesMediaTypes...)
if err := request.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil {
return nil, nil, err
}
if auth == nil && r.DefaultAuthentication != nil {
auth = runtime.ClientAuthInfoWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
if req.GetHeaderParams().Get(runtime.HeaderAuthorization) != "" {
return nil
}
return r.DefaultAuthentication.AuthenticateRequest(req, reg)
})
}
// if auth != nil {
// if err := auth.AuthenticateRequest(request, r.Formats); err != nil {
// return nil, err
// }
//}
// TODO: pick appropriate media type
cmt := r.DefaultMediaType
for _, mediaType := range operation.ConsumesMediaTypes {
// Pick first non-empty media type
if mediaType != "" {
cmt = mediaType
break
}
}
if _, ok := r.Producers[cmt]; !ok && cmt != runtime.MultipartFormMime && cmt != runtime.URLencodedFormMime {
return nil, nil, fmt.Errorf("none of producers: %v registered. try %s", r.Producers, cmt)
}
req, err := request.buildHTTP(cmt, r.BasePath, r.Producers, r.Formats, auth)
if err != nil {
return nil, nil, err
}
req.URL.Scheme = r.pickScheme(operation.Schemes)
req.URL.Host = r.Host
req.Host = r.Host
return request, req, nil
}
func (r *Runtime) CreateHttpRequest(operation *runtime.ClientOperation) (req *http.Request, err error) { //nolint:revive,stylecheck
func (r *Runtime) CreateHttpRequest(operation *runtime.ClientOperation) (req *http.Request, err error) { //nolint:revive
_, req, err = r.createHttpRequest(operation)
return
}
@ -550,3 +480,96 @@ func (r *Runtime) SetResponseReader(f ClientResponseFunc) {
}
r.response = f
}
func (r *Runtime) pickScheme(schemes []string) string {
if v := r.selectScheme(r.schemes); v != "" {
return v
}
if v := r.selectScheme(schemes); v != "" {
return v
}
return schemeHTTP
}
func (r *Runtime) selectScheme(schemes []string) string {
schLen := len(schemes)
if schLen == 0 {
return ""
}
scheme := schemes[0]
// prefer https, but skip when not possible
if scheme != schemeHTTPS && schLen > 1 {
for _, sch := range schemes {
if sch == schemeHTTPS {
scheme = sch
break
}
}
}
return scheme
}
func transportOrDefault(left, right http.RoundTripper) http.RoundTripper {
if left == nil {
return right
}
return left
}
// takes a client operation and creates equivalent http.Request
func (r *Runtime) createHttpRequest(operation *runtime.ClientOperation) (*request, *http.Request, error) { //nolint:revive
params, _, auth := operation.Params, operation.Reader, operation.AuthInfo
request := newRequest(operation.Method, operation.PathPattern, params)
var accept []string
accept = append(accept, operation.ProducesMediaTypes...)
if err := request.SetHeaderParam(runtime.HeaderAccept, accept...); err != nil {
return nil, nil, err
}
if auth == nil && r.DefaultAuthentication != nil {
auth = runtime.ClientAuthInfoWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error {
if req.GetHeaderParams().Get(runtime.HeaderAuthorization) != "" {
return nil
}
return r.DefaultAuthentication.AuthenticateRequest(req, reg)
})
}
// if auth != nil {
// if err := auth.AuthenticateRequest(request, r.Formats); err != nil {
// return nil, err
// }
//}
// TODO: pick appropriate media type
cmt := r.DefaultMediaType
for _, mediaType := range operation.ConsumesMediaTypes {
// Pick first non-empty media type
if mediaType != "" {
cmt = mediaType
break
}
}
if _, ok := r.Producers[cmt]; !ok && cmt != runtime.MultipartFormMime && cmt != runtime.URLencodedFormMime {
return nil, nil, fmt.Errorf("none of producers: %v registered. try %s", r.Producers, cmt)
}
req, err := request.buildHTTP(cmt, r.BasePath, r.Producers, r.Formats, auth)
if err != nil {
return nil, nil, err
}
req.URL.Scheme = r.pickScheme(operation.Schemes)
req.URL.Host = r.Host
req.Host = r.Host
return request, req, nil
}
func basePool(pool *x509.CertPool) *x509.CertPool {
if pool == nil {
return x509.NewCertPool()
}
return pool
}

View file

@ -20,7 +20,8 @@ import (
"io"
)
// A ClientResponse represents a client response
// A ClientResponse represents a client response.
//
// This bridges between responses obtained from different transports
type ClientResponse interface {
Code() int
@ -44,6 +45,13 @@ type ClientResponseReader interface {
ReadResponse(ClientResponse, Consumer) (interface{}, error)
}
// APIError wraps an error model and captures the status code
type APIError struct {
OperationName string
Response interface{}
Code int
}
// NewAPIError creates a new API error
func NewAPIError(opName string, payload interface{}, code int) *APIError {
return &APIError{
@ -53,13 +61,6 @@ func NewAPIError(opName string, payload interface{}, code int) *APIError {
}
}
// APIError wraps an error model and captures the status code
type APIError struct {
OperationName string
Response interface{}
Code int
}
func (o *APIError) Error() string {
var resp []byte
if err, ok := o.Response.(error); ok {
@ -74,27 +75,31 @@ func (o *APIError) String() string {
return o.Error()
}
// IsSuccess returns true when this elapse o k response returns a 2xx status code
// IsSuccess returns true when this API response returns a 2xx status code
func (o *APIError) IsSuccess() bool {
return o.Code/100 == 2
const statusOK = 2
return o.Code/100 == statusOK
}
// IsRedirect returns true when this elapse o k response returns a 3xx status code
// IsRedirect returns true when this API response returns a 3xx status code
func (o *APIError) IsRedirect() bool {
return o.Code/100 == 3
const statusRedirect = 3
return o.Code/100 == statusRedirect
}
// IsClientError returns true when this elapse o k response returns a 4xx status code
// IsClientError returns true when this API response returns a 4xx status code
func (o *APIError) IsClientError() bool {
return o.Code/100 == 4
const statusClientError = 4
return o.Code/100 == statusClientError
}
// IsServerError returns true when this elapse o k response returns a 5xx status code
// IsServerError returns true when this API response returns a 5xx status code
func (o *APIError) IsServerError() bool {
return o.Code/100 == 5
const statusServerError = 5
return o.Code/100 == statusServerError
}
// IsCode returns true when this elapse o k response returns a 4xx status code
// IsCode returns true when this API response returns a given status code
func (o *APIError) IsCode(code int) bool {
return o.Code == code
}

View file

@ -5,7 +5,7 @@ import (
"io"
)
// CSVOpts alter the behavior of the CSV consumer or producer.
// CSVOpt alter the behavior of the CSV consumer or producer.
type CSVOpt func(*csvOpts)
type csvOpts struct {

View file

@ -14,6 +14,6 @@
package runtime
import "github.com/go-openapi/swag"
import "github.com/go-openapi/swag/fileutils"
type File = swag.File
type File = fileutils.File

6
vendor/github.com/go-openapi/runtime/go.work generated vendored Normal file
View file

@ -0,0 +1,6 @@
use (
.
./client-middleware/opentracing
)
go 1.24.0

88
vendor/github.com/go-openapi/runtime/go.work.sum generated vendored Normal file
View file

@ -0,0 +1,88 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/go-openapi/errors v0.22.2/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0=
github.com/go-openapi/jsonpointer v0.22.0/go.mod h1:xt3jV88UtExdIkkL7NloURjRQjbeUgcxFblMjq2iaiU=
github.com/go-openapi/jsonreference v0.21.1/go.mod h1:PWs8rO4xxTUqKGu+lEvvCxD5k2X7QYkKAepJyCmSTT8=
github.com/go-openapi/swag v0.24.1/go.mod h1:sm8I3lCPlspsBBwUm1t5oZeWZS0s7m/A+Psg0ooRU0A=
github.com/go-openapi/swag/cmdutils v0.24.0/go.mod h1:uxib2FAeQMByyHomTlsP8h1TtPd54Msu2ZDU/H5Vuf8=
github.com/go-openapi/swag/conv v0.24.0/go.mod h1:jbn140mZd7EW2g8a8Y5bwm8/Wy1slLySQQ0ND6DPc2c=
github.com/go-openapi/swag/fileutils v0.24.0/go.mod h1:3SCrCSBHyP1/N+3oErQ1gP+OX1GV2QYFSnrTbzwli90=
github.com/go-openapi/swag/jsonname v0.24.0/go.mod h1:GXqrPzGJe611P7LG4QB9JKPtUZ7flE4DOVechNaDd7Q=
github.com/go-openapi/swag/jsonutils v0.24.0/go.mod h1:vBowZtF5Z4DDApIoxcIVfR8v0l9oq5PpYRUuteVu6f0=
github.com/go-openapi/swag/loading v0.24.0/go.mod h1:gShCN4woKZYIxPxbfbyHgjXAhO61m88tmjy0lp/LkJk=
github.com/go-openapi/swag/mangling v0.24.0/go.mod h1:Jm5Go9LHkycsz0wfoaBDkdc4CkpuSnIEf62brzyCbhc=
github.com/go-openapi/swag/netutils v0.24.0/go.mod h1:WRgiHcYTnx+IqfMCtu0hy9oOaPR0HnPbmArSRN1SkZM=
github.com/go-openapi/swag/stringutils v0.24.0/go.mod h1:5nUXB4xA0kw2df5PRipZDslPJgJut+NjL7D25zPZ/4w=
github.com/go-openapi/swag/typeutils v0.24.0/go.mod h1:q8C3Kmk/vh2VhpCLaoR2MVWOGP8y7Jc8l82qCTd1DYI=
github.com/go-openapi/swag/yamlutils v0.24.0/go.mod h1:DpKv5aYuaGm/sULePoeiG8uwMpZSfReo1HR3Ik0yaG8=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
golang.org/x/telemetry v0.0.0-20250807160809-1a19826ec488/go.mod h1:fGb/2+tgXXjhjHsTNdVEEMZNWA0quBnfrO+AfoDSAKw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -218,8 +218,8 @@ func NewRoutableContext(spec *loads.Document, routableAPI RoutableAPI, routes Ro
// If a nil Router is provided, the DefaultRouter (denco-based) will be used.
func NewRoutableContextWithAnalyzedSpec(spec *loads.Document, an *analysis.Spec, routableAPI RoutableAPI, routes Router) *Context {
// Either there are no spec doc and analysis, or both of them.
if !((spec == nil && an == nil) || (spec != nil && an != nil)) {
panic(errors.New(http.StatusInternalServerError, "routable context requires either both spec doc and analysis, or none of them"))
if (spec != nil || an != nil) && (spec == nil || an == nil) {
panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, "routable context requires either both spec doc and analysis, or none of them"))
}
return &Context{
@ -307,6 +307,9 @@ type contentTypeValue struct {
// BasePath returns the base path for this API
func (c *Context) BasePath() string {
if c.spec == nil {
return ""
}
return c.spec.BasePath()
}
@ -341,7 +344,7 @@ func (c *Context) BindValidRequest(request *http.Request, route *MatchedRoute, b
if len(res) == 0 {
cons, ok := route.Consumers[ct]
if !ok {
res = append(res, errors.New(500, "no consumer registered for %s", ct))
res = append(res, errors.New(http.StatusInternalServerError, "no consumer registered for %s", ct))
} else {
route.Consumer = cons
requestContentType = ct
@ -486,7 +489,7 @@ func (c *Context) Authorize(request *http.Request, route *MatchedRoute) (interfa
return nil, nil, err
}
return nil, nil, errors.New(http.StatusForbidden, err.Error())
return nil, nil, errors.New(http.StatusForbidden, "%v", err)
}
}
@ -552,7 +555,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
pr, ok := prods[c.api.DefaultProduces()]
if !ok {
panic(errors.New(http.StatusInternalServerError, cantFindProducer(format)))
panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format)))
}
prod = pr
}
@ -585,7 +588,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
producers := c.api.ProducersFor(normalizeOffers(offers))
prod, ok := producers[format]
if !ok {
panic(errors.New(http.StatusInternalServerError, cantFindProducer(format)))
panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format)))
}
if err := prod.Produce(rw, data); err != nil {
panic(err) // let the recovery middleware deal with this
@ -606,7 +609,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
prods := c.api.ProducersFor(normalizeOffers([]string{c.api.DefaultProduces()}))
pr, ok := prods[c.api.DefaultProduces()]
if !ok {
panic(errors.New(http.StatusInternalServerError, cantFindProducer(format)))
panic(fmt.Errorf("%d: %s", http.StatusInternalServerError, cantFindProducer(format)))
}
prod = pr
}
@ -617,7 +620,7 @@ func (c *Context) Respond(rw http.ResponseWriter, r *http.Request, produces []st
return
}
c.api.ServeErrorFor(route.Operation.ID)(rw, r, errors.New(http.StatusInternalServerError, "can't produce response"))
c.api.ServeErrorFor(route.Operation.ID)(rw, r, fmt.Errorf("%d: %s", http.StatusInternalServerError, "can't produce response"))
}
// APIHandlerSwaggerUI returns a handler to serve the API.
@ -677,6 +680,15 @@ func (c *Context) APIHandler(builder Builder, opts ...UIOption) http.Handler {
return Spec(specPath, c.spec.Raw(), Redoc(redocOpts, c.RoutesHandler(b)), specOpts...)
}
// RoutesHandler returns a handler to serve the API, just the routes and the contract defined in the swagger spec
func (c *Context) RoutesHandler(builder Builder) http.Handler {
b := builder
if b == nil {
b = PassthroughBuilder
}
return NewRouter(c, b(NewOperationExecutor(c)))
}
func (c Context) uiOptionsForHandler(opts []UIOption) (string, uiOptions, []SpecOption) {
var title string
sp := c.spec.Spec()
@ -708,15 +720,6 @@ func (c Context) uiOptionsForHandler(opts []UIOption) (string, uiOptions, []Spec
return pth, uiOpts, []SpecOption{WithSpecDocument(doc)}
}
// RoutesHandler returns a handler to serve the API, just the routes and the contract defined in the swagger spec
func (c *Context) RoutesHandler(builder Builder) http.Handler {
b := builder
if b == nil {
b = PassthroughBuilder
}
return NewRouter(c, b(NewOperationExecutor(c)))
}
func cantFindProducer(format string) string {
return "can't find a producer for " + format
}

View file

@ -25,7 +25,7 @@ const (
PathParamCharacter = '='
// MaxSize is max size of records and internal slice.
MaxSize = (1 << 22) - 1
MaxSize = (1 << 22) - 1 //nolint:mnd
)
// Router represents a URL router.
@ -62,7 +62,7 @@ func (rt *Router) Lookup(path string) (data interface{}, params Params, found bo
if !found {
return nil, nil, false
}
for i := 0; i < len(params); i++ {
for i := range params {
params[i].Name = nd.paramNames[i]
}
return nd.data, params, true
@ -138,12 +138,17 @@ func newDoubleArray() *doubleArray {
// 32 10 8 0
type baseCheck uint32
const (
flagsBits = 10
checkBits = 8
)
func (bc baseCheck) Base() int {
return int(bc >> 10)
return int(bc >> flagsBits)
}
func (bc *baseCheck) SetBase(base int) {
*bc |= baseCheck(base) << 10
*bc |= baseCheck(base) << flagsBits //nolint:gosec // integer conversion is ok
}
func (bc baseCheck) Check() byte {
@ -171,24 +176,27 @@ func (bc baseCheck) IsAnyParam() bool {
}
func (bc *baseCheck) SetSingleParam() {
*bc |= (1 << 8)
*bc |= (1 << checkBits)
}
func (bc *baseCheck) SetWildcardParam() {
*bc |= (1 << 9)
*bc |= (1 << (checkBits + 1))
}
const (
paramTypeSingle = 0x0100
paramTypeWildcard = 0x0200
paramTypeAny = 0x0300
indexOffset = 32
indexMask = uint64(0xffffffff)
)
func (da *doubleArray) lookup(path string, params []Param, idx int) (*node, []Param, bool) {
indices := make([]uint64, 0, 1)
for i := 0; i < len(path); i++ {
for i := range len(path) {
if da.bc[idx].IsAnyParam() {
indices = append(indices, (uint64(i)<<32)|(uint64(idx)&0xffffffff))
indices = append(indices, (uint64(i)<<indexOffset)|(uint64(idx)&indexMask)) //nolint:gosec // integer conversion is okay
}
c := path[i]
if idx = nextIndex(da.bc[idx].Base(), c); idx >= len(da.bc) || da.bc[idx].Check() != c {
@ -201,7 +209,7 @@ func (da *doubleArray) lookup(path string, params []Param, idx int) (*node, []Pa
BACKTRACKING:
for j := len(indices) - 1; j >= 0; j-- {
i, idx := int(indices[j]>>32), int(indices[j]&0xffffffff)
i, idx := int(indices[j]>>indexOffset), int(indices[j]&indexMask) //nolint:gosec // integer conversion is okay
if da.bc[idx].IsSingleParam() {
nextIdx := nextIndex(da.bc[idx].Base(), ParamCharacter)
if nextIdx >= len(da.bc) {
@ -428,6 +436,7 @@ func NewRecord(key string, value interface{}) Record {
// record represents a record that use to build the Double-Array.
type record struct {
Record
paramNames []string
}

View file

@ -25,6 +25,11 @@ const (
isSpace
)
const (
asciiMaxControlChar = 31
asciiMaxChar = 127
)
func init() {
// OCTET = <any 8-bit sequence of data>
// CHAR = <any US-ASCII character (octets 0 - 127)>
@ -42,10 +47,10 @@ func init() {
// token = 1*<any CHAR except CTLs or separators>
// qdtext = <any TEXT except <">>
for c := 0; c < 256; c++ {
for c := range 256 {
var t octetType
isCtl := c <= 31 || c == 127
isChar := 0 <= c && c <= 127
isCtl := c <= asciiMaxControlChar || c == asciiMaxChar
isChar := 0 <= c && c <= asciiMaxChar
isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c))
if strings.ContainsRune(" \t\r\n", rune(c)) {
t |= isSpace
@ -92,7 +97,7 @@ func ParseList(header http.Header, key string) []string {
end := 0
escape := false
quote := false
for i := 0; i < len(s); i++ {
for i := range len(s) {
b := s[i]
switch {
case escape:

View file

@ -94,5 +94,6 @@ func normalizeOffers(orig []string) (norm []string) {
}
func normalizeOffer(orig string) string {
return strings.SplitN(orig, ";", 2)[0]
const maxParts = 2
return strings.SplitN(orig, ";", maxParts)[0]
}

View file

@ -24,12 +24,12 @@ import (
"strconv"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
"github.com/go-openapi/spec"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/swag/conv"
"github.com/go-openapi/swag/stringutils"
"github.com/go-openapi/validate"
"github.com/go-openapi/runtime"
)
const defaultMaxMemory = 32 << 20
@ -66,85 +66,6 @@ func (p *untypedParamBinder) Type() reflect.Type {
return p.typeForSchema(p.parameter.Type, p.parameter.Format, p.parameter.Items)
}
func (p *untypedParamBinder) typeForSchema(tpe, format string, items *spec.Items) reflect.Type {
switch tpe {
case "boolean":
return reflect.TypeOf(true)
case typeString:
if tt, ok := p.formats.GetType(format); ok {
return tt
}
return reflect.TypeOf("")
case "integer":
switch format {
case "int8":
return reflect.TypeOf(int8(0))
case "int16":
return reflect.TypeOf(int16(0))
case "int32":
return reflect.TypeOf(int32(0))
case "int64":
return reflect.TypeOf(int64(0))
default:
return reflect.TypeOf(int64(0))
}
case "number":
switch format {
case "float":
return reflect.TypeOf(float32(0))
case "double":
return reflect.TypeOf(float64(0))
}
case typeArray:
if items == nil {
return nil
}
itemsType := p.typeForSchema(items.Type, items.Format, items.Items)
if itemsType == nil {
return nil
}
return reflect.MakeSlice(reflect.SliceOf(itemsType), 0, 0).Type()
case "file":
return reflect.TypeOf(&runtime.File{}).Elem()
case "object":
return reflect.TypeOf(map[string]interface{}{})
}
return nil
}
func (p *untypedParamBinder) allowsMulti() bool {
return p.parameter.In == "query" || p.parameter.In == "formData"
}
func (p *untypedParamBinder) readValue(values runtime.Gettable, target reflect.Value) ([]string, bool, bool, error) {
name, in, cf, tpe := p.parameter.Name, p.parameter.In, p.parameter.CollectionFormat, p.parameter.Type
if tpe == typeArray {
if cf == "multi" {
if !p.allowsMulti() {
return nil, false, false, errors.InvalidCollectionFormat(name, in, cf)
}
vv, hasKey, _ := values.GetOK(name)
return vv, false, hasKey, nil
}
v, hk, hv := values.GetOK(name)
if !hv {
return nil, false, hk, nil
}
d, c, e := p.readFormattedSliceFieldValue(v[len(v)-1], target)
return d, c, hk, e
}
vv, hk, _ := values.GetOK(name)
return vv, false, hk, nil
}
func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams, consumer runtime.Consumer, target reflect.Value) error {
// fmt.Println("binding", p.name, "as", p.Type())
switch p.parameter.In {
@ -264,10 +185,89 @@ func (p *untypedParamBinder) Bind(request *http.Request, routeParams RouteParams
target.Set(reflect.Indirect(newValue))
return nil
default:
return errors.New(500, fmt.Sprintf("invalid parameter location %q", p.parameter.In))
return fmt.Errorf("%d: invalid parameter location %q", http.StatusInternalServerError, p.parameter.In)
}
}
func (p *untypedParamBinder) typeForSchema(tpe, format string, items *spec.Items) reflect.Type {
switch tpe {
case "boolean":
return reflect.TypeOf(true)
case typeString:
if tt, ok := p.formats.GetType(format); ok {
return tt
}
return reflect.TypeOf("")
case "integer":
switch format {
case "int8":
return reflect.TypeOf(int8(0))
case "int16":
return reflect.TypeOf(int16(0))
case "int32":
return reflect.TypeOf(int32(0))
case "int64":
return reflect.TypeOf(int64(0))
default:
return reflect.TypeOf(int64(0))
}
case "number":
switch format {
case "float":
return reflect.TypeOf(float32(0))
case "double":
return reflect.TypeOf(float64(0))
}
case typeArray:
if items == nil {
return nil
}
itemsType := p.typeForSchema(items.Type, items.Format, items.Items)
if itemsType == nil {
return nil
}
return reflect.MakeSlice(reflect.SliceOf(itemsType), 0, 0).Type()
case "file":
return reflect.TypeOf(&runtime.File{}).Elem()
case "object":
return reflect.TypeOf(map[string]interface{}{})
}
return nil
}
func (p *untypedParamBinder) allowsMulti() bool {
return p.parameter.In == "query" || p.parameter.In == "formData"
}
func (p *untypedParamBinder) readValue(values runtime.Gettable, target reflect.Value) ([]string, bool, bool, error) {
name, in, cf, tpe := p.parameter.Name, p.parameter.In, p.parameter.CollectionFormat, p.parameter.Type
if tpe == typeArray {
if cf == "multi" {
if !p.allowsMulti() {
return nil, false, false, errors.InvalidCollectionFormat(name, in, cf)
}
vv, hasKey, _ := values.GetOK(name)
return vv, false, hasKey, nil
}
v, hk, hv := values.GetOK(name)
if !hv {
return nil, false, hk, nil
}
d, c, e := p.readFormattedSliceFieldValue(v[len(v)-1], target)
return d, c, hk, e
}
vv, hk, _ := values.GetOK(name)
return vv, false, hk, nil
}
func (p *untypedParamBinder) bindValue(data []string, hasKey bool, target reflect.Value) error {
if p.parameter.Type == typeArray {
return p.setSliceFieldValue(target, p.parameter.Default, data, hasKey)
@ -331,7 +331,7 @@ func (p *untypedParamBinder) setFieldValue(target reflect.Value, defaultValue in
}
return nil
}
b, err := swag.ConvertBool(data)
b, err := conv.ConvertBool(data)
if err != nil {
return err
}
@ -431,7 +431,7 @@ func (p *untypedParamBinder) tryUnmarshaler(target reflect.Value, defaultValue i
return false, nil
}
// When a type implements encoding.TextUnmarshaler we'll use that instead of reflecting some more
if reflect.PtrTo(target.Type()).Implements(textUnmarshalType) {
if reflect.PointerTo(target.Type()).Implements(textUnmarshalType) {
if defaultValue != nil && len(data) == 0 {
target.Set(reflect.ValueOf(defaultValue))
return true, nil
@ -455,7 +455,7 @@ func (p *untypedParamBinder) readFormattedSliceFieldValue(data string, target re
return nil, true, nil
}
return swag.SplitByFormat(data, p.parameter.CollectionFormat), false, nil
return stringutils.SplitByFormat(data, p.parameter.CollectionFormat), false, nil
}
func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultValue interface{}, data []string, hasKey bool) error {
@ -479,7 +479,7 @@ func (p *untypedParamBinder) setSliceFieldValue(target reflect.Value, defaultVal
value := reflect.MakeSlice(reflect.SliceOf(target.Type().Elem()), sz, sz)
for i := 0; i < sz; i++ {
for i := range sz {
if err := p.setFieldValue(value.Index(i), nil, data[i], hasKey); err != nil {
return err
}

View file

@ -77,7 +77,7 @@ func (o *UntypedRequestBinder) Bind(request *http.Request, routeParams RoutePara
}
if !target.IsValid() {
result = append(result, errors.New(500, "parameter name %q is an unknown field", binder.Name))
result = append(result, errors.New(http.StatusInternalServerError, "parameter name %q is an unknown field", binder.Name))
continue
}

View file

@ -22,18 +22,16 @@ import (
"regexp"
"strings"
"github.com/go-openapi/runtime/logger"
"github.com/go-openapi/runtime/security"
"github.com/go-openapi/swag"
"github.com/go-openapi/analysis"
"github.com/go-openapi/errors"
"github.com/go-openapi/loads"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/logger"
"github.com/go-openapi/runtime/middleware/denco"
"github.com/go-openapi/runtime/security"
"github.com/go-openapi/spec"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware/denco"
"github.com/go-openapi/swag/stringutils"
)
// RouteParam is a object to capture route params in a framework agnostic way.
@ -336,6 +334,7 @@ type routeEntry struct {
// MatchedRoute represents the route that was matched in this request
type MatchedRoute struct {
routeEntry
Params RouteParams
Consumer runtime.Consumer
Producer runtime.Producer
@ -377,7 +376,8 @@ func (d *defaultRouter) Lookup(method, path string) (*MatchedRoute, bool) {
}
// a workaround to handle fragment/composing parameters until they are supported in denco router
// check if this parameter is a fragment within a path segment
if xpos := strings.Index(entry.PathPattern, fmt.Sprintf("{%s}", p.Name)) + len(p.Name) + 2; xpos < len(entry.PathPattern) && entry.PathPattern[xpos] != '/' {
const enclosureSize = 2
if xpos := strings.Index(entry.PathPattern, fmt.Sprintf("{%s}", p.Name)) + len(p.Name) + enclosureSize; xpos < len(entry.PathPattern) && entry.PathPattern[xpos] != '/' {
// extract fragment parameters
ep := strings.Split(entry.PathPattern[xpos:], "/")[0]
pnames, pvalues := decodeCompositParams(p.Name, v, ep, nil, nil)
@ -460,11 +460,11 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
parameters := d.analyzer.ParamsFor(method, strings.TrimPrefix(path, bp))
// add API defaults if not part of the spec
if defConsumes := d.api.DefaultConsumes(); defConsumes != "" && !swag.ContainsStringsCI(consumes, defConsumes) {
if defConsumes := d.api.DefaultConsumes(); defConsumes != "" && !stringutils.ContainsStringsCI(consumes, defConsumes) {
consumes = append(consumes, defConsumes)
}
if defProduces := d.api.DefaultProduces(); defProduces != "" && !swag.ContainsStringsCI(produces, defProduces) {
if defProduces := d.api.DefaultProduces(); defProduces != "" && !stringutils.ContainsStringsCI(produces, defProduces) {
produces = append(produces, defProduces)
}
@ -489,6 +489,20 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper
}
}
func (d *defaultRouteBuilder) Build() *defaultRouter {
routers := make(map[string]*denco.Router)
for method, records := range d.records {
router := denco.New()
_ = router.Build(records)
routers[method] = router
}
return &defaultRouter{
spec: d.spec,
routers: routers,
debugLogf: d.debugLogf,
}
}
func (d *defaultRouteBuilder) buildAuthenticators(operation *spec.Operation) RouteAuthenticators {
requirements := d.analyzer.SecurityRequirementsFor(operation)
auths := make([]RouteAuthenticator, 0, len(requirements))
@ -515,17 +529,3 @@ func (d *defaultRouteBuilder) buildAuthenticators(operation *spec.Operation) Rou
}
return auths
}
func (d *defaultRouteBuilder) Build() *defaultRouter {
routers := make(map[string]*denco.Router)
for method, records := range d.records {
router := denco.New()
_ = router.Build(records)
routers[method] = router
}
return &defaultRouter{
spec: d.spec,
routers: routers,
debugLogf: d.debugLogf,
}
}

View file

@ -168,6 +168,6 @@ func serveUI(pth string, assets []byte, next http.Handler) http.Handler {
rw.Header().Set(contentTypeHeader, "text/plain")
rw.WriteHeader(http.StatusNotFound)
_, _ = rw.Write([]byte(fmt.Sprintf("%q not found", pth)))
_, _ = fmt.Fprintf(rw, "%q not found", pth)
})
}

View file

@ -29,25 +29,10 @@ import (
"github.com/go-openapi/runtime"
)
// NewAPI creates the default untyped API
func NewAPI(spec *loads.Document) *API {
var an *analysis.Spec
if spec != nil && spec.Spec() != nil {
an = analysis.New(spec.Spec())
}
api := &API{
spec: spec,
analyzer: an,
consumers: make(map[string]runtime.Consumer, 10),
producers: make(map[string]runtime.Producer, 10),
authenticators: make(map[string]runtime.Authenticator),
operations: make(map[string]map[string]runtime.OperationHandler),
ServeError: errors.ServeError,
Models: make(map[string]func() interface{}),
formats: strfmt.NewFormats(),
}
return api.WithJSONDefaults()
}
const (
smallPreallocatedSlots = 10
mediumPreallocatedSlots = 30
)
// API represents an untyped mux for a swagger spec
type API struct {
@ -61,10 +46,31 @@ type API struct {
authorizer runtime.Authorizer
operations map[string]map[string]runtime.OperationHandler
ServeError func(http.ResponseWriter, *http.Request, error)
Models map[string]func() interface{}
Models map[string]func() any
formats strfmt.Registry
}
// NewAPI creates the default untyped API
func NewAPI(spec *loads.Document) *API {
var an *analysis.Spec
if spec != nil && spec.Spec() != nil {
an = analysis.New(spec.Spec())
}
api := &API{
spec: spec,
analyzer: an,
consumers: make(map[string]runtime.Consumer, smallPreallocatedSlots),
producers: make(map[string]runtime.Producer, smallPreallocatedSlots),
authenticators: make(map[string]runtime.Authenticator),
operations: make(map[string]map[string]runtime.OperationHandler),
ServeError: errors.ServeError,
Models: make(map[string]func() any),
formats: strfmt.NewFormats(),
}
return api.WithJSONDefaults()
}
// WithJSONDefaults loads the json defaults for this api
func (d *API) WithJSONDefaults() *API {
d.DefaultConsumes = runtime.JSONMime
@ -115,7 +121,7 @@ func (d *API) RegisterAuthorizer(handler runtime.Authorizer) {
// RegisterConsumer registers a consumer for a media type.
func (d *API) RegisterConsumer(mediaType string, handler runtime.Consumer) {
if d.consumers == nil {
d.consumers = make(map[string]runtime.Consumer, 10)
d.consumers = make(map[string]runtime.Consumer, smallPreallocatedSlots)
}
d.consumers[strings.ToLower(mediaType)] = handler
}
@ -123,7 +129,7 @@ func (d *API) RegisterConsumer(mediaType string, handler runtime.Consumer) {
// RegisterProducer registers a producer for a media type
func (d *API) RegisterProducer(mediaType string, handler runtime.Producer) {
if d.producers == nil {
d.producers = make(map[string]runtime.Producer, 10)
d.producers = make(map[string]runtime.Producer, smallPreallocatedSlots)
}
d.producers[strings.ToLower(mediaType)] = handler
}
@ -131,7 +137,7 @@ func (d *API) RegisterProducer(mediaType string, handler runtime.Producer) {
// RegisterOperation registers an operation handler for an operation name
func (d *API) RegisterOperation(method, path string, handler runtime.OperationHandler) {
if d.operations == nil {
d.operations = make(map[string]map[string]runtime.OperationHandler, 30)
d.operations = make(map[string]map[string]runtime.OperationHandler, mediumPreallocatedSlots)
}
um := strings.ToUpper(method)
if b, ok := d.operations[um]; !ok || b == nil {

View file

@ -20,9 +20,8 @@ import (
"strings"
"github.com/go-openapi/errors"
"github.com/go-openapi/swag"
"github.com/go-openapi/runtime"
"github.com/go-openapi/swag/stringutils"
)
type validation struct {
@ -30,7 +29,7 @@ type validation struct {
result []error
request *http.Request
route *MatchedRoute
bound map[string]interface{}
bound map[string]any
}
// ContentType validates the content type of a request
@ -42,14 +41,14 @@ func validateContentType(allowed []string, actual string) error {
if err != nil {
return errors.InvalidContentType(actual, allowed)
}
if swag.ContainsStringsCI(allowed, mt) {
if stringutils.ContainsStringsCI(allowed, mt) {
return nil
}
if swag.ContainsStringsCI(allowed, "*/*") {
if stringutils.ContainsStringsCI(allowed, "*/*") {
return nil
}
parts := strings.Split(actual, "/")
if len(parts) == 2 && swag.ContainsStringsCI(allowed, parts[0]+"/*") {
if len(parts) == 2 && stringutils.ContainsStringsCI(allowed, parts[0]+"/*") {
return nil
}
return errors.InvalidContentType(actual, allowed)
@ -60,7 +59,7 @@ func validateRequest(ctx *Context, request *http.Request, route *MatchedRoute) *
context: ctx,
request: request,
route: route,
bound: make(map[string]interface{}),
bound: make(map[string]any),
}
validate.debugLogf("validating request %s %s", request.Method, request.URL.EscapedPath())
@ -83,7 +82,7 @@ func (v *validation) parameters() {
v.debugLogf("validating request parameters for %s %s", v.request.Method, v.request.URL.EscapedPath())
if result := v.route.Binder.Bind(v.request, v.route.Params, v.route.Consumer, v.bound); result != nil {
if result.Error() == "validation failure list" {
for _, e := range result.(*errors.Validation).Value.([]interface{}) {
for _, e := range result.(*errors.Validation).Value.([]any) {
v.result = append(v.result, e.(error))
}
return
@ -111,7 +110,7 @@ func (v *validation) contentType() {
if ct != "" && v.route.Consumer == nil {
cons, ok := v.route.Consumers[ct]
if !ok {
v.result = append(v.result, errors.New(500, "no consumer registered for %s", ct))
v.result = append(v.result, errors.New(http.StatusInternalServerError, "no consumer registered for %s", ct))
} else {
v.route.Consumer = cons
}

View file

@ -22,7 +22,7 @@ import (
"net/http"
"strings"
"github.com/go-openapi/swag"
"github.com/go-openapi/swag/stringutils"
)
// CanHaveBody returns true if this method can have a body
@ -50,7 +50,7 @@ func HasBody(r *http.Request) bool {
return true
}
if r.Header.Get("content-length") != "" {
if r.Header.Get("Content-Length") != "" {
// in this case, no Transfer-Encoding should be present
// we have a header set but it was explicitly set to 0, so we assume no body
return false
@ -145,5 +145,5 @@ func ReadSingleValue(values Gettable, name string) string {
// ReadCollectionValue reads a collection value from a string data source
func ReadCollectionValue(values Gettable, name, collectionFormat string) []string {
v := ReadSingleValue(values, name)
return swag.SplitByFormat(v, collectionFormat)
return stringutils.SplitByFormat(v, collectionFormat)
}

View file

@ -31,7 +31,7 @@ const (
)
// HttpAuthenticator is a function that authenticates a HTTP request
func HttpAuthenticator(handler func(*http.Request) (bool, interface{}, error)) runtime.Authenticator { //nolint:revive,stylecheck
func HttpAuthenticator(handler func(*http.Request) (bool, interface{}, error)) runtime.Authenticator { //nolint:revive
return runtime.AuthenticatorFunc(func(params interface{}) (bool, interface{}, error) {
if request, ok := params.(*http.Request); ok {
return handler(request)
@ -159,7 +159,7 @@ func APIKeyAuth(name, in string, authenticate TokenAuthentication) runtime.Authe
inl := strings.ToLower(in)
if inl != query && inl != header {
// panic because this is most likely a typo
panic(errors.New(500, "api key auth: in value needs to be either \"query\" or \"header\""))
panic(errors.New(http.StatusInternalServerError, "api key auth: in value needs to be either \"query\" or \"header\""))
}
var getToken func(*http.Request) string
@ -187,7 +187,7 @@ func APIKeyAuthCtx(name, in string, authenticate TokenAuthenticationCtx) runtime
inl := strings.ToLower(in)
if inl != query && inl != header {
// panic because this is most likely a typo
panic(errors.New(500, "api key auth: in value needs to be either \"query\" or \"header\""))
panic(errors.New(http.StatusInternalServerError, "api key auth: in value needs to be either \"query\" or \"header\""))
}
var getToken func(*http.Request) string

View file

@ -22,7 +22,7 @@ import (
"io"
"reflect"
"github.com/go-openapi/swag"
"github.com/go-openapi/swag/jsonutils"
)
// TextConsumer creates a new text consumer
@ -99,7 +99,7 @@ func TextProducer() Producer {
v := reflect.Indirect(reflect.ValueOf(data))
if t := v.Type(); t.Kind() == reflect.Struct || t.Kind() == reflect.Slice {
b, err := swag.WriteJSON(data)
b, err := jsonutils.WriteJSON(data)
if err != nil {
return err
}

View file

@ -18,12 +18,12 @@ import (
"io"
"github.com/go-openapi/runtime"
"gopkg.in/yaml.v3"
yaml "go.yaml.in/yaml/v3"
)
// YAMLConsumer creates a consumer for yaml data
func YAMLConsumer() runtime.Consumer {
return runtime.ConsumerFunc(func(r io.Reader, v interface{}) error {
return runtime.ConsumerFunc(func(r io.Reader, v any) error {
dec := yaml.NewDecoder(r)
return dec.Decode(v)
})
@ -31,7 +31,7 @@ func YAMLConsumer() runtime.Consumer {
// YAMLProducer creates a producer for yaml data
func YAMLProducer() runtime.Producer {
return runtime.ProducerFunc(func(w io.Writer, v interface{}) error {
return runtime.ProducerFunc(func(w io.Writer, v any) error {
enc := yaml.NewEncoder(w)
defer enc.Close()
return enc.Encode(v)