-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from InVisionApp/add-statics
Adding static file handlers
- Loading branch information
Showing
10 changed files
with
397 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package rye | ||
|
||
import ( | ||
"net/http" | ||
) | ||
|
||
type staticFile struct { | ||
path string | ||
} | ||
|
||
/* | ||
NewStaticFile creates a new handler to serve a file from a path on the local filesystem. | ||
The path should be an absolute path -> i.e., it's up to the program using Rye to | ||
correctly determine what path it should be serving from. An example is available | ||
in the `static_example.go` file which shows setting up a path relative to | ||
the go executable. | ||
The purpose of this handler is to serve a specific file for any requests through the | ||
route handler. For instance, in the example below, any requests made to `/ui` will | ||
always be routed to /dist/index.html. This is important for single page applications | ||
which happen to use client-side routers. Therefore, you might have a webpack application | ||
with it's entrypoint `/dist/index.html`. That file may point at your `bundle.js`. | ||
Every request into the app will need to always be routed to `/dist/index.html` | ||
Example use case: | ||
routes.PathPrefix("/ui/").Handler(middlewareHandler.Handle([]rye.Handler{ | ||
rye.MiddlewareRouteLogger(), | ||
rye.NewStaticFile(pwd + "/dist/index.html"), | ||
})) | ||
*/ | ||
func NewStaticFile(path string) func(rw http.ResponseWriter, req *http.Request) *Response { | ||
s := &staticFile{ | ||
path: path, | ||
} | ||
return s.handle | ||
} | ||
|
||
func (s *staticFile) handle(rw http.ResponseWriter, req *http.Request) *Response { | ||
http.ServeFile(rw, req, s.path) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package rye | ||
|
||
import ( | ||
"io/ioutil" | ||
"net/http" | ||
"net/http/httptest" | ||
"net/url" | ||
"os" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("Static File Middleware", func() { | ||
|
||
var ( | ||
request *http.Request | ||
response *httptest.ResponseRecorder | ||
|
||
path string | ||
testPath string | ||
) | ||
|
||
BeforeEach(func() { | ||
response = httptest.NewRecorder() | ||
request = &http.Request{} | ||
testPath, _ = os.Getwd() | ||
}) | ||
|
||
Describe("handle", func() { | ||
Context("when a valid file is referenced", func() { | ||
It("should return a response", func() { | ||
path = "/static-examples/dist/index.html" | ||
url, _ := url.Parse("/thisstuff") | ||
request.URL = url | ||
resp := NewStaticFile(testPath+path)(response, request) | ||
Expect(resp).To(BeNil()) | ||
Expect(response).ToNot(BeNil()) | ||
Expect(response.Code).To(Equal(200)) | ||
|
||
body, err := ioutil.ReadAll(response.Body) | ||
Expect(err).To(BeNil()) | ||
Expect(body).To(ContainSubstring("Index.html")) | ||
}) | ||
|
||
It("should return a Moved Permanently response", func() { | ||
path = "/static-examples/dist/index.html" | ||
url, _ := url.Parse("/thisstuff") | ||
request.URL = url | ||
resp := NewStaticFile("")(response, request) | ||
Expect(resp).To(BeNil()) | ||
Expect(response).ToNot(BeNil()) | ||
Expect(response.Code).To(Equal(301)) | ||
}) | ||
|
||
It("should return a File Not Found response", func() { | ||
path = "/static-examples/dist/index.html" | ||
url, _ := url.Parse("/thisstuff") | ||
request.URL = url | ||
resp := NewStaticFile(path)(response, request) | ||
Expect(resp).To(BeNil()) | ||
Expect(response).ToNot(BeNil()) | ||
Expect(response.Code).To(Equal(404)) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package rye | ||
|
||
import ( | ||
"net/http" | ||
) | ||
|
||
type staticFilesystem struct { | ||
path string | ||
stripPrefix string | ||
} | ||
|
||
/* | ||
NewStaticFilesystem creates a new handler to serve a filesystem from a path | ||
on the local filesystem. The path should be an absolute path -> i.e., it's | ||
up to the program using Rye to correctly determine what path it should be | ||
serving from. An example is available in the `static_example.go` file which | ||
shows setting up a path relative to the go executable. | ||
The primary benefit of this is to serve an entire set of files. You can | ||
pre-pend typical Rye middlewares to the chain. The static filesystem | ||
middleware should always be last in a chain, however. The `stripPrefix` allows | ||
you to ignore the prefix on requests so that the proper files will be matched. | ||
Example use case: | ||
routes.PathPrefix("/dist/").Handler(middlewareHandler.Handle([]rye.Handler{ | ||
rye.MiddlewareRouteLogger(), | ||
rye.NewStaticFilesystem(pwd+"/dist/", "/dist/"), | ||
})) | ||
*/ | ||
func NewStaticFilesystem(path string, stripPrefix string) func(rw http.ResponseWriter, req *http.Request) *Response { | ||
s := &staticFilesystem{ | ||
path: path, | ||
stripPrefix: stripPrefix, | ||
} | ||
return s.handle | ||
} | ||
|
||
func (s *staticFilesystem) handle(rw http.ResponseWriter, req *http.Request) *Response { | ||
x := http.StripPrefix(s.stripPrefix, http.FileServer(http.Dir(s.path))) | ||
x.ServeHTTP(rw, req) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package rye | ||
|
||
import ( | ||
"io/ioutil" | ||
"net/http" | ||
"net/http/httptest" | ||
"os" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("Static File Middleware", func() { | ||
|
||
var ( | ||
request *http.Request | ||
response *httptest.ResponseRecorder | ||
|
||
path string | ||
testPath string | ||
) | ||
|
||
BeforeEach(func() { | ||
response = httptest.NewRecorder() | ||
request = &http.Request{} | ||
testPath, _ = os.Getwd() | ||
}) | ||
|
||
Describe("handle", func() { | ||
Context("when a valid file is referenced", func() { | ||
It("should return a response", func() { | ||
path = "/static-examples/dist/" | ||
|
||
request, _ := http.NewRequest("GET", "/dist/test.html", nil) | ||
|
||
resp := NewStaticFilesystem(testPath+path, "/dist/")(response, request) | ||
Expect(resp).To(BeNil()) | ||
Expect(response).ToNot(BeNil()) | ||
Expect(response.Code).To(Equal(200)) | ||
|
||
body, err := ioutil.ReadAll(response.Body) | ||
Expect(err).To(BeNil()) | ||
Expect(body).To(ContainSubstring("Test.html")) | ||
}) | ||
|
||
It("should return Index.html when request is just path", func() { | ||
path = "/static-examples/dist/" | ||
|
||
request, _ := http.NewRequest("GET", "/dist/", nil) | ||
|
||
resp := NewStaticFilesystem(testPath+path, "/dist/")(response, request) | ||
Expect(resp).To(BeNil()) | ||
Expect(response).ToNot(BeNil()) | ||
Expect(response.Code).To(Equal(200)) | ||
|
||
body, err := ioutil.ReadAll(response.Body) | ||
Expect(err).To(BeNil()) | ||
Expect(body).To(ContainSubstring("Index.html")) | ||
}) | ||
|
||
It("should return Index.html when strip prefix is empty", func() { | ||
path = "/static-examples/dist/" | ||
|
||
request, _ := http.NewRequest("GET", "/", nil) | ||
|
||
resp := NewStaticFilesystem(testPath+path, "")(response, request) | ||
Expect(resp).To(BeNil()) | ||
Expect(response).ToNot(BeNil()) | ||
Expect(response.Code).To(Equal(200)) | ||
|
||
body, err := ioutil.ReadAll(response.Body) | ||
Expect(err).To(BeNil()) | ||
Expect(body).To(ContainSubstring("Index.html")) | ||
}) | ||
|
||
It("should return Index.html when strip prefix is empty", func() { | ||
path = "/static-examples/dist/" | ||
|
||
request, _ := http.NewRequest("GET", "/ASDads.HTML", nil) | ||
|
||
resp := NewStaticFilesystem(testPath+path, "")(response, request) | ||
Expect(resp).To(BeNil()) | ||
Expect(response).ToNot(BeNil()) | ||
Expect(response.Code).To(Equal(404)) | ||
}) | ||
|
||
It("should return test.css on subpath", func() { | ||
path = "/static-examples/dist/" | ||
|
||
request, _ := http.NewRequest("GET", "/styles/test.css", nil) | ||
|
||
resp := NewStaticFilesystem(testPath+path, "")(response, request) | ||
Expect(resp).To(BeNil()) | ||
Expect(response).ToNot(BeNil()) | ||
Expect(response.Code).To(Equal(200)) | ||
|
||
body, err := ioutil.ReadAll(response.Body) | ||
Expect(err).To(BeNil()) | ||
Expect(body).To(ContainSubstring("test.css")) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<html> | ||
<head> | ||
<title>Index.html</title> | ||
<link rel="stylesheet" type="text/css" href="/dist/styles/index.css"> | ||
</head> | ||
<body> | ||
<h1> | ||
Index.html | ||
</h1> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
h1 { | ||
color: #0000AC; | ||
margin-left: 120px; | ||
margin-top: 120px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* test.css */ | ||
h1 { | ||
color: #ff0000; | ||
margin-left: 20px; | ||
margin-top: 20px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<html> | ||
<head> | ||
<title>Test.html</title> | ||
<link rel="stylesheet" type="text/css" href="styles/test.css"> | ||
</head> | ||
<body> | ||
<h1> | ||
Test.html | ||
</h1> | ||
</body> | ||
</html> |
Oops, something went wrong.