fox

package module
v0.0.0-...-477296f Latest Latest
Warning

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

Go to latest
Published: May 8, 2023 License: MIT Imports: 19 Imported by: 0

README

Fox

GoDoc

Web application framework built during school and free time.

Session feature uses sqlite as session storage, you'll need an gcc compiler to run your program.

Install

go get github.com/robin-andreasson/fox

Layout

//Initialize root router
r := fox.Init()

/*
    ...routes and middlewares
*/

//Start server at port 3000
r.Listen(3000)

Features

Routing

Map functions to url paths

r.Get("/", handler)

r.Post("/", handler)

r.Put("/", handler)

r.Delete("/", handler)
Groups

Add path prefixes to remove redundancy

auth := r.Group("auth")

// -> /auth/signin
auth.Post("/signin", handler)
// -> /auth/signup
auth.Post("/signup", handler)
Path variables

Add variables in url paths, colon as delimiter

//Path variable named id
r.Get("/task/:id", getTask)

func getTask(c *fox.Context) error {
    //get id
    id := c.Params("id")
}

Regex pattern for specifying possible path variable values, semicolon as delimiter.

/*
Trigger handler only if page variable matches the regex ^\d+$

Fox wraps your regex statement between ^ and $
e.g. \d+ becomes ^\d+$
*/
r.Get("/book/:name/:page;\d+")
Body parsing and fox.Get

Fox parses incoming http bodies and maps them to an interface typed field in fox.Context called Body.

Multipart/form-data example:

/*
c.Body: 
{
    "Files": {
        "file-name": {
            "Data": []byte
            "Filename": string
            "Content-Type": string
        }
    }
}
*/
r.Post("/image", handler)

func handler(c *fox.Context) error {

    //retrieve data from nested map interfaces with fox.Get
    image := fox.Get[map[string]any](c.Body, "Files", "file-name")

    data := fox.Get[[]byte](image, "Data")
    filename := fox.Get[string](image, "Filename")

    if err := os.WriteFile(filename, data, 777); err != nil {
        return c.Status(fox.Status.InternalServerError)
    }

    return c.JSON(fox.Status.Created, map[string]string{"message": "successfully created image"})
}
Session

A way to store information to be used across multiple pages.


/*
Initialize session options
*/
fox.Session(fox.SessionOptions{
    Secret:           "YOUR_SECRET",
    TimeOut:          1000 * 60 * 60 * 24 * 30,
    ClearProbability: 2.5,
    Path: "./storage/session.sql",

    Cookie: fox.CookieAttributes{
    	HttpOnly:  true,
    	Secure:    true,
    	SameSite:  "Lax",
    	Path:      "/",
    	ExpiresIn: 1000 * 60 * 60 * 24 * 30,
    },
})


/*
Set session
*/
r.Post("/auth/signin", signin)

func signin(c *fox.Context) error {
    //store information and create FOXSESSID cookie
    c.SetSession(map[string]string{/*...data*/})
 
    c.Status(fox.Status.Ok)
}


/*
Get session
*/
r.Post("/session", session)

func session(c *fox.Context) error {
    c.Session// -> map[string]string{/*...data*/}
}
Refresh

Allows the client to receive new jwt access token through the X-Fox-Access-Token header.

//initialize refresh options
fox.Refresh(fox.RefreshOptions{
    //Found in X-Fox-Access-Token header
    AccessToken: fox.TokenOptions{
    	Secret: "YOUR_ACCESS_TOKEN_SECRET",
    	Exp:    1000 * 60 * 5,
    },
    //Stored in FOXREFRESH cookie
    RefreshToken: fox.TokenOptions{
    	Secret: "YOUR_REFRESH_TOKEN_SECRET",
    	Exp:    1000 * 60 * 60 * 24,
    },
    Cookie: fox.CookieAttributes{
    	HttpOnly:  true,
    	Secure:    true,
    	SameSite:  "Lax",
    	Path:      "/",
    	ExpiresIn: 1000 * 60 * 60 * 24,
    },
    RefreshFunction: handleRefresh,
})

/*
used to fetch the new access token data after it has expired.

refreshdata parameter is the data stored in refresh token.
*/
func handleRefresh(refreshdata any) (any, error) {

    id := fox.Get[string](refreshdata, "id")

    /*    
        fetch new access token data with the help of refresh token data 
    */
    result := fetch(id)

    return result, nil
}


r.Post("/auth/signin", signin)

func signin(c *fox.Context) error {

    //add non vulnerable data for fetching new access token data
    refreshData := map[string]string{/*...data */}

    accessData := map[string]string{/*...data */}
    
    c.SetRefresh(accessData, refreshData)
 
    c.Status(fox.Status.Ok)
}

