fix(web_connectivity@v0.5): limit number of redirects (#965)
Part of https://github.com/ooni/probe/issues/2237
This commit is contained in:
parent
700f94b62e
commit
ad01856beb
|
@ -38,6 +38,9 @@ type CleartextFlow struct {
|
||||||
// Logger is the MANDATORY logger to use.
|
// Logger is the MANDATORY logger to use.
|
||||||
Logger model.Logger
|
Logger model.Logger
|
||||||
|
|
||||||
|
// NumRedirects it the MANDATORY counter of the number of redirects.
|
||||||
|
NumRedirects *NumRedirects
|
||||||
|
|
||||||
// TestKeys is MANDATORY and contains the TestKeys.
|
// TestKeys is MANDATORY and contains the TestKeys.
|
||||||
TestKeys *TestKeys
|
TestKeys *TestKeys
|
||||||
|
|
||||||
|
@ -259,8 +262,8 @@ func (t *CleartextFlow) httpTransaction(ctx context.Context, network, address, a
|
||||||
|
|
||||||
// maybeFollowRedirects follows redirects if configured and needed
|
// maybeFollowRedirects follows redirects if configured and needed
|
||||||
func (t *CleartextFlow) maybeFollowRedirects(ctx context.Context, resp *http.Response) {
|
func (t *CleartextFlow) maybeFollowRedirects(ctx context.Context, resp *http.Response) {
|
||||||
if !t.FollowRedirects {
|
if !t.FollowRedirects || !t.NumRedirects.CanFollowOneMoreRedirect() {
|
||||||
return // not configured
|
return // not configured or too many redirects
|
||||||
}
|
}
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 301, 302, 307, 308:
|
case 301, 302, 307, 308:
|
||||||
|
@ -270,19 +273,20 @@ func (t *CleartextFlow) maybeFollowRedirects(ctx context.Context, resp *http.Res
|
||||||
}
|
}
|
||||||
t.Logger.Infof("redirect to: %s", location.String())
|
t.Logger.Infof("redirect to: %s", location.String())
|
||||||
resolvers := &DNSResolvers{
|
resolvers := &DNSResolvers{
|
||||||
CookieJar: t.CookieJar,
|
CookieJar: t.CookieJar,
|
||||||
DNSCache: t.DNSCache,
|
DNSCache: t.DNSCache,
|
||||||
Domain: location.Hostname(),
|
Domain: location.Hostname(),
|
||||||
IDGenerator: t.IDGenerator,
|
IDGenerator: t.IDGenerator,
|
||||||
Logger: t.Logger,
|
Logger: t.Logger,
|
||||||
TestKeys: t.TestKeys,
|
NumRedirects: t.NumRedirects,
|
||||||
URL: location,
|
TestKeys: t.TestKeys,
|
||||||
ZeroTime: t.ZeroTime,
|
URL: location,
|
||||||
WaitGroup: t.WaitGroup,
|
ZeroTime: t.ZeroTime,
|
||||||
Referer: resp.Request.URL.String(),
|
WaitGroup: t.WaitGroup,
|
||||||
Session: nil, // no need to issue another control request
|
Referer: resp.Request.URL.String(),
|
||||||
THAddr: "", // ditto
|
Session: nil, // no need to issue another control request
|
||||||
UDPAddress: t.UDPAddress,
|
THAddr: "", // ditto
|
||||||
|
UDPAddress: t.UDPAddress,
|
||||||
}
|
}
|
||||||
resolvers.Start(ctx)
|
resolvers.Start(ctx)
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -39,6 +39,9 @@ type DNSResolvers struct {
|
||||||
// Logger is the MANDATORY logger to use.
|
// Logger is the MANDATORY logger to use.
|
||||||
Logger model.Logger
|
Logger model.Logger
|
||||||
|
|
||||||
|
// NumRedirects it the MANDATORY counter of the number of redirects.
|
||||||
|
NumRedirects *NumRedirects
|
||||||
|
|
||||||
// TestKeys is MANDATORY and contains the TestKeys.
|
// TestKeys is MANDATORY and contains the TestKeys.
|
||||||
TestKeys *TestKeys
|
TestKeys *TestKeys
|
||||||
|
|
||||||
|
@ -434,6 +437,7 @@ func (t *DNSResolvers) startCleartextFlows(
|
||||||
DNSCache: t.DNSCache,
|
DNSCache: t.DNSCache,
|
||||||
IDGenerator: t.IDGenerator,
|
IDGenerator: t.IDGenerator,
|
||||||
Logger: t.Logger,
|
Logger: t.Logger,
|
||||||
|
NumRedirects: t.NumRedirects,
|
||||||
TestKeys: t.TestKeys,
|
TestKeys: t.TestKeys,
|
||||||
ZeroTime: t.ZeroTime,
|
ZeroTime: t.ZeroTime,
|
||||||
WaitGroup: t.WaitGroup,
|
WaitGroup: t.WaitGroup,
|
||||||
|
@ -475,6 +479,7 @@ func (t *DNSResolvers) startSecureFlows(
|
||||||
DNSCache: t.DNSCache,
|
DNSCache: t.DNSCache,
|
||||||
IDGenerator: t.IDGenerator,
|
IDGenerator: t.IDGenerator,
|
||||||
Logger: t.Logger,
|
Logger: t.Logger,
|
||||||
|
NumRedirects: t.NumRedirects,
|
||||||
TestKeys: t.TestKeys,
|
TestKeys: t.TestKeys,
|
||||||
ZeroTime: t.ZeroTime,
|
ZeroTime: t.ZeroTime,
|
||||||
WaitGroup: t.WaitGroup,
|
WaitGroup: t.WaitGroup,
|
||||||
|
|
|
@ -36,7 +36,7 @@ func (m *Measurer) ExperimentName() string {
|
||||||
|
|
||||||
// ExperimentVersion implements model.ExperimentMeasurer.
|
// ExperimentVersion implements model.ExperimentMeasurer.
|
||||||
func (m *Measurer) ExperimentVersion() string {
|
func (m *Measurer) ExperimentVersion() string {
|
||||||
return "0.5.17"
|
return "0.5.18"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run implements model.ExperimentMeasurer.
|
// Run implements model.ExperimentMeasurer.
|
||||||
|
@ -108,19 +108,20 @@ func (m *Measurer) Run(ctx context.Context, sess model.ExperimentSession,
|
||||||
|
|
||||||
// start background tasks
|
// start background tasks
|
||||||
resos := &DNSResolvers{
|
resos := &DNSResolvers{
|
||||||
DNSCache: NewDNSCache(),
|
DNSCache: NewDNSCache(),
|
||||||
Domain: URL.Hostname(),
|
Domain: URL.Hostname(),
|
||||||
IDGenerator: idGenerator,
|
IDGenerator: idGenerator,
|
||||||
Logger: sess.Logger(),
|
Logger: sess.Logger(),
|
||||||
TestKeys: tk,
|
NumRedirects: NewNumRedirects(5),
|
||||||
URL: URL,
|
TestKeys: tk,
|
||||||
ZeroTime: measurement.MeasurementStartTimeSaved,
|
URL: URL,
|
||||||
WaitGroup: wg,
|
ZeroTime: measurement.MeasurementStartTimeSaved,
|
||||||
CookieJar: jar,
|
WaitGroup: wg,
|
||||||
Referer: "",
|
CookieJar: jar,
|
||||||
Session: sess,
|
Referer: "",
|
||||||
THAddr: thAddr,
|
Session: sess,
|
||||||
UDPAddress: "",
|
THAddr: thAddr,
|
||||||
|
UDPAddress: "",
|
||||||
}
|
}
|
||||||
resos.Start(ctx)
|
resos.Start(ctx)
|
||||||
|
|
||||||
|
|
23
internal/experiment/webconnectivity/redirects.go
Normal file
23
internal/experiment/webconnectivity/redirects.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package webconnectivity
|
||||||
|
|
||||||
|
import "github.com/ooni/probe-cli/v3/internal/atomicx"
|
||||||
|
|
||||||
|
// NumRedirects counts the number of redirects left.
|
||||||
|
type NumRedirects struct {
|
||||||
|
count *atomicx.Int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNumRedirects creates a new NumRedirects instance.
|
||||||
|
func NewNumRedirects(n int64) *NumRedirects {
|
||||||
|
count := &atomicx.Int64{}
|
||||||
|
count.Add(n)
|
||||||
|
return &NumRedirects{
|
||||||
|
count: count,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanFollowOneMoreRedirect returns true if we are
|
||||||
|
// allowed to follow one more redirect.
|
||||||
|
func (nr *NumRedirects) CanFollowOneMoreRedirect() bool {
|
||||||
|
return nr.count.Add(-1) > 0
|
||||||
|
}
|
|
@ -39,6 +39,9 @@ type SecureFlow struct {
|
||||||
// Logger is the MANDATORY logger to use.
|
// Logger is the MANDATORY logger to use.
|
||||||
Logger model.Logger
|
Logger model.Logger
|
||||||
|
|
||||||
|
// NumRedirects it the MANDATORY counter of the number of redirects.
|
||||||
|
NumRedirects *NumRedirects
|
||||||
|
|
||||||
// TestKeys is MANDATORY and contains the TestKeys.
|
// TestKeys is MANDATORY and contains the TestKeys.
|
||||||
TestKeys *TestKeys
|
TestKeys *TestKeys
|
||||||
|
|
||||||
|
@ -311,8 +314,8 @@ func (t *SecureFlow) httpTransaction(ctx context.Context, network, address, alpn
|
||||||
|
|
||||||
// maybeFollowRedirects follows redirects if configured and needed
|
// maybeFollowRedirects follows redirects if configured and needed
|
||||||
func (t *SecureFlow) maybeFollowRedirects(ctx context.Context, resp *http.Response) {
|
func (t *SecureFlow) maybeFollowRedirects(ctx context.Context, resp *http.Response) {
|
||||||
if !t.FollowRedirects {
|
if !t.FollowRedirects || !t.NumRedirects.CanFollowOneMoreRedirect() {
|
||||||
return // not configured
|
return // not configured or too many redirects
|
||||||
}
|
}
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 301, 302, 307, 308:
|
case 301, 302, 307, 308:
|
||||||
|
@ -322,19 +325,20 @@ func (t *SecureFlow) maybeFollowRedirects(ctx context.Context, resp *http.Respon
|
||||||
}
|
}
|
||||||
t.Logger.Infof("redirect to: %s", location.String())
|
t.Logger.Infof("redirect to: %s", location.String())
|
||||||
resolvers := &DNSResolvers{
|
resolvers := &DNSResolvers{
|
||||||
CookieJar: t.CookieJar,
|
CookieJar: t.CookieJar,
|
||||||
DNSCache: t.DNSCache,
|
DNSCache: t.DNSCache,
|
||||||
Domain: location.Hostname(),
|
Domain: location.Hostname(),
|
||||||
IDGenerator: t.IDGenerator,
|
IDGenerator: t.IDGenerator,
|
||||||
Logger: t.Logger,
|
Logger: t.Logger,
|
||||||
TestKeys: t.TestKeys,
|
NumRedirects: t.NumRedirects,
|
||||||
URL: location,
|
TestKeys: t.TestKeys,
|
||||||
ZeroTime: t.ZeroTime,
|
URL: location,
|
||||||
WaitGroup: t.WaitGroup,
|
ZeroTime: t.ZeroTime,
|
||||||
Referer: resp.Request.URL.String(),
|
WaitGroup: t.WaitGroup,
|
||||||
Session: nil, // no need to issue another control request
|
Referer: resp.Request.URL.String(),
|
||||||
THAddr: "", // ditto
|
Session: nil, // no need to issue another control request
|
||||||
UDPAddress: t.UDPAddress,
|
THAddr: "", // ditto
|
||||||
|
UDPAddress: t.UDPAddress,
|
||||||
}
|
}
|
||||||
resolvers.Start(ctx)
|
resolvers.Start(ctx)
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user