This source file includes following definitions.
- CaptivePortalResultToString
- DetectCaptivePortal
- Cancel
- OnURLFetchComplete
- GetCaptivePortalResultFromResponse
- GetCurrentTime
- FetchingURL
#include "chrome/browser/captive_portal/captive_portal_detector.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/profiles/profile.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request_status.h"
namespace captive_portal {
namespace {
const char* const kCaptivePortalResultNames[] = {
"InternetConnected",
"NoResponse",
"BehindCaptivePortal",
"NumCaptivePortalResults",
};
COMPILE_ASSERT(arraysize(kCaptivePortalResultNames) == RESULT_COUNT + 1,
captive_portal_result_name_count_mismatch);
}
const char CaptivePortalDetector::kDefaultURL[] =
"http://www.gstatic.com/generate_204";
CaptivePortalDetector::CaptivePortalDetector(
const scoped_refptr<net::URLRequestContextGetter>& request_context)
: request_context_(request_context) {
}
CaptivePortalDetector::~CaptivePortalDetector() {
}
std::string CaptivePortalDetector::CaptivePortalResultToString(Result result) {
DCHECK_GE(result, 0);
DCHECK_LT(static_cast<unsigned int>(result),
arraysize(kCaptivePortalResultNames));
return kCaptivePortalResultNames[result];
}
void CaptivePortalDetector::DetectCaptivePortal(
const GURL& url,
const DetectionCallback& detection_callback) {
DCHECK(CalledOnValidThread());
DCHECK(!FetchingURL());
DCHECK(detection_callback_.is_null());
detection_callback_ = detection_callback;
url_fetcher_.reset(net::URLFetcher::Create(0,
url,
net::URLFetcher::GET,
this));
url_fetcher_->SetAutomaticallyRetryOn5xx(false);
url_fetcher_->SetRequestContext(request_context_.get());
url_fetcher_->SetLoadFlags(
net::LOAD_BYPASS_CACHE |
net::LOAD_DO_NOT_PROMPT_FOR_LOGIN |
net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SEND_AUTH_DATA);
url_fetcher_->Start();
}
void CaptivePortalDetector::Cancel() {
url_fetcher_.reset();
detection_callback_.Reset();
}
void CaptivePortalDetector::OnURLFetchComplete(const net::URLFetcher* source) {
DCHECK(CalledOnValidThread());
DCHECK(FetchingURL());
DCHECK_EQ(url_fetcher_.get(), source);
DCHECK(!detection_callback_.is_null());
Results results;
GetCaptivePortalResultFromResponse(url_fetcher_.get(), &results);
DetectionCallback callback = detection_callback_;
url_fetcher_.reset();
detection_callback_.Reset();
callback.Run(results);
}
void CaptivePortalDetector::GetCaptivePortalResultFromResponse(
const net::URLFetcher* url_fetcher,
Results* results) const {
DCHECK(results);
DCHECK(!url_fetcher->GetStatus().is_io_pending());
results->result = RESULT_NO_RESPONSE;
results->response_code = url_fetcher->GetResponseCode();
results->retry_after_delta = base::TimeDelta();
results->landing_url = url_fetcher->GetURL();
if (url_fetcher->GetStatus().status() != net::URLRequestStatus::SUCCESS)
return;
if (results->response_code == 503) {
net::HttpResponseHeaders* headers = url_fetcher->GetResponseHeaders();
std::string retry_after_string;
if (!headers->EnumerateHeader(NULL, "Retry-After", &retry_after_string))
return;
int seconds;
base::Time full_date;
if (base::StringToInt(retry_after_string, &seconds)) {
results->retry_after_delta = base::TimeDelta::FromSeconds(seconds);
} else if (headers->GetTimeValuedHeader("Retry-After", &full_date)) {
base::Time now = GetCurrentTime();
if (full_date > now)
results->retry_after_delta = full_date - now;
}
return;
}
if (results->response_code == 511) {
results->result = RESULT_BEHIND_CAPTIVE_PORTAL;
return;
}
if (results->response_code >= 400 || results->response_code < 200)
return;
if (results->response_code == 204) {
results->result = RESULT_INTERNET_CONNECTED;
return;
}
results->result = RESULT_BEHIND_CAPTIVE_PORTAL;
}
base::Time CaptivePortalDetector::GetCurrentTime() const {
if (time_for_testing_.is_null())
return base::Time::Now();
else
return time_for_testing_;
}
bool CaptivePortalDetector::FetchingURL() const {
return url_fetcher_.get() != NULL;
}
}