Skip to content

Commit

Permalink
Documentation additions to session, flash, field, controller, and http
Browse files Browse the repository at this point in the history
  • Loading branch information
ijl committed Jan 7, 2014
1 parent 4601eb8 commit 724e506
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 27 deletions.
15 changes: 11 additions & 4 deletions controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ func NewController(req *Request, resp *Response) *Controller {
}
}

// FlashParams serializes the contents of Controller.Params to the Flash
// cookie.
func (c *Controller) FlashParams() {
for key, vals := range c.Params.Values {
c.Flash.Out[key] = strings.Join(vals, ",")
Expand Down Expand Up @@ -143,7 +145,8 @@ func (c *Controller) RenderHtml(html string) Result {
return &RenderHtmlResult{html}
}

// Render a "todo" indicating that the action isn't done yet.
// Todo returns an HTTP 501 Not Implemented "todo" indicating that the
// action isn't done yet.
func (c *Controller) Todo() Result {
c.Response.Status = http.StatusNotImplemented
return c.RenderError(&Error{
Expand All @@ -152,6 +155,8 @@ func (c *Controller) Todo() Result {
})
}

// NotFound returns an HTTP 404 Not Found response whose body is the
// formatted string of msg and objs.
func (c *Controller) NotFound(msg string, objs ...interface{}) Result {
finalText := msg
if len(objs) > 0 {
Expand All @@ -164,6 +169,8 @@ func (c *Controller) NotFound(msg string, objs ...interface{}) Result {
})
}

// Forbidden returns an HTTP 403 Forbidden response whose body is the
// formatted string of msg and objs.
func (c *Controller) Forbidden(msg string, objs ...interface{}) Result {
finalText := msg
if len(objs) > 0 {
Expand All @@ -176,8 +183,8 @@ func (c *Controller) Forbidden(msg string, objs ...interface{}) Result {
})
}

// Return a file, either displayed inline or downloaded as an attachment.
// The name and size are taken from the file info.
// RenderFile returns a file, either displayed inline or downloaded
// as an attachment. The name and size are taken from the file info.
func (c *Controller) RenderFile(file *os.File, delivery ContentDisposition) Result {
var (
modtime = time.Now()
Expand Down Expand Up @@ -332,7 +339,7 @@ type MethodArg struct {
Type reflect.Type
}

// Searches for a given exported method (case insensitive)
// Method searches for a given exported method (case insensitive)
func (ct *ControllerType) Method(name string) *MethodType {
lowerName := strings.ToLower(name)
for _, method := range ct.Methods {
Expand Down
12 changes: 6 additions & 6 deletions field.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"strings"
)

// Field represents a data fieid that may be collected in a web form.
// Field represents a data field that may be collected in a web form.
type Field struct {
Name string
Error *ValidationError
Expand All @@ -21,18 +21,18 @@ func NewField(name string, renderArgs map[string]interface{}) *Field {
}
}

// Returns an identifier suitable for use as an HTML id.
// Id returns an identifier suitable for use as an HTML id.
func (f *Field) Id() string {
return strings.Replace(f.Name, ".", "_", -1)
}

// Returned the flashed value of this field.
// Flash returns the flashed value of this Field.
func (f *Field) Flash() string {
v, _ := f.renderArgs["flash"].(map[string]string)[f.Name]
return v
}

// Returned the flashed value of this field as a list.
// FlashArray returns the flashed value of this Field as a list split on comma.
func (f *Field) FlashArray() []string {
v := f.Flash()
if v == "" {
Expand All @@ -41,7 +41,7 @@ func (f *Field) FlashArray() []string {
return strings.Split(v, ",")
}

// Return the current value of this field.
// Value returns the current value of this Field.
func (f *Field) Value() interface{} {
pieces := strings.Split(f.Name, ".")
answer, ok := f.renderArgs[pieces[0]]
Expand All @@ -63,7 +63,7 @@ func (f *Field) Value() interface{} {
return val.Interface()
}

// Return ERROR_CLASS if this field has a validation error, else empty string.
// ErrorClass returns ERROR_CLASS if this field has a validation error, else empty string.
func (f *Field) ErrorClass() string {
if f.Error != nil {
return ERROR_CLASS
Expand Down
14 changes: 11 additions & 3 deletions flash.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import (
"net/url"
)

// Flash represents a cookie that gets overwritten on each request.
// Flash represents a cookie that is overwritten on each request.
// It allows data to be stored across one page at a time.
// This is commonly used to implement success or error messages.
// e.g. the Post/Redirect/Get pattern: http://en.wikipedia.org/wiki/Post/Redirect/Get
// E.g. the Post/Redirect/Get pattern:
// http://en.wikipedia.org/wiki/Post/Redirect/Get
type Flash struct {
Data, Out map[string]string
}

// Error serializes the given msg and args to an "error" key within
// the Flash cookie.
func (f Flash) Error(msg string, args ...interface{}) {
if len(args) == 0 {
f.Out["error"] = msg
Expand All @@ -22,6 +25,8 @@ func (f Flash) Error(msg string, args ...interface{}) {
}
}

// Success serializes the given msg and args to a "success" key within
// the Flash cookie.
func (f Flash) Success(msg string, args ...interface{}) {
if len(args) == 0 {
f.Out["success"] = msg
Expand All @@ -30,6 +35,9 @@ func (f Flash) Success(msg string, args ...interface{}) {
}
}

// FlashFilter is a Revel Filter that retrieves and sets the flash cookie.
// Within Revel, it is available as a Flash attribute on Controller instances.
// The name of the Flash cookie is set as CookiePrefix + "_FLASH".
func FlashFilter(c *Controller, fc []Filter) {
c.Flash = restoreFlash(c.Request.Request)
c.RenderArgs["flash"] = c.Flash.Data
Expand All @@ -50,7 +58,7 @@ func FlashFilter(c *Controller, fc []Filter) {
})
}

// Restore flash from a request.
// restoreFlash deserializes a Flash cookie struct from a request.
func restoreFlash(req *http.Request) Flash {
flash := Flash{
Data: make(map[string]string),
Expand Down
17 changes: 11 additions & 6 deletions http.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ func ResolveContentType(req *http.Request) string {
return strings.ToLower(strings.TrimSpace(strings.Split(contentType, ";")[0]))
}

// Resolve the accept request header.
// ResolveFormat maps the request's Accept MIME type declaration to
// a Request.Format attribute, specifically "html", "xml", "json", or "txt",
// returning a default of "html" when Accept header cannot be mapped to a
// value above.
func ResolveFormat(req *http.Request) string {
accept := req.Header.Get("accept")

Expand All @@ -87,13 +90,13 @@ func ResolveFormat(req *http.Request) string {
return "html"
}

// A single language from the Accept-Language HTTP header.
// AcceptLanguage is a single language from the Accept-Language HTTP header.
type AcceptLanguage struct {
Language string
Quality float32
}

// A collection of sortable AcceptLanguage instances.
// AcceptLanguages is collection of sortable AcceptLanguage instances.
type AcceptLanguages []AcceptLanguage

func (al AcceptLanguages) Len() int { return len(al) }
Expand All @@ -110,10 +113,12 @@ func (al AcceptLanguages) String() string {
return output.String()
}

// Resolve the Accept-Language header value.
// ResolveAcceptLanguage returns a sorted list of Accept-Language
// header values.
//
// The results are sorted using the quality defined in the header for each language range with the
// most qualified language range as the first element in the slice.
// The results are sorted using the quality defined in the header for each
// language range with the most qualified language range as the first
// element in the slice.
//
// See the HTTP header fields specification
// (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4) for more details.
Expand Down
32 changes: 24 additions & 8 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const (
TS_KEY = "_TS"
)

// expireAfterDuration is the time to live, in seconds, of a session cookie.
// It may be specified in config as "session.expires". Values greater than 0
// set a persistent cookie with a time to live as specified, and the value 0
// sets a session cookie.
var expireAfterDuration time.Duration

func init() {
Expand All @@ -35,7 +39,8 @@ func init() {
})
}

// Return a UUID identifying this session.
// Id retrieves from the cookie or creates a time-based UUID identifying this
// session.
func (s Session) Id() string {
if uuidStr, ok := s[SESSION_ID_KEY]; ok {
return uuidStr
Expand All @@ -49,15 +54,15 @@ func (s Session) Id() string {
return s[SESSION_ID_KEY]
}

// Return a time.Time with session expiration date
// getSessionExpiration return a time.Time with the session's expiration date
func getSessionExpiration() time.Time {
if expireAfterDuration == 0 {
return time.Time{}
}
return time.Now().Add(expireAfterDuration)
}

// Returns an http.Cookie containing the signed session.
// cookie returns an http.Cookie containing the signed session.
func (s Session) cookie() *http.Cookie {
var sessionValue string
ts := getSessionExpiration()
Expand All @@ -83,6 +88,9 @@ func (s Session) cookie() *http.Cookie {
}
}

// sessionTimeoutExpiredOrMissing returns a boolean of whether the session
// cookie is either not present or present but beyond its time to live; i.e.,
// whether there is not a valid session.
func sessionTimeoutExpiredOrMissing(session Session) bool {
if exp, present := session[TS_KEY]; !present {
return true
Expand All @@ -94,7 +102,8 @@ func sessionTimeoutExpiredOrMissing(session Session) bool {
return false
}

// Returns a Session pulled from signed cookie.
// getSessionFromCookie returns a Session struct pulled from the signed
// session cookie.
func getSessionFromCookie(cookie *http.Cookie) Session {
session := make(Session)

Expand Down Expand Up @@ -122,6 +131,9 @@ func getSessionFromCookie(cookie *http.Cookie) Session {
return session
}

// SessionFilter is a Revel Filter that retrieves and sets the session cookie.
// Within Revel, it is available as a Session attribute on Controller instances.
// The name of the Session cookie is set as CookiePrefix + "_SESSION".
func SessionFilter(c *Controller, fc []Filter) {
c.Session = restoreSession(c.Request.Request)
// Make session vars available in templates as {{.session.xyz}}
Expand All @@ -133,16 +145,20 @@ func SessionFilter(c *Controller, fc []Filter) {
c.SetCookie(c.Session.cookie())
}

// restoreSession returns either the current session, retrieved from the
// session cookie, or a new session.
func restoreSession(req *http.Request) Session {
session := make(Session)
cookie, err := req.Cookie(CookiePrefix + "_SESSION")
if err != nil {
return session
return make(Session)
} else {
return getSessionFromCookie(cookie)
}

return getSessionFromCookie(cookie)
}

// getSessionExpirationCookie retrieves the cookie's time to live as a
// string of either the number of seconds, for a persistent cookie, or
// "session".
func getSessionExpirationCookie(t time.Time) string {
if t.IsZero() {
return "session"
Expand Down

0 comments on commit 724e506

Please sign in to comment.