Work around Reddit's TLS handshake detection

This commit is contained in:
Svilen Markov
2026-05-30 21:07:07 +01:00
parent 315e39d61e
commit d63afc2c6d
3 changed files with 49 additions and 7 deletions
+36 -3
View File
@@ -2,17 +2,22 @@ package glance
import (
"context"
"crypto/tls"
"errors"
"fmt"
"html"
"html/template"
"io"
"net"
"net/http"
"net/url"
"regexp"
"strconv"
"strings"
"time"
utls "github.com/refraction-networking/utls"
"golang.org/x/net/http2"
)
var (
@@ -160,7 +165,7 @@ func (widget *redditWidget) parseCustomCommentsURL(subreddit, postId, postPath s
}
func (widget *redditWidget) fetchSubredditPosts() (forumPostList, error) {
var client requestDoer = defaultHTTPClient
var client requestDoer = redditHTTPClient
var baseURL string
var requestURL string
var headers http.Header
@@ -318,6 +323,34 @@ func (widget *redditWidget) fetchNewAppAccessToken() error {
return nil
}
// On Windows the default HTTP client works fine, but on Linux it seems to
// get detected and blocked by reddit (or cloudflare) presumably because of TLS fingerprinting,
// so we use uTLS to mimic a real browser's TLS fingerprint, which seems to work around the issue
var redditHTTPClient = &http.Client{Transport: &http2.Transport{
DialTLSContext: func(ctx context.Context, network, addr string, _ *tls.Config) (net.Conn, error) {
host, _, err := net.SplitHostPort(addr)
if err != nil {
return nil, err
}
tcpConn, err := (&net.Dialer{}).DialContext(ctx, network, addr)
if err != nil {
return nil, err
}
uconn := utls.UClient(tcpConn, &utls.Config{
ServerName: host,
}, utls.HelloFirefox_Auto)
if err := uconn.HandshakeContext(ctx); err != nil {
tcpConn.Close()
return nil, err
}
return uconn, nil
},
}}
var (
redditChallengePattern = regexp.MustCompile(`await\(async \w+\s*=>\s*\w+\s*\+\s*\w+\)\("([^"]+)"\)`)
redditTokenPattern = regexp.MustCompile(`name="token"\s+value="([^"]+)"`)
@@ -361,7 +394,7 @@ func fetchRedditLoidCookie() (string, error) {
setBrowserUserAgentHeader(request)
response, err := http.DefaultClient.Do(request)
response, err := redditHTTPClient.Do(request)
if err != nil {
return "", err
}
@@ -403,7 +436,7 @@ func fetchRedditLoidCookie() (string, error) {
setBrowserUserAgentHeader(request)
response, err = http.DefaultClient.Do(request)
response, err = redditHTTPClient.Do(request)
if err != nil {
return "", err
}