jantar

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

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

Go to latest
Published: Jul 25, 2015 License: MIT Imports: 31 Imported by: 4

README

Jantar Build Status GoDoc

Jantar is a lightweight mvc web framework with emphasis on security written in golang. It has initially been largely inspired by Martini but prefers performance over syntactic sugar and aims to provide crucial security settings and features right out of the box.

DEPRECATED

WARNING: This project is deprecated and is not maintained anymore. The default security settings and feature are out of date and not secure anymore! Use this as reference only!

Features

  • RESTful pattern with protection against cross-site request forgery
  • Secure default settings for TLS
    • No RC4, DES or similar insecure cipher
    • No SSL, requires at least TLS 1.1
    • Prefered cipher: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • Secure default HTTP header
    • Strict-Transport-Security: max-age=31536000;includeSubDomains
    • X-Frame-Options: sameorigin
    • X-XSS-Protection: 1;mode=block
    • X-Content-Type-Options: nosniff
  • Encrypted and signed cookies using AES256 and HMAC(SHA256)
  • Simple Middleware interface
  • Compatible with http.HandlerFunc
  • Responsive to current events
    • Preview

Requirements

  • go >= 1.2

Table of Contents

Getting Started

First you have to download and install the package into the import path. This can easily be done with go get:

go get github.com/tsurai/jantar

Now you can import jantar and create a simple website

package main

import (
	"net/http"
	"github.com/tsurai/jantar"
)

func main() {
	j := jantar.New(&jantar.Config {
		Hostname: "localhost",
		Port:     3000,
	})

	j.AddRoute("GET", "/", func(respw http.ResponseWriter, req *http.Request) {
		respw.Write([]byte("Hello World"))
	})

	j.Run()
}
Controller

Using Controller and rendering Templates is very easy with Jantar. For this simple example I'm going to assume the following directory structure. A detailed description will follow soon.

|- controllers/
|-- app.go
|- views/
|-- app/
|--- index.html
| main.go

-- controllers/app.go

package controller

import (
	"github.com/tsurai/jantar"
)

type App struct {
	jantar.Controller
}

func (c *App) Index() {
	c.Render()
}

-- views/app/index.html

<h1>Hello Controller</h1>

-- main.go

package main

import (
	"github.com/tsurai/jantar"
	c "controllers"
)

func main() {
	j := jantar.New(&jantar.Config {
		Hostname: "localhost",
		Port:     3000,
	})

	j.AddRoute("GET", "/", (*c.App).Index)

	j.Run()
}

A note on security

Jantar is by no means secure in the literal sense of the word. What it does is providing easy and fast ways to protect against the most common vulnerabilities. Security should never be left out because it is too troublesome to implement.

/dev/urandom

Some might wonder why Jantar is using /dev/urandom instead of the seemingly more secure /dev/random. Please take some minutes and read this interesting article about /dev/urandom/

Todo List

  • more consistency in error handling
  • flexible config
    • custom public directory
    • custom cookie names for internal modules
  • more hooks and a better middleware interface
  • better routing for static files
  • better test coverage

Inspirations

These frameworks have been a source of inspiration and ideas during Jantars development.

Documentation

Overview

Package jantar is a lightweight mvc web framework with emphasis on security written in golang.

