From 79887329f008ba184aac8d7c606859986a9ef20e Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 15 Aug 2008 05:15:31 +0000 Subject: Add primitive read-only HTTP interface (point browser to http://localhost:16180/). git-svn-id: http://svn.drobilla.net/lad/ingen@1390 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/engine/HTTPEngineReceiver.cpp | 125 +++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/libs/engine/HTTPEngineReceiver.cpp (limited to 'src/libs/engine/HTTPEngineReceiver.cpp') diff --git a/src/libs/engine/HTTPEngineReceiver.cpp b/src/libs/engine/HTTPEngineReceiver.cpp new file mode 100644 index 00000000..baa522ba --- /dev/null +++ b/src/libs/engine/HTTPEngineReceiver.cpp @@ -0,0 +1,125 @@ +/* This file is part of Ingen. + * Copyright (C) 2007 Dave Robillard + * + * Ingen is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include "types.hpp" +#include +#include +#include "interface/ClientInterface.hpp" +#include "engine/ThreadManager.hpp" +#include "HTTPEngineReceiver.hpp" +#include "QueuedEventSource.hpp" +#include "ClientBroadcaster.hpp" +#include "ObjectStore.hpp" + +using namespace std; + +namespace Ingen { + + +HTTPEngineReceiver::HTTPEngineReceiver(Engine& engine, uint16_t port) + : QueuedEngineInterface(engine, 2, 2) + , _server(soup_server_new(SOUP_SERVER_PORT, port, NULL)) +{ + _receive_thread = new ReceiveThread(*this); + + soup_server_add_handler(_server, NULL, message_callback, this, NULL); + + cout << "Started HTTP server on port " << soup_server_get_port(_server) << endl; + Thread::set_name("HTTP receiver"); +} + + +HTTPEngineReceiver::~HTTPEngineReceiver() +{ + deactivate(); + + if (_server != NULL) { + soup_server_quit(_server); + _server = NULL; + } +} + + +void +HTTPEngineReceiver::activate() +{ + QueuedEventSource::activate(); + _receive_thread->set_name("HTTP Receiver"); + _receive_thread->start(); +} + + +void +HTTPEngineReceiver::deactivate() +{ + cout << "[HTTPEngineReceiver] Stopped HTTP listening thread" << endl; + _receive_thread->stop(); + QueuedEventSource::deactivate(); +} + + +void +HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const char* path, + GHashTable *query, SoupClientContext* client, void* data) +{ + HTTPEngineReceiver* me = (HTTPEngineReceiver*)data; + + if (msg->method != SOUP_METHOD_GET) { + soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); + return; + } + + // FIXME: not thread safe! + + ObjectStore* store = me->_engine.object_store(); + if (!Path::is_valid(path)) { + soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); + return; + } + + ObjectStore::Objects::iterator start = store->find(path); + if (start == store->objects().end()) { + soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); + return; + } + + ObjectStore::Objects::iterator end = store->objects().find_descendants_end(start); + + string response; + for (ObjectStore::Objects::iterator i = start; i != end; ++i) + response.append(i->first).append("\n"); + + soup_message_set_status (msg, SOUP_STATUS_OK); + soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, + response.c_str(), response.length()); +} + + +/** Override the semaphore driven _run method of QueuedEngineInterface + * to wait on HTTP requests and process them immediately in this thread. + */ +void +HTTPEngineReceiver::ReceiveThread::_run() +{ + soup_server_run(_receiver._server); +} + + +} // namespace Ingen -- cgit v1.2.1