f

package module
v0.0.0-...-e5fdbec Latest Latest
Warning

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

Go to latest
Published: Sep 17, 2015 License: MIT Imports: 18 Imported by: 9

README

Forgery

Build Status

STABLE VERSION 1.0: Version 2.x is in development here forgery2

Forgery is a minimal and flexible golang web application framework, providing a robust set of features for building single and multi-page, web applications.

package main

import(
    "github.com/ricallinson/forgery"
)

func init() {
    app := f.CreateServer()
    app.Get("/", func(req *f.Request, res *f.Response, next func()) {
        res.Send("Hello world.")
    })
    app.Listen(3000)
}
  • Built on Stackr
  • Robust routing (almost there)
  • HTTP helpers (redirection, caching, etc)
  • View system supporting 1 template engine (hopefully more will come)
  • Content negotiation
  • Focus on high performance
  • Environment based configuration
  • High test coverage

Testing

The following should all be executed from the forgery directory $GOPATH/src/github.com/ricallinson/forgery/.

Install
go get github.com/ricallinson/simplebdd
Run
go test
Code Coverage
Install
go get github.com/axw/gocov/gocov
go get -u github.com/matm/gocov-html
Generate
gocov test | gocov-html > ./reports/coverage.html

Notes

This project started out as a clone of the superb Node.js library Express.

Documentation

Overview

__WARNING: WORK IN PROGRESS__

Forgery is a minimal and flexible golang web application framework, providing a robust set of features for building single and multi-page, web applications.

