File: context.go

package info (click to toggle)
mirrorbits 0.6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 984 kB
  • sloc: sh: 675; makefile: 93
file content (150 lines) | stat: -rw-r--r-- 3,412 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright (c) 2014-2019 Ludovic Fauvet
// Licensed under the MIT license

package http

import (
	"net/http"
	"net/url"
	"strings"

	. "github.com/etix/mirrorbits/config"
)

// RequestType defines the type of the request
type RequestType int

// SecureOption is the type that defines TLS requirements
type SecureOption int

const (
	STANDARD RequestType = iota
	MIRRORLIST
	FILESTATS
	MIRRORSTATS
	CHECKSUM

	UNDEFINED SecureOption = iota
	WITHTLS
	WITHOUTTLS
)

// Context represents the context of a request
type Context struct {
	r             *http.Request
	w             http.ResponseWriter
	t             Templates
	v             url.Values
	typ           RequestType
	isMirrorList  bool
	isMirrorStats bool
	isFileStats   bool
	isChecksum    bool
	isPretty      bool
	secureOption  SecureOption
}

// NewContext returns a new instance of Context
func NewContext(w http.ResponseWriter, r *http.Request, t Templates) *Context {
	c := &Context{r: r, w: w, t: t, v: r.URL.Query()}

	if c.paramBool("mirrorlist") {
		c.typ = MIRRORLIST
		c.isMirrorList = true
	} else if c.paramBool("stats") {
		c.typ = FILESTATS
		c.isFileStats = true
	} else if c.paramBool("mirrorstats") {
		c.typ = MIRRORSTATS
		c.isMirrorStats = true
	} else if c.paramBool("md5") || c.paramBool("sha1") || c.paramBool("sha256") {
		c.typ = CHECKSUM
		c.isChecksum = true
	} else {
		c.typ = STANDARD
	}

	if c.paramBool("pretty") {
		c.isPretty = true
	}

	// Check for HTTPS requirements
	proto := strings.ToLower(r.Header.Get("X-Forwarded-Proto"))
	if proto == "https" {
		c.secureOption = WITHTLS
	} else if proto == "http" && GetConfig().AllowHTTPToHTTPSRedirects == false {
		c.secureOption = WITHOUTTLS
	}

	// Check if the query sets (thus overrides) HTTPS requirements
	v, ok := c.v["https"]
	if ok {
		if v[0] == "1" {
			c.secureOption = WITHTLS
		} else if v[0] == "0" {
			c.secureOption = WITHOUTTLS
		}
	}

	return c
}

// Request returns the underlying http.Request of the current request
func (c *Context) Request() *http.Request {
	return c.r
}

// ResponseWriter returns the underlying http.ResponseWriter of the current request
func (c *Context) ResponseWriter() http.ResponseWriter {
	return c.w
}

// Templates returns the instance of precompiled templates
func (c *Context) Templates() Templates {
	return c.t
}

// Type returns the type of the current request
func (c *Context) Type() RequestType {
	return c.typ
}

// IsMirrorlist returns true if the mirror list has been requested
func (c *Context) IsMirrorlist() bool {
	return c.isMirrorList
}

// IsFileStats returns true if the file stats has been requested
func (c *Context) IsFileStats() bool {
	return c.isFileStats
}

// IsMirrorStats returns true if the mirror stats has been requested
func (c *Context) IsMirrorStats() bool {
	return c.isMirrorStats
}

// IsChecksum returns true if a checksum has been requested
func (c *Context) IsChecksum() bool {
	return c.isChecksum
}

// IsPretty returns true if the pretty json has been requested
func (c *Context) IsPretty() bool {
	return c.isPretty
}

// QueryParam returns the value associated with the given query parameter
func (c *Context) QueryParam(key string) string {
	return c.v.Get(key)
}

// SecureOption returns the selected secure option
func (c *Context) SecureOption() SecureOption {
	return c.secureOption
}

func (c *Context) paramBool(key string) bool {
	_, ok := c.v[key]
	return ok
}