Home | History | Annotate | Download | only in captive_portal
      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 CHROME_BROWSER_CAPTIVE_PORTAL_CAPTIVE_PORTAL_DETECTOR_H_
      6 #define CHROME_BROWSER_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 "net/url_request/url_fetcher.h"
     16 #include "net/url_request/url_fetcher_delegate.h"
     17 #include "net/url_request/url_request_context_getter.h"
     18 
     19 class GURL;
     20 
     21 namespace captive_portal {
     22 
     23 // Possible results of an attempt to detect a captive portal.
     24 enum Result {
     25   // There's a confirmed connection to the Internet.
     26   RESULT_INTERNET_CONNECTED,
     27   // The URL request received a network or HTTP error, or a non-HTTP response.
     28   RESULT_NO_RESPONSE,
     29   // The URL request apparently encountered a captive portal.  It received a
     30   // a valid HTTP response with a 2xx other than 204, 3xx, or 511 status code.
     31   RESULT_BEHIND_CAPTIVE_PORTAL,
     32   RESULT_COUNT
     33 };
     34 
     35 class CaptivePortalDetector : public net::URLFetcherDelegate,
     36                               public base::NonThreadSafe {
     37  public:
     38   struct Results {
     39     Results()
     40         : result(RESULT_NO_RESPONSE),
     41           response_code(net::URLFetcher::RESPONSE_CODE_INVALID) {
     42     }
     43 
     44     Result result;
     45     int response_code;
     46     base::TimeDelta retry_after_delta;
     47   };
     48 
     49   typedef base::Callback<void(const Results& results)> DetectionCallback;
     50 
     51   // The test URL.  When connected to the Internet, it should return a
     52   // blank page with a 204 status code.  When behind a captive portal,
     53   // requests for this URL should get an HTTP redirect or a login
     54   // page.  When neither is true, no server should respond to requests
     55   // for this URL.
     56   static const char kDefaultURL[];
     57 
     58   explicit CaptivePortalDetector(
     59       const scoped_refptr<net::URLRequestContextGetter>& request_context);
     60   virtual ~CaptivePortalDetector();
     61 
     62   static std::string CaptivePortalResultToString(Result result);
     63 
     64   // Triggers a check for a captive portal. After completion, runs the
     65   // |callback|.
     66   void DetectCaptivePortal(const GURL& url, const DetectionCallback& callback);
     67 
     68   // Cancels captive portal check.
     69   void Cancel();
     70 
     71  private:
     72   friend class CaptivePortalDetectorTestBase;
     73 
     74   // net::URLFetcherDelegate:
     75   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
     76 
     77   // Takes a net::URLFetcher that has finished trying to retrieve the
     78   // test URL, and fills a Results struct based on its result.  If the
     79   // response is a 503 with a Retry-After header, |retry_after| field
     80   // of |results| is populated accordingly.  Otherwise, it's set to
     81   // base::TimeDelta().
     82   void GetCaptivePortalResultFromResponse(const net::URLFetcher* url_fetcher,
     83                                           Results* results) const;
     84 
     85   // Returns the current time. Used only when determining time until a
     86   // Retry-After date.
     87   base::Time GetCurrentTime() const;
     88 
     89   // Returns true if a captive portal check is currently running.
     90   bool FetchingURL() const;
     91 
     92   // Sets current test time. Used by unit tests.
     93   void set_time_for_testing(const base::Time& time) {
     94     time_for_testing_ = time;
     95   }
     96 
     97   // Advances current test time. Used by unit tests.
     98   void advance_time_for_testing(const base::TimeDelta& delta) {
     99     time_for_testing_ += delta;
    100   }
    101 
    102   // URL request context.
    103   scoped_refptr<net::URLRequestContextGetter> request_context_;
    104 
    105   DetectionCallback detection_callback_;
    106 
    107   scoped_ptr<net::URLFetcher> url_fetcher_;
    108 
    109   // Test time used by unit tests.
    110   base::Time time_for_testing_;
    111 
    112   DISALLOW_COPY_AND_ASSIGN(CaptivePortalDetector);
    113 };
    114 
    115 }  // namespace captive_portal
    116 
    117 #endif  // CHROME_BROWSER_CAPTIVE_PORTAL_CAPTIVE_PORTAL_DETECTOR_H_
    118