Note: This project started out as a clone of the superb Node.js library [Express](http://expressjs.com/).

Index

Constants

View Source
const (
	TRUE  = "true"
	FALSE = "false"
)

Variables

View Source
var ErrorHandler = stackr.ErrorHandler

Convenience attribute for accessing "stackr.ErrorHandler".

View Source
var Favicon = stackr.Favicon

Convenience attribute for accessing "stackr.Favicon".

View Source
var Logger = stackr.Logger

Convenience attribute for accessing "stackr.Logger".

View Source
var MethodOverride = stackr.MethodOverride

Convenience attribute for accessing "stackr.MethodOverride".

View Source
var ResponseTime = stackr.ResponseTime

Convenience attribute for accessing "stackr.ResponseTime".

View Source
var Static = stackr.Static

Convenience attribute for accessing "stackr.Static".

Functions

func Decode

func Decode(value string) (string, error)

Decodes a value using base64.

func Encode

func Encode(value string) string

Encodes a value using base64.

func Sign

func Sign(v string, s string) string

Returns a string signed with a hash.

func StringSliceReverse

func StringSliceReverse(in []string) (out []string)

Reverses a slice of strings.

func Unsign

func Unsign(v string, s string) string

Returns a verified string or and empty string.

Types

type Renderer

type Renderer interface {
	Render(string, ...interface{}) (string, error)
}

type Request

type Request struct {

	// The stackr.Request type.
	*stackr.Request

	// Return the remote address, or when "trust proxy" is enabled - the upstream address.
	Ip string

	// When "trust proxy" is `true`, parse the "X-Forwarded-For" ip address list and return a slice,
	// otherwise an empty slice is returned. For example if the value were "client, proxy1, proxy2"
	// you would receive the slice {"client", "proxy1", "proxy2"} where "proxy2" is the furthest down-stream.
	Ips []string

	// Returns the request URL pathname.
	Path string

	// Check if the request was issued with the "X-Requested-With" header field set to "XMLHttpRequest" (jQuery etc).
	Xhr bool

	// Return the protocol string "http" or "https" when requested with TLS.
	// When the "trust proxy" setting is enabled the "X-Forwarded-Proto" header field will be trusted.
	// If you're running behind a reverse proxy that supplies https for you this may be enabled.
	Protocol string

	// Check if a TLS connection is established. This is a short-hand for: "https" == req.Protocol
	Secure bool

	// This property is a slice containing properties mapped to the named route "parameters".
	// For example if you have the route "/user/:name", then the "name" property is available
	// to you as req.params["name"]. This object defaults to {}.
	Params map[string]string

	// The currently matched Route containing several properties such as the
	// route's original path string, the regexp generated, and so on.
	Route *Route
	// contains filtered or unexported fields
}

A Request represents an HTTP request received by the server.

func (*Request) Accepted

func (this *Request) Accepted() []string

Return an slice of Accepted media types ordered from highest quality to lowest.

func (*Request) AcceptedCharsets

func (this *Request) AcceptedCharsets() []string

Return an slice of Accepted charsets ordered from highest quality to lowest.

func (*Request) AcceptedLanguages

func (this *Request) AcceptedLanguages() []string

Return an slice of Accepted languages ordered from highest quality to lowest.

func (*Request) Accepts

func (this *Request) Accepts(t string) bool

Check if the given type is acceptable, returning true or false - in which case you should respond with 406 "Not Acceptable".

func (*Request) AcceptsCharset

func (this *Request) AcceptsCharset(c string) bool

Check if the given "charset" is acceptable.

func (*Request) AcceptsLanguage

func (this *Request) AcceptsLanguage(l string) bool

Check if the given "lang" is acceptable.

func (*Request) Cookie

func (this *Request) Cookie(n string, i ...interface{}) string

Contains the cookies sent by the user-agent.

func (*Request) Fresh

func (this *Request) Fresh() bool

WARNING: Not complete! Check if the request is fresh - aka Last-Modified and/or the ETag still match, indicating that the resource is "fresh".

func (*Request) Get

func (this *Request) Get(f string) string

Get the case-insensitive request header field.

func (*Request) Is

func (this *Request) Is(t string) bool

Check if the incoming request contains the "Content-Type" header field, and it matches the give mime "type".

func (*Request) Param

func (this *Request) Param(n string) string

Return the value of param "name" when present. Lookup is performed in the following order:

* Params * Body * Query

Direct access to req.body, req.params, and req.query should be favored for clarity - unless you truly accept input from each object.

func (*Request) SetApplication

func (this *Request) SetApplication(app *Server)

Set the Application this Request will use.

func (*Request) SetResponse

func (this *Request) SetResponse(res *Response)

Set the Response this Response will use.

func (*Request) SignedCookie

func (this *Request) SignedCookie(n string, i ...interface{}) string

Contains the signed cookies sent by the user-agent, unsigned and ready for use. Signed cookies are accessed by a different function to show developer intent, otherwise a malicious attack could be placed on `req.Cookie` values which are easy to spoof. Note that signing a cookie does not mean it is "hidden" nor encrypted, this simply prevents tampering as the secret used to sign is private.

func (*Request) Stale

func (this *Request) Stale() bool

Check if the request is stale - aka Last-Modified and/or the ETag do not match, indicating that the resource is "stale".

func (*Request) Subdomains

func (this *Request) Subdomains() []string

Return subdomains as a slice of strings.

type Response

type Response struct {

	// The stackr.Response.
	*stackr.Response

	// Assign the charset. Defaults to "utf-8".
	Charset string

	// Response local variables are scoped to the request, thus only available
	// to the view(s) rendered during that request / response cycle, if any.
	// Otherwise this API is identical to app.Locals.
	Locals map[string]string
	// contains filtered or unexported fields
}

Response represents the response from an HTTP request.

func (*Response) Attachment

func (this *Response) Attachment(f ...string)

Sets the Content-Disposition header field to "attachment". If a filename is given then the Content-Type will be automatically set based on the extname via res.Type(), and the Content-Disposition's "filename=" parameter will be set.

res.Attachment(); // Content-Disposition: attachment

res.Attachment('path/to/logo.png'); // Content-Disposition: attachment; filename="logo.png" // Content-Type: image/png

func (*Response) ClearCookie

func (this *Response) ClearCookie(n string, o ...*http.Cookie)

Clear cookie "name". The "path" option defaults to "/".

func (*Response) Clone

func (this *Response) Clone() *Response

Return a clone of the this Response.

func (*Response) ContentType

func (this *Response) ContentType(t string)

Sets the Content-Type to the mime lookup of type, or when "/" is present the Content-Type is simply set to this literal value.

Examples:

res.type('.html');
res.type('html');
res.type('json');
res.type('application/json');
res.type('png');

func (*Response) Cookie

func (this *Response) Cookie(n string, i interface{}, o ...*http.Cookie)

Set cookie "name" to "value", where "value" may be a string or interface converted to JSON. The "path" option defaults to "/".

Set cookie `name` to `val`, with the given `options`.

Options:

  • `maxAge` max-age in milliseconds, converted to `expires`
  • `signed` sign the cookie
  • `path` defaults to "/"

Examples:

// "Remember Me" for 15 minutes
res.Cookie("rememberme", "1", &httpCookie{ expires: new Date(Date.now() + 900000), httpOnly: true });

// save as above
res.Cookie("rememberme", "1", &httpCookie{ maxAge: 900000, httpOnly: true })

func (*Response) Download

func (this *Response) Download(path string, f ...string)

Transfer the file at path as an "attachment", typically browsers will prompt the user for download. The Content-Disposition "filename=" parameter, aka the one that will appear in the browser dialog is set to path by default, however you may provide an override filename.

func (*Response) Etag

func (this *Response) Etag(body string) string

Return ETag for "body"

func (*Response) Format

func (this *Response) Format(opt map[string]func())

Performs content-negotiation on the request Accept header field when present. This method uses "req.Accepted", a slice of acceptable types ordered by their quality values, otherwise the first callback is invoked. When no match is performed the server responds with 406 "Not Acceptable", or invokes the "default" callback.

func (*Response) Get

func (this *Response) Get(f string) string

Get the case-insensitive response header "field".

func (*Response) Json

func (this *Response) Json(i interface{}, s ...int)

Send a JSON response. This method is identical to res.Send() when an object or slice is passed, however it may be used for explicit JSON conversion of non-objects (null, undefined, etc), though these are technically not valid JSON.

res.Json(null) res.Json(map[string]string{"user": "ric"}) res.Json(map[string]string{"error": "msg"}, 500)

func (*Response) Jsonp

func (this *Response) Jsonp(i interface{}, s ...int)

Send a JSON response with JSONP support. This method is identical to "res.Json()" however opts-in to JSONP callback support.

func (this *Response) Links(link string, rel string)

Use the given "link", "rel" to populate the "Link" response header field. If the filed is already set the given "link", "rel" will be appended.

func (*Response) Location

func (this *Response) Location(uri string)

Set the location header.

func (*Response) Redirect

func (this *Response) Redirect(uri string, s ...int)

Redirect to the given "url" with optional "status" code defaulting to 302 "Found".

func (*Response) Render

func (this *Response) Render(view string, i ...interface{})

Render a "view". When an error occurs next(err) is invoked internally.

func (*Response) Send

func (this *Response) Send(b interface{}, s ...int)

Send a response. This method performs a myriad of useful tasks for simple non-streaming responses such as automatically assigning the Content-Length unless previously defined and providing automatic HEAD and HTTP cache freshness support.

res.Send([]byte{114, 105, 99}]); res.Send(map[string]string{"some": "json"}); res.Send("some html"); res.Send("Sorry, we cannot find that!", 404); res.Send(map[string]string{"error": "msg"}, 500); res.Send(200);

