Path: blob/main/components/ws-proxy/pkg/proxy/cookies.go
2500 views
package proxy12import (3"net/http"4"net/textproto"5"strings"6)78// All code below is copied from the Go standard library and subject9// to the following license:10// Copyright 2009 The Go Authors. All rights reserved.11// Use of this source code is governed by a BSD-style12// license that can be found in the LICENSE file.13//14// We copied this code to remove the isCookieNameValid check, in order15// to support the bad habbit of PHP applications to produce invalid cookie16// names (see https://github.com/gitpod-io/gitpod/issues/2470).17//1819// readCookies parses all "Cookie" values from the header h and20// returns the successfully parsed Cookies.21//22// if filter isn't empty, only cookies of that name are returned.23func readCookies(h http.Header, filter string) []*http.Cookie {24lines := h["Cookie"]25if len(lines) == 0 {26return []*http.Cookie{}27}2829cookies := make([]*http.Cookie, 0, len(lines)+strings.Count(lines[0], ";"))30for _, line := range lines {31line = textproto.TrimString(line)3233var part string34for len(line) > 0 { // continue since we have rest35if splitIndex := strings.Index(line, ";"); splitIndex > 0 {36part, line = line[:splitIndex], line[splitIndex+1:]37} else {38part, line = line, ""39}40part = textproto.TrimString(part)41if len(part) == 0 {42continue43}44name, val := part, ""45if j := strings.Index(part, "="); j >= 0 {46name, val = name[:j], name[j+1:]47}48if filter != "" && filter != name {49continue50}51val, quoted, ok := parseCookieValue(val, true)52if !ok {53continue54}55cookies = append(cookies, &http.Cookie{Name: name, Value: val, Quoted: quoted})56}57}58return cookies59}6061// parseCookieValue parses a cookie value according to RFC 6265.62// If allowDoubleQuote is true, parseCookieValue will consider that it63// is parsing the cookie-value;64// otherwise, it will consider that it is parsing a cookie-av value65// (cookie attribute-value).66//67// It returns the parsed cookie value, a boolean indicating whether the68// parsing was successful, and a boolean indicating whether the parsed69// value was enclosed in double quotes.70func parseCookieValue(raw string, allowDoubleQuote bool) (value string, quoted, ok bool) {71// Strip the quotes, if present.72if allowDoubleQuote && len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' {73raw = raw[1 : len(raw)-1]74quoted = true75}76for i := 0; i < len(raw); i++ {77if !validCookieValueByte(raw[i]) {78return "", quoted, false79}80}81return raw, quoted, true82}8384func validCookieValueByte(b byte) bool {85return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\'86}878889