From 5d1f579900182f283a1c21ad4e59daf7f035e219 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 9 Nov 2008 01:32:38 +0000 Subject: Move patch to /patch via HTTP to give a place for RESTful access to other things. Implement HTTP access to plugins. Work towards client being able to use HTTP to connect. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1712 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/HTTPEngineReceiver.cpp | 95 ++++++++++++++++++++++++++------------- src/engine/HTTPEngineReceiver.hpp | 4 ++ src/engine/NodeFactory.cpp | 3 +- src/engine/OSCClientSender.cpp | 2 +- src/engine/OSCEngineReceiver.cpp | 2 +- src/engine/PluginImpl.hpp | 19 -------- 6 files changed, 71 insertions(+), 54 deletions(-) (limited to 'src/engine') diff --git a/src/engine/HTTPEngineReceiver.cpp b/src/engine/HTTPEngineReceiver.cpp index 4c5c3b36..8a035175 100644 --- a/src/engine/HTTPEngineReceiver.cpp +++ b/src/engine/HTTPEngineReceiver.cpp @@ -48,7 +48,7 @@ HTTPEngineReceiver::HTTPEngineReceiver(Engine& engine, uint16_t port) 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"); + Thread::set_name("HTTP Receiver"); if (!engine.world()->serialisation_module) engine.world()->serialisation_module = Ingen::Shared::load_module("ingen_serialisation"); @@ -64,12 +64,17 @@ HTTPEngineReceiver::HTTPEngineReceiver(Engine& engine, uint16_t port) } else { cerr << "WARNING: Failed to load ingen_serialisation module, HTTP disabled." << endl; } + + Thread::set_name("HTTP Receiver"); } HTTPEngineReceiver::~HTTPEngineReceiver() { deactivate(); + stop(); + _receive_thread->stop(); + delete _receive_thread; if (_server != NULL) { soup_server_quit(_server); @@ -97,7 +102,7 @@ HTTPEngineReceiver::deactivate() void -HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const char* path, +HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const char* path_str, GHashTable *query, SoupClientContext* client, void* data) { HTTPEngineReceiver* me = (HTTPEngineReceiver*)data; @@ -108,10 +113,51 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const return; } + string path = path_str; + if (path[path.length()-1] == '/') { + path = path.substr(0, path.length()-1); + } + + SharedPtr serialiser = me->_engine.world()->serialiser; + + const string base_uri = ""; + const char* mime_type = "text/plain"; + + if (path == "/" || path == "") { + const string r = string("@prefix rdfs: .\n") + .append("\n<> rdfs:seeAlso ;") + .append("\n rdfs:seeAlso ."); + soup_message_set_status(msg, SOUP_STATUS_OK); + soup_message_set_response(msg, mime_type, SOUP_MEMORY_COPY, r.c_str(), r.length()); + return; + + } else if (path.substr(0, 8) == "/plugins") { + // FIXME: kludge + me->load_plugins(); + me->_receive_thread->whip(); + + serialiser->start_to_string("/", base_uri); + for (NodeFactory::Plugins::const_iterator p = me->_engine.node_factory()->plugins().begin(); + p != me->_engine.node_factory()->plugins().end(); ++p) + serialiser->serialise_plugin(*(Shared::Plugin*)p->second); + const string r = serialiser->finish(); + soup_message_set_status(msg, SOUP_STATUS_OK); + soup_message_set_response(msg, mime_type, SOUP_MEMORY_COPY, r.c_str(), r.length()); + return; + } else if (path.substr(0, 6) == "/patch") { + path = '/' + path.substr(6); + } else { + cout << "UNKNOWN PATH: " << path << endl; + soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND); + soup_message_set_response(msg, "text/plain", SOUP_MEMORY_STATIC, + "Unknown path\n\n", 14); + return; + } + if (!Path::is_valid(path)) { soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); const string& err = (boost::format("Bad path: %1%") % path).str(); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, + soup_message_set_response(msg, "text/plain", SOUP_MEMORY_COPY, err.c_str(), err.length()); return; } @@ -122,9 +168,9 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const // Find object Store::const_iterator start = store->find(path); if (start == store->end()) { - soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); + soup_message_set_status(msg, SOUP_STATUS_NOT_FOUND); const string& err = (boost::format("No such object: %1%") % path).str(); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, + soup_message_set_response(msg, "text/plain", SOUP_MEMORY_COPY, err.c_str(), err.length()); return; } @@ -132,35 +178,22 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const // Get serialiser SharedPtr serialiser = me->_engine.world()->serialiser; if (!serialiser) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, + soup_message_set_status(msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + soup_message_set_response(msg, "text/plain", SOUP_MEMORY_STATIC, "No serialiser available\n", 24); return; } -#if 0 - SoupMessageHeaders* in_head = msg->request_headers; + /*SoupMessageHeaders* in_head = msg->request_headers; const char* str = soup_message_headers_get(in_head, "Accept"); - cout << "Accept: " << str << endl; -#endif + cout << "Accept: " << str << endl;*/ // Serialise object const string response = serialiser->to_string(start->second, - "http://example.org", GraphObject::Variables()); - -#if 0 - FILE* xhtml_file = fopen("/home/dave/ingen_ui.xhtml", "r"); - string response; - while (!feof(xhtml_file)) { - int c = fgetc(xhtml_file); - if (c != EOF) - response += (char)c; - } - fclose(xhtml_file); -#endif - - soup_message_set_status (msg, SOUP_STATUS_OK); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, + "http://localhost:16180/patch", GraphObject::Variables()); + + soup_message_set_status(msg, SOUP_STATUS_OK); + soup_message_set_response(msg, mime_type, SOUP_MEMORY_COPY, response.c_str(), response.length()); } else if (msg->method == SOUP_METHOD_PUT) { @@ -169,26 +202,26 @@ HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const // Be sure object doesn't exist Store::const_iterator start = store->find(path); if (start != store->end()) { - soup_message_set_status (msg, SOUP_STATUS_CONFLICT); + soup_message_set_status(msg, SOUP_STATUS_CONFLICT); return; } // Get parser SharedPtr parser = me->_engine.world()->parser; if (!parser) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); + soup_message_set_status(msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); return; } //cout << "POST: " << msg->request_body->data << endl; // Load object - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); } else if (msg->method == SOUP_METHOD_POST) { //cout << "PUT: " << msg->request_body->data << endl; - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); } else { - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); + soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); } } diff --git a/src/engine/HTTPEngineReceiver.hpp b/src/engine/HTTPEngineReceiver.hpp index 18f0a972..07b730b0 100644 --- a/src/engine/HTTPEngineReceiver.hpp +++ b/src/engine/HTTPEngineReceiver.hpp @@ -40,6 +40,10 @@ private: struct ReceiveThread : public Raul::Thread { ReceiveThread(HTTPEngineReceiver& receiver) : _receiver(receiver) {} virtual void _run(); + virtual void whip() { + while (_receiver.unprepared_events()) + _receiver.whip(); + } private: HTTPEngineReceiver& _receiver; }; diff --git a/src/engine/NodeFactory.cpp b/src/engine/NodeFactory.cpp index 45da0a03..91f44a83 100644 --- a/src/engine/NodeFactory.cpp +++ b/src/engine/NodeFactory.cpp @@ -87,8 +87,7 @@ NodeFactory::plugin(const string& type, const string& lib, const string& label) #ifdef HAVE_LADSPA for (Plugins::const_iterator i = _plugins.begin(); i != _plugins.end(); ++i) { LADSPAPlugin* lp = dynamic_cast(i->second); - if (lp && lp->type_string() == type - && lp->library_name() == lib + if (lp && lp->library_name() == lib && lp->label() == label) return lp; } diff --git a/src/engine/OSCClientSender.cpp b/src/engine/OSCClientSender.cpp index 95b6ec65..162f02cd 100644 --- a/src/engine/OSCClientSender.cpp +++ b/src/engine/OSCClientSender.cpp @@ -294,7 +294,7 @@ OSCClientSender::port_activity(const std::string& port_path) /** \page client_osc_namespace *