It has been largely inspired by Martini(https://github.com/codegangsta/martini) but prefers performance over syntactic sugar and aims to provide crucial security settings and features right out of the box.

Index

Constants

View Source
const (
	LogLevelDebug   = iota
	LogLevelInfo    = iota
	LogLevelWarning = iota
	LogLevelError   = iota
	LogLevelFatal   = iota
	LogLevelPanic   = iota
)

Defines the various logging level

View Source
const (
	ModuleTemplateManager = iota
	ModuleRouter          = iota
)

Constants for accessing jantars core modules

View Source
const (
	TmBeforeParse  = iota
	TmBeforeRender = iota
)

TemplateManager hooks

View Source
const (
	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
	TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384   uint16 = 0xc030
	TLS_RSA_WITH_AES_128_CBC_SHA256         uint16 = 0x003c
	TLS_RSA_WITH_AES_256_CBC_SHA256         uint16 = 0x003d
	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023
	TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256   uint16 = 0xc027
)

Additional TLS cipher

Variables

View Source
var (
	ErrHookDuplicateID    = errors.New("id already in use")
	ErrHookUnknownID      = errors.New("unknown hook Id")
	ErrHookInvalidHandler = errors.New("handler is not a function")
)

Hook error codes

View Source
var StatusHandler map[int]func(http.ResponseWriter, *http.Request)

StatusHandler is a map containing a http.HandlerFunc for each client side http status code. This allows developer to add their own custom http.HandlerFunc for given status codes.

Functions

func ErrorHandler

func ErrorHandler(status int) func(http.ResponseWriter, *http.Request)

ErrorHandler returns a http.HandlerFunc for a given http status code or nil if no handler can be found for that code. Developer can add their own handler by changing the StatusHandler map. Note that only 4xx codes are handled by default as 1xx, 2xx and 3xx are no error codes and 5xx should not be catchable.

func GetModule

func GetModule(key int) interface{}

GetModule returns the module specified by key. Returns nil for an invalid key

func SecureCookie

func SecureCookie(usertoken string, data string) *http.Cookie

SecureCookie saves given data in an AES256 encrypted and HMAC(SHA256) signed cookie

func UnlockCookie

func UnlockCookie(cookie *http.Cookie) *http.Cookie

UnlockCookie decrypts a given SecureCookie and checks its MAC before returning an unencrypted http.Cookie

Types

type Config

type Config struct {
	Hostname string
	Port     int
	TLS      *TLSConfig
}

Config is the main configuration struct for jantar

type Controller

type Controller struct {
	Respw      http.ResponseWriter
	Req        *http.Request
	RenderArgs map[string]interface{}
	// contains filtered or unexported fields
}

Controller implements core functionalities of the IController interface

func (*Controller) Redirect

func (c *Controller) Redirect(to string, args ...interface{})

Redirect redirects the current request to a given named route using args to complete url variables

func (*Controller) Render

func (c *Controller) Render()

Render gets the template for the calling action and renders it

func (*Controller) UrlParam

func (c *Controller) UrlParam() map[string]string

type IController

type IController interface {
	Render()
	// contains filtered or unexported methods
}

IController describes a Controller

type IMiddleware

type IMiddleware interface {
	Initialize()
	Cleanup()
	Call(rw http.ResponseWriter, r *http.Request) bool
	Yield(rw http.ResponseWriter, r *http.Request)
	// contains filtered or unexported methods
}

IMiddleware is an interface that describes a Middleware

type JLData

type JLData map[string]interface{}

JLData is a type describing map that can be passed to Data<Level>f functions for debug output

type JLogger

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

JLogger is a simple Log with some handy functions. Largely inspired by https://github.com/Sirupsen/logrus

var (
	Log *JLogger
)

Log is a package global Log instance using the prefix "jantar " on outputs

func NewJLogger

func NewJLogger(out io.Writer, prefix string, minLevel uint) *JLogger

NewJLogger creates a new JLogger instance

func (*JLogger) Debug

func (l *JLogger) Debug(v ...interface{})

Debug is equivalent to Info but uses a different logging level

func (*JLogger) Debugd

func (l *JLogger) Debugd(data JLData, v ...interface{})

Debugd is equivalent to Infod but uses a different logging level

func (*JLogger) Debugdf

func (l *JLogger) Debugdf(data JLData, format string, v ...interface{})

Debugdf is equivalent to Infodf but uses a different logging level

func (*JLogger) Debugf

func (l *JLogger) Debugf(format string, v ...interface{})

Debugf is equivalent to Infof but uses a different logging level

func (*JLogger) Error

func (l *JLogger) Error(v ...interface{})

Error is equivalent to Info but uses a different logging level

func (*JLogger) Errord

func (l *JLogger) Errord(data JLData, v ...interface{})

Errord is equivalent to Infod but uses a different logging level

func (*JLogger) Errordf

func (l *JLogger) Errordf(data JLData, format string, v ...interface{})

Errordf is equivalent to Infodf but uses a different logging level

func (*JLogger) Errorf

func (l *JLogger) Errorf(format string, v ...interface{})

Errorf is equivalent to Infof but uses a different logging level

func (*JLogger) Fatal

func (l *JLogger) Fatal(v ...interface{})

Fatal is equivalent to Info but uses a different logging level and calls fatal afterwards

func (*JLogger) Fatald

func (l *JLogger) Fatald(data JLData, v ...interface{})

Fatald is equivalent to Infod but uses a different logging level and calls fatal afterwards

func (*JLogger) Fataldf

func (l *JLogger) Fataldf(data JLData, format string, v ...interface{})

Fataldf is equivalent to Infodf but uses a different logging level and calls fatal afterwards

func (*JLogger) Fatalf

func (l *JLogger) Fatalf(format string, v ...interface{})

Fatalf is equivalent to Infof but uses a different logging level and calls fatal afterwards

func (*JLogger) Info

func (l *JLogger) Info(v ...interface{})

Info is similar to log.Print but uses a special markup indicating the message severity

func (*JLogger) Infod

func (l *JLogger) Infod(data JLData, v ...interface{})

Infod is equivalent to Info but takes additional data to display

func (*JLogger) Infodf

func (l *JLogger) Infodf(data JLData, format string, v ...interface{})

Infodf is equivalent to Infof but takes additional data to display

func (*JLogger) Infof

func (l *JLogger) Infof(format string, v ...interface{})

Infof is similar to log.Printf but uses a special markup indicating the message severity

func (*JLogger) Panic

func (l *JLogger) Panic(v ...interface{})

Panic is equivalent to Info but uses a different logging level and calls panic afterwards

func (*JLogger) Panicd

func (l *JLogger) Panicd(data JLData, v ...interface{})

Panicd is equivalent to Infod but uses a different logging level and calls panic afterwards

func (*JLogger) Panicdf

func (l *JLogger) Panicdf(data JLData, format string, v ...interface{})

Panicdf is equivalent to Infodf but uses a different logging level and calls fatal afterwards

func (*JLogger) Panicf

func (l *JLogger) Panicf(format string, v ...interface{})

Panicf is equivalent to Infof but uses a different logging level and calls panic afterwards

func (*JLogger) SetMinLevel

func (l *JLogger) SetMinLevel(minLevel uint)

SetMinLevel changes the loggers current minimal logging level

func (*JLogger) Warning

func (l *JLogger) Warning(v ...interface{})

Warning is equivalent to Info but uses a different logging level

func (*JLogger) Warningd

func (l *JLogger) Warningd(data JLData, v ...interface{})

Warningd is equivalent to Infod but uses a different logging level

func (*JLogger) Warningdf

func (l *JLogger) Warningdf(data JLData, format string, v ...interface{})

Warningdf is equivalent to Infodf but uses a different logging level

func (*JLogger) Warningf

func (l *JLogger) Warningf(format string, v ...interface{})

Warningf is equivalent to Infof but uses a different logging level

type Jantar

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

Jantar is the top level application type

func New

func New(config *Config) *Jantar

New creates a new Jantar instance ready to listen on a given hostname and port. Choosing a port small than 1 will cause Jantar to use the standard ports.

func (*Jantar) AddMiddleware

func (j *Jantar) AddMiddleware(mware IMiddleware)

AddMiddleware adds a given middleware to the current middleware list. Middlewares are executed once for every request before the actual route handler is called

func (*Jantar) AddRoute

func (j *Jantar) AddRoute(method string, pattern string, handler interface{}) *route

AddRoute adds a route with given method, pattern and handler to the Router

func (*Jantar) Run

func (j *Jantar) Run()

Run starts the http server and listens on the hostname and port given to New

func (*Jantar) ServeHTTP

func (j *Jantar) ServeHTTP(respw http.ResponseWriter, req *http.Request)

ServeHTTP implements the http.Handler interface

func (*Jantar) Stop

func (j *Jantar) Stop()

Stop closes the listener and stops the server when all pending requests have been finished

type Middleware

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

Middleware implements core functionalities of the IMiddlware interface. Developer who want to write a Middleware should add Middleware as an anonymous field and implement Call().

func (*Middleware) Yield

func (m *Middleware) Yield(rw http.ResponseWriter, r *http.Request)

Yield suspends the current Middlware until all other Middlewares have been executed. This way a Middleware can execute code after all other Middlewares are done

type TLSConfig

type TLSConfig struct {
	CertFile string
	KeyFile  string
	CertPem  []byte
	KeyPem   []byte
	// contains filtered or unexported fields
}

TLSConfig can be given to Jantar to enable tls support

type TemplateManager

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

TemplateManager is responsible for loading, watching and rendering templates

func (*TemplateManager) AddHook

func (h *TemplateManager) AddHook(hookID int, handler interface{}) error

func (*TemplateManager) AddTmplFunc

func (tm *TemplateManager) AddTmplFunc(name string, fn interface{})

AddTmplFunc adds a template function with a given name and function pointer. Note: AddTmplFunc has no effect if called after the templates have been parsed.

func (*TemplateManager) RenderTemplate

func (tm *TemplateManager) RenderTemplate(w io.Writer, req *http.Request, name string, args map[string]interface{}) error

RenderTemplate renders a template with the given name and arguments. Note: A Controller should call its Render function instead.

Directories

Path Synopsis
Package context is a small package for arbitrary per-request, global data and modules Module data are set by jantar and are read-only by default.
Package context is a small package for arbitrary per-request, global data and modules Module data are set by jantar and are read-only by default.

Jump to

Keyboard shortcuts

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