summaryrefslogtreecommitdiffstats
path: root/chrome_frame/test/test_server.h
diff options
context:
space:
mode:
authorslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
committerslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
commitf781782dd67077478e117c61dca4ea5eefce3544 (patch)
tree4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/test/test_server.h
parent63cf4759efa2373e33436fb5df6849f930081226 (diff)
downloadchromium_src-f781782dd67077478e117c61dca4ea5eefce3544.zip
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.gz
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.bz2
Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming in a separate CL.
BUG=None TEST=None Review URL: http://codereview.chromium.org/218019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/test/test_server.h')
-rw-r--r--chrome_frame/test/test_server.h296
1 files changed, 296 insertions, 0 deletions
diff --git a/chrome_frame/test/test_server.h b/chrome_frame/test/test_server.h
new file mode 100644
index 0000000..896b2b3
--- /dev/null
+++ b/chrome_frame/test/test_server.h
@@ -0,0 +1,296 @@
+// Copyright (c) 2006-2008 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.
+
+#ifndef CHROME_FRAME_TEST_TEST_SERVER_H_
+#define CHROME_FRAME_TEST_TEST_SERVER_H_
+
+// Implementation of an HTTP server for tests.
+// To instantiate the server, make sure you have a message loop on the
+// current thread and then create an instance of the SimpleWebServer class.
+// The server uses two basic concepts, a request and a response.
+// The Response interface represents an item (e.g. a document) available from
+// the server. A Request object represents a request from a client (e.g. a
+// browser). There are several basic Response classes implemented in this file,
+// all derived from the Response interface.
+//
+// Here's a simple example that starts a web server that can serve up
+// a single document (http://localhost:1337/foo).
+// All other requests will get a 404.
+//
+// MessageLoopForUI loop;
+// test_server::SimpleWebServer server(1337);
+// test_server::SimpleResponse document("/foo", "Hello World!");
+// test_server.AddResponse(&document);
+// loop.MessageLoop::Run();
+//
+// To close the web server, just go to http://localhost:1337/quit.
+//
+// All Response classes count how many times they have been accessed. Just
+// call Response::accessed().
+//
+// To implement a custom response object (e.g. to match against a request
+// based on some data, serve up dynamic content or take some action on the
+// server), just inherit from one of the response classes or directly from the
+// Response interface and add your response object to the server's list of
+// response objects.
+
+#include <list>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/file_util.h"
+#include "net/base/listen_socket.h"
+
+namespace test_server {
+
+class Request {
+ public:
+ Request() : content_length_(0) {
+ }
+
+ void ParseHeaders(const std::string& headers);
+
+ const std::string& method() const {
+ return method_;
+ }
+
+ const std::string& path() const {
+ return path_;
+ }
+
+ const std::string& headers() const {
+ return headers_;
+ }
+
+ size_t content_length() const {
+ return content_length_;
+ }
+
+ protected:
+ std::string method_;
+ std::string path_;
+ std::string version_;
+ std::string headers_;
+ size_t content_length_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Request);
+};
+
+// Manages request headers for a single request.
+// For each successful request that's made, the server will keep an instance
+// of this class so that they can be checked even after the server has been
+// shut down.
+class Connection {
+ public:
+ explicit Connection(ListenSocket* sock) : socket_(sock) {
+ }
+
+ ~Connection() {
+ }
+
+ bool IsSame(const ListenSocket* socket) const {
+ return socket_ == socket;
+ }
+
+ void AddData(const std::string& data) {
+ data_ += data;
+ }
+
+ bool CheckRequestReceived();
+
+ const Request& request() const {
+ return request_;
+ }
+
+ protected:
+ scoped_refptr<ListenSocket> socket_;
+ std::string data_;
+ Request request_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Connection);
+};
+
+// Abstract interface with default implementations for some of the methods and
+// a counter for how many times the response object has served requests.
+class Response {
+ public:
+ Response() : accessed_(0) {
+ }
+
+ virtual ~Response() {
+ }
+
+ // Returns true if this response object should be used for a given request.
+ virtual bool Matches(const Request& r) const = 0;
+
+ // Response objects can optionally supply their own HTTP headers, completely
+ // bypassing the default ones.
+ virtual bool GetCustomHeaders(std::string* headers) const {
+ return false;
+ }
+
+ // Optionally provide a content type. Return false if you don't specify
+ // a content type.
+ virtual bool GetContentType(std::string* content_type) const {
+ return false;
+ }
+
+ virtual size_t ContentLength() const {
+ return 0;
+ }
+
+ virtual void WriteContents(ListenSocket* socket) const {
+ }
+
+ void IncrementAccessCounter() {
+ accessed_++;
+ }
+
+ size_t accessed() const {
+ return accessed_;
+ }
+
+ protected:
+ size_t accessed_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Response);
+};
+
+// Partial implementation of Response that matches a request's path.
+// This is just a convenience implementation for the boilerplate implementation
+// of Matches(). Don't instantiate directly.
+class ResponseForPath : public Response {
+ public:
+ explicit ResponseForPath(const char* request_path)
+ : request_path_(request_path) {
+ }
+
+ virtual bool Matches(const Request& r) const {
+ return r.path().compare(request_path_) == 0;
+ }
+
+ protected:
+ std::string request_path_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ResponseForPath);
+};
+
+// A very basic implementation of a response.
+// A simple response matches a single document path on the server
+// (e.g. "/foo") and returns a document in the form of a string.
+class SimpleResponse : public ResponseForPath {
+ public:
+ SimpleResponse(const char* request_path, const std::string& contents)
+ : ResponseForPath(request_path), contents_(contents) {
+ }
+
+ virtual void WriteContents(ListenSocket* socket) const {
+ socket->Send(contents_.c_str(), contents_.length(), false);
+ }
+
+ virtual size_t ContentLength() const {
+ return contents_.length();
+ }
+
+ protected:
+ std::string contents_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SimpleResponse);
+};
+
+// To serve up files from the web server, create an instance of FileResponse
+// and add it to the server's list of responses. The content type of the
+// file will be determined by calling FindMimeFromData which examines the
+// contents of the file and performs registry lookups.
+class FileResponse : public ResponseForPath {
+ public:
+ FileResponse(const char* request_path, const FilePath& file_path)
+ : ResponseForPath(request_path), file_path_(file_path) {
+ }
+
+ virtual bool GetContentType(std::string* content_type) const;
+ virtual void WriteContents(ListenSocket* socket) const;
+ virtual size_t ContentLength() const;
+
+ protected:
+ FilePath file_path_;
+ mutable scoped_ptr<file_util::MemoryMappedFile> file_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FileResponse);
+};
+
+// Returns a 302 (temporary redirect) to redirect the client from a path
+// on the test server to a different URL.
+class RedirectResponse : public ResponseForPath {
+ public:
+ RedirectResponse(const char* request_path, const std::string& redirect_url)
+ : ResponseForPath(request_path), redirect_url_(redirect_url) {
+ }
+
+ virtual bool GetCustomHeaders(std::string* headers) const;
+
+ protected:
+ std::string redirect_url_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RedirectResponse);
+};
+
+// typedef for a list of connections. Used by SimpleWebServer.
+typedef std::list<Connection*> ConnectionList;
+
+// Implementation of a simple http server.
+// Before creating an instance of the server, make sure the current thread
+// has a message loop.
+class SimpleWebServer : public ListenSocket::ListenSocketDelegate {
+ public:
+ explicit SimpleWebServer(int port);
+ virtual ~SimpleWebServer();
+
+ void AddResponse(Response* response);
+
+ // ListenSocketDelegate overrides.
+ virtual void DidAccept(ListenSocket* server, ListenSocket* connection);
+ virtual void DidRead(ListenSocket* connection, const std::string& data);
+ virtual void DidClose(ListenSocket* sock);
+
+ const ConnectionList& connections() {
+ return connections_;
+ }
+
+ protected:
+ class QuitResponse : public SimpleResponse {
+ public:
+ QuitResponse()
+ : SimpleResponse("/quit", "So long and thanks for all the fish.") {
+ }
+
+ virtual void QuitResponse::WriteContents(ListenSocket* socket) const {
+ SimpleResponse::WriteContents(socket);
+ MessageLoop::current()->Quit();
+ }
+ };
+
+ Response* FindResponse(const Request& request) const;
+ Connection* FindConnection(const ListenSocket* socket) const;
+
+ protected:
+ scoped_refptr<ListenSocket> server_;
+ ConnectionList connections_;
+ std::list<Response*> responses_;
+ QuitResponse quit_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SimpleWebServer);
+};
+
+} // namespace test_server
+
+#endif // CHROME_FRAME_TEST_TEST_SERVER_H_