/*
Get refresh
*/
r.Post("/refresh", session)

func session(c *fox.Context) error {
    c.Refresh// -> map[string]string{/*...data*/}
}
Middleware

Add functions to be called before the main handler


r.Post("/", middleware, handler)

func middleware(c *fox.Context) error {
    //continue to the next middleware/handler in the stack
    return c.Next()    
}
Statically serve files

Specify folder to be used to serve static files when the client endpoint requests them

/*
    wd: /src/internal
*/

//Serve folder named public in /src/internal 
r.Static("public")

//Serve folder named static in /src
r.Static("static", "../")

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Status status = status{
	100, 101, 102, 103,

	200, 201, 202, 203, 204, 205, 206, 207, 208, 226,

	300, 301, 302, 303, 304, 305, 306, 307, 308,

	400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451,

	500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511,
}

Functions

func CORS

func CORS(options CorsOptions)

Set Cross-Origin Resource Sharing headers and handle OPTIONS requests

func Dir

func Dir(path string) string

func Ext

func Ext(path string) (string, error)

func Get

func Get[T any](target any, keys ...string) T

Get value from nested map interfaces

error returns the zero value equivalent to type T

func Init

func Init() *router

Initializes root router

func Refresh

func Refresh(options RefreshOptions)

creates a refresh middleware

will create refresh and access tokens

searches for the "authorization" header with bearer when it comes to access token

func Session

func Session(options SessionOptions)

Initialize Sessions

returns Session middleware

NOTE: sqlite3 is used as session store meaning that a gcc compiler is needed

Types

type Context

type Context struct {
	Url     string
	Method  string
	Headers map[string]string

	Body    any // Body from the http request
	Session any // Session payload received from the Session middleware
	Refresh any // Refresh payload received from the Refresh middleware
	Error   []error

	Params  map[string]string
	Query   map[string]string
	Cookies map[string]string

	Raw []byte
	// contains filtered or unexported fields
}

func (*Context) Cookie

func (c *Context) Cookie(name string, value string, attributes CookieAttributes) error

Set a cookie

func (*Context) File

func (c *Context) File(code int, path string) error

Send file data to the request endpoint

mime types like images, zips, fonts, audio, pdf and mp4 files are calculated.

mime types from e.g. script files that is in need for a sniffing technique is found through file extension

func (*Context) JSON

func (c *Context) JSON(code int, body any) error

Send json data to the request endpoint

func (*Context) Next

func (c *Context) Next() error

func (*Context) Redirect

func (c *Context) Redirect(path string) error

redirect the client to the specified url path

func (*Context) ResHeaders

func (c *Context) ResHeaders() map[string][]string

returns set response headers

func (*Context) SetHeader

func (c *Context) SetHeader(name string, value string) error

Set a header by passing a name and value

func (*Context) SetRefresh

func (c *Context) SetRefresh(accesstoken_payload any, refreshtoken_payload any) error

set a refresh session

returns access token

func (*Context) SetSession

func (c *Context) SetSession(payload any) error

create a session

func (*Context) Status

func (c *Context) Status(code int) error

send empty body to the request endpoint

func (*Context) Text

func (c *Context) Text(code int, body string) error

Send text to the request endpoint

content type is set to text/html; charset=utf-8

type CookieAttributes

type CookieAttributes struct {
	HttpOnly    bool
	BASE64      bool
	Secure      bool
	Partitioned bool
	Path        string
	Domain      string
	SameSite    string //strict, lax or none
	ExpiresIn   int
	MaxAge      int
}

type CorsOptions

type CorsOptions struct {
	Origins     []string
	Methods     []string
	Headers     []string
	Credentials bool
}

type RefreshOptions

type RefreshOptions struct {
	AccessToken     TokenOptions
	RefreshToken    TokenOptions
	RefreshFunction func(refreshobj any) (any, error) // retrieve payload you plan to store inside access token
	Cookie          CookieAttributes
	// contains filtered or unexported fields
}

type SessionOptions

type SessionOptions struct {
	Secret           string  // String used in session id hashing
	TimeOut          int     // Milliseconds until session is expired in the session store, defaults to 24 hours
	ClearProbability float64 // value between 0 - 100 that represents the chance of fox clearing expired sessions
	Path             string  // path to the session store
	Cookie           CookieAttributes
	// contains filtered or unexported fields
}

type TokenOptions

type TokenOptions struct {
	Secret string // string used to encode jwt tokens
	Exp    int    // Milliseconds until token expires
	Nbf    int    // Milliseconds until before activated
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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