1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_CAPTIVE_PORTAL_CAPTIVE_PORTAL_DETECTOR_H_ 6 #define COMPONENTS_CAPTIVE_PORTAL_CAPTIVE_PORTAL_DETECTOR_H_ 7 8 #include "base/basictypes.h" 9 #include "base/callback.h" 10 #include "base/compiler_specific.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/threading/non_thread_safe.h" 14 #include "base/time/time.h" 15 #include "components/captive_portal/captive_portal_export.h" 16 #include "components/captive_portal/captive_portal_types.h" 17 #include "net/url_request/url_fetcher.h" 18 #include "net/url_request/url_fetcher_delegate.h" 19 #include "net/url_request/url_request_context_getter.h" 20 21 class GURL; 22 23 namespace captive_portal { 24 25 class CAPTIVE_PORTAL_EXPORT CaptivePortalDetector 26 : public net::URLFetcherDelegate, 27 public base::NonThreadSafe { 28 public: 29 struct Results { ResultsResults30 Results() 31 : result(captive_portal::RESULT_NO_RESPONSE), 32 response_code(net::URLFetcher::RESPONSE_CODE_INVALID) { 33 } 34 35 captive_portal::CaptivePortalResult result; 36 int response_code; 37 base::TimeDelta retry_after_delta; 38 GURL landing_url; 39 }; 40 41 typedef base::Callback<void(const Results& results)> DetectionCallback; 42 43 // The test URL. When connected to the Internet, it should return a 44 // blank page with a 204 status code. When behind a captive portal, 45 // requests for this URL should get an HTTP redirect or a login 46 // page. When neither is true, no server should respond to requests 47 // for this URL. 48 static const char kDefaultURL[]; 49 50 explicit CaptivePortalDetector( 51 const scoped_refptr<net::URLRequestContextGetter>& request_context); 52 virtual ~CaptivePortalDetector(); 53 54 // Triggers a check for a captive portal. After completion, runs the 55 // |callback|. 56 void DetectCaptivePortal(const GURL& url, const DetectionCallback& callback); 57 58 // Cancels captive portal check. 59 void Cancel(); 60 61 private: 62 friend class CaptivePortalDetectorTestBase; 63 64 // net::URLFetcherDelegate: 65 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 66 67 // Takes a net::URLFetcher that has finished trying to retrieve the 68 // test URL, and fills a Results struct based on its result. If the 69 // response is a 503 with a Retry-After header, |retry_after| field 70 // of |results| is populated accordingly. Otherwise, it's set to 71 // base::TimeDelta(). 72 void GetCaptivePortalResultFromResponse(const net::URLFetcher* url_fetcher, 73 Results* results) const; 74 75 // Returns the current time. Used only when determining time until a 76 // Retry-After date. 77 base::Time GetCurrentTime() const; 78 79 // Returns true if a captive portal check is currently running. 80 bool FetchingURL() const; 81 82 // Sets current test time. Used by unit tests. set_time_for_testing(const base::Time & time)83 void set_time_for_testing(const base::Time& time) { 84 time_for_testing_ = time; 85 } 86 87 // Advances current test time. Used by unit tests. advance_time_for_testing(const base::TimeDelta & delta)88 void advance_time_for_testing(const base::TimeDelta& delta) { 89 time_for_testing_ += delta; 90 } 91 92 // URL request context. 93 scoped_refptr<net::URLRequestContextGetter> request_context_; 94 95 DetectionCallback detection_callback_; 96 97 scoped_ptr<net::URLFetcher> url_fetcher_; 98 99 // Test time used by unit tests. 100 base::Time time_for_testing_; 101 102 DISALLOW_COPY_AND_ASSIGN(CaptivePortalDetector); 103 }; 104 105 } // namespace captive_portal 106 107 #endif // COMPONENTS_CAPTIVE_PORTAL_CAPTIVE_PORTAL_DETECTOR_H_ 108