Files
2026-06-12 13:43:37 +02:00

483 lines
13 KiB
Go

// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0
package middleware
import (
"net/http"
"path"
"strings"
"github.com/go-openapi/runtime/server-middleware/docui"
"github.com/go-openapi/runtime/server-middleware/negotiate"
)
/////////////////////////////////////////////////////////:
// Seam to the negotiate options introduced in v0.29.5
/////////////////////////////////////////////////////////:
// NegotiateOption configures [NegotiateContentType] behaviour.
//
// Deprecated: moved to the [negotiate] package. Use [negotiate.Option] instead.
type NegotiateOption = negotiate.Option
// NegotiateContentType returns the best offered content type for the
// request's Accept header.
//
// Deprecated: moved to the [negotiate] package. Use [negotiate.ContentType] instead.
func NegotiateContentType(r *http.Request, offers []string, defaultOffer string, opts ...NegotiateOption) string {
return negotiate.ContentType(r, offers, defaultOffer, opts...)
}
// NegotiateContentEncoding returns the best offered content encoding for
// the request's Accept-Encoding header.
//
// Deprecated: moved to the [negotiate] package. Use [negotiate.ContentEncoding] instead.
func NegotiateContentEncoding(r *http.Request, offers []string) string {
return negotiate.ContentEncoding(r, offers)
}
// WithIgnoreParameters returns a [NegotiateOption] that strips MIME-type
// parameters from both Accept entries and offers before matching,
// restoring the pre-v0.30 behaviour.
//
// Deprecated: moved to the [negotiate] package. Use [negotiate.WithIgnoreParameters] instead.
func WithIgnoreParameters(ignore bool) NegotiateOption {
return negotiate.WithIgnoreParameters(ignore)
}
/////////////////////////////////////////////////////////:
// Seam to the UI options
/////////////////////////////////////////////////////////:
// RapiDoc creates a [http.Handler] to serve a documentation site for a swagger spec.
//
// This allows for altering the spec before starting the [http] listener.
//
// Deprecated: moved to the [docui] package. Use [docui.RapiDoc] instead.
func RapiDoc(opts RapiDocOpts, next http.Handler) http.Handler {
return docui.RapiDoc(next, opts.toFuncOptions()...)
}
// Redoc creates a [http.Handler] to serve a documentation site for a swagger spec.
//
// This allows for altering the spec before starting the [http] listener.
//
// Deprecated: moved to the [docui] package. Use [docui.Redoc] instead.
func Redoc(opts RedocOpts, next http.Handler) http.Handler {
return docui.Redoc(next, opts.toFuncOptions()...)
}
// SwaggerUI creates a [http.Handler] to serve a documentation site for a swagger spec.
//
// This allows for altering the spec before starting the [http] listener.
//
// Deprecated: moved to the [docui] package. Use [docui.SwaggerUI] instead.
func SwaggerUI(opts SwaggerUIOpts, next http.Handler) http.Handler {
return docui.SwaggerUI(next, opts.toFuncOptions()...)
}
// SwaggerUIOAuth2Callback creates a middleware that serves the OAuth2 callback page used by Swagger UI.
//
// Deprecated: moved to the [docui] package. Use [docui.SwaggerUIOAuth2Callback] instead.
func SwaggerUIOAuth2Callback(opts SwaggerUIOpts, next http.Handler) http.Handler {
return docui.SwaggerUIOAuth2Callback(next, opts.toFuncOptions()...)
}
/////////////////////////////////////////////////////////:
// Seam to the spec middleware options
/////////////////////////////////////////////////////////:
// SpecOption can be applied to the [Spec] serving [middleware].
//
// Deprecated: moved to the [docui] package. Use [docui.SpecOption] instead.
type SpecOption func(*specOptions)
type specOptions struct {
BasePath string
Path string
Document string
}
func (o specOptions) fullPath() string {
return path.Join(o.BasePath, o.Path, o.Document)
}
func specOptionsWithDefaults(basePath string, opts []SpecOption) specOptions {
o := specOptions{
BasePath: "/",
Path: "",
Document: "swagger.json",
}
for _, apply := range opts {
apply(&o)
}
if basePath != "" {
o.BasePath = basePath
}
return o
}
// Spec creates a [middleware] to serve a swagger spec as a JSON document.
//
// This allows for altering the spec before starting the [http] listener.
//
// The basePath argument indicates the path of the spec document (defaults to "/").
// Additional [SpecOption] can be used to change the name of the document (defaults to "swagger.json").
//
// Deprecated: moved to the [docui] package as [docui.ServeSpec].
func Spec(basePath string, spec []byte, next http.Handler, opts ...SpecOption) http.Handler {
o := specOptionsWithDefaults(basePath, opts)
return docui.ServeSpec(spec, next, docui.WithSpecPath(o.fullPath()))
}
// WithSpecPath sets the path to be joined to the base path of the
// spec-serving middleware (see [docui.ServeSpec]).
//
// This is empty by default.
func WithSpecPath(pth string) SpecOption {
return func(o *specOptions) {
o.Path = pth
}
}
// WithSpecDocument sets the name of the JSON document served as a spec.
//
// By default, this is "swagger.json".
func WithSpecDocument(doc string) SpecOption {
return func(o *specOptions) {
if doc == "" {
return
}
o.Document = doc
}
}
// UIOptions defines common options for UI serving middlewares.
//
// Deprecated: use instead the function options provided by [docui].
type UIOptions struct {
// BasePath for the UI, defaults to: /
BasePath string
// Path combines with BasePath to construct the path to the UI, defaults to: "docs".
Path string
// SpecURL is the URL of the spec document.
//
// Defaults to: /swagger.json
SpecURL string
// Title for the documentation site, default to: API documentation
Title string
// Template specifies a custom template to serve the UI
Template string
}
// toFuncOptions bridges the deprecated options struct with the newer function options in [docui].
func (o UIOptions) toFuncOptions() []docui.Option {
const structMembers = 5
opts := make([]docui.Option, 0, structMembers)
if o.BasePath != "" {
opts = append(opts, docui.WithUIBasePath(o.BasePath))
}
if o.Path != "" {
opts = append(opts, docui.WithUIPath(o.Path))
}
if o.SpecURL != "" {
opts = append(opts, docui.WithSpecURL(o.SpecURL))
}
if o.Title != "" {
opts = append(opts, docui.WithUITitle(o.Title))
}
if o.Template != "" {
opts = append(opts, docui.WithUITemplate(o.Template))
}
return opts
}
// RapiDocOpts configures the [RapiDoc] middlewares.
//
// Deprecated: use instead the function options provided by [docui].
type RapiDocOpts struct {
// BasePath for the UI, defaults to: /
BasePath string
// Path combines with BasePath to construct the path to the UI, defaults to: "docs".
Path string
// SpecURL is the URL of the spec document.
//
// Defaults to: /swagger.json
SpecURL string
// Title for the documentation site, default to: API documentation
Title string
// Template specifies a custom template to serve the UI
Template string
// RapiDocURL points to the js asset that generates the rapidoc site.
//
// Defaults to https://unpkg.com/rapidoc/dist/rapidoc-min.js
RapiDocURL string
}
func (o RapiDocOpts) toFuncOptions() []docui.Option {
const structMembers = 6
opts := make([]docui.Option, 0, structMembers)
if o.BasePath != "" {
opts = append(opts, docui.WithUIBasePath(o.BasePath))
}
if o.Path != "" {
opts = append(opts, docui.WithUIPath(o.Path))
}
if o.SpecURL != "" {
opts = append(opts, docui.WithSpecURL(o.SpecURL))
}
if o.Title != "" {
opts = append(opts, docui.WithUITitle(o.Title))
}
if o.Template != "" {
opts = append(opts, docui.WithUITemplate(o.Template))
}
if o.RapiDocURL != "" {
opts = append(opts, docui.WithUIAssetsURL(o.RapiDocURL))
}
return opts
}
// RedocOpts configures the [Redoc] middlewares.
//
// Deprecated: use instead the function options provided by [docui].
type RedocOpts struct {
// BasePath for the UI, defaults to: /
BasePath string
// Path combines with BasePath to construct the path to the UI, defaults to: "docs".
Path string
// SpecURL is the URL of the spec document.
//
// Defaults to: /swagger.json
SpecURL string
// Title for the documentation site, default to: API documentation
Title string
// Template specifies a custom template to serve the UI
Template string
// RedocURL points to the js that generates the redoc site.
//
// Defaults to: https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js
RedocURL string
}
func (o RedocOpts) toFuncOptions() []docui.Option {
const structMembers = 6
opts := make([]docui.Option, 0, structMembers)
if o.BasePath != "" {
opts = append(opts, docui.WithUIBasePath(o.BasePath))
}
if o.Path != "" {
opts = append(opts, docui.WithUIPath(o.Path))
}
if o.SpecURL != "" {
opts = append(opts, docui.WithSpecURL(o.SpecURL))
}
if o.Title != "" {
opts = append(opts, docui.WithUITitle(o.Title))
}
if o.Template != "" {
opts = append(opts, docui.WithUITemplate(o.Template))
}
if o.RedocURL != "" {
opts = append(opts, docui.WithUIAssetsURL(o.RedocURL))
}
return opts
}
// SwaggerUIOpts configures the [SwaggerUI] [middleware].
//
// Deprecated: use instead the function options provided by [docui].
type SwaggerUIOpts struct {
// BasePath for the API, defaults to: /
BasePath string
// Path combines with BasePath to construct the path to the UI, defaults to: "docs".
Path string
// SpecURL is the URL of the spec document.
//
// Defaults to: /swagger.json
SpecURL string
// Title for the documentation site, default to: API documentation
Title string
// Template specifies a custom template to serve the UI
Template string
// OAuthCallbackURL the url called after OAuth2 login
//
// NOTE: in the new [docui.SwaggerUIOptions] type, this field is named `OAuth2CallbackURL`,
// which is more appropriate.
OAuthCallbackURL string
// The three components needed to embed swagger-ui
// SwaggerURL points to the js that generates the SwaggerUI site.
//
// Defaults to: https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js
SwaggerURL string
SwaggerPresetURL string
SwaggerStylesURL string
Favicon32 string
Favicon16 string
}
func (o SwaggerUIOpts) toFuncOptions() []docui.Option {
const structMembers = 6
opts := make([]docui.Option, 0, structMembers)
if o.BasePath != "" {
opts = append(opts, docui.WithUIBasePath(o.BasePath))
}
if o.Path != "" {
opts = append(opts, docui.WithUIPath(o.Path))
}
if o.SpecURL != "" {
opts = append(opts, docui.WithSpecURL(o.SpecURL))
}
if o.Title != "" {
opts = append(opts, docui.WithUITitle(o.Title))
}
if o.Template != "" {
opts = append(opts, docui.WithUITemplate(o.Template))
}
if o.SwaggerURL != "" {
opts = append(opts, docui.WithUIAssetsURL(o.SwaggerURL))
}
var empty SwaggerUIOpts
if o != empty {
swaggeruiOpts := docui.SwaggerUIOptions{
OAuth2CallbackURL: o.OAuthCallbackURL,
SwaggerPresetURL: o.SwaggerPresetURL,
SwaggerStylesURL: o.SwaggerStylesURL,
Favicon32: o.Favicon32,
Favicon16: o.Favicon16,
}
opts = append(opts, docui.WithSwaggerUIOptions(swaggeruiOpts))
}
return opts
}
// UIOption can be applied to UI serving [middleware] to alter the default
// behavior.
//
// Deprecated: use instead the function options provided by [docui].
type UIOption func(*UIOptions)
// uiOptionsWithDefaults applies the given options on top of an empty
// [UIOptions]. Per-flavor handlers ([SwaggerUI], [Redoc], [RapiDoc])
// fill in the remaining defaults via [UIOptions.EnsureDefaults] when
// the option struct is used.
func uiOptionsWithDefaults(opts []UIOption) UIOptions {
var o UIOptions
for _, apply := range opts {
apply(&o)
}
return o
}
// WithUIBasePath sets the base path from where to serve the UI assets.
//
// Deprecated: use instead the function options provided by [docui].
func WithUIBasePath(base string) UIOption {
return func(o *UIOptions) {
if !strings.HasPrefix(base, "/") {
base = "/" + base
}
o.BasePath = base
}
}
// WithUIPath sets the path from where to serve the UI assets (i.e. /{basepath}/{path}.
//
// Deprecated: use instead the function options provided by [docui].
func WithUIPath(pth string) UIOption {
return func(o *UIOptions) {
o.Path = pth
}
}
// WithUISpecURL sets the path from where to serve swagger spec document.
//
// This may be specified as a full URL or a path.
//
// By default, this is "/swagger.json".
//
// Deprecated: use instead the function options provided by [docui].
func WithUISpecURL(specURL string) UIOption {
return func(o *UIOptions) {
o.SpecURL = specURL
}
}
// WithUITitle sets the title of the UI.
//
// Deprecated: use instead the function options provided by [docui].
func WithUITitle(title string) UIOption {
return func(o *UIOptions) {
o.Title = title
}
}
// WithTemplate allows to set a custom template for the UI.
//
// UI [middleware] will panic if the template does not parse or execute properly.
//
// Deprecated: use instead the function options provided by [docui].
func WithTemplate(tpl string) UIOption {
return func(o *UIOptions) {
o.Template = tpl
}
}