func (*Response) Sendfile

func (this *Response) Sendfile(filename string, opt ...interface{})

Transfer the file at the given path. Automatically defaults the Content-Type response header field based on the filename's extension.

func (*Response) Set

func (this *Response) Set(f string, v string)

Set header "field" to "value".

func (*Response) SetApplication

func (this *Response) SetApplication(app *Server)

Set the Application this Response will use.

func (*Response) SetNext

func (this *Response) SetNext(next func())

Set the Next function this Response will use.

func (*Response) SetRequest

func (this *Response) SetRequest(req *Request)

Set the Request this Response will use.

func (*Response) SignedCookie

func (this *Response) SignedCookie(n string, i interface{}, o ...*http.Cookie)

func (*Response) Status

func (this *Response) Status(c int)

Chainable alias of stackr's "res.StatusCode=".

func (*Response) Vary

func (this *Response) Vary(field string)

Add `field` to Vary. If already present in the Vary set, then this call is simply ignored.

type Route

type Route struct {

	// HTTP Method
	Method string

	// URL Path
	Path string

	// The regex used to match the route.
	Regex *regexp.Regexp

	// Slice of functions
	Callbacks []func(*Request, *Response, func())

	// The slice of param names to return from the path.
	ParamNames []string

	// Enable case-sensitive routes
	CaseSensitive bool

	// Enable strict matching for trailing slashes
	Strict bool
}

