Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/ws-proxy/pkg/proxy/cookies.go
2500 views
1
package proxy
2
3
import (
4
"net/http"
5
"net/textproto"
6
"strings"
7
)
8
9
// All code below is copied from the Go standard library and subject
10
// to the following license:
11
// Copyright 2009 The Go Authors. All rights reserved.
12
// Use of this source code is governed by a BSD-style
13
// license that can be found in the LICENSE file.
14
//
15
// We copied this code to remove the isCookieNameValid check, in order
16
// to support the bad habbit of PHP applications to produce invalid cookie
17
// names (see https://github.com/gitpod-io/gitpod/issues/2470).
18
//
19
20
// readCookies parses all "Cookie" values from the header h and
21
// returns the successfully parsed Cookies.
22
//
23
// if filter isn't empty, only cookies of that name are returned.
24
func readCookies(h http.Header, filter string) []*http.Cookie {
25
lines := h["Cookie"]
26
if len(lines) == 0 {
27
return []*http.Cookie{}
28
}
29
30
cookies := make([]*http.Cookie, 0, len(lines)+strings.Count(lines[0], ";"))
31
for _, line := range lines {
32
line = textproto.TrimString(line)
33
34
var part string
35
for len(line) > 0 { // continue since we have rest
36
if splitIndex := strings.Index(line, ";"); splitIndex > 0 {
37
part, line = line[:splitIndex], line[splitIndex+1:]
38
} else {
39
part, line = line, ""
40
}
41
part = textproto.TrimString(part)
42
if len(part) == 0 {
43
continue
44
}
45
name, val := part, ""
46
if j := strings.Index(part, "="); j >= 0 {
47
name, val = name[:j], name[j+1:]
48
}
49
if filter != "" && filter != name {
50
continue
51
}
52
val, quoted, ok := parseCookieValue(val, true)
53
if !ok {
54
continue
55
}
56
cookies = append(cookies, &http.Cookie{Name: name, Value: val, Quoted: quoted})
57
}
58
}
59
return cookies
60
}
61
62
// parseCookieValue parses a cookie value according to RFC 6265.
63
// If allowDoubleQuote is true, parseCookieValue will consider that it
64
// is parsing the cookie-value;
65
// otherwise, it will consider that it is parsing a cookie-av value
66
// (cookie attribute-value).
67
//
68
// It returns the parsed cookie value, a boolean indicating whether the
69
// parsing was successful, and a boolean indicating whether the parsed
70
// value was enclosed in double quotes.
71
func parseCookieValue(raw string, allowDoubleQuote bool) (value string, quoted, ok bool) {
72
// Strip the quotes, if present.
73
if allowDoubleQuote && len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' {
74
raw = raw[1 : len(raw)-1]
75
quoted = true
76
}
77
for i := 0; i < len(raw); i++ {
78
if !validCookieValueByte(raw[i]) {
79
return "", quoted, false
80
}
81
}
82
return raw, quoted, true
83
}
84
85
func validCookieValueByte(b byte) bool {
86
return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\'
87
}
88
89