...

Source file src/github.com/go-openapi/runtime/middleware/swaggerui.go

Documentation: github.com/go-openapi/runtime/middleware

     1  package middleware
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"html/template"
     7  	"net/http"
     8  	"path"
     9  )
    10  
    11  // SwaggerUIOpts configures the SwaggerUI middleware
    12  type SwaggerUIOpts struct {
    13  	// BasePath for the API, defaults to: /
    14  	BasePath string
    15  
    16  	// Path combines with BasePath to construct the path to the UI, defaults to: "docs".
    17  	Path string
    18  
    19  	// SpecURL is the URL of the spec document.
    20  	//
    21  	// Defaults to: /swagger.json
    22  	SpecURL string
    23  
    24  	// Title for the documentation site, default to: API documentation
    25  	Title string
    26  
    27  	// Template specifies a custom template to serve the UI
    28  	Template string
    29  
    30  	// OAuthCallbackURL the url called after OAuth2 login
    31  	OAuthCallbackURL string
    32  
    33  	// The three components needed to embed swagger-ui
    34  
    35  	// SwaggerURL points to the js that generates the SwaggerUI site.
    36  	//
    37  	// Defaults to: https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js
    38  	SwaggerURL string
    39  
    40  	SwaggerPresetURL string
    41  	SwaggerStylesURL string
    42  
    43  	Favicon32 string
    44  	Favicon16 string
    45  }
    46  
    47  // EnsureDefaults in case some options are missing
    48  func (r *SwaggerUIOpts) EnsureDefaults() {
    49  	r.ensureDefaults()
    50  
    51  	if r.Template == "" {
    52  		r.Template = swaggeruiTemplate
    53  	}
    54  }
    55  
    56  func (r *SwaggerUIOpts) EnsureDefaultsOauth2() {
    57  	r.ensureDefaults()
    58  
    59  	if r.Template == "" {
    60  		r.Template = swaggerOAuthTemplate
    61  	}
    62  }
    63  
    64  func (r *SwaggerUIOpts) ensureDefaults() {
    65  	common := toCommonUIOptions(r)
    66  	common.EnsureDefaults()
    67  	fromCommonToAnyOptions(common, r)
    68  
    69  	// swaggerui-specifics
    70  	if r.OAuthCallbackURL == "" {
    71  		r.OAuthCallbackURL = path.Join(r.BasePath, r.Path, "oauth2-callback")
    72  	}
    73  	if r.SwaggerURL == "" {
    74  		r.SwaggerURL = swaggerLatest
    75  	}
    76  	if r.SwaggerPresetURL == "" {
    77  		r.SwaggerPresetURL = swaggerPresetLatest
    78  	}
    79  	if r.SwaggerStylesURL == "" {
    80  		r.SwaggerStylesURL = swaggerStylesLatest
    81  	}
    82  	if r.Favicon16 == "" {
    83  		r.Favicon16 = swaggerFavicon16Latest
    84  	}
    85  	if r.Favicon32 == "" {
    86  		r.Favicon32 = swaggerFavicon32Latest
    87  	}
    88  }
    89  
    90  // SwaggerUI creates a middleware to serve a documentation site for a swagger spec.
    91  //
    92  // This allows for altering the spec before starting the http listener.
    93  func SwaggerUI(opts SwaggerUIOpts, next http.Handler) http.Handler {
    94  	opts.EnsureDefaults()
    95  
    96  	pth := path.Join(opts.BasePath, opts.Path)
    97  	tmpl := template.Must(template.New("swaggerui").Parse(opts.Template))
    98  	assets := bytes.NewBuffer(nil)
    99  	if err := tmpl.Execute(assets, opts); err != nil {
   100  		panic(fmt.Errorf("cannot execute template: %w", err))
   101  	}
   102  
   103  	return serveUI(pth, assets.Bytes(), next)
   104  }
   105  
   106  const (
   107  	swaggerLatest          = "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js"
   108  	swaggerPresetLatest    = "https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js"
   109  	swaggerStylesLatest    = "https://unpkg.com/swagger-ui-dist/swagger-ui.css"
   110  	swaggerFavicon32Latest = "https://unpkg.com/swagger-ui-dist/favicon-32x32.png"
   111  	swaggerFavicon16Latest = "https://unpkg.com/swagger-ui-dist/favicon-16x16.png"
   112  	swaggeruiTemplate      = `
   113  <!DOCTYPE html>
   114  <html lang="en">
   115    <head>
   116      <meta charset="UTF-8">
   117  		<title>{{ .Title }}</title>
   118  
   119      <link rel="stylesheet" type="text/css" href="{{ .SwaggerStylesURL }}" >
   120      <link rel="icon" type="image/png" href="{{ .Favicon32 }}" sizes="32x32" />
   121      <link rel="icon" type="image/png" href="{{ .Favicon16 }}" sizes="16x16" />
   122      <style>
   123        html
   124        {
   125          box-sizing: border-box;
   126          overflow: -moz-scrollbars-vertical;
   127          overflow-y: scroll;
   128        }
   129  
   130        *,
   131        *:before,
   132        *:after
   133        {
   134          box-sizing: inherit;
   135        }
   136  
   137        body
   138        {
   139          margin:0;
   140          background: #fafafa;
   141        }
   142      </style>
   143    </head>
   144  
   145    <body>
   146      <div id="swagger-ui"></div>
   147  
   148      <script src="{{ .SwaggerURL }}"> </script>
   149      <script src="{{ .SwaggerPresetURL }}"> </script>
   150      <script>
   151      window.onload = function() {
   152        // Begin Swagger UI call region
   153        const ui = SwaggerUIBundle({
   154          url: '{{ .SpecURL }}',
   155          dom_id: '#swagger-ui',
   156          deepLinking: true,
   157          presets: [
   158            SwaggerUIBundle.presets.apis,
   159            SwaggerUIStandalonePreset
   160          ],
   161          plugins: [
   162            SwaggerUIBundle.plugins.DownloadUrl
   163          ],
   164          layout: "StandaloneLayout",
   165  		oauth2RedirectUrl: '{{ .OAuthCallbackURL }}'
   166        })
   167        // End Swagger UI call region
   168  
   169        window.ui = ui
   170      }
   171    </script>
   172    </body>
   173  </html>
   174  `
   175  )
   176  

View as plain text