Skip to content

Commit

Permalink
embeds swagger ui
Browse files Browse the repository at this point in the history
  • Loading branch information
casualjim committed Jan 23, 2015
1 parent 25483d9 commit d9f0ec4
Show file tree
Hide file tree
Showing 30 changed files with 14,138 additions and 26 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ before_install:

# get the dependencies etc
- go get github.com/tools/godep
- go get github.com/jteeuwen/go-bindata/go-bindata
- go get github.com/jteeuwen/go-bindata/...
- go get github.com/elazarl/go-bindata-assetfs/...
- godep restore

script:
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Swagger 2.0

[![Build Status](https://travis-ci.org/casualjim/go-swagger.svg?branch=feature/serve)](https://travis-ci.org/casualjim/go-swagger)
[![Coverage Status](https://coveralls.io/repos/casualjim/go-swagger/badge.png?branch=feature/serve)](https://coveralls.io/r/casualjim/go-swagger?branch=feature/serve)
[![Build Status](https://travis-ci.org/casualjim/go-swagger.svg?branch=master)](https://travis-ci.org/casualjim/go-swagger)
[![Coverage Status](https://coveralls.io/repos/casualjim/go-swagger/badge.svg?branch=master)](https://coveralls.io/r/casualjim/go-swagger?branch=master)
[![GoDoc](https://godoc.org/github.com/casualjim/go-swagger?status.svg)](http://godoc.org/github.com/casualjim/go-swagger)
[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/swagger-api/swagger-spec/master/LICENSE)

Expand Down Expand Up @@ -45,6 +45,7 @@ Currently there is a spec validator tool:
- [ ] generate tests based on swagger spec for server
- [ ] generate tests based on swagger spec for client
- [x] Middlewares:
- [x] serve spec
- [x] routing
- [x] validation
- [ ] authorization
Expand Down
169 changes: 147 additions & 22 deletions assets/bindata.go

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion middleware/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/casualjim/go-swagger/httputils"
"github.com/casualjim/go-swagger/router"
"github.com/casualjim/go-swagger/spec"
"github.com/casualjim/go-swagger/swagger-ui"
"github.com/casualjim/go-swagger/validate"
"github.com/golang/gddo/httputil"
"github.com/gorilla/context"
Expand Down Expand Up @@ -35,8 +36,10 @@ func Serve(spec *spec.Document, api *swagger.API) http.Handler {

terminator := context.OperationHandlerMiddleware()
validator := context.ValidationMiddleware(terminator)
router := context.RouterMiddleware(validator)
swaggerUI := swaggerui.Middleware(router)

return specMiddleware(context, context.RouterMiddleware(validator))
return specMiddleware(context, swaggerUI)
}

type contextKey int8
Expand Down
192 changes: 192 additions & 0 deletions swagger-ui/assetfs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package swaggerui

import (
"bytes"
"errors"
"io"
"io/ioutil"
"net/http"
"os"
"path"
"path/filepath"
"strings"
"time"
)

var (
fileTimestamp = time.Now()
)

// FakeFile implements os.FileInfo interface for a given path and size
type FakeFile struct {
// Path is the path of this file
Path string
// Dir marks of the path is a directory
Dir bool
// Len is the length of the fake file, zero if it is a directory
Len int64
}

func (f *FakeFile) Name() string {
_, name := filepath.Split(f.Path)
return name
}

func (f *FakeFile) Mode() os.FileMode {
mode := os.FileMode(0644)
if f.Dir {
return mode | os.ModeDir
}
return mode
}

func (f *FakeFile) ModTime() time.Time {
return fileTimestamp
}

func (f *FakeFile) Size() int64 {
return f.Len
}

func (f *FakeFile) IsDir() bool {
return f.Mode().IsDir()
}

func (f *FakeFile) Sys() interface{} {
return nil
}

// AssetFile implements http.File interface for a no-directory file with content
type AssetFile struct {
*bytes.Reader
io.Closer
FakeFile
}

func NewAssetFile(name string, content []byte) *AssetFile {
return &AssetFile{
bytes.NewReader(content),
ioutil.NopCloser(nil),
FakeFile{name, false, int64(len(content))}}
}

func (f *AssetFile) Readdir(count int) ([]os.FileInfo, error) {
return nil, errors.New("not a directory")
}

func (f *AssetFile) Stat() (os.FileInfo, error) {
return f, nil
}

// AssetDirectory implements http.File interface for a directory
type AssetDirectory struct {
AssetFile
ChildrenRead int
Children []os.FileInfo
}

func NewAssetDirectory(name string, children []string, fs *AssetFS) *AssetDirectory {
fileinfos := make([]os.FileInfo, 0, len(children))
for _, child := range children {
_, err := fs.AssetDir(filepath.Join(name, child))
fileinfos = append(fileinfos, &FakeFile{child, err == nil, 0})
}
return &AssetDirectory{
AssetFile{
bytes.NewReader(nil),
ioutil.NopCloser(nil),
FakeFile{name, true, 0},
},
0,
fileinfos}
}

func (f *AssetDirectory) Readdir(count int) ([]os.FileInfo, error) {
if count <= 0 {
return f.Children, nil
}
if f.ChildrenRead+count > len(f.Children) {
count = len(f.Children) - f.ChildrenRead
}
rv := f.Children[f.ChildrenRead : f.ChildrenRead+count]
f.ChildrenRead += count
return rv, nil
}

func (f *AssetDirectory) Stat() (os.FileInfo, error) {
return f, nil
}

// AssetFS implements http.FileSystem, allowing
// embedded files to be served from net/http package.
type AssetFS struct {
// Asset should return content of file in path if exists
Asset func(path string) ([]byte, error)
// AssetDir should return list of files in the path
AssetDir func(path string) ([]string, error)
// Prefix would be prepended to http requests
Prefix string

Strip string
}

func (fs *AssetFS) Open(name string) (http.File, error) {
if name == fs.Strip {
name = fs.Strip + "/index.html"
}

// name = path.Join(fs.Prefix, name)
if len(name) > 0 && name[0] == '/' {
name = name[1:]
}
if name == "" || name == fs.Strip {
name = fs.Strip + "/index.html"
}

if strings.Count(name, "/") > 1 {
if children, err := fs.AssetDir(name); err == nil {
return NewAssetDirectory(name, children, fs), nil
}

}

b, err := fs.Asset(name)
if err != nil {
return nil, err
}
return NewAssetFile(path.Join(fs.Prefix, name), b), nil
}

// Middleware creates a middleware to serve swagger-ui at /swagger-ui
func Middleware(next http.Handler) http.Handler {
return middlewareAt("/swagger-ui", next)
}

// MiddlewareAt creates a middleware to serve swagger ui at the specified basePath
func middlewareAt(basePath string, next http.Handler) http.Handler {
assetFS := func() *AssetFS {
for k := range _bintree.Children {
return &AssetFS{Asset: Asset, AssetDir: AssetDir, Prefix: basePath + "/" + k, Strip: basePath}
}
panic("unreachable")
}

fileServer := http.FileServer(assetFS())

return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/favico") {
rw.WriteHeader(http.StatusNotFound)
}

if strings.HasPrefix(r.URL.Path, basePath) {
fileServer.ServeHTTP(rw, r)
return
}

if next == nil {
rw.WriteHeader(http.StatusNotFound)
} else {
next.ServeHTTP(rw, r)
}
})
}
757 changes: 757 additions & 0 deletions swagger-ui/bindata.go

Large diffs are not rendered by default.

125 changes: 125 additions & 0 deletions swagger-ui/css/reset.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 */
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
ol,
ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
Loading

0 comments on commit d9f0ec4

Please sign in to comment.