etp

package module
v0.0.0-...-19c6864 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 27, 2016 License: GPL-3.0 Imports: 14 Imported by: 0

README

etp

ETP (Easy Transport Protocol) is copy from HTTP, support simple message route & dispatch.

Example

package main

import (
	"fmt"

	"github.com/ooclab/etp"
)

var routes = []etp.Route{
	{"GET", "/zen", zenHandler},
	{"POST", `/ping/([\-0-9a-fA-F]+)`, pingHandler},
}

func zenHandler(w etp.ResponseWriter, req *etp.Request) {
	w.WriteHeader(etp.StatusOK)
	w.Write([]byte("KISS"))
}

func pingHandler(w etp.ResponseWriter, req *etp.Request) {
	w.WriteHeader(etp.StatusOK)
	etp.WriteJSON(w, 200, etp.H{"ping": "pong"})
}

func request(in, out chan []byte, method, url string, body []byte) (*etp.Response, error) {
	req, err := etp.NewRequest(method, url, body)
	if err != nil {
		return nil, err
	}

	in <- req.Bytes()
	respPayload := <-out

	return etp.ReadResponse(respPayload)
}

func main() {
	in := make(chan []byte)
	out := make(chan []byte)
	quit := make(chan bool)

	router := etp.NewRouter()
	router.AddRoutes(routes)

	go func() {
		var reqPayload []byte
		for {
			// wait a request message
			select {
			case reqPayload = <-in:
				if reqPayload == nil {
					fmt.Println("reqPayload is nil ")
					return
				}
			case <-quit:
				fmt.Println("got quit")
				return
			}

			// read request struct
			req, err := etp.ReadRequest(reqPayload)
			if err != nil {
				fmt.Printf("bad request: %s\n", err)
				continue
			}

			// prepare to dispatch message
			w := etp.NewResponseWriter()
			err = router.Dispatch(w, req)
			if err != nil {
				fmt.Printf("handle error: %s\n%s\n", err, reqPayload)
				w.WriteHeader(etp.StatusBadRequest)
			}

			// send response
			out <- w.Bytes()
		}
	}()

	// client: sent request
	var resp *etp.Response
	var err error

	resp, err = request(in, out, "GET", "/zen", nil)
	if err != nil {
		fmt.Printf("request failed: %s\n", err)
	} else {
		fmt.Printf("GET /zen\n%#v\n", resp)
	}

	close(quit)
	close(in)
	close(out)
}

run:

GET /zen
&etp.Response{Status:"200 OK", StatusCode:200, Proto:"ETP/1.0", ProtoMajor:1, ProtoMinor:0, PathArgs:[]string(nil), QueryArgs:map[string][]string(nil), Header:http.Header{"Content-Length":[]string{"4"}}, Body:[]uint8{0x4b, 0x49, 0x53, 0x53}, ContentLength:4}

Documentation

Overview

Package etp is a simple message dispatcher

ETP (Easy Transport Protocol) is copy from HTTP, support simple message route & dispatch.

contains:

- Request - Response - Route - Router

Index

Constants

View Source
const (
	StatusContinue           = 100
	StatusSwitchingProtocols = 101

	StatusOK                   = 200
	StatusCreated              = 201
	StatusAccepted             = 202
	StatusNonAuthoritativeInfo = 203
	StatusNoContent            = 204
	StatusResetContent         = 205
	StatusPartialContent       = 206

	StatusMultipleChoices   = 300
	StatusMovedPermanently  = 301
	StatusFound             = 302
	StatusSeeOther          = 303
	StatusNotModified       = 304
	StatusUseProxy          = 305
	StatusTemporaryRedirect = 307

	StatusBadRequest                   = 400
	StatusUnauthorized                 = 401
	StatusPaymentRequired              = 402
	StatusForbidden                    = 403
	StatusNotFound                     = 404
	StatusMethodNotAllowed             = 405
	StatusNotAcceptable                = 406
	StatusProxyAuthRequired            = 407
	StatusRequestTimeout               = 408
	StatusConflict                     = 409
	StatusGone                         = 410
	StatusLengthRequired               = 411
	StatusPreconditionFailed           = 412
	StatusRequestEntityTooLarge        = 413
	StatusRequestURITooLong            = 414
	StatusUnsupportedMediaType         = 415
	StatusRequestedRangeNotSatisfiable = 416
	StatusExpectationFailed            = 417
	StatusTeapot                       = 418

	StatusInternalServerError     = 500
	StatusNotImplemented          = 501
	StatusBadGateway              = 502
	StatusServiceUnavailable      = 503
	StatusGatewayTimeout          = 504
	StatusHTTPVersionNotSupported = 505
)