func (*Route) CompileRegex

func (this *Route) CompileRegex(path string) *regexp.Regexp

Parse the given path to return a regex and slice of param names.

Path: /foo/:param1/bar/:param2/baz => ^/foo/(.*)/bar/(.*)/baz$ => [":param1", :param2]

func (*Route) Match

func (this *Route) Match(method string, path string) (map[string]string, bool)

This func is in the serving path so has to be super fast!

method: An uppercase HTTP Verb. math: A path segment from a URL.

type Router

type Router struct {

	// Holds the route mappings this Router will use.
	Routes []*Route

	// Params that trigger functions
	ParamFuncs map[string]func(*Request, *Response, func())

	// Enable case-sensitive routes
	CaseSensitive bool

	// Enable strict matching for trailing slashes
	Strict bool
}

func (*Router) AddParamFunc

func (this *Router) AddParamFunc(name string, fn func(*Request, *Response, func()))

Add a "param" function to the Router.

func (*Router) AddRoute

func (this *Router) AddRoute(verb string, path string, funcs ...func(*Request, *Response, func()))

Add a new route to the Router.

func (*Router) Middleware

func (this *Router) Middleware(app *Server) func(req *stackr.Request, res *stackr.Response, next func())

type Server

type Server struct {

	// A stackr.Server type
	*stackr.Server

	// Application local variables are provided to all templates rendered within the application.
	// This is useful for providing helper functions to templates, as well as app-level data.
	Locals map[string]string

	// The Router middleware function.
	Router *Router
	// contains filtered or unexported fields
}

func CreateServer

func CreateServer() *Server

Create a new stackr server.

* "env" Environment mode, defaults to $GO_ENV or "development" * "trust proxy" Enables reverse proxy support, disabled by default * "jsonp callback name" Changes the default callback name of "?callback=" * "json spaces" JSON response spaces for formatting, defaults to 2 in development, 0 in production * "case sensitive routing" Enable case sensitivity, disabled by default, treating "/Foo" and "/foo" as the same * "strict routing" Enable strict routing, by default "/foo" and "/foo/" are treated the same by the router * X "view cache" Enables view template compilation caching, enabled in production by default * "view engine" The default engine extension to use when omitted * "views" The view directory path, defaulting to "./views"

func (*Server) All

func (this *Server) All(path string, fn ...func(*Request, *Response, func()))

This method functions just like the app.Verb(verb, ...) method, however it matches all HTTP verbs.

func (*Server) Checkout

