Skip to content

Commit

Permalink
feat(#7): support mux composition, add examples
Browse files Browse the repository at this point in the history
  • Loading branch information
h2non committed Feb 24, 2016
1 parent 030ac0a commit 38c5d03
Show file tree
Hide file tree
Showing 34 changed files with 183 additions and 55 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ Plugin-driven, middleware-oriented library to easily create rich, versatile and
go get -u gopkg.in/h2non/gentleman.v0
```

Note: I strongly recommend you to use `gopkg.in` when depending on third-party packages to prevent unexpected breaks of the interface contract in upcoming major versions of the package.
In minor versions the contract will be strictly maintained.
Note: I strongly recommend you to use `gopkg.in` when depending on third-party packages to prevent unexpected breaks of the interface contract in upcoming major versions of the package.

## Goals

Expand Down
2 changes: 1 addition & 1 deletion _examples/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
cli.Use(auth.Basic("user", "pas$w0rd"))

// Perform the request
res, err := cli.Request().URL("http://httpbin.org/headers").End()
res, err := cli.Request().URL("http://httpbin.org/headers").Send()
if err != nil {
fmt.Printf("Request error: %s", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/body/body.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func main() {
cli.Use(body.JSON(data))

// Perform the request
res, err := cli.Request().Method("POST").URL("http://httpbin.org/post").End()
res, err := cli.Request().Method("POST").URL("http://httpbin.org/post").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/bodytype/bodytype.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func main() {
cli.Use(bodytype.Type("json"))

// Perform the request
res, err := cli.Request().Method("POST").URL("http://httpbin.org/post").End()
res, err := cli.Request().Method("POST").URL("http://httpbin.org/post").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/compression/compression.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
cli.Use(compression.Disable())

// Perform the request
res, err := cli.Request().URL("http://httpbin.org/gzip").End()
res, err := cli.Request().URL("http://httpbin.org/gzip").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/cookies/cookies.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func main() {
cli.Use(cookies.Jar())

// Perform the request
res, err := cli.Request().URL("http://httpbin.org/cookies").End()
res, err := cli.Request().URL("http://httpbin.org/cookies").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/headers/headers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func main() {
cli.Use(headers.Del("User-Agent"))

// Perform the request
res, err := cli.Request().URL("http://httpbin.org/headers").End()
res, err := cli.Request().URL("http://httpbin.org/headers").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/multipart/multipart.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func main() {
cli.Use(multipart.Fields(fields))

// Perform the request
res, err := cli.Request().Method("POST").URL("http://httpbin.org/post").End()
res, err := cli.Request().Method("POST").URL("http://httpbin.org/post").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
39 changes: 39 additions & 0 deletions _examples/multiplexer/composition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"fmt"
"gopkg.in/h2non/gentleman.v0"
"gopkg.in/h2non/gentleman.v0/mux"
"gopkg.in/h2non/gentleman.v0/plugins/url"
)

func main() {
// Create a new client
cli := gentleman.New()

// Define the server url (must be first)
cli.Use(url.URL("http://httpbin.org"))

// Create a new multiplexer based on multiple matchers
mx := mux.If(mux.Method("GET"), mux.Host("httpbin.org"))

// Attach a custom plugin on the multiplexer that will be executed if the matchers passes
mx.Use(url.Path("/headers"))

// Attach the multiplexer on the main client
cli.Use(mx)

// Perform the request
res, err := cli.Request().Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
}
if !res.Ok {
fmt.Printf("Invalid server response: %d\n", res.StatusCode)
return
}

fmt.Printf("Status: %d\n", res.StatusCode)
fmt.Printf("Body: %s", res.String())
}
2 changes: 1 addition & 1 deletion _examples/multiplexer/multiplexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func main() {
}).Use(url.URL("http://httpbin.org/headers")))

// Perform the request
res, err := cli.Request().End()
res, err := cli.Request().Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/query/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func main() {
cli.Use(query.Del("bar"))

// Perform the request
res, err := cli.Request().End()
res, err := cli.Request().Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/redirect/redirect.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
cli.Use(redirect.Limit(20))

// Perform the request
res, err := cli.Request().URL("http://httpbin.org/headers").End()
res, err := cli.Request().URL("http://httpbin.org/headers").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/timeout/timeout.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func main() {
cli.Use(timeout.Dial(5*time.Second, 30*time.Second))

// Perform the request
res, err := cli.Request().URL("http://httpbin.org/headers").End()
res, err := cli.Request().URL("http://httpbin.org/headers").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/transport/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func main() {
cli.Use(transport.Set(http.DefaultTransport))

// Perform the request
res, err := cli.Request().URL("http://httpbin.org/headers").End()
res, err := cli.Request().URL("http://httpbin.org/headers").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
2 changes: 1 addition & 1 deletion _examples/url/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func main() {
cli.Use(url.Param("resource", "headers"))

// Perform the request
res, err := cli.Request().End()
res, err := cli.Request().Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
46 changes: 45 additions & 1 deletion mux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ See [godoc](https://godoc.org/github.com/h2non/gentleman/mux) reference.

## Example

Create a multiplexer with a custom matcher function:
```go
package main

Expand All @@ -35,7 +36,50 @@ func main() {
}).Use(url.URL("http://httpbin.org/headers")))

