Skip to content

Commit

Permalink
feat(#8): support extended middleware phases
Browse files Browse the repository at this point in the history
  • Loading branch information
h2non committed Feb 25, 2016
1 parent 7c78550 commit c1df2c7
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 14 deletions.
2 changes: 1 addition & 1 deletion History.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
## 0.1.0 / 21-02-2016
## 0.1.0 / 25-02-2016

- First release.
2 changes: 2 additions & 0 deletions context/context.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Package context implements a simple request-aware HTTP context
// designed to share polymorfic data types across plugins in the middleware call chain.
package context

import (
Expand Down
74 changes: 65 additions & 9 deletions dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import (
)

// Dispatcher dispatches a given request triggering the middleware
// layer and handling the request/response state.
// layer per specific phase and handling the request/response/error
// states accondingly.
type Dispatcher struct {
req *Request
}
Expand All @@ -18,12 +19,13 @@ func NewDispatcher(req *Request) *Dispatcher {
// Dispatch triggers the middleware chains and performs the HTTP request.
func (d *Dispatcher) Dispatch() *context.Context {
ctx := d.req.Context
mw := d.req.Middleware

// Run the request middleware
ctx = d.req.Middleware.Run("request", ctx)
ctx = mw.Run("request", ctx)
// Handle error
if ctx.Error != nil {
ctx = d.req.Middleware.Run("error", ctx)
ctx = mw.Run("error", ctx)
if ctx.Error != nil {
return ctx
}
Expand All @@ -32,23 +34,54 @@ func (d *Dispatcher) Dispatch() *context.Context {
// Verify if the request was intercepted
if ctx.Response.StatusCode != 0 {
// Then trigger the response middleware
ctx = d.req.Middleware.Run("response", ctx)
ctx = mw.Run("response", ctx)
if ctx.Error != nil {
ctx = d.req.Middleware.Run("error", ctx)
ctx = mw.Run("error", ctx)
}
return ctx
}

// If manually stopped
if ctx.Stopped {
return ctx
ctx = mw.Run("stopped", ctx)
if ctx.Error != nil {
ctx = mw.Run("error", ctx)
if ctx.Error != nil {
return ctx
}
}
if ctx.Stopped {
return ctx
}
}

// Trigger the before dial phase
ctx = mw.Run("before dial", ctx)
if ctx.Error != nil {
ctx = mw.Run("error", ctx)
if ctx.Error != nil {
return ctx
}
}
// If manually stopped
if ctx.Stopped {
ctx = mw.Run("stopped", ctx)
if ctx.Error != nil {
ctx = mw.Run("error", ctx)
if ctx.Error != nil {
return ctx
}
}
if ctx.Stopped {
return ctx
}
}

// Perform the request via ctx.Client
res, err := ctx.Client.Do(ctx.Request)
ctx.Error = err
if err != nil {
ctx = d.req.Middleware.Run("error", ctx)
ctx = mw.Run("error", ctx)
if ctx.Error != nil {
return ctx
}
Expand All @@ -57,10 +90,33 @@ func (d *Dispatcher) Dispatch() *context.Context {
ctx.Response = res
}

// Trigger the after dial phase
ctx = mw.Run("after dial", ctx)
if ctx.Error != nil {
ctx = mw.Run("error", ctx)
if ctx.Error != nil {
return ctx
}
}

// If manually stopped
if ctx.Stopped {
ctx = mw.Run("stopped", ctx)
if ctx.Error != nil {
ctx = mw.Run("error", ctx)
if ctx.Error != nil {
return ctx
}
}
if ctx.Stopped {
return ctx
}
}

// Run the response middleware
ctx = d.req.Middleware.Run("response", ctx)
ctx = mw.Run("response", ctx)
if ctx.Error != nil {
ctx = d.req.Middleware.Run("error", ctx)
ctx = mw.Run("error", ctx)
}

return ctx
Expand Down
5 changes: 2 additions & 3 deletions middleware/middleware.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Package middleware implements a HTTP client domain-specific middleware layer
// used internally by gentleman packages.
// It's able to execute plugin based on especific responses.
// Package middleware implements an HTTP client domain-specific phase-oriented
// middleware layer used internally by gentleman packages.
package middleware

import (
Expand Down
2 changes: 1 addition & 1 deletion mux/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# gentleman/mux [![Build Status](https://travis-ci.org/h2non/gentleman.png)](https://travis-ci.org/h2non/gentleman) [![GoDoc](https://godoc.org/github.com/h2non/gentleman/mux?status.svg)](https://godoc.org/github.com/h2non/gentleman/mux) [![API](https://img.shields.io/badge/status-stable-green.svg?style=flat)](https://godoc.org/github.com/h2non/gentleman/mux) [![Go Report Card](https://goreportcard.com/badge/github.com/h2non/gentleman/mux)](https://goreportcard.com/report/github.com/h2non/gentleman/mux)

`mux` package implements a versatile HTTP client multiplexer with built-in matchers for easy plugin composition.
`mux` package implements a versatile HTTP client multiplexer with built-in matchers for easy plugin logic composition.

## Installation

Expand Down
2 changes: 2 additions & 0 deletions mux/mux.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Package mux implements an HTTP domain-specific traffic multiplexer
// with built-in matchers and features for easy plugin composition and activable logic.
package mux

import (
Expand Down
9 changes: 9 additions & 0 deletions plugin/plugin.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
// Package plugin implements a plugin layer for gentleman components.
// Exports the required interface that must be implemented by plugins.
//
// Plugins are phase-oriented middleware function handlers encapsulated
// in a simple interface that will be consumed by the middleware layer in
// order to trigger the plugin handler.
//
// Plugin implementors can decide to build a plugin to handle a unique
// middleware phase or instead handle multiple phases: request, response, error...
package plugin

import (
Expand Down
2 changes: 2 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Package utils provides a set of reusable HTTP client utilities used internally
// in gentleman for required functionality and testing.
package utils

import (
Expand Down

0 comments on commit c1df2c7

Please sign in to comment.