func (this *Server) Checkout(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for CHECKOUT requests to the given "path".

func (*Server) Configure

func (this *Server) Configure(i ...interface{})

Configure callback for zero or more envs, when no `env` is specified that callback will be invoked for all environments. Any combination can be used multiple times, in any order desired.

Examples:

app.Configure(func() {
  // executed for all envs
})

app.Configure("stage", func() {
  // executed staging env
})

app.Configure("stage", "production", func() {
  // executed for stage and production
})

Note:

These callbacks are invoked immediately, and are effectively sugar for the following:

var env = os.Getenv("GO_ENV")

switch (env) { case 'development': ... case 'stage': ... case 'production': ... }

func (*Server) Copy

func (this *Server) Copy(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for COPY requests to the given "path".

func (*Server) Delete

func (this *Server) Delete(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for DELETE requests to the given "path".

func (*Server) Disable

func (this *Server) Disable(n string)

Set setting "name" to "false".

func (*Server) Disabled

func (this *Server) Disabled(n string) bool

Check if setting "name" is disabled.

func (*Server) Enable

func (this *Server) Enable(n string)

Set setting "name" to "true".

func (*Server) Enabled

func (this *Server) Enabled(n string) bool

Check if setting "name" is enabled.

func (*Server) Engine

func (this *Server) Engine(ext string, fn Renderer)

Register the given template engine callback as ext.

func (*Server) Get

func (this *Server) Get(path string, fn ...func(*Request, *Response, func())) string

Get setting "name" value. or; Provides the routing functionality for GET requests to the given "path".

func (*Server) Head

func (this *Server) Head(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for HEAD requests to the given "path".

func (*Server) Lock

func (this *Server) Lock(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for LOCK requests to the given "path".

func (*Server) Merge

func (this *Server) Merge(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for MERGE requests to the given "path".

func (*Server) Mkactivity

func (this *Server) Mkactivity(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for MKACTIVITY requests to the given "path".

func (*Server) Mkcol

func (this *Server) Mkcol(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for MKCOL requests to the given "path".

func (*Server) Move

func (this *Server) Move(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for MOVE requests to the given "path".

func (*Server) Msearch

func (this *Server) Msearch(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for M-SEARCH requests to the given "path".

func (*Server) Notify

func (this *Server) Notify(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for NOTIFY requests to the given "path".

func (*Server) Options

func (this *Server) Options(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for OPTIONS requests to the given "path".

func (*Server) Param

func (this *Server) Param(p string, fn func(*Request, *Response, func()))

Map logic to route parameters. For example when ":user" is present in a route path you may map user loading logic to automatically provide req.Map["user"] to the route, or perform validations on the parameter input.

func (*Server) Patch

func (this *Server) Patch(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for PATCH requests to the given "path".

func (*Server) Path

func (this *Server) Path() string

Returns the root of this app.

func (*Server) Post

func (this *Server) Post(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for POST requests to the given "path".

func (*Server) Propfind

func (this *Server) Propfind(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for PROPFIND requests to the given "path".

func (*Server) Proppatch

func (this *Server) Proppatch(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for PROPPATCH requests to the given "path".

func (*Server) Put

func (this *Server) Put(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for PUT requests to the given "path".

func (*Server) Render

func (this *Server) Render(view string, i ...interface{}) (string, error)

Render a "view" responding with the rendered string. This is the app-level variant of "res.render()", and otherwise behaves the same way.

func (*Server) Report

func (this *Server) Report(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for REPORT requests to the given "path".

func (*Server) Set

func (this *Server) Set(n string, v ...string) string

Assigns setting "name" to "value".

func (*Server) Subscribe

func (this *Server) Subscribe(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for SUBSCRIBE requests to the given "path".

func (*Server) Trace

func (this *Server) Trace(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for TRACE requests to the given "path".

func (*Server) Unlock

func (this *Server) Unlock(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for UNLOCK requests to the given "path".

func (*Server) Unsubscribe

func (this *Server) Unsubscribe(path string, fn ...func(*Request, *Response, func()))

The method provides the routing functionality for UNSUBSCRIBE requests to the given "path".

func (*Server) Verb

func (this *Server) Verb(verb string, path string, funcs ...func(*Request, *Response, func()))

The method provides the routing functionality in Forgery, where "verb" is one of the HTTP verbs, such as app.Verb("post", ...). Multiple callbacks may be given, all are treated equally, and behave just like middleware, with the one exception that these callbacks may invoke next('route') to bypass the remaining route callback(s). This mechanism can be used to perform pre-conditions on a route then pass control to subsequent routes when there is no reason to proceed with the route matched.

Jump to

Keyboard shortcuts

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