public bool BeforeRequest(Session session, Rule rule) { // HTTPS Everywhere: https://www.eff.org/https-everywhere if (!session.isHTTPS && session.port != 443) { var host = new Uri(session.fullUrl).Host; foreach (var ruleset in Rulesets) { if (ruleset.MatchRule != null) { if (!ruleset.MatchRule.IsMatch(session.fullUrl)) { continue; } } if (ruleset.Exclusions.Any(ex => ex.IsMatch(session.fullUrl))) { continue; } if (ruleset.Targets.Any() && !ruleset.Targets.Any(t => t.IsMatch(host))) { continue; } foreach (var rulesetRule in ruleset.Rule) { if (!rulesetRule.From.IsMatch(session.fullUrl)) { continue; } var secureUrl = rulesetRule.From.Replace(session.fullUrl, rulesetRule.To); // So here we are checking for a redirect loop, if we get 10 redirects in a row in 30 seconds then we need to drop back to HTTP. lock (RedirectLocker) { if (RedirectCounter.Any() && RedirectCounter.Last().Item1 == session.fullUrl) { if (RedirectCounter.Count > 5 && (RedirectCounter.Max(t => t.Item3) - RedirectCounter.Min(t => t.Item3)).TotalSeconds < 30) { RuleLog.Current.AddRule( rule, session, String.Format("HttpsEverywhere (Failed): {0} ({1})", ruleset.Name, session.hostname)); return true; } } else { RedirectCounter.Clear(); } RedirectCounter.Add(Tuple.Create(session.fullUrl, secureUrl, DateTime.UtcNow)); } if (this.FakeHttps) // BUG: This doesn't really work at the moment. { return !session.OverrideRequest(secureUrl); } rule.ResponseLog.FireEvent(session, new ResponseSummaryEventArgs { FullUrl = session.fullUrl, Referer = (session.oRequest["Referer"].HasValue() ? session.oRequest["Referer"] : "None"), ResponseCode = 302, ResponseCodeText = "302 Moved to SSL Connection", Length = 0 }); session.RedirectSession(secureUrl, false); RuleLog.Current.AddRule( rule, session, String.Format("HttpsEverywhere: {0} ({1})", ruleset.Name, session.hostname)); return false; } } } return true; }