Allow using a standard HTTP proxy in reddit widget

This commit is contained in:
Svilen Markov
2025-01-06 20:40:46 +00:00
parent abbb4950a5
commit 108c83588c
3 changed files with 105 additions and 16 deletions

View File

@@ -1,7 +1,10 @@
package glance
import (
"crypto/tls"
"fmt"
"net/http"
"net/url"
"regexp"
"strconv"
"strings"
@@ -169,3 +172,50 @@ func (i *customIconField) UnmarshalYAML(node *yaml.Node) error {
*i = newCustomIconField(value)
return nil
}
type proxyOptionsField struct {
URL string `yaml:"url"`
AllowInsecure bool `yaml:"allow-insecure"`
Timeout durationField `yaml:"timeout"`
client *http.Client `yaml:"-"`
}
func (p *proxyOptionsField) UnmarshalYAML(node *yaml.Node) error {
type proxyOptionsFieldAlias proxyOptionsField
alias := (*proxyOptionsFieldAlias)(p)
var proxyURL string
if err := node.Decode(&proxyURL); err != nil {
if err := node.Decode(alias); err != nil {
return err
}
}
if proxyURL == "" && p.URL == "" {
return nil
}
if p.URL != "" {
proxyURL = p.URL
}
parsedUrl, err := url.Parse(proxyURL)
if err != nil {
return fmt.Errorf("parsing proxy URL: %v", err)
}
var timeout = defaultClientTimeout
if p.Timeout > 0 {
timeout = time.Duration(p.Timeout)
}
p.client = &http.Client{
Timeout: timeout,
Transport: &http.Transport{
Proxy: http.ProxyURL(parsedUrl),
TLSClientConfig: &tls.Config{InsecureSkipVerify: p.AllowInsecure},
},
}
return nil
}

View File

@@ -19,19 +19,20 @@ var (
type redditWidget struct {
widgetBase `yaml:",inline"`
Posts forumPostList `yaml:"-"`
Subreddit string `yaml:"subreddit"`
Style string `yaml:"style"`
ShowThumbnails bool `yaml:"show-thumbnails"`
ShowFlairs bool `yaml:"show-flairs"`
SortBy string `yaml:"sort-by"`
TopPeriod string `yaml:"top-period"`
Search string `yaml:"search"`
ExtraSortBy string `yaml:"extra-sort-by"`
CommentsUrlTemplate string `yaml:"comments-url-template"`
Limit int `yaml:"limit"`
CollapseAfter int `yaml:"collapse-after"`
RequestUrlTemplate string `yaml:"request-url-template"`
Posts forumPostList `yaml:"-"`
Subreddit string `yaml:"subreddit"`
Proxy proxyOptionsField `yaml:"proxy"`
Style string `yaml:"style"`
ShowThumbnails bool `yaml:"show-thumbnails"`
ShowFlairs bool `yaml:"show-flairs"`
SortBy string `yaml:"sort-by"`
TopPeriod string `yaml:"top-period"`
Search string `yaml:"search"`
ExtraSortBy string `yaml:"extra-sort-by"`
CommentsUrlTemplate string `yaml:"comments-url-template"`
Limit int `yaml:"limit"`
CollapseAfter int `yaml:"collapse-after"`
RequestUrlTemplate string `yaml:"request-url-template"`
}
func (widget *redditWidget) initialize() error {
@@ -94,6 +95,7 @@ func (widget *redditWidget) update(ctx context.Context) {
widget.Search,
widget.CommentsUrlTemplate,
widget.RequestUrlTemplate,
widget.Proxy.client,
widget.ShowFlairs,
)
@@ -161,7 +163,16 @@ func templateRedditCommentsURL(template, subreddit, postId, postPath string) str
return template
}
func fetchSubredditPosts(subreddit, sort, topPeriod, search, commentsUrlTemplate, requestUrlTemplate string, showFlairs bool) (forumPostList, error) {
func fetchSubredditPosts(
subreddit,
sort,
topPeriod,
search,
commentsUrlTemplate,
requestUrlTemplate string,
proxyClient *http.Client,
showFlairs bool,
) (forumPostList, error) {
query := url.Values{}
var requestUrl string
@@ -180,8 +191,12 @@ func fetchSubredditPosts(subreddit, sort, topPeriod, search, commentsUrlTemplate
requestUrl = fmt.Sprintf("https://www.reddit.com/r/%s/%s.json?%s", subreddit, sort, query.Encode())
}
var client requestDoer = defaultHTTPClient
if requestUrlTemplate != "" {
requestUrl = strings.ReplaceAll(requestUrlTemplate, "{REQUEST-URL}", requestUrl)
} else if proxyClient != nil {
client = proxyClient
}
request, err := http.NewRequest("GET", requestUrl, nil)
@@ -191,7 +206,7 @@ func fetchSubredditPosts(subreddit, sort, topPeriod, search, commentsUrlTemplate
// Required to increase rate limit, otherwise Reddit randomly returns 429 even after just 2 requests
setBrowserUserAgentHeader(request)
responseJson, err := decodeJsonFromRequest[subredditResponseJson](defaultHTTPClient, request)
responseJson, err := decodeJsonFromRequest[subredditResponseJson](client, request)
if err != nil {
return nil, err
}