\b /ingen/plugin - Notification of the existance of a plugin * \arg \b uri (string) - URI of plugin (e.g. http://example.org/filtermatic) - * \arg \b type (string) - Type of plugin (e.g. "ingen:LV2Plugin") + * \arg \b type (string) - Type of plugin (e.g. "lv2:Plugin", "ingen:LADSPAPlugin") * \arg \b symbol (string) - Valid symbol for plugin (default symbol for nodes) (e.g. "adsr") * \arg \b name (string) - Descriptive human-readable name of plugin (e.g. "ADSR Envelope") */ diff --git a/src/engine/OSCEngineReceiver.cpp b/src/engine/OSCEngineReceiver.cpp index e0299556..ba3e65c1 100644 --- a/src/engine/OSCEngineReceiver.cpp +++ b/src/engine/OSCEngineReceiver.cpp @@ -120,7 +120,7 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t lo_server_add_method(_server, NULL, NULL, unknown_cb, NULL); - Thread::set_name("OSC Pre-Processor"); + Thread::set_name("OSC Receiver"); } diff --git a/src/engine/PluginImpl.hpp b/src/engine/PluginImpl.hpp index 8262bf74..53275313 100644 --- a/src/engine/PluginImpl.hpp +++ b/src/engine/PluginImpl.hpp @@ -67,25 +67,6 @@ public: void load(); void unload(); - const char* type_string() const { - if (_type == LADSPA) return "LADSPA"; - else if (_type == LV2) return "LV2"; - else if (_type == Internal) return "Internal"; - else if (_type == Patch) return "Patch"; - else return ""; - } - - const string type_uri() const { - return string("ingen:").append(type_string()); - } - - void set_type(const string& type_string) { - if (type_string == "LADSPA") _type = LADSPA; - else if (type_string == "LV2") _type = LV2; - else if (type_string == "Internal") _type = Internal; - else if (type_string == "Patch") _type = Patch; - } - Plugin::Type type() const { return _type; } void type(Plugin::Type t) { _type = t; } const string& uri() const { return _uri; } -- cgit v1.2.1