// Perform the request
res, err := cli.Request().End()
res, err := cli.Request().Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
}
if !res.Ok {
fmt.Printf("Invalid server response: %d\n", res.StatusCode)
return
}

fmt.Printf("Status: %d\n", res.StatusCode)
fmt.Printf("Body: %s", res.String())
}
```

Multiplexer composition:
```go
package main

import (
"fmt"
"gopkg.in/h2non/gentleman.v0"
"gopkg.in/h2non/gentleman.v0/mux"
"gopkg.in/h2non/gentleman.v0/plugins/url"
)

func main() {
// Create a new client
cli := gentleman.New()

// Define the server url (must be first)
cli.Use(url.URL("http://httpbin.org"))

// Create a new multiplexer based on multiple matchers
mx := mux.If(mux.Method("GET"), mux.Host("httpbin.org"))

// Attach a custom plugin on the multiplexer that will be executed if the matchers passes
mx.Use(url.Path("/headers"))

// Attach the multiplexer on the main client
cli.Use(mx)

// Perform the request
res, err := cli.Request().Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
18 changes: 11 additions & 7 deletions mux/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,20 @@ import (
c "gopkg.in/h2non/gentleman.v0/context"
)

// If creates a new multiplexer that will be executed if all the matchers passes.
func If(matchers ...Matcher) *Mux {
return Match(matchers...)
// If creates a new multiplexer that will be executed if all the mux matchers passes.
func If(muxes ...*Mux) *Mux {
mx := New()
for _, mm := range muxes {
mx.AddMatcher(mm.Matchers...)
}
return mx
}

// Or creates a new multiplexer that will be executed if at least one matcher passes.
func Or(matchers ...Matcher) *Mux {
// Or creates a new multiplexer that will be executed if at least one mux matcher passes.
func Or(muxes ...*Mux) *Mux {
return Match(func(ctx *c.Context) bool {
for _, matcher := range matchers {
if matcher(ctx) {
for _, mm := range muxes {
if mm.Match(ctx) {
return true
}
}
Expand Down
44 changes: 42 additions & 2 deletions mux/compose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,54 @@ import (
"testing"
)

func testMuxMethod(t *testing.T) {
func TestMuxComposeIfMatches(t *testing.T) {
mx := New()
mx.Use(Method("GET").UseRequest(func(ctx *context.Context, h context.Handler) {
mx.Use(If(Method("GET"), Host("foo.com")).UseRequest(func(ctx *context.Context, h context.Handler) {
ctx.Request.Header.Set("foo", "bar")
h.Next(ctx)
}))
ctx := context.New()
ctx.Request.Method = "GET"
ctx.Request.URL.Host = "foo.com"
mx.Run("request", ctx)
st.Expect(t, ctx.Request.Header.Get("foo"), "bar")
}

func TestMuxComposeIfUnmatch(t *testing.T) {
mx := New()
mx.Use(If(Method("GET"), Host("bar.com")).UseRequest(func(ctx *context.Context, h context.Handler) {
ctx.Request.Header.Set("foo", "bar")
h.Next(ctx)
}))
ctx := context.New()
ctx.Request.Method = "GET"
ctx.Request.URL.Host = "foo.com"
mx.Run("request", ctx)
st.Expect(t, ctx.Request.Header.Get("foo"), "")
}

func TestMuxComposeOrMatch(t *testing.T) {
mx := New()
mx.Use(Or(Method("GET"), Host("bar.com")).UseRequest(func(ctx *context.Context, h context.Handler) {
ctx.Request.Header.Set("foo", "bar")
h.Next(ctx)
}))
ctx := context.New()
ctx.Request.Method = "GET"
ctx.Request.URL.Host = "foo.com"
mx.Run("request", ctx)
st.Expect(t, ctx.Request.Header.Get("foo"), "bar")
}

func TestMuxComposeOrUnMatch(t *testing.T) {
mx := New()
mx.Use(Or(Method("GET"), Host("bar.com")).UseRequest(func(ctx *context.Context, h context.Handler) {
ctx.Request.Header.Set("foo", "bar")
h.Next(ctx)
}))
ctx := context.New()
ctx.Request.Method = "POST"
ctx.Request.URL.Host = "foo.com"
mx.Run("request", ctx)
st.Expect(t, ctx.Request.Header.Get("foo"), "")
}
2 changes: 1 addition & 1 deletion mux/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (m *Mux) Match(ctx *c.Context) bool {
return true
}

// AddMatcher adds a new matcher function in the current multiplexer matchers stack.
// AddMatcher adds a new matcher function in the current mumultiplexer matchers stack.
func (m *Mux) AddMatcher(matchers ...Matcher) *Mux {
m.Matchers = append(m.Matchers, matchers...)
return m
Expand Down
4 changes: 2 additions & 2 deletions plugins/auth/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# gentleman/auth [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GitHub release](https://img.shields.io/github/tag/h2non/gentleman.svg)](https://github.com/h2non/gentleman/releases) [![GoDoc](https://godoc.org/github.com/h2non/gentleman?status.svg)](https://godoc.org/github.com/h2non/gentleman/plugins/auth) [![API](https://img.shields.io/badge/api-stable-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman/plugins/auth) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman)
# gentleman/auth [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GoDoc](https://godoc.org/github.com/h2non/gentleman?status.svg)](https://godoc.org/github.com/h2non/gentleman/plugins/auth) [![API](https://img.shields.io/badge/api-stable-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman/plugins/auth) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman)

gentleman's plugin to easily define HTTP authorization headers based on multiple schemas.

Expand Down Expand Up @@ -31,7 +31,7 @@ func main() {
cli.Use(auth.Basic("user", "pas$w0rd"))

// Perform the request
res, err := cli.Request().Method().URL("http://httpbin.org/headers").End()
res, err := cli.Request().Method().URL("http://httpbin.org/headers").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
4 changes: 2 additions & 2 deletions plugins/body/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# gentleman/body [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GitHub release](https://img.shields.io/github/tag/h2non/gentleman.svg)](https://github.com/h2non/gentleman/releases) [![GoDoc](https://godoc.org/github.com/h2non/gentleman/plugins/body?status.svg)](https://godoc.org/github.com/h2non/gentleman/plugins/body) [![API](https://img.shields.io/badge/api-stable-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman)
# gentleman/body [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GoDoc](https://godoc.org/github.com/h2non/gentleman/plugins/body?status.svg)](https://godoc.org/github.com/h2non/gentleman/plugins/body) [![API](https://img.shields.io/badge/api-stable-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman)

gentleman's plugin to easy define HTTP bodies. Supports JSON, XML, strings or streams with interface polymorphism.

Expand Down Expand Up @@ -32,7 +32,7 @@ func main() {
cli.Use(body.JSON(data))

// Perform the request
res, err := cli.Request().Method("POST").URL("http://httpbin.org/post").End()
res, err := cli.Request().Method("POST").URL("http://httpbin.org/post").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
4 changes: 2 additions & 2 deletions plugins/bodytype/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# gentleman/bodytype [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GitHub release](https://img.shields.io/github/tag/h2non/gentleman.svg)](https://github.com/h2non/gentleman/releases) [![GoDoc](https://godoc.org/github.com/h2non/gentleman/plugins/bodytype?status.svg)](https://godoc.org/github.com/h2non/gentleman/plugins/bodytype) [![API](https://img.shields.io/badge/api-stable-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman/plugins/bodytype) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman)
# gentleman/bodytype [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GoDoc](https://godoc.org/github.com/h2non/gentleman/plugins/bodytype?status.svg)](https://godoc.org/github.com/h2non/gentleman/plugins/bodytype) [![API](https://img.shields.io/badge/api-stable-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman/plugins/bodytype) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman)

gentleman's plugin to easy define HTTP bodies. Supports JSON, XML, strings or streams with interface polymorphism.

Expand Down Expand Up @@ -36,7 +36,7 @@ func main() {
cli.Use(bodytype.Type("json"))

// Perform the request
res, err := cli.Request().Method("POST").URL("http://httpbin.org/post").End()
res, err := cli.Request().Method("POST").URL("http://httpbin.org/post").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
4 changes: 2 additions & 2 deletions plugins/compression/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# gentleman/compression [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GitHub release](https://img.shields.io/github/tag/h2non/gentleman.svg)](https://github.com/h2non/gentleman/releases) [![GoDoc](https://godoc.org/github.com/h2non/gentleman/plugins/compression?status.svg)](https://godoc.org/github.com/h2non/gentleman/plugins/compression) [![API](https://img.shields.io/badge/api-beta-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman/plugins/compression) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman)
# gentleman/compression [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GoDoc](https://godoc.org/github.com/h2non/gentleman/plugins/compression?status.svg)](https://godoc.org/github.com/h2non/gentleman/plugins/compression) [![API](https://img.shields.io/badge/api-beta-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman/plugins/compression) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman)

gentleman's plugin to disable and customize data compression in HTTP requests/responses.

Expand Down Expand Up @@ -31,7 +31,7 @@ func main() {
cli.Use(compression.Disable())

// Perform the request
res, err := cli.Request().URL("http://httpbin.org/gzip").End()
res, err := cli.Request().URL("http://httpbin.org/gzip").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
4 changes: 2 additions & 2 deletions plugins/cookies/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# gentleman/cookies [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GitHub release](https://img.shields.io/github/tag/h2non/gentleman.svg)](https://github.com/h2non/gentleman/releases) [![GoDoc](https://godoc.org/github.com/h2non/gentleman/plugins/cookies?status.svg)](https://godoc.org/github.com/h2non/gentleman/plugins/cookies) [![API](https://img.shields.io/badge/api-beta-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman/plugins/cookies) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman)
# gentleman/cookies [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GoDoc](https://godoc.org/github.com/h2non/gentleman/plugins/cookies?status.svg)](https://godoc.org/github.com/h2non/gentleman/plugins/cookies) [![API](https://img.shields.io/badge/api-beta-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman/plugins/cookies) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman)](https://goreportcard.com/report/github.com/h2non/gentleman)

gentleman's plugin to easily deal and manage cookies HTTP clients.

Expand Down Expand Up @@ -34,7 +34,7 @@ func main() {
cli.Use(cookies.Jar())

// Perform the request
res, err := cli.Request().URL("http://httpbin.org/cookies").End()
res, err := cli.Request().URL("http://httpbin.org/cookies").Send()
if err != nil {
fmt.Printf("Request error: %s\n", err)
return
Expand Down
Loading

0 comments on commit 38c5d03

Please sign in to comment.