HTTP status codes, defined in RFC 2616.

Variables

View Source
var (
	ErrNoHandler     = errors.New("no matched handler")
	ErrNoMethod      = errors.New("no matched method")
	ErrRequestError  = errors.New("convert msg to request failed")
	ErrContentLength = errors.New("Conn.Write wrote more than the declared Content-Length")
)

Functions

func Error

func Error(w ResponseWriter, error string, code int)

Error replies to the request with the specified error message and HTTP code. The error message should be plain text.

func NotFound

func NotFound(w ResponseWriter, r *Request)

NotFound replies to the request with an HTTP 404 not found error.

func ParseHTTPVersion

func ParseHTTPVersion(vers string) (major, minor int, ok bool)

ParseHTTPVersion parses a HTTP version string. "HTTP/1.0" returns (1, 0, true).

func StatusText

func StatusText(code int) string

StatusText returns a text for the HTTP status code. It returns the empty string if the code is unknown.

func WriteJSON

func WriteJSON(w ResponseWriter, code int, v interface{}) error

Types

type H

type H map[string]interface{}

type HandlerFunc

type HandlerFunc func(ResponseWriter, *Request)

func (HandlerFunc) ServeETP

func (f HandlerFunc) ServeETP(w ResponseWriter, r *Request)

ServeETP calls f(r)

type Request

type Request struct {
	Method string
	URL    *url.URL

	Proto      string // "ETP/1.0"
	ProtoMajor int    // 1
	ProtoMinor int    // 0

	PathArgs  []string
	QueryArgs map[string][]string // TODO:
	ExtHeader http.Header         // 扩展头部

	Header http.Header
	Body   []byte

	ContentLength int64 // TODO: needed?

	RequestURI string
}

func NewRequest

func NewRequest(method, urlStr string, body []byte) (req *Request, err error)

func ReadRequest

func ReadRequest(data []byte) (req *Request, err error)

func (*Request) BodyQuery

func (req *Request) BodyQuery() *jsonq.JsonQuery

func (*Request) Bytes

func (req *Request) Bytes() []byte

func (*Request) Query

func (req *Request) Query() *jsonq.JsonQuery

type Response

type Response struct {
	Status     string // e.g. "200 OK"
	StatusCode int    // e.g. 200

	Proto      string // "ETP/1.0"
	ProtoMajor int    // 1
	ProtoMinor int    // 0

	PathArgs  []string
	QueryArgs map[string][]string // TODO:

	Header http.Header
	Body   []byte

	ContentLength int64 // TODO: needed?
}

func ReadResponse

func ReadResponse(data []byte) (resp *Response, err error)

func (*Response) BodyError

func (resp *Response) BodyError() string

func (*Response) BodyLoads

func (resp *Response) BodyLoads(obj interface{}) error

func (*Response) BodyQuery

func (resp *Response) BodyQuery() *jsonq.JsonQuery

type ResponseWriter

type ResponseWriter interface {
	Header() http.Header
	Write([]byte) (int, error)
	WriteString(string) (int, error)
	WriteHeader(int)
	Bytes() []byte
	Status() int
}

参考 http.ResponseWriter

func NewResponseWriter

func NewResponseWriter() ResponseWriter

type Route

type Route struct {
	Method  string
	Pattern string
	Handler HandlerFunc
}

type Router

type Router struct {
	// contains filtered or unexported fields
}

func NewRouter

func NewRouter() *Router

func (*Router) AddRoute

func (r *Router) AddRoute(route Route)

func (*Router) AddRoutes

func (r *Router) AddRoutes(routes []Route)

func (*Router) Dispatch

func (r *Router) Dispatch(w ResponseWriter, req *Request) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL