// Copyright 2020 The Macaron Authors
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package middleware
import (
"net/http"
"net/url"
"time"
"code.gitea.io/gitea/modules/setting"
)
// MaxAge sets the maximum age for a provided cookie
func MaxAge(maxAge int) func(*http.Cookie) {
return func(c *http.Cookie) {
c.MaxAge = maxAge
}
// Path sets the path for a provided cookie
func Path(path string) func(*http.Cookie) {
c.Path = path
// Domain sets the domain for a provided cookie
func Domain(domain string) func(*http.Cookie) {
c.Domain = domain
// Secure sets the secure setting for a provided cookie
func Secure(secure bool) func(*http.Cookie) {
c.Secure = secure
// HTTPOnly sets the HttpOnly setting for a provided cookie
func HTTPOnly(httpOnly bool) func(*http.Cookie) {
c.HttpOnly = httpOnly
// Expires sets the expires and rawexpires for a provided cookie
func Expires(expires time.Time) func(*http.Cookie) {
c.Expires = expires
c.RawExpires = expires.Format(time.UnixDate)
// SameSite sets the SameSite for a provided cookie
func SameSite(sameSite http.SameSite) func(*http.Cookie) {
c.SameSite = sameSite
// NewCookie creates a cookie
func NewCookie(name, value string, maxAge int) *http.Cookie {
return &http.Cookie{
Name: name,
Value: value,
HttpOnly: true,
Path: setting.SessionConfig.CookiePath,
Domain: setting.SessionConfig.Domain,
MaxAge: maxAge,
Secure: setting.SessionConfig.Secure,
// SetCookie set the cookies
// TODO: Copied from gitea.com/macaron/macaron and should be improved after macaron removed.
func SetCookie(resp http.ResponseWriter, name string, value string, others ...interface{}) {
cookie := http.Cookie{}
cookie.Name = name
cookie.Value = url.QueryEscape(value)
if len(others) > 0 {
switch v := others[0].(type) {
case int:
cookie.MaxAge = v
case int64:
cookie.MaxAge = int(v)
case int32:
case func(*http.Cookie):
v(&cookie)
cookie.Path = "/"
if len(others) > 1 {
if v, ok := others[1].(string); ok && len(v) > 0 {
cookie.Path = v
} else if v, ok := others[1].(func(*http.Cookie)); ok {
if len(others) > 2 {
if v, ok := others[2].(string); ok && len(v) > 0 {
cookie.Domain = v
if len(others) > 3 {
switch v := others[3].(type) {
case bool:
cookie.Secure = v
default:
if others[3] != nil {
cookie.Secure = true
if len(others) > 4 {
if v, ok := others[4].(bool); ok && v {
cookie.HttpOnly = true
if len(others) > 5 {
if v, ok := others[5].(time.Time); ok {
cookie.Expires = v
cookie.RawExpires = v.Format(time.UnixDate)
if len(others) > 6 {
for _, other := range others[6:] {
if v, ok := other.(func(*http.Cookie)); ok {
resp.Header().Add("Set-Cookie", cookie.String())
// GetCookie returns given cookie value from request header.
func GetCookie(req *http.Request, name string) string {
cookie, err := req.Cookie(name)
if err != nil {
return ""
val, _ := url.QueryUnescape(cookie.Value)
return val