Skip to content

Commit

Permalink
Notify WebSocket opening handshake information to the renderer.
Browse files Browse the repository at this point in the history
In order to show the information in the inspector, notify the handshake
request and response information to the renderer.
Currently the browser always send the notification to the renderer.
It should be fixed in the future.

BUG=310405
R=ricea@chromium.org

Review URL: https://codereview.chromium.org/115003003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@246319 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
yhirano@chromium.org committed Jan 22, 2014
1 parent e5c03a0 commit cd48ed1
Show file tree
Hide file tree
Showing 19 changed files with 702 additions and 17 deletions.
40 changes: 39 additions & 1 deletion content/browser/renderer_host/websocket_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
#include "content/browser/renderer_host/websocket_dispatcher_host.h"
#include "content/common/websocket_messages.h"
#include "ipc/ipc_message_macros.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/websockets/websocket_channel.h"
#include "net/websockets/websocket_event_interface.h"
#include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode
#include "net/websockets/websocket_handshake_request_info.h"
#include "net/websockets/websocket_handshake_response_info.h"

namespace content {

Expand Down Expand Up @@ -93,6 +97,10 @@ class WebSocketEventHandler : public net::WebSocketEventInterface {
virtual ChannelState OnDropChannel(uint16 code,
const std::string& reason) OVERRIDE;
virtual ChannelState OnFailChannel(const std::string& message) OVERRIDE;
virtual ChannelState OnStartOpeningHandshake(
scoped_ptr<net::WebSocketHandshakeRequestInfo> request) OVERRIDE;
virtual ChannelState OnFinishOpeningHandshake(
scoped_ptr<net::WebSocketHandshakeResponseInfo> response) OVERRIDE;

private:
WebSocketDispatcherHost* const dispatcher_;
Expand Down Expand Up @@ -158,6 +166,37 @@ ChannelState WebSocketEventHandler::OnFailChannel(const std::string& message) {
return StateCast(dispatcher_->NotifyFailure(routing_id_, message));
}

ChannelState WebSocketEventHandler::OnStartOpeningHandshake(
scoped_ptr<net::WebSocketHandshakeRequestInfo> request) {
// TODO(yhirano) Do nothing if the inspector is not attached.
DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake";
WebSocketHandshakeRequest request_to_pass;
request_to_pass.url.Swap(&request->url);
net::HttpRequestHeaders::Iterator it(request->headers);
while (it.GetNext())
request_to_pass.headers.push_back(std::make_pair(it.name(), it.value()));
request_to_pass.request_time = request->request_time;
return StateCast(dispatcher_->SendStartOpeningHandshake(routing_id_,
request_to_pass));
}

ChannelState WebSocketEventHandler::OnFinishOpeningHandshake(
scoped_ptr<net::WebSocketHandshakeResponseInfo> response) {
// TODO(yhirano) Do nothing if the inspector is not attached.
DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake";
WebSocketHandshakeResponse response_to_pass;
response_to_pass.url.Swap(&response->url);
response_to_pass.status_code = response->status_code;
response_to_pass.status_text.swap(response->status_text);
void* iter = NULL;
std::string name, value;
while (response->headers->EnumerateHeaderLines(&iter, &name, &value))
response_to_pass.headers.push_back(std::make_pair(name, value));
response_to_pass.response_time = response->response_time;
return StateCast(dispatcher_->SendFinishOpeningHandshake(routing_id_,
response_to_pass));
}

} // namespace

WebSocketHost::WebSocketHost(int routing_id,
Expand Down Expand Up @@ -227,5 +266,4 @@ void WebSocketHost::OnDropChannel(bool was_clean,
channel_->StartClosingHandshake(code, reason);
}


} // namespace content
4 changes: 4 additions & 0 deletions net/net.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,10 @@
'websockets/websocket_handshake_constants.h',
'websockets/websocket_handshake_handler.cc',
'websockets/websocket_handshake_handler.h',
'websockets/websocket_handshake_request_info.cc',
'websockets/websocket_handshake_request_info.h',
'websockets/websocket_handshake_response_info.cc',
'websockets/websocket_handshake_response_info.h',
'websockets/websocket_handshake_stream_base.h',
'websockets/websocket_handshake_stream_create_helper.cc',
'websockets/websocket_handshake_stream_create_helper.h',
Expand Down
4 changes: 4 additions & 0 deletions net/websockets/README
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ websocket_handshake_stream_base.h
websocket_handshake_stream_create_helper.cc
websocket_handshake_stream_create_helper.h
websocket_handshake_stream_create_helper_test.cc
websocket_handshake_request_info.cc
websocket_handshake_request_info.h
websocket_handshake_response_info.cc
websocket_handshake_response_info.h
websocket_inflater.cc
websocket_inflater.h
websocket_inflater_test.cc
Expand Down
37 changes: 36 additions & 1 deletion net/websockets/websocket_basic_handshake_stream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>

#include "base/base64.h"
#include "base/basictypes.h"
Expand All @@ -15,6 +16,7 @@
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "crypto/random.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_request_info.h"
Expand All @@ -27,6 +29,8 @@
#include "net/websockets/websocket_extension_parser.h"
#include "net/websockets/websocket_handshake_constants.h"
#include "net/websockets/websocket_handshake_handler.h"
#include "net/websockets/websocket_handshake_request_info.h"
#include "net/websockets/websocket_handshake_response_info.h"
#include "net/websockets/websocket_stream.h"

namespace net {
Expand Down Expand Up @@ -230,10 +234,12 @@ bool ValidateExtensions(const HttpResponseHeaders* headers,

WebSocketBasicHandshakeStream::WebSocketBasicHandshakeStream(
scoped_ptr<ClientSocketHandle> connection,
WebSocketStream::ConnectDelegate* connect_delegate,
bool using_proxy,
std::vector<std::string> requested_sub_protocols,
std::vector<std::string> requested_extensions)
: state_(connection.release(), using_proxy),
connect_delegate_(connect_delegate),
http_response_info_(NULL),
requested_sub_protocols_(requested_sub_protocols),
requested_extensions_(requested_extensions) {}
Expand All @@ -245,6 +251,7 @@ int WebSocketBasicHandshakeStream::InitializeStream(
RequestPriority priority,
const BoundNetLog& net_log,
const CompletionCallback& callback) {
url_ = request_info->url;
state_.Initialize(request_info, priority, net_log, callback);
return OK;
}
Expand Down Expand Up @@ -287,6 +294,12 @@ int WebSocketBasicHandshakeStream::SendRequest(
ComputeSecWebSocketAccept(handshake_challenge,
&handshake_challenge_response_);

DCHECK(connect_delegate_);
scoped_ptr<WebSocketHandshakeRequestInfo> request(
new WebSocketHandshakeRequestInfo(url_, base::Time::Now()));
request->headers.CopyFrom(enriched_headers);
connect_delegate_->OnStartOpeningHandshake(request.Pass());

return parser()->SendRequest(
state_.GenerateRequestLine(), enriched_headers, response, callback);
}
Expand All @@ -301,7 +314,12 @@ int WebSocketBasicHandshakeStream::ReadResponseHeaders(
base::Bind(&WebSocketBasicHandshakeStream::ReadResponseHeadersCallback,
base::Unretained(this),
callback));
return rv == OK ? ValidateResponse() : rv;
if (rv == ERR_IO_PENDING)
return rv;
if (rv == OK)
return ValidateResponse();
OnFinishOpeningHandshake();
return rv;
}

const HttpResponseInfo* WebSocketBasicHandshakeStream::GetResponseInfo() const {
Expand Down Expand Up @@ -401,16 +419,32 @@ void WebSocketBasicHandshakeStream::ReadResponseHeadersCallback(
int result) {
if (result == OK)
result = ValidateResponse();
else
OnFinishOpeningHandshake();
callback.Run(result);
}

void WebSocketBasicHandshakeStream::OnFinishOpeningHandshake() {
DCHECK(connect_delegate_);
DCHECK(http_response_info_);
scoped_refptr<HttpResponseHeaders> headers = http_response_info_->headers;
scoped_ptr<WebSocketHandshakeResponseInfo> response(
new WebSocketHandshakeResponseInfo(url_,
headers->response_code(),
headers->GetStatusText(),
headers,
http_response_info_->response_time));
connect_delegate_->OnFinishOpeningHandshake(response.Pass());
}

int WebSocketBasicHandshakeStream::ValidateResponse() {
DCHECK(http_response_info_);
const scoped_refptr<HttpResponseHeaders>& headers =
http_response_info_->headers;

switch (headers->response_code()) {
case HTTP_SWITCHING_PROTOCOLS:
OnFinishOpeningHandshake();
return ValidateUpgradeResponse(headers);

// We need to pass these through for authentication to work.
Expand All @@ -423,6 +457,7 @@ int WebSocketBasicHandshakeStream::ValidateResponse() {
default:
failure_message_ = base::StringPrintf("Unexpected status code: %d",
headers->response_code());
OnFinishOpeningHandshake();
return ERR_INVALID_RESPONSE;
}
}
Expand Down
11 changes: 11 additions & 0 deletions net/websockets/websocket_basic_handshake_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "net/base/net_export.h"
#include "net/http/http_basic_state.h"
#include "net/websockets/websocket_handshake_stream_base.h"
#include "url/gurl.h"

namespace net {

Expand All @@ -26,6 +27,7 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
public:
WebSocketBasicHandshakeStream(
scoped_ptr<ClientSocketHandle> connection,
WebSocketStream::ConnectDelegate* connect_delegate,
bool using_proxy,
std::vector<std::string> requested_sub_protocols,
std::vector<std::string> requested_extensions);
Expand Down Expand Up @@ -80,6 +82,8 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
void ReadResponseHeadersCallback(const CompletionCallback& callback,
int result);

void OnFinishOpeningHandshake();

// Validates the response from the server and returns OK or
// ERR_INVALID_RESPONSE.
int ValidateResponse();
Expand All @@ -91,9 +95,16 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream

HttpStreamParser* parser() const { return state_.parser(); }

// The request URL.
GURL url_;

// HttpBasicState holds most of the handshake-related state.
HttpBasicState state_;

// Owned by another object.
// |connect_delegate| will live during the lifetime of this object.
WebSocketStream::ConnectDelegate* connect_delegate_;

// This is stored in SendRequest() for use by ReadResponseHeaders().
HttpResponseInfo* http_response_info_;

Expand Down
Loading

0 comments on commit cd48ed1

Please sign in to comment.