12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CHROME_TEST_CHROMEDRIVER_NET_TEST_HTTP_SERVER_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CHROME_TEST_CHROMEDRIVER_NET_TEST_HTTP_SERVER_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/lock.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/waitable_event.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/server/http_server.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class WaitableEvent;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTP server for web socket testing purposes that runs on its own thread.
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// All public methods are thread safe and may be called on any thread, unless
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// noted otherwise.
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestHttpServer : public net::HttpServer::Delegate {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum WebSocketRequestAction {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kAccept,
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kNotFound,
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kClose,
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum WebSocketMessageAction {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kEchoMessage,
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kCloseOnMessage
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Creates an http server. By default it accepts WebSockets and echoes
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebSocket messages back.
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestHttpServer();
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TestHttpServer();
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Starts the server. Returns whether it was started successfully.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool Start();
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Stops the server. May be called multiple times.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Stop();
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Waits until all open connections are closed. Returns true if all
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connections are closed, or false if a timeout is exceeded.
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool WaitForConnectionsToClose();
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets the action to perform when receiving a WebSocket connect request.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetRequestAction(WebSocketRequestAction action);
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Sets the action to perform when receiving a WebSocket message.
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetMessageAction(WebSocketMessageAction action);
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the web socket URL that points to the server.
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL web_socket_url() const;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Overridden from net::HttpServer::Delegate:
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void OnConnect(int connection_id) OVERRIDE;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnHttpRequest(int connection_id,
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const net::HttpServerRequestInfo& info) OVERRIDE {}
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWebSocketRequest(
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int connection_id,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const net::HttpServerRequestInfo& info) OVERRIDE;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnWebSocketMessage(int connection_id,
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const std::string& data) OVERRIDE;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnClose(int connection_id) OVERRIDE;
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartOnServerThread(bool* success, base::WaitableEvent* event);
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StopOnServerThread(base::WaitableEvent* event);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Thread thread_;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Access only on the server thread.
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<net::HttpServer> server_;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Access only on the server thread.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<int> connections_;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::WaitableEvent all_closed_event_;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Protects |web_socket_url_|.
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mutable base::Lock url_lock_;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GURL web_socket_url_;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Protects the action flags.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Lock action_lock_;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebSocketRequestAction request_action_;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebSocketMessageAction message_action_;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestHttpServer);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CHROME_TEST_CHROMEDRIVER_NET_TEST_HTTP_SERVER_H_
101