Commit 7c17b699 authored by jam@chromium.org's avatar jam@chromium.org

Add a menu item to content_shell to open devtools to make it more discoverable.

Since the devtools server is running for each content shell browser process, the user doesn't specify a server port anymore. Instead I let the system pick. This made it necessary to plumb the data back from net::HttpServer.

For now I only added Windows and Linux UI. Mac UI will be done later.

BUG=90445
Review URL: https://chromiumcodereview.appspot.com/10837177

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150808 0039d316-1c4b-4281-b951-d872f2087c98
parent 9e52129b
...@@ -1134,6 +1134,9 @@ const char kReloadKilledTabs[] = "reload-killed-tabs"; ...@@ -1134,6 +1134,9 @@ const char kReloadKilledTabs[] = "reload-killed-tabs";
// Uses custom front-end URL for the remote debugging. // Uses custom front-end URL for the remote debugging.
const char kRemoteDebuggingFrontend[] = "remote-debugging-frontend"; const char kRemoteDebuggingFrontend[] = "remote-debugging-frontend";
// Enables remote debug over HTTP on the specified port.
const char kRemoteDebuggingPort[] = "remote-debugging-port";
// Enables print preview in the renderer. This flag is generated internally by // Enables print preview in the renderer. This flag is generated internally by
// Chrome and does nothing when directly passed to the browser. // Chrome and does nothing when directly passed to the browser.
const char kRendererPrintPreview[] = "renderer-print-preview"; const char kRendererPrintPreview[] = "renderer-print-preview";
......
...@@ -302,6 +302,7 @@ extern const char kRecordStats[]; ...@@ -302,6 +302,7 @@ extern const char kRecordStats[];
extern const char kRecordMode[]; extern const char kRecordMode[];
extern const char kReloadKilledTabs[]; extern const char kReloadKilledTabs[];
extern const char kRemoteDebuggingFrontend[]; extern const char kRemoteDebuggingFrontend[];
extern const char kRemoteDebuggingPort[];
extern const char kRendererPrintPreview[]; extern const char kRendererPrintPreview[];
extern const char kResetVariationState[]; extern const char kResetVariationState[];
extern const char kRestoreLastSession[]; extern const char kRestoreLastSession[];
......
...@@ -167,6 +167,17 @@ void DevToolsHttpHandlerImpl::SetRenderViewHostBinding( ...@@ -167,6 +167,17 @@ void DevToolsHttpHandlerImpl::SetRenderViewHostBinding(
binding_ = default_binding_.get(); binding_ = default_binding_.get();
} }
GURL DevToolsHttpHandlerImpl::GetFrontendURL(RenderViewHost* render_view_host) {
net::IPEndPoint ip_address;
if (server_->GetLocalAddress(&ip_address))
return GURL();
std::string host = ip_address.ToString();
std::string id = binding_->GetIdentifier(render_view_host);
return GURL(std::string("http://") +
ip_address.ToString() +
GetFrontendURLInternal(id, host));
}
static std::string PathWithoutParams(const std::string& path) { static std::string PathWithoutParams(const std::string& path) {
size_t query_position = path.find("?"); size_t query_position = path.find("?");
if (query_position != std::string::npos) if (query_position != std::string::npos)
...@@ -377,6 +388,17 @@ DevToolsHttpHandlerImpl::PageList DevToolsHttpHandlerImpl::GeneratePageList() { ...@@ -377,6 +388,17 @@ DevToolsHttpHandlerImpl::PageList DevToolsHttpHandlerImpl::GeneratePageList() {
return page_list; return page_list;
} }
std::string DevToolsHttpHandlerImpl::GetFrontendURLInternal(
const std::string rvh_id,
const std::string& host) {
return base::StringPrintf(
"%s%sws=%s/devtools/page/%s",
overridden_frontend_url_.c_str(),
overridden_frontend_url_.find("?") == std::string::npos ? "?" : "&",
host.c_str(),
rvh_id.c_str());
}
void DevToolsHttpHandlerImpl::OnJsonRequestUI( void DevToolsHttpHandlerImpl::OnJsonRequestUI(
int connection_id, int connection_id,
const net::HttpServerRequestInfo& info) { const net::HttpServerRequestInfo& info) {
...@@ -396,12 +418,8 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI( ...@@ -396,12 +418,8 @@ void DevToolsHttpHandlerImpl::OnJsonRequestUI(
base::StringPrintf("ws://%s/devtools/page/%s", base::StringPrintf("ws://%s/devtools/page/%s",
host.c_str(), host.c_str(),
i->id.c_str())); i->id.c_str()));
std::string devtools_frontend_url = base::StringPrintf( std::string devtools_frontend_url = GetFrontendURLInternal(i->id.c_str(),
"%s%sws=%s/devtools/page/%s", host);
overridden_frontend_url_.c_str(),
overridden_frontend_url_.find("?") == std::string::npos ? "?" : "&",
host.c_str(),
i->id.c_str());
page_info->SetString("devtoolsFrontendUrl", devtools_frontend_url); page_info->SetString("devtoolsFrontendUrl", devtools_frontend_url);
} }
} }
......
...@@ -53,6 +53,7 @@ class DevToolsHttpHandlerImpl ...@@ -53,6 +53,7 @@ class DevToolsHttpHandlerImpl
virtual void Stop() OVERRIDE; virtual void Stop() OVERRIDE;
virtual void SetRenderViewHostBinding( virtual void SetRenderViewHostBinding(
RenderViewHostBinding* binding) OVERRIDE; RenderViewHostBinding* binding) OVERRIDE;
virtual GURL GetFrontendURL(RenderViewHost* render_view_host) OVERRIDE;
// net::HttpServer::Delegate implementation. // net::HttpServer::Delegate implementation.
virtual void OnHttpRequest(int connection_id, virtual void OnHttpRequest(int connection_id,
...@@ -64,15 +65,12 @@ class DevToolsHttpHandlerImpl ...@@ -64,15 +65,12 @@ class DevToolsHttpHandlerImpl
const std::string& data) OVERRIDE; const std::string& data) OVERRIDE;
virtual void OnClose(int connection_id) OVERRIDE; virtual void OnClose(int connection_id) OVERRIDE;
PageList GeneratePageList(); void OnJsonRequestUI(int connection_id,
const net::HttpServerRequestInfo& info);
virtual void OnJsonRequestUI(int connection_id, void OnWebSocketRequestUI(int connection_id,
const net::HttpServerRequestInfo& info); const net::HttpServerRequestInfo& info);
virtual void OnWebSocketRequestUI(int connection_id, void OnWebSocketMessageUI(int connection_id, const std::string& data);
const net::HttpServerRequestInfo& info); void OnCloseUI(int connection_id);
virtual void OnWebSocketMessageUI(int connection_id,
const std::string& data);
virtual void OnCloseUI(int connection_id);
// net::URLRequest::Delegate implementation. // net::URLRequest::Delegate implementation.
virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE; virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE;
...@@ -93,6 +91,12 @@ class DevToolsHttpHandlerImpl ...@@ -93,6 +91,12 @@ class DevToolsHttpHandlerImpl
void AcceptWebSocket(int connection_id, void AcceptWebSocket(int connection_id,
const net::HttpServerRequestInfo& request); const net::HttpServerRequestInfo& request);
PageList GeneratePageList();
// Returns the front end url without the host at the beginning.
std::string GetFrontendURLInternal(const std::string rvh_id,
const std::string& host);
std::string overridden_frontend_url_; std::string overridden_frontend_url_;
scoped_ptr<const net::StreamListenSocketFactory> socket_factory_; scoped_ptr<const net::StreamListenSocketFactory> socket_factory_;
scoped_refptr<net::HttpServer> server_; scoped_refptr<net::HttpServer> server_;
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "content/common/content_export.h" #include "content/common/content_export.h"
class GURL;
namespace net { namespace net {
class StreamListenSocketFactory; class StreamListenSocketFactory;
class URLRequestContextGetter; class URLRequestContextGetter;
...@@ -56,6 +58,9 @@ class DevToolsHttpHandler { ...@@ -56,6 +58,9 @@ class DevToolsHttpHandler {
// default implementation will be used. // default implementation will be used.
virtual void SetRenderViewHostBinding(RenderViewHostBinding* binding) = 0; virtual void SetRenderViewHostBinding(RenderViewHostBinding* binding) = 0;
// Returns the URL for the address to debug |render_view_host|.
virtual GURL GetFrontendURL(RenderViewHost* render_view_host) = 0;
protected: protected:
virtual ~DevToolsHttpHandler() {} virtual ~DevToolsHttpHandler() {}
}; };
......
...@@ -527,9 +527,6 @@ const char kProcessType[] = "type"; ...@@ -527,9 +527,6 @@ const char kProcessType[] = "type";
// Register Pepper plugins (see pepper_plugin_registry.cc for its format). // Register Pepper plugins (see pepper_plugin_registry.cc for its format).
const char kRegisterPepperPlugins[] = "register-pepper-plugins"; const char kRegisterPepperPlugins[] = "register-pepper-plugins";
// Enables remote debug over HTTP on the specified port.
const char kRemoteDebuggingPort[] = "remote-debugging-port";
// Causes the renderer process to throw an assertion on launch. // Causes the renderer process to throw an assertion on launch.
const char kRendererAssertTest[] = "renderer-assert-test"; const char kRendererAssertTest[] = "renderer-assert-test";
......
...@@ -166,7 +166,6 @@ CONTENT_EXPORT extern const char kProcessPerSite[]; ...@@ -166,7 +166,6 @@ CONTENT_EXPORT extern const char kProcessPerSite[];
CONTENT_EXPORT extern const char kProcessPerTab[]; CONTENT_EXPORT extern const char kProcessPerTab[];
CONTENT_EXPORT extern const char kProcessType[]; CONTENT_EXPORT extern const char kProcessType[];
CONTENT_EXPORT extern const char kRegisterPepperPlugins[]; CONTENT_EXPORT extern const char kRegisterPepperPlugins[];
CONTENT_EXPORT extern const char kRemoteDebuggingPort[];
CONTENT_EXPORT extern const char kRendererAssertTest[]; CONTENT_EXPORT extern const char kRendererAssertTest[];
extern const char kRendererCmdPrefix[]; extern const char kRendererCmdPrefix[];
CONTENT_EXPORT extern const char kRendererProcess[]; CONTENT_EXPORT extern const char kRendererProcess[];
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#define IDM_EXIT 105 #define IDM_EXIT 105
#define IDM_CLOSE_WINDOW 106 #define IDM_CLOSE_WINDOW 106
#define IDM_NEW_WINDOW 107 #define IDM_NEW_WINDOW 107
#define IDM_SHOW_DEVELOPER_TOOLS 108
#define IDC_CONTENTSHELL 109 #define IDC_CONTENTSHELL 109
#define IDD_ALERT 130 #define IDD_ALERT 130
#define IDD_CONFIRM 131 #define IDD_CONFIRM 131
......
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "content/public/browser/devtools_http_handler.h"
#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_details.h" #include "content/public/browser/notification_details.h"
...@@ -17,6 +19,9 @@ ...@@ -17,6 +19,9 @@
#include "content/public/browser/notification_types.h" #include "content/public/browser/notification_types.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/shell/shell_browser_main_parts.h"
#include "content/shell/shell_content_browser_client.h"
#include "content/shell/shell_devtools_delegate.h"
#include "content/shell/shell_javascript_dialog_creator.h" #include "content/shell/shell_javascript_dialog_creator.h"
#include "content/shell/shell_messages.h" #include "content/shell/shell_messages.h"
#include "content/shell/shell_switches.h" #include "content/shell/shell_switches.h"
...@@ -151,6 +156,19 @@ void Shell::UpdateNavigationControls() { ...@@ -151,6 +156,19 @@ void Shell::UpdateNavigationControls() {
PlatformEnableUIControl(STOP_BUTTON, web_contents_->IsLoading()); PlatformEnableUIControl(STOP_BUTTON, web_contents_->IsLoading());
} }
void Shell::ShowDevTools() {
ShellContentBrowserClient* browser_client =
static_cast<ShellContentBrowserClient*>(
GetContentClient()->browser());
ShellDevToolsDelegate* delegate =
browser_client->shell_browser_main_parts()->devtools_delegate();
GURL url = delegate->devtools_http_handler()->GetFrontendURL(
web_contents()->GetRenderViewHost());
CreateNewWindow(
web_contents()->GetBrowserContext(),
url, NULL, MSG_ROUTING_NONE, NULL);
}
gfx::NativeView Shell::GetContentView() { gfx::NativeView Shell::GetContentView() {
if (!web_contents_.get()) if (!web_contents_.get())
return NULL; return NULL;
......
...@@ -58,6 +58,7 @@ class Shell : public WebContentsDelegate, ...@@ -58,6 +58,7 @@ class Shell : public WebContentsDelegate,
void Stop(); void Stop();
void UpdateNavigationControls(); void UpdateNavigationControls();
void Close(); void Close();
void ShowDevTools();
// Do one time initialization at application startup. // Do one time initialization at application startup.
static void PlatformInitialize(); static void PlatformInitialize();
......
...@@ -30,6 +30,10 @@ BEGIN ...@@ -30,6 +30,10 @@ BEGIN
MENUITEM "&Close Window", IDM_CLOSE_WINDOW MENUITEM "&Close Window", IDM_CLOSE_WINDOW
MENUITEM "E&xit", IDM_EXIT MENUITEM "E&xit", IDM_EXIT
END END
POPUP "&Debug"
BEGIN
MENUITEM "&Show Developer Tools...", IDM_SHOW_DEVELOPER_TOOLS
END
END END
......
...@@ -16,7 +16,6 @@ namespace content { ...@@ -16,7 +16,6 @@ namespace content {
class DownloadManagerDelegate; class DownloadManagerDelegate;
class ResourceContext; class ResourceContext;
class ShellBrowserMainParts;
class ShellDownloadManagerDelegate; class ShellDownloadManagerDelegate;
class ShellBrowserContext : public BrowserContext { class ShellBrowserContext : public BrowserContext {
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/string_number_conversions.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
...@@ -82,22 +81,10 @@ void ShellBrowserMainParts::PreMainMessageLoopRun() { ...@@ -82,22 +81,10 @@ void ShellBrowserMainParts::PreMainMessageLoopRun() {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
devtools_delegate_ = new ShellDevToolsDelegate( devtools_delegate_ = new ShellDevToolsDelegate(
0, // On android the port number isn't used.
browser_context_->GetRequestContext()); browser_context_->GetRequestContext());
#else #else
const CommandLine& command_line = *CommandLine::ForCurrentProcess(); devtools_delegate_ = new ShellDevToolsDelegate(
if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) { browser_context_->GetRequestContext());
std::string port_str =
command_line.GetSwitchValueASCII(switches::kRemoteDebuggingPort);
int port;
if (base::StringToInt(port_str, &port) && port > 0 && port < 65535) {
devtools_delegate_ = new ShellDevToolsDelegate(
port,
browser_context_->GetRequestContext());
} else {
DLOG(WARNING) << "Invalid http debugger port number " << port;
}
}
#endif #endif
if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) { if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) {
......
...@@ -44,6 +44,9 @@ class ShellContentBrowserClient : public ContentBrowserClient { ...@@ -44,6 +44,9 @@ class ShellContentBrowserClient : public ContentBrowserClient {
ShellResourceDispatcherHostDelegate* resource_dispatcher_host_delegate() { ShellResourceDispatcherHostDelegate* resource_dispatcher_host_delegate() {
return resource_dispatcher_host_delegate_.get(); return resource_dispatcher_host_delegate_.get();
} }
ShellBrowserMainParts* shell_browser_main_parts() {
return shell_browser_main_parts_;
}
private: private:
scoped_ptr<ShellResourceDispatcherHostDelegate> scoped_ptr<ShellResourceDispatcherHostDelegate>
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
#include "content/shell/shell_devtools_delegate.h" #include "content/shell/shell_devtools_delegate.h"
#include <algorithm>
#include "content/public/browser/devtools_http_handler.h" #include "content/public/browser/devtools_http_handler.h"
#include "grit/shell_resources.h" #include "grit/shell_resources.h"
#include "net/base/tcp_listen_socket.h" #include "net/base/tcp_listen_socket.h"
...@@ -16,11 +14,10 @@ ...@@ -16,11 +14,10 @@
namespace content { namespace content {
ShellDevToolsDelegate::ShellDevToolsDelegate( ShellDevToolsDelegate::ShellDevToolsDelegate(
int port,
net::URLRequestContextGetter* context_getter) net::URLRequestContextGetter* context_getter)
: context_getter_(context_getter) { : context_getter_(context_getter) {
devtools_http_handler_ = DevToolsHttpHandler::Start( devtools_http_handler_ = DevToolsHttpHandler::Start(
new net::TCPListenSocketFactory("127.0.0.1", port), new net::TCPListenSocketFactory("127.0.0.1", 0),
"", "",
context_getter_, context_getter_,
this); this);
......
...@@ -21,7 +21,7 @@ class DevToolsHttpHandler; ...@@ -21,7 +21,7 @@ class DevToolsHttpHandler;
class ShellDevToolsDelegate : public DevToolsHttpHandlerDelegate { class ShellDevToolsDelegate : public DevToolsHttpHandlerDelegate {
public: public:
ShellDevToolsDelegate(int port, net::URLRequestContextGetter* context_getter); explicit ShellDevToolsDelegate(net::URLRequestContextGetter* context_getter);
virtual ~ShellDevToolsDelegate(); virtual ~ShellDevToolsDelegate();
// Stops http server. // Stops http server.
...@@ -32,6 +32,10 @@ class ShellDevToolsDelegate : public DevToolsHttpHandlerDelegate { ...@@ -32,6 +32,10 @@ class ShellDevToolsDelegate : public DevToolsHttpHandlerDelegate {
virtual bool BundlesFrontendResources() OVERRIDE; virtual bool BundlesFrontendResources() OVERRIDE;
virtual std::string GetFrontendResourcesBaseURL() OVERRIDE; virtual std::string GetFrontendResourcesBaseURL() OVERRIDE;
DevToolsHttpHandler* devtools_http_handler() {
return devtools_http_handler_;
}
private: private:
net::URLRequestContextGetter* context_getter_; net::URLRequestContextGetter* context_getter_;
DevToolsHttpHandler* devtools_http_handler_; DevToolsHttpHandler* devtools_http_handler_;
......
...@@ -28,7 +28,6 @@ const char kFrontEndURL[] = ...@@ -28,7 +28,6 @@ const char kFrontEndURL[] =
namespace content { namespace content {
ShellDevToolsDelegate::ShellDevToolsDelegate( ShellDevToolsDelegate::ShellDevToolsDelegate(
int port,
net::URLRequestContextGetter* context_getter) net::URLRequestContextGetter* context_getter)
: context_getter_(context_getter) { : context_getter_(context_getter) {
devtools_http_handler_ = DevToolsHttpHandler::Start( devtools_http_handler_ = DevToolsHttpHandler::Start(
......
...@@ -23,6 +23,40 @@ ...@@ -23,6 +23,40 @@
namespace content { namespace content {
namespace {
// Callback for Debug > Show web inspector... menu item.
gboolean ShowWebInspectorActivated(GtkWidget* widget, Shell* shell) {
shell->ShowDevTools();
return FALSE; // Don't stop this message.
}
GtkWidget* AddMenuEntry(GtkWidget* menu_widget, const char* text,
GCallback callback, Shell* shell) {
GtkWidget* entry = gtk_menu_item_new_with_label(text);
g_signal_connect(entry, "activate", callback, shell);
gtk_menu_shell_append(GTK_MENU_SHELL(menu_widget), entry);
return entry;
}
GtkWidget* CreateMenu(GtkWidget* menu_bar, const char* text) {
GtkWidget* menu_widget = gtk_menu_new();
GtkWidget* menu_header = gtk_menu_item_new_with_label(text);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_header), menu_widget);
gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_header);
return menu_widget;
}
GtkWidget* CreateMenuBar(Shell* shell) {
GtkWidget* menu_bar = gtk_menu_bar_new();
GtkWidget* debug_menu = CreateMenu(menu_bar, "Debug");
AddMenuEntry(debug_menu, "Show web inspector...",
G_CALLBACK(ShowWebInspectorActivated), shell);
return menu_bar;
}
} // namespace
void Shell::PlatformInitialize() { void Shell::PlatformInitialize() {
} }
...@@ -73,6 +107,10 @@ void Shell::PlatformCreateWindow(int width, int height) { ...@@ -73,6 +107,10 @@ void Shell::PlatformCreateWindow(int width, int height) {
vbox_ = gtk_vbox_new(FALSE, 0); vbox_ = gtk_vbox_new(FALSE, 0);
// Create the menu bar.
GtkWidget* menu_bar = CreateMenuBar(this);
gtk_box_pack_start(GTK_BOX(vbox_), menu_bar, FALSE, FALSE, 0);
// Create the object that mediates accelerators. // Create the object that mediates accelerators.
GtkAccelGroup* accel_group = gtk_accel_group_new(); GtkAccelGroup* accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(window_), accel_group); gtk_window_add_accel_group(GTK_WINDOW(window_), accel_group);
......
...@@ -236,6 +236,9 @@ LRESULT CALLBACK Shell::WndProc(HWND hwnd, UINT message, WPARAM wParam, ...@@ -236,6 +236,9 @@ LRESULT CALLBACK Shell::WndProc(HWND hwnd, UINT message, WPARAM wParam,
case IDM_EXIT: case IDM_EXIT:
PlatformExit(); PlatformExit();
break; break;
case IDM_SHOW_DEVELOPER_TOOLS:
shell->ShowDevTools();
break;
case IDC_NAV_BACK: case IDC_NAV_BACK:
shell->GoBackOrForward(-1); shell->GoBackOrForward(-1);
break; break;
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "base/sys_byteorder.h" #include "base/sys_byteorder.h"
#include "base/threading/platform_thread.h" #include "base/threading/platform_thread.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h" #include "net/base/net_util.h"
using std::string; using std::string;
...@@ -115,6 +117,21 @@ void StreamListenSocket::Send(const string& str, bool append_linefeed) { ...@@ -115,6 +117,21 @@ void StreamListenSocket::Send(const string& str, bool append_linefeed) {
Send(str.data(), static_cast<int>(str.length()), append_linefeed); Send(str.data(), static_cast<int>(str.length()), append_linefeed);
} }
int StreamListenSocket::GetLocalAddress(IPEndPoint* address) {
SockaddrStorage storage;
if (getsockname(socket_, storage.addr, &storage.addr_len)) {
#if defined(OS_WIN)
int err = WSAGetLastError();
#else
int err = errno;
#endif
return MapSystemError(err);
}
if (!address->FromSockAddr(storage.addr, storage.addr_len))
return ERR_FAILED;
return OK;
}
SocketDescriptor StreamListenSocket::AcceptSocket() { SocketDescriptor StreamListenSocket::AcceptSocket() {
SocketDescriptor conn = HANDLE_EINTR(accept(socket_, NULL, NULL)); SocketDescriptor conn = HANDLE_EINTR(accept(socket_, NULL, NULL));
if (conn == kInvalidSocket) if (conn == kInvalidSocket)
......
...@@ -47,6 +47,8 @@ typedef SOCKET SocketDescriptor; ...@@ -47,6 +47,8 @@ typedef SOCKET SocketDescriptor;
namespace net { namespace net {
class IPEndPoint;
class NET_EXPORT StreamListenSocket class NET_EXPORT StreamListenSocket
: public base::RefCountedThreadSafe<StreamListenSocket>, : public base::RefCountedThreadSafe<StreamListenSocket>,
#if defined(OS_WIN) #if defined(OS_WIN)
...@@ -79,6 +81,9 @@ class NET_EXPORT StreamListenSocket ...@@ -79,6 +81,9 @@ class NET_EXPORT StreamListenSocket
void Send(const char* bytes, int len, bool append_linefeed = false); void Send(const char* bytes, int len, bool append_linefeed = false);
void Send(const std::string& str, bool append_linefeed = false); void Send(const std::string& str, bool append_linefeed = false);
// Copies the local address to |address|. Returns a network error code.
int GetLocalAddress(IPEndPoint* address);
static const SocketDescriptor kInvalidSocket; static const SocketDescriptor kInvalidSocket;
static const int kSocketError; static const int kSocketError;
......
...@@ -83,8 +83,7 @@ void HttpServer::Send500(int connection_id, const std::string& message) { ...@@ -83,8 +83,7 @@ void HttpServer::Send500(int connection_id, const std::string& message) {
connection->Send500(message); connection->Send500(message);
} }
void HttpServer::Close(int connection_id) void HttpServer::Close(int connection_id) {
{
HttpConnection* connection = FindConnection(connection_id); HttpConnection* connection = FindConnection(connection_id);
if (connection == NULL) if (connection == NULL)
return; return;
...@@ -94,6 +93,10 @@ void HttpServer::Close(int connection_id) ...@@ -94,6 +93,10 @@ void HttpServer::Close(int connection_id)
DidClose(connection->socket_); DidClose(connection->socket_);
} }
int HttpServer::GetLocalAddress(IPEndPoint* address) {
return server_->GetLocalAddress(address);
}
void HttpServer::DidAccept(StreamListenSocket* server, void HttpServer::DidAccept(StreamListenSocket* server,
StreamListenSocket* socket) { StreamListenSocket* socket) {
HttpConnection* connection = new HttpConnection(this, socket); HttpConnection* connection = new HttpConnection(this, socket);
......
...@@ -16,6 +16,7 @@ namespace net { ...@@ -16,6 +16,7 @@ namespace net {
class HttpConnection; class HttpConnection;
class HttpServerRequestInfo; class HttpServerRequestInfo;
class IPEndPoint;
class WebSocket; class WebSocket;
class HttpServer : public StreamListenSocket::Delegate, class HttpServer : public StreamListenSocket::Delegate,
...@@ -53,6 +54,9 @@ class HttpServer : public StreamListenSocket::Delegate, ...@@ -53,6 +54,9 @@ class HttpServer : public StreamListenSocket::Delegate,
void Send500(int connection_id, const std::string& message); void Send500(int connection_id, const std::string& message);
void Close(int connection_id); void Close(int connection_id);
// Copies the local address to |address|. Returns a network error code.
int GetLocalAddress(IPEndPoint* address);
// ListenSocketDelegate // ListenSocketDelegate
virtual void DidAccept(StreamListenSocket* server, virtual void DidAccept(StreamListenSocket* server,
StreamListenSocket* socket) OVERRIDE; StreamListenSocket* socket) OVERRIDE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment