Skip to content

Commit

Permalink
chore(cov): better testing and coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
Noooste committed Dec 21, 2024
1 parent 38aa575 commit ec339a3
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 184 deletions.
138 changes: 0 additions & 138 deletions cookies.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ package azuretls
import (
"bytes"
http "github.com/Noooste/fhttp"
"golang.org/x/net/http/httpguts"
"net/textproto"
"strconv"
"strings"
"time"
)

var cookieNameSanitizer = strings.NewReplacer("\n", "-", "\r", "-")
Expand Down Expand Up @@ -41,137 +37,3 @@ func GetCookiesMap(cookies []*http.Cookie) map[string]string {

return result
}

func ReadSetCookies(h http.Header) []*http.Cookie {
cookieCount := len(h["Set-Cookie"])
if cookieCount == 0 {
return []*http.Cookie{}
}
cookies := make([]*http.Cookie, 0, cookieCount)
for _, line := range h["Set-Cookie"] {
parts := strings.Split(textproto.TrimString(line), ";")
if len(parts) == 1 && parts[0] == "" {
continue
}
parts[0] = textproto.TrimString(parts[0])
j := strings.Index(parts[0], "=")
if j < 0 {
continue
}
name, value := parts[0][:j], parts[0][j+1:]
if !isCookieNameValid(name) {
continue
}
value, ok := parseCookieValue(value, true)
if !ok {
continue
}
c := &http.Cookie{
Name: name,
Value: value,
Raw: line,
}
for i := 1; i < len(parts); i++ {
parts[i] = textproto.TrimString(parts[i])
if len(parts[i]) == 0 {
continue
}

attr, val := parts[i], ""
if j := strings.Index(attr, "="); j >= 0 {
attr, val = attr[:j], attr[j+1:]
}
lowerAttr := strings.ToLower(attr)
val, ok = parseCookieValue(val, false)
if !ok {
c.Unparsed = append(c.Unparsed, parts[i])
continue
}
switch lowerAttr {
case "samesite":
lowerVal := strings.ToLower(val)
switch lowerVal {
case "lax":
c.SameSite = http.SameSiteLaxMode
case "strict":
c.SameSite = http.SameSiteStrictMode
case "none":
c.SameSite = http.SameSiteNoneMode
default:
c.SameSite = http.SameSiteDefaultMode
}
continue
case "secure":
c.Secure = true
continue
case "httponly":
c.HttpOnly = true
continue
case "domain":
c.Domain = val
continue
case "max-age":
secs, err := strconv.Atoi(val)
if err != nil || secs != 0 && val[0] == '0' {
break
}
if secs <= 0 {
secs = -1
}
c.MaxAge = secs
continue
case "expires":
c.RawExpires = val
exptime, err := time.Parse(time.RFC1123, val)
if err != nil {
exptime, err = time.Parse("Mon, 02-Jan-2006 15:04:05 MST", val)
if err != nil {
c.Expires = time.Time{}
break
}
}
c.Expires = exptime.UTC()
continue
case "path":
c.Path = val
continue
}
c.Unparsed = append(c.Unparsed, parts[i])
}
cookies = append(cookies, c)
}
return cookies
}

// Disallows illegal characters in cookie value. Ignores illegal character `"`, some cookies have the " value
func validCookieValueByte(b byte) bool {
return 0x20 <= b &&
b < 0x7f &&
// b != '"' &&
b != ';' &&
b != '\\'
}

func parseCookieValue(raw string, allowDoubleQuote bool) (string, bool) {
// Strip the quotes, if present.
if allowDoubleQuote && len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' {
raw = raw[1 : len(raw)-1]
}
for i := 0; i < len(raw); i++ {
if !validCookieValueByte(raw[i]) {
return "", false
}
}
return raw, true
}

func isCookieNameValid(raw string) bool {
if raw == "" {
return false
}
return strings.IndexFunc(raw, isNotToken) < 0
}

func isNotToken(r rune) bool {
return !httpguts.IsTokenRune(r)
}
24 changes: 1 addition & 23 deletions ja3.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (s *Session) ApplyJa3(ja3, navigator string) error {
//
// Any absent field in the client hello will raise an error.
func (s *Session) ApplyJa3WithSpecifications(ja3 string, specifications *TlsSpecifications, navigator string) error {
_, err := stringToSpec(ja3, DefaultTlsSpecifications(navigator), navigator)
_, err := stringToSpec(ja3, specifications, navigator)
if err != nil {
return err
}
Expand Down Expand Up @@ -522,28 +522,6 @@ func getSupportedAlgorithms(navigator string) []tls.SignatureScheme {
tls.PSSWithSHA512,
tls.PKCS1WithSHA512,
}
case Opera:
return []tls.SignatureScheme{
1027,
1283,
1539,
2052,
2053,
2054,
2057,
2058,
2059,
1025,
1281,
1537,
1026,
771,
769,
770,
515,
513,
514,
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion response.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (s *Session) buildResponse(response *Response, httpResponse *http.Response)
u, _ = url.Parse(response.Url)
}

cookies := ReadSetCookies(httpResponse.Header)
cookies := httpResponse.Cookies()
s.CookieJar.SetCookies(u, cookies)
response.Cookies = GetCookiesMap(cookies)
response.ContentLength = httpResponse.ContentLength
Expand Down
17 changes: 17 additions & 0 deletions test/ja3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,3 +400,20 @@ func TestIosProfile(t *testing.T) {
t.Fatal("Expected different hashes")
}
}

func TestGetApplyJa3WithoutSpecifications(t *testing.T) {
session := azuretls.NewSession()
defer session.Close()

err := session.ApplyJa3WithSpecifications("771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-65037,29-23-24-25-256-257,0", &azuretls.TlsSpecifications{}, azuretls.Firefox)
if err != nil {
log.Fatal(err)
return
}

err = session.ApplyJa3WithSpecifications("771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-65037,29-23-24-25-256-257,0", &azuretls.TlsSpecifications{}, azuretls.Chrome)
if err != nil {
log.Fatal(err)
return
}
}
23 changes: 1 addition & 22 deletions websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/Noooste/websocket"
"net"
url2 "net/url"
"time"
)

type Websocket struct {
Expand Down Expand Up @@ -87,27 +86,7 @@ func (s *Session) NewWebsocketWithContext(ctx context.Context, url string, readB
ctx = context.WithValue(ctx, forceHTTP1Key, true)
return s.dialTLS(ctx, network, addr)
},
NetDialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
dialer := &net.Dialer{
Timeout: s.TimeOut,
KeepAlive: 30 * time.Second,
}

if s.ModifyDialer != nil {
if err = s.ModifyDialer(dialer); err != nil {
return nil, err
}
}

return dialer.DialContext(s.ctx, network, addr)
},
Proxy: func(*http.Request) (*url2.URL, error) {
if s.Proxy == "" {
return nil, nil
}

return url2.Parse(s.Proxy)
},
NetDialContext: s.dial,
}

c, resp, err := ws.dialer.DialContext(ctx, req.Url, req.HttpRequest.Header, req.HttpRequest.Header[http.HeaderOrderKey])
Expand Down

0 comments on commit ec339a3

Please sign in to comment.