Skip to content

Commit

Permalink
Merge pull request #20 from kkrull/redirect
Browse files Browse the repository at this point in the history
RedirectPath
  • Loading branch information
kkrull authored May 7, 2018
2 parents cb322a3 + a51b908 commit a4a2b9a
Show file tree
Hide file tree
Showing 51 changed files with 984 additions and 332 deletions.
10 changes: 5 additions & 5 deletions capability/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

func NewRoute() *ServerCapabilityRoute {
controller := &StaticCapabilityServer{
AvailableMethods: []string{"GET", "HEAD"},
AvailableMethods: []string{http.GET, http.HEAD},
}

return &ServerCapabilityRoute{Controller: controller}
Expand All @@ -19,11 +19,11 @@ type ServerCapabilityRoute struct {
Controller ServerResource
}

func (route *ServerCapabilityRoute) Route(requested *http.RequestLine) http.Request {
if requested.Target != "*" {
func (route *ServerCapabilityRoute) Route(requested http.RequestMessage) http.Request {
if requested.Target() != "*" {
return nil
} else if requested.Method != "OPTIONS" {
return clienterror.MethodNotAllowed("OPTIONS")
} else if requested.Method() != http.OPTIONS {
return clienterror.MethodNotAllowed(http.OPTIONS)
}

return &optionsRequest{Resource: route.Controller}
Expand Down
16 changes: 8 additions & 8 deletions capability/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var _ = Describe("::NewRoute", func() {
route := capability.NewRoute()
Expect(route.Controller).To(BeEquivalentTo(
&capability.StaticCapabilityServer{
AvailableMethods: []string{"GET", "HEAD"},
AvailableMethods: []string{http.GET, http.HEAD},
},
))
})
Expand All @@ -31,7 +31,7 @@ var _ = Describe("ServerCapabilityRoute", func() {
var (
router http.Route
controller *ServerCapabilityServerMock
requested *http.RequestLine
requested http.RequestMessage
routedRequest http.Request
)

Expand All @@ -40,23 +40,23 @@ var _ = Describe("ServerCapabilityRoute", func() {
router = &capability.ServerCapabilityRoute{Controller: controller}
})

Context("when the target is *", func() {
Context("when the path is *", func() {
It("routes OPTIONS to ServerResource", func() {
requested = &http.RequestLine{Method: "OPTIONS", Target: "*"}
requested = http.NewOptionsMessage("*")
routedRequest = router.Route(requested)
routedRequest.Handle(&bufio.Writer{})
controller.OptionsShouldHaveBeenCalled()
})

It("returns MethodNotAllowed for any other method", func() {
requested = &http.RequestLine{Method: "GET", Target: "*"}
requested = http.NewGetMessage("*")
routedRequest = router.Route(requested)
Expect(routedRequest).To(BeEquivalentTo(clienterror.MethodNotAllowed("OPTIONS")))
Expect(routedRequest).To(BeEquivalentTo(clienterror.MethodNotAllowed(http.OPTIONS)))
})
})

It("returns nil to pass on any other target", func() {
requested = &http.RequestLine{Method: "OPTIONS", Target: "/"}
It("returns nil to pass on any other path", func() {
requested = http.NewOptionsMessage("/")
routedRequest = router.Route(requested)
Expect(routedRequest).To(BeNil())
})
Expand Down
3 changes: 2 additions & 1 deletion capability/server_capability.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"

"github.com/kkrull/gohttp/msg"
"github.com/kkrull/gohttp/msg/success"
)

// Reports on server capabilities that are defined during startup and do not change after that
Expand All @@ -13,7 +14,7 @@ type StaticCapabilityServer struct {
}

func (controller *StaticCapabilityServer) Options(client io.Writer) {
msg.WriteStatusLine(client, 200, "OK")
msg.WriteStatus(client, success.OKStatus)
msg.WriteHeader(client, "Allow", strings.Join(controller.AvailableMethods, ","))
msg.WriteContentLengthHeader(client, 0)
msg.WriteEndOfMessageHeader(client)
Expand Down
9 changes: 5 additions & 4 deletions capability/server_capability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"

"github.com/kkrull/gohttp/capability"
"github.com/kkrull/gohttp/http"
"github.com/kkrull/gohttp/httptest"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand All @@ -20,7 +21,7 @@ var _ = Describe("StaticCapabilityServer", func() {
BeforeEach(func() {
responseBuffer = &bytes.Buffer{}
controller = &capability.StaticCapabilityServer{
AvailableMethods: []string{"CONNECT", "TRACE"},
AvailableMethods: []string{http.CONNECT, http.TRACE},
}
controller.Options(responseBuffer)
response = httptest.ParseResponse(responseBuffer)
Expand All @@ -40,22 +41,22 @@ var _ = Describe("StaticCapabilityServer", func() {
BeforeEach(func() {
responseBuffer = &bytes.Buffer{}
controller = &capability.StaticCapabilityServer{
AvailableMethods: []string{"OPTIONS"},
AvailableMethods: []string{http.OPTIONS},
}
controller.Options(responseBuffer)
response = httptest.ParseResponse(responseBuffer)
})

It("sets Allow to that one method", func() {
response.HeaderShould("Allow", Equal("OPTIONS"))
response.HeaderShould("Allow", Equal(http.OPTIONS))
})
})

Context("given 2 or more available methods", func() {
BeforeEach(func() {
responseBuffer = &bytes.Buffer{}
controller = &capability.StaticCapabilityServer{
AvailableMethods: []string{"CONNECT", "TRACE"},
AvailableMethods: []string{http.CONNECT, http.TRACE},
}
controller.Options(responseBuffer)
response = httptest.ParseResponse(responseBuffer)
Expand Down
3 changes: 2 additions & 1 deletion fs/directory_listing.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"path"

"github.com/kkrull/gohttp/msg"
"github.com/kkrull/gohttp/msg/success"
)

type DirectoryListing struct {
Expand All @@ -22,7 +23,7 @@ func (listing *DirectoryListing) WriteTo(client io.Writer) error {
}

func (listing *DirectoryListing) WriteHeader(client io.Writer) error {
msg.WriteStatusLine(client, 200, "OK")
msg.WriteStatus(client, success.OKStatus)
msg.WriteContentTypeHeader(client, "text/html")

listing.body = listing.messageListingFiles()
Expand Down
3 changes: 2 additions & 1 deletion fs/file_contents.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strconv"

"github.com/kkrull/gohttp/msg"
"github.com/kkrull/gohttp/msg/success"
)

type FileContents struct {
Expand All @@ -21,7 +22,7 @@ func (contents *FileContents) WriteTo(client io.Writer) error {
}

func (contents *FileContents) WriteHeader(client io.Writer) error {
msg.WriteStatusLine(client, 200, "OK")
msg.WriteStatus(client, success.OKStatus)
contents.writeHeadersDescribingFile(client)
msg.WriteEndOfMessageHeader(client)
return nil
Expand Down
11 changes: 6 additions & 5 deletions fs/fs_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"io"
"testing"

"github.com/kkrull/gohttp/http"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
Expand All @@ -14,20 +15,20 @@ func TestFs(t *testing.T) {
}

type FileSystemResourceMock struct {
getTarget string
getPath string
headTarget string
}

func (mock *FileSystemResourceMock) Name() string {
return "File system mock"
}

func (mock *FileSystemResourceMock) Get(client io.Writer, target string) {
mock.getTarget = target
func (mock *FileSystemResourceMock) Get(client io.Writer, req http.RequestMessage) {
mock.getPath = req.Path()
}

func (mock *FileSystemResourceMock) GetShouldHaveReceived(target string) {
ExpectWithOffset(1, mock.getTarget).To(Equal(target))
func (mock *FileSystemResourceMock) GetShouldHaveReceived(path string) {
ExpectWithOffset(1, mock.getPath).To(Equal(path))
}

func (mock *FileSystemResourceMock) Head(client io.Writer, target string) {
Expand Down
18 changes: 9 additions & 9 deletions fs/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func (controller *ReadOnlyFileSystem) Name() string {
return "Readonly file system"
}

func (controller *ReadOnlyFileSystem) Get(client io.Writer, target string) {
response := controller.determineResponse(target)
func (controller *ReadOnlyFileSystem) Get(client io.Writer, req http.RequestMessage) {
response := controller.determineResponse(req.Path())
response.WriteTo(client)
}

Expand All @@ -28,18 +28,18 @@ func (controller *ReadOnlyFileSystem) Head(client io.Writer, target string) {
response.WriteHeader(client)
}

func (controller *ReadOnlyFileSystem) determineResponse(requestedTarget string) http.Response {
resolvedTarget := path.Join(controller.BaseDirectory, requestedTarget)
info, err := os.Stat(resolvedTarget)
func (controller *ReadOnlyFileSystem) determineResponse(requestedPath string) http.Response {
resolvedPath := path.Join(controller.BaseDirectory, requestedPath)
info, err := os.Stat(resolvedPath)
if err != nil {
return &clienterror.NotFound{Target: requestedTarget}
return &clienterror.NotFound{Path: requestedPath}
} else if info.IsDir() {
files, _ := ioutil.ReadDir(resolvedTarget)
files, _ := ioutil.ReadDir(resolvedPath)
return &DirectoryListing{
Files: readFileNames(files),
HrefPrefix: requestedTarget}
HrefPrefix: requestedPath}
} else {
return &FileContents{Filename: resolvedTarget}
return &FileContents{Filename: resolvedPath}
}
}

Expand Down
23 changes: 12 additions & 11 deletions fs/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"path"

"github.com/kkrull/gohttp/fs"
"github.com/kkrull/gohttp/http"
"github.com/kkrull/gohttp/httptest"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand All @@ -28,9 +29,9 @@ var _ = Describe("ReadOnlyFileSystem", func() {
})

Describe("#Get", func() {
Context("when the resolved target does not exist", func() {
Context("when the resolved path does not exist", func() {
BeforeEach(func() {
controller.Get(responseBuffer, "/missing.txt")
controller.Get(responseBuffer, http.NewGetMessage("/missing.txt"))
response = httptest.ParseResponse(responseBuffer)
})

Expand All @@ -48,11 +49,11 @@ var _ = Describe("ReadOnlyFileSystem", func() {
})
})

Context("when the target is a readable text file in the base path", func() {
Context("when the path is a readable text file in the base path", func() {
BeforeEach(func() {
existingFile := path.Join(basePath, "readable.txt")
Expect(createTextFile(existingFile, "A")).To(Succeed())
controller.Get(responseBuffer, "/readable.txt")
controller.Get(responseBuffer, http.NewGetMessage("/readable.txt"))
response = httptest.ParseResponse(responseBuffer)
})

Expand All @@ -70,40 +71,40 @@ var _ = Describe("ReadOnlyFileSystem", func() {
})
})

Context("when the target is a readable file named with a registered extension", func() {
Context("when the path is a readable file named with a registered extension", func() {
BeforeEach(func() {
existingFile := path.Join(basePath, "image.jpeg")
Expect(createTextFile(existingFile, "A")).To(Succeed())
})

It("sets Content-Type to the MIME type registered for that extension", func() {
controller.Get(responseBuffer, "/image.jpeg")
controller.Get(responseBuffer, http.NewGetMessage("/image.jpeg"))
response = httptest.ParseResponse(responseBuffer)
response.HeaderShould("Content-Type", Equal("image/jpeg"))
})
})

Context("when the target is a readable file without an extension", func() {
Context("when the path is a readable file without an extension", func() {
BeforeEach(func() {
existingFile := path.Join(basePath, "assumed-text")
Expect(createTextFile(existingFile, "A")).To(Succeed())
})

It("sets Content-Type to text/plain", func() {
controller.Get(responseBuffer, "/assumed-text")
controller.Get(responseBuffer, http.NewGetMessage("/assumed-text"))
response = httptest.ParseResponse(responseBuffer)
response.HeaderShould("Content-Type", Equal("text/plain"))
})
})

Context("when the target is /", func() {
Context("when the path is /", func() {
BeforeEach(func() {
existingFile := path.Join(basePath, "one")
Expect(createTextFile(existingFile, "1")).To(Succeed())
})

It("responds with 200 OK", func() {
controller.Get(responseBuffer, "/")
controller.Get(responseBuffer, http.NewGetMessage("/"))
response = httptest.ParseResponse(responseBuffer)
response.StatusShouldBe(200, "OK")
})
Expand All @@ -117,7 +118,7 @@ var _ = Describe("ReadOnlyFileSystem", func() {
)

BeforeEach(func() {
controller.Get(getResponseBuffer, "/missing.txt")
controller.Get(getResponseBuffer, http.NewGetMessage("/missing.txt"))
getResponse = httptest.ParseResponse(getResponseBuffer)

controller.Head(responseBuffer, "/missing.txt")
Expand Down
6 changes: 3 additions & 3 deletions fs/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ type FileSystemRoute struct {
Resource FileSystemResource
}

func (route FileSystemRoute) Route(requested *http.RequestLine) http.Request {
return http.MakeResourceRequest(requested, route.Resource)
func (route FileSystemRoute) Route(requested http.RequestMessage) http.Request {
return requested.MakeResourceRequest(route.Resource)
}

// Represents files and directories on the file system
type FileSystemResource interface {
Name() string
Get(client io.Writer, target string)
Get(client io.Writer, req http.RequestMessage)
Head(client io.Writer, target string)
}
8 changes: 4 additions & 4 deletions fs/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,23 @@ var _ = Describe("FileSystemRoute", func() {

Describe("#Route", func() {
It("routes GET requests to GetRequest", func() {
requested := &http.RequestLine{Method: "GET", Target: "/foo"}
requested := http.NewGetMessage("/foo")
routedRequest := route.Route(requested)
routedRequest.Handle(response)
resource.GetShouldHaveReceived("/foo")
})

It("routes HEAD requests to HeadRequest", func() {
requested := &http.RequestLine{Method: "HEAD", Target: "/foo"}
requested := http.NewHeadMessage("/foo")
routedRequest := route.Route(requested)
routedRequest.Handle(response)
resource.HeadShouldHaveReceived("/foo")
})

It("routes any other method to MethodNotAllowed", func() {
requested := &http.RequestLine{Method: "TRACE", Target: "/"}
requested := http.NewTraceMessage("/")
routedRequest := route.Route(requested)
Expect(routedRequest).To(BeEquivalentTo(clienterror.MethodNotAllowed("GET", "HEAD", "OPTIONS")))
Expect(routedRequest).To(BeEquivalentTo(clienterror.MethodNotAllowed(http.GET, http.HEAD, http.OPTIONS)))
})
})
})
Loading

0 comments on commit a4a2b9a

Please sign in to comment.