| Index: chrome/browser/net/websocket_experiment/websocket_experiment_task.cc
|
| diff --git a/chrome/browser/net/websocket_experiment/websocket_experiment_task.cc b/chrome/browser/net/websocket_experiment/websocket_experiment_task.cc
|
| deleted file mode 100644
|
| index 4933d40c72cb9bf9aadcc5fea1f9f85e19ef1d67..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/net/websocket_experiment/websocket_experiment_task.cc
|
| +++ /dev/null
|
| @@ -1,645 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/net/websocket_experiment/websocket_experiment_task.h"
|
| -
|
| -#include "base/hash_tables.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "content/browser/browser_thread.h"
|
| -#include "net/base/host_resolver.h"
|
| -#include "net/base/load_flags.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/url_request/url_request_context_getter.h"
|
| -#include "net/websockets/websocket.h"
|
| -
|
| -using base::Histogram;
|
| -using base::LinearHistogram;
|
| -
|
| -namespace chrome_browser_net_websocket_experiment {
|
| -
|
| -static std::string GetProtocolVersionName(
|
| - net::WebSocket::ProtocolVersion protocol_version) {
|
| - switch (protocol_version) {
|
| - case net::WebSocket::DEFAULT_VERSION:
|
| - return "default protocol";
|
| - case net::WebSocket::DRAFT75:
|
| - return "draft 75 protocol";
|
| - default:
|
| - NOTREACHED();
|
| - }
|
| - return "";
|
| -}
|
| -
|
| -URLFetcher* WebSocketExperimentTask::Context::CreateURLFetcher(
|
| - const Config& config, URLFetcher::Delegate* delegate) {
|
| - net::URLRequestContextGetter* getter =
|
| - Profile::Deprecated::GetDefaultRequestContext();
|
| - // Profile::Deprecated::GetDefaultRequestContext() is initialized lazily, on
|
| - // the UI thread. So here, where we access it from the IO thread, if the task
|
| - // runs before it has gotten lazily initialized yet.
|
| - if (!getter)
|
| - return NULL;
|
| - URLFetcher* fetcher =
|
| - new URLFetcher(config.http_url, URLFetcher::GET, delegate);
|
| - fetcher->set_request_context(getter);
|
| - fetcher->set_load_flags(
|
| - net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
|
| - net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SEND_AUTH_DATA |
|
| - net::LOAD_IGNORE_CERT_AUTHORITY_INVALID);
|
| - return fetcher;
|
| -}
|
| -
|
| -net::WebSocket* WebSocketExperimentTask::Context::CreateWebSocket(
|
| - const Config& config, net::WebSocketDelegate* delegate) {
|
| - net::URLRequestContextGetter* getter =
|
| - Profile::Deprecated::GetDefaultRequestContext();
|
| - // Profile::Deprecated::GetDefaultRequestContext() is initialized lazily, on
|
| - // the UI thread. So here, where we access it from the IO thread, if the task
|
| - // runs before it has gotten lazily initialized yet.
|
| - if (!getter)
|
| - return NULL;
|
| - net::WebSocket::Request* request(
|
| - new net::WebSocket::Request(config.url,
|
| - config.ws_protocol,
|
| - config.ws_origin,
|
| - config.ws_location,
|
| - config.protocol_version,
|
| - getter->GetURLRequestContext()));
|
| - return new net::WebSocket(request, delegate);
|
| -}
|
| -
|
| -// Expects URL Fetch and WebSocket connection handshake will finish in
|
| -// a few seconds.
|
| -static const int kUrlFetchDeadlineSec = 10;
|
| -static const int kWebSocketConnectDeadlineSec = 10;
|
| -// Expects WebSocket live experiment server echoes message back within a few
|
| -// seconds.
|
| -static const int kWebSocketEchoDeadlineSec = 5;
|
| -// WebSocket live experiment server keeps idle for 1.5 seconds and sends
|
| -// a message. So, expects idle for at least 1 second and expects message
|
| -// arrives within 1 second after that.
|
| -static const int kWebSocketIdleSec = 1;
|
| -static const int kWebSocketPushDeadlineSec = 1;
|
| -// WebSocket live experiment server sends "bye" message soon.
|
| -static const int kWebSocketByeDeadlineSec = 10;
|
| -// WebSocket live experiment server closes after it receives "bye" message.
|
| -static const int kWebSocketCloseDeadlineSec = 5;
|
| -
|
| -// All of above are expected within a few seconds. We'd like to see time
|
| -// distribution between 0 to 10 seconds.
|
| -static const int kWebSocketTimeSec = 10;
|
| -static const int kTimeBucketCount = 50;
|
| -
|
| -// Holds Histogram objects during experiments run.
|
| -static base::hash_map<std::string, Histogram*>* g_histogram_table;
|
| -
|
| -WebSocketExperimentTask::Config::Config()
|
| - : ws_protocol("google-websocket-liveexperiment"),
|
| - ws_origin("http://dev.chromium.org/"),
|
| - protocol_version(net::WebSocket::DEFAULT_VERSION),
|
| - url_fetch_deadline_ms(kUrlFetchDeadlineSec * 1000),
|
| - websocket_onopen_deadline_ms(kWebSocketConnectDeadlineSec * 1000),
|
| - websocket_hello_message("Hello"),
|
| - websocket_hello_echoback_deadline_ms(kWebSocketEchoDeadlineSec * 1000),
|
| - // Note: websocket live experiment server is configured to wait 1.5 sec
|
| - // in websocket_experiment_def.txt on server. So, client expects idle
|
| - // at least 1 sec and expects a message arrival within next 1 sec.
|
| - websocket_idle_ms(kWebSocketIdleSec * 1000),
|
| - websocket_receive_push_message_deadline_ms(
|
| - kWebSocketPushDeadlineSec * 1000),
|
| - websocket_bye_message("Bye"),
|
| - websocket_bye_deadline_ms(kWebSocketByeDeadlineSec * 1000),
|
| - websocket_close_deadline_ms(kWebSocketCloseDeadlineSec * 1000) {
|
| -}
|
| -
|
| -WebSocketExperimentTask::Config::~Config() {}
|
| -
|
| -WebSocketExperimentTask::WebSocketExperimentTask(
|
| - const Config& config,
|
| - net::CompletionCallback* callback)
|
| - : config_(config),
|
| - context_(ALLOW_THIS_IN_INITIALIZER_LIST(new Context())),
|
| - method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
|
| - callback_(callback),
|
| - next_state_(STATE_NONE),
|
| - last_websocket_error_(net::OK) {
|
| -}
|
| -
|
| -WebSocketExperimentTask::~WebSocketExperimentTask() {
|
| - DCHECK(!websocket_);
|
| -}
|
| -
|
| -/* static */
|
| -void WebSocketExperimentTask::InitHistogram() {
|
| - DCHECK(!g_histogram_table);
|
| - g_histogram_table = new base::hash_map<std::string, Histogram*>;
|
| -}
|
| -
|
| -static std::string GetCounterNameForConfig(
|
| - const WebSocketExperimentTask::Config& config, const std::string& name) {
|
| - std::string protocol_version = "";
|
| - switch (config.protocol_version) {
|
| - case net::WebSocket::DEFAULT_VERSION:
|
| - protocol_version = "Draft76";
|
| - break;
|
| - case net::WebSocket::DRAFT75:
|
| - protocol_version = "";
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - }
|
| - if (config.url.SchemeIs("wss")) {
|
| - return "WebSocketExperiment.Secure" + protocol_version + "." + name;
|
| - } else if (config.url.has_port() && config.url.IntPort() != 80) {
|
| - return "WebSocketExperiment.NoDefaultPort" + protocol_version + "." + name;
|
| - } else {
|
| - return "WebSocketExperiment.Basic" + protocol_version + "." + name;
|
| - }
|
| -}
|
| -
|
| -static Histogram* GetEnumsHistogramForConfig(
|
| - const WebSocketExperimentTask::Config& config,
|
| - const std::string& name,
|
| - Histogram::Sample boundary_value) {
|
| - DCHECK(g_histogram_table);
|
| - std::string counter_name = GetCounterNameForConfig(config, name);
|
| - base::hash_map<std::string, Histogram*>::iterator found =
|
| - g_histogram_table->find(counter_name);
|
| - if (found != g_histogram_table->end()) {
|
| - return found->second;
|
| - }
|
| - Histogram* counter = LinearHistogram::FactoryGet(
|
| - counter_name, 1, boundary_value, boundary_value + 1,
|
| - Histogram::kUmaTargetedHistogramFlag);
|
| - g_histogram_table->insert(std::make_pair(counter_name, counter));
|
| - return counter;
|
| -}
|
| -
|
| -static Histogram* GetTimesHistogramForConfig(
|
| - const WebSocketExperimentTask::Config& config,
|
| - const std::string& name,
|
| - base::TimeDelta min,
|
| - base::TimeDelta max,
|
| - size_t bucket_count) {
|
| - DCHECK(g_histogram_table);
|
| - std::string counter_name = GetCounterNameForConfig(config, name);
|
| - base::hash_map<std::string, Histogram*>::iterator found =
|
| - g_histogram_table->find(counter_name);
|
| - if (found != g_histogram_table->end()) {
|
| - return found->second;
|
| - }
|
| - Histogram* counter = Histogram::FactoryTimeGet(
|
| - counter_name, min, max, bucket_count,
|
| - Histogram::kUmaTargetedHistogramFlag);
|
| - g_histogram_table->insert(std::make_pair(counter_name, counter));
|
| - return counter;
|
| -}
|
| -
|
| -static void UpdateHistogramEnums(
|
| - const WebSocketExperimentTask::Config& config,
|
| - const std::string& name,
|
| - Histogram::Sample sample,
|
| - Histogram::Sample boundary_value) {
|
| - Histogram* counter = GetEnumsHistogramForConfig(config, name, boundary_value);
|
| - counter->Add(sample);
|
| -}
|
| -
|
| -static void UpdateHistogramTimes(
|
| - const WebSocketExperimentTask::Config& config,
|
| - const std::string& name,
|
| - base::TimeDelta sample,
|
| - base::TimeDelta min,
|
| - base::TimeDelta max,
|
| - size_t bucket_count) {
|
| - Histogram* counter = GetTimesHistogramForConfig(
|
| - config, name, min, max, bucket_count);
|
| - counter->AddTime(sample);
|
| -}
|
| -
|
| -/* static */
|
| -void WebSocketExperimentTask::ReleaseHistogram() {
|
| - DCHECK(g_histogram_table);
|
| - delete g_histogram_table;
|
| - g_histogram_table = NULL;
|
| -}
|
| -
|
| -void WebSocketExperimentTask::Run() {
|
| - DVLOG(1) << "Run WebSocket experiment for " << config_.url << " "
|
| - << GetProtocolVersionName(config_.protocol_version);
|
| - next_state_ = STATE_URL_FETCH;
|
| - DoLoop(net::OK);
|
| -}
|
| -
|
| -void WebSocketExperimentTask::Cancel() {
|
| - next_state_ = STATE_NONE;
|
| - DoLoop(net::OK);
|
| -}
|
| -
|
| -void WebSocketExperimentTask::SaveResult() const {
|
| - DVLOG(1) << "WebSocket experiment save result for " << config_.url
|
| - << " last_state=" << result_.last_state;
|
| - UpdateHistogramEnums(config_, "LastState", result_.last_state, NUM_STATES);
|
| - UpdateHistogramTimes(config_, "UrlFetch", result_.url_fetch,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromSeconds(kUrlFetchDeadlineSec),
|
| - kTimeBucketCount);
|
| -
|
| - if (result_.last_state < STATE_WEBSOCKET_CONNECT_COMPLETE)
|
| - return;
|
| -
|
| - UpdateHistogramTimes(config_, "WebSocketConnect", result_.websocket_connect,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromSeconds(
|
| - kWebSocketConnectDeadlineSec),
|
| - kTimeBucketCount);
|
| -
|
| - if (result_.last_state < STATE_WEBSOCKET_RECV_HELLO)
|
| - return;
|
| -
|
| - UpdateHistogramTimes(config_, "WebSocketEcho", result_.websocket_echo,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromSeconds(
|
| - kWebSocketEchoDeadlineSec),
|
| - kTimeBucketCount);
|
| -
|
| - if (result_.last_state < STATE_WEBSOCKET_KEEP_IDLE)
|
| - return;
|
| -
|
| - UpdateHistogramTimes(config_, "WebSocketIdle", result_.websocket_idle,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromSeconds(
|
| - kWebSocketIdleSec + kWebSocketPushDeadlineSec),
|
| - kTimeBucketCount);
|
| -
|
| - if (result_.last_state < STATE_WEBSOCKET_CLOSE_COMPLETE)
|
| - return;
|
| -
|
| - UpdateHistogramTimes(config_, "WebSocketTotal", result_.websocket_total,
|
| - base::TimeDelta::FromMilliseconds(1),
|
| - base::TimeDelta::FromSeconds(kWebSocketTimeSec),
|
| - kTimeBucketCount);
|
| -}
|
| -
|
| -// URLFetcher::Delegate method.
|
| -void WebSocketExperimentTask::OnURLFetchComplete(
|
| - const URLFetcher* source,
|
| - const GURL& url,
|
| - const net::URLRequestStatus& status,
|
| - int response_code,
|
| - const net::ResponseCookies& cookies,
|
| - const std::string& data) {
|
| - result_.url_fetch = base::TimeTicks::Now() - url_fetch_start_time_;
|
| - RevokeTimeoutTimer();
|
| - int result = net::ERR_FAILED;
|
| - if (next_state_ != STATE_URL_FETCH_COMPLETE) {
|
| - DVLOG(1) << "unexpected state=" << next_state_
|
| - << " at OnURLFetchComplete for " << config_.http_url;
|
| - result = net::ERR_UNEXPECTED;
|
| - } else if (response_code == 200 || response_code == 304) {
|
| - result = net::OK;
|
| - }
|
| - DoLoop(result);
|
| -}
|
| -
|
| -// net::WebSocketDelegate
|
| -void WebSocketExperimentTask::OnOpen(net::WebSocket* websocket) {
|
| - result_.websocket_connect =
|
| - base::TimeTicks::Now() - websocket_connect_start_time_;
|
| - RevokeTimeoutTimer();
|
| - int result = net::ERR_UNEXPECTED;
|
| - if (next_state_ == STATE_WEBSOCKET_CONNECT_COMPLETE)
|
| - result = net::OK;
|
| - else
|
| - DVLOG(1) << "unexpected state=" << next_state_
|
| - << " at OnOpen for " << config_.url
|
| - << " " << GetProtocolVersionName(config_.protocol_version);
|
| - DoLoop(result);
|
| -}
|
| -
|
| -void WebSocketExperimentTask::OnMessage(
|
| - net::WebSocket* websocket, const std::string& msg) {
|
| - if (!result_.websocket_echo.ToInternalValue())
|
| - result_.websocket_echo =
|
| - base::TimeTicks::Now() - websocket_echo_start_time_;
|
| - if (!websocket_idle_start_time_.is_null() &&
|
| - !result_.websocket_idle.ToInternalValue())
|
| - result_.websocket_idle =
|
| - base::TimeTicks::Now() - websocket_idle_start_time_;
|
| - RevokeTimeoutTimer();
|
| - received_messages_.push_back(msg);
|
| - int result = net::ERR_UNEXPECTED;
|
| - switch (next_state_) {
|
| - case STATE_WEBSOCKET_RECV_HELLO:
|
| - case STATE_WEBSOCKET_RECV_PUSH_MESSAGE:
|
| - case STATE_WEBSOCKET_RECV_BYE:
|
| - result = net::OK;
|
| - break;
|
| - default:
|
| - DVLOG(1) << "unexpected state=" << next_state_
|
| - << " at OnMessage for " << config_.url
|
| - << " " << GetProtocolVersionName(config_.protocol_version);
|
| - break;
|
| - }
|
| - DoLoop(result);
|
| -}
|
| -
|
| -void WebSocketExperimentTask::OnError(net::WebSocket* websocket) {
|
| - // TODO(ukai): record error count?
|
| -}
|
| -
|
| -void WebSocketExperimentTask::OnClose(
|
| - net::WebSocket* websocket, bool was_clean) {
|
| - RevokeTimeoutTimer();
|
| - websocket_ = NULL;
|
| - result_.websocket_total =
|
| - base::TimeTicks::Now() - websocket_connect_start_time_;
|
| - int result = net::ERR_CONNECTION_CLOSED;
|
| - if (last_websocket_error_ != net::OK)
|
| - result = last_websocket_error_;
|
| - DVLOG(1) << "WebSocket onclose was_clean=" << was_clean
|
| - << " next_state=" << next_state_
|
| - << " last_error=" << net::ErrorToString(result);
|
| - if (config_.protocol_version == net::WebSocket::DEFAULT_VERSION) {
|
| - if (next_state_ == STATE_WEBSOCKET_CLOSE_COMPLETE && was_clean)
|
| - result = net::OK;
|
| - } else {
|
| - // DRAFT75 doesn't report was_clean correctly.
|
| - if (next_state_ == STATE_WEBSOCKET_CLOSE_COMPLETE)
|
| - result = net::OK;
|
| - }
|
| - DoLoop(result);
|
| -}
|
| -
|
| -void WebSocketExperimentTask::OnSocketError(
|
| - const net::WebSocket* websocket, int error) {
|
| - DVLOG(1) << "WebSocket socket level error=" << net::ErrorToString(error)
|
| - << " next_state=" << next_state_
|
| - << " for " << config_.url
|
| - << " " << GetProtocolVersionName(config_.protocol_version);
|
| - last_websocket_error_ = error;
|
| -}
|
| -
|
| -void WebSocketExperimentTask::SetContext(Context* context) {
|
| - context_.reset(context);
|
| -}
|
| -
|
| -void WebSocketExperimentTask::OnTimedOut() {
|
| - DVLOG(1) << "OnTimedOut next_state=" << next_state_
|
| - << " for " << config_.url
|
| - << " " << GetProtocolVersionName(config_.protocol_version);
|
| - RevokeTimeoutTimer();
|
| - DoLoop(net::ERR_TIMED_OUT);
|
| -}
|
| -
|
| -void WebSocketExperimentTask::DoLoop(int result) {
|
| - if (next_state_ == STATE_NONE) {
|
| - Finish(net::ERR_ABORTED);
|
| - return;
|
| - }
|
| - do {
|
| - State state = next_state_;
|
| - next_state_ = STATE_NONE;
|
| - switch (state) {
|
| - case STATE_URL_FETCH:
|
| - result = DoURLFetch();
|
| - break;
|
| - case STATE_URL_FETCH_COMPLETE:
|
| - result = DoURLFetchComplete(result);
|
| - break;
|
| - case STATE_WEBSOCKET_CONNECT:
|
| - result = DoWebSocketConnect();
|
| - break;
|
| - case STATE_WEBSOCKET_CONNECT_COMPLETE:
|
| - result = DoWebSocketConnectComplete(result);
|
| - break;
|
| - case STATE_WEBSOCKET_SEND_HELLO:
|
| - result = DoWebSocketSendHello();
|
| - break;
|
| - case STATE_WEBSOCKET_RECV_HELLO:
|
| - result = DoWebSocketReceiveHello(result);
|
| - break;
|
| - case STATE_WEBSOCKET_KEEP_IDLE:
|
| - result = DoWebSocketKeepIdle();
|
| - break;
|
| - case STATE_WEBSOCKET_KEEP_IDLE_COMPLETE:
|
| - result = DoWebSocketKeepIdleComplete(result);
|
| - break;
|
| - case STATE_WEBSOCKET_RECV_PUSH_MESSAGE:
|
| - result = DoWebSocketReceivePushMessage(result);
|
| - break;
|
| - case STATE_WEBSOCKET_ECHO_BACK_MESSAGE:
|
| - result = DoWebSocketEchoBackMessage();
|
| - break;
|
| - case STATE_WEBSOCKET_RECV_BYE:
|
| - result = DoWebSocketReceiveBye(result);
|
| - break;
|
| - case STATE_WEBSOCKET_CLOSE:
|
| - result = DoWebSocketClose();
|
| - break;
|
| - case STATE_WEBSOCKET_CLOSE_COMPLETE:
|
| - result = DoWebSocketCloseComplete(result);
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| - result_.last_state = state;
|
| - } while (result != net::ERR_IO_PENDING && next_state_ != STATE_NONE);
|
| -
|
| - if (result != net::ERR_IO_PENDING)
|
| - Finish(result);
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoURLFetch() {
|
| - DCHECK(!url_fetcher_.get());
|
| -
|
| - url_fetcher_.reset(context_->CreateURLFetcher(config_, this));
|
| - if (!url_fetcher_.get()) {
|
| - // Request context is not ready.
|
| - next_state_ = STATE_NONE;
|
| - return net::ERR_UNEXPECTED;
|
| - }
|
| -
|
| - next_state_ = STATE_URL_FETCH_COMPLETE;
|
| - SetTimeout(config_.url_fetch_deadline_ms);
|
| - url_fetch_start_time_ = base::TimeTicks::Now();
|
| - url_fetcher_->Start();
|
| - return net::ERR_IO_PENDING;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoURLFetchComplete(int result) {
|
| - url_fetcher_.reset();
|
| -
|
| - if (result < 0)
|
| - return result;
|
| -
|
| - next_state_ = STATE_WEBSOCKET_CONNECT;
|
| - return net::OK;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketConnect() {
|
| - DCHECK(!websocket_);
|
| -
|
| - websocket_ = context_->CreateWebSocket(config_, this);
|
| - if (!websocket_) {
|
| - // Request context is not ready.
|
| - next_state_ = STATE_NONE;
|
| - return net::ERR_UNEXPECTED;
|
| - }
|
| - next_state_ = STATE_WEBSOCKET_CONNECT_COMPLETE;
|
| - websocket_connect_start_time_ = base::TimeTicks::Now();
|
| - websocket_->Connect();
|
| -
|
| - SetTimeout(config_.websocket_onopen_deadline_ms);
|
| - return net::ERR_IO_PENDING;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketConnectComplete(int result) {
|
| - if (result < 0)
|
| - return result;
|
| - DCHECK(websocket_);
|
| -
|
| - next_state_ = STATE_WEBSOCKET_SEND_HELLO;
|
| - return net::OK;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketSendHello() {
|
| - DCHECK(websocket_);
|
| -
|
| - next_state_ = STATE_WEBSOCKET_RECV_HELLO;
|
| -
|
| - websocket_echo_start_time_ = base::TimeTicks::Now();
|
| - websocket_->Send(config_.websocket_hello_message);
|
| - SetTimeout(config_.websocket_hello_echoback_deadline_ms);
|
| - return net::ERR_IO_PENDING;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketReceiveHello(int result) {
|
| - if (result < 0)
|
| - return result;
|
| -
|
| - DCHECK(websocket_);
|
| -
|
| - if (received_messages_.size() != 1)
|
| - return net::ERR_INVALID_RESPONSE;
|
| -
|
| - std::string msg = received_messages_.front();
|
| - received_messages_.pop_front();
|
| - if (msg != config_.websocket_hello_message)
|
| - return net::ERR_INVALID_RESPONSE;
|
| -
|
| - next_state_ = STATE_WEBSOCKET_KEEP_IDLE;
|
| - return net::OK;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketKeepIdle() {
|
| - DCHECK(websocket_);
|
| -
|
| - next_state_ = STATE_WEBSOCKET_KEEP_IDLE_COMPLETE;
|
| - websocket_idle_start_time_ = base::TimeTicks::Now();
|
| - SetTimeout(config_.websocket_idle_ms);
|
| - return net::ERR_IO_PENDING;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketKeepIdleComplete(int result) {
|
| - if (result != net::ERR_TIMED_OUT) {
|
| - // Server sends back too early, or unexpected close?
|
| - if (result == net::OK)
|
| - result = net::ERR_UNEXPECTED;
|
| - return result;
|
| - }
|
| -
|
| - DCHECK(websocket_);
|
| -
|
| - next_state_ = STATE_WEBSOCKET_RECV_PUSH_MESSAGE;
|
| - SetTimeout(config_.websocket_receive_push_message_deadline_ms);
|
| - return net::ERR_IO_PENDING;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketReceivePushMessage(int result) {
|
| - if (result < 0)
|
| - return result;
|
| -
|
| - DCHECK(websocket_);
|
| - if (received_messages_.size() != 1)
|
| - return net::ERR_INVALID_RESPONSE;
|
| -
|
| - push_message_ = received_messages_.front();
|
| - received_messages_.pop_front();
|
| -
|
| - next_state_ = STATE_WEBSOCKET_ECHO_BACK_MESSAGE;
|
| - return net::OK;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketEchoBackMessage() {
|
| - DCHECK(websocket_);
|
| - DCHECK(!push_message_.empty());
|
| -
|
| - next_state_ = STATE_WEBSOCKET_RECV_BYE;
|
| - websocket_->Send(push_message_);
|
| - SetTimeout(config_.websocket_bye_deadline_ms);
|
| - return net::ERR_IO_PENDING;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketReceiveBye(int result) {
|
| - if (result < 0)
|
| - return result;
|
| -
|
| - DCHECK(websocket_);
|
| -
|
| - if (received_messages_.size() != 1)
|
| - return net::ERR_INVALID_RESPONSE;
|
| -
|
| - std::string bye = received_messages_.front();
|
| - received_messages_.pop_front();
|
| -
|
| - if (bye != config_.websocket_bye_message)
|
| - return net::ERR_INVALID_RESPONSE;
|
| -
|
| - next_state_ = STATE_WEBSOCKET_CLOSE;
|
| - return net::OK;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketClose() {
|
| - DCHECK(websocket_);
|
| -
|
| - next_state_ = STATE_WEBSOCKET_CLOSE_COMPLETE;
|
| - websocket_->Close();
|
| - SetTimeout(config_.websocket_close_deadline_ms);
|
| - return net::ERR_IO_PENDING;
|
| -}
|
| -
|
| -int WebSocketExperimentTask::DoWebSocketCloseComplete(int result) {
|
| - websocket_ = NULL;
|
| - return result;
|
| -}
|
| -
|
| -void WebSocketExperimentTask::SetTimeout(int64 deadline_ms) {
|
| - bool r = BrowserThread::PostDelayedTask(
|
| - BrowserThread::IO,
|
| - FROM_HERE,
|
| - method_factory_.NewRunnableMethod(&WebSocketExperimentTask::OnTimedOut),
|
| - deadline_ms);
|
| - DCHECK(r) << "No IO thread running?";
|
| -}
|
| -
|
| -void WebSocketExperimentTask::RevokeTimeoutTimer() {
|
| - method_factory_.RevokeAll();
|
| -}
|
| -
|
| -void WebSocketExperimentTask::Finish(int result) {
|
| - url_fetcher_.reset();
|
| - scoped_refptr<net::WebSocket> websocket = websocket_;
|
| - websocket_ = NULL;
|
| - if (websocket)
|
| - websocket->DetachDelegate();
|
| - DVLOG(1) << "Finish WebSocket experiment for " << config_.url
|
| - << " " << GetProtocolVersionName(config_.protocol_version)
|
| - << " next_state=" << next_state_
|
| - << " result=" << net::ErrorToString(result);
|
| - callback_->Run(result); // will release this.
|
| -}
|
| -
|
| -} // namespace chrome_browser_net
|
|
|