forked from openshift/osin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
response.go
138 lines (120 loc) · 3.05 KB
/
response.go
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
package osin
import (
"errors"
"fmt"
"net/http"
"net/url"
)
// Data for response output
type ResponseData map[string]interface{}
// Response type enum
type ResponseType int
const (
DATA ResponseType = iota
REDIRECT
)
// Server response
type Response struct {
Type ResponseType
StatusCode int
StatusText string
ErrorStatusCode int
URL string
Output ResponseData
Headers http.Header
IsError bool
InternalError error
RedirectInFragment bool
// Storage to use in this response - required
Storage Storage
}
func NewResponse(storage Storage) *Response {
r := &Response{
Type: DATA,
StatusCode: 200,
ErrorStatusCode: 200,
Output: make(ResponseData),
Headers: make(http.Header),
IsError: false,
Storage: storage.Clone(),
}
r.Headers.Add(
"Cache-Control",
"no-cache, no-store, max-age=0, must-revalidate",
)
r.Headers.Add("Pragma", "no-cache")
r.Headers.Add("Expires", "Fri, 01 Jan 1990 00:00:00 GMT")
return r
}
// SetError sets an error id and description on the Response
// state and uri are left blank
func (r *Response) SetError(id string, description string) {
r.SetErrorUri(id, description, "", "")
}
// SetErrorState sets an error id, description, and state on the Response
// uri is left blank
func (r *Response) SetErrorState(id string, description string, state string) {
r.SetErrorUri(id, description, "", state)
}
// SetErrorUri sets an error id, description, state, and uri on the Response
func (r *Response) SetErrorUri(id string, description string, uri string, state string) {
// get default error message
if description == "" {
description = deferror.Get(id)
}
// set error parameters
r.IsError = true
r.StatusCode = r.ErrorStatusCode
if r.StatusCode != 200 {
r.StatusText = description
} else {
r.StatusText = ""
}
r.Output = make(ResponseData) // clear output
r.Output["error"] = id
r.Output["error_description"] = description
if uri != "" {
r.Output["error_uri"] = uri
}
if state != "" {
r.Output["state"] = state
}
}
// SetErrorUri changes the response to redirect to the given url
func (r *Response) SetRedirect(url string) {
// set redirect parameters
r.Type = REDIRECT
r.URL = url
}
// SetRedirectFragment sets redirect values to be passed in fragment instead of as query parameters
func (r *Response) SetRedirectFragment(f bool) {
r.RedirectInFragment = f
}
// GetRedirectUrl returns the redirect url with all query string parameters
func (r *Response) GetRedirectUrl() (string, error) {
if r.Type != REDIRECT {
return "", errors.New("Not a redirect response")
}
u, err := url.Parse(r.URL)
if err != nil {
return "", err
}
// add parameters
q := u.Query()
for n, v := range r.Output {
q.Set(n, fmt.Sprint(v))
}
if r.RedirectInFragment {
u.RawQuery = ""
u.Fragment, err = url.QueryUnescape(q.Encode())
if err != nil {
return "", err
}
} else {
u.RawQuery = q.Encode()
}
return u.String(), nil
}
func (r *Response) Close() {
r.Storage.Close()
}