Browse Source

Start working on web server, just for fun

tags/v1.9.11
falkTX FilipeCSnuk 6 years ago
parent
commit
d1d4d7d45f
2 changed files with 298 additions and 0 deletions
  1. +63
    -0
      source/rest/Makefile
  2. +235
    -0
      source/rest/rest-server.cpp

+ 63
- 0
source/rest/Makefile View File

@@ -0,0 +1,63 @@
#!/usr/bin/make -f
# Makefile for carla-interposer #
# ----------------------------- #
# Created by falkTX
#

CWD=..
include $(CWD)/Makefile.mk

# ----------------------------------------------------------------------------------------------------------------------

BINDIR := $(CWD)/../bin

ifeq ($(DEBUG),true)
OBJDIR := $(CWD)/../build/interposer/Debug
MODULEDIR := $(CWD)/../build/modules/Debug
else
OBJDIR := $(CWD)/../build/interposer/Release
MODULEDIR := $(CWD)/../build/modules/Release
endif

# ----------------------------------------------------------------------------------------------------------------------

BUILD_CXX_FLAGS += -I$(CWD) -I$(CWD)/backend -I$(CWD)/includes -I$(CWD)/modules -I$(CWD)/utils

LINK_FLAGS += -L$(BINDIR) -lcarla_utils -lrestbed -Wl,-rpath=$(shell realpath $(CWD)/../bin)

# ----------------------------------------------------------------------------------------------------------------------

OBJS =
TARGETS = $(BINDIR)/carla-rest-server

# ----------------------------------------------------------------------------------------------------------------------

all: $(TARGETS)

# ----------------------------------------------------------------------------------------------------------------------

clean:
rm -f $(OBJDIR)/*.o $(TARGETS)

debug:
$(MAKE) DEBUG=true

# ----------------------------------------------------------------------------------------------------------------------

$(BINDIR)/carla-rest-server: $(OBJDIR)/rest-server.cpp.o
-@mkdir -p $(BINDIR)
@echo "Linking carla-rest-server"
@$(CXX) $< $(LINK_FLAGS) -o $@

# ----------------------------------------------------------------------------------------------------------------------

$(OBJDIR)/rest-server.cpp.o: rest-server.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $<"
@$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

# ----------------------------------------------------------------------------------------------------------------------

-include $(OBJS:%.o=%.d)

# ----------------------------------------------------------------------------------------------------------------------

+ 235
- 0
source/rest/rest-server.cpp View File

@@ -0,0 +1,235 @@
/*
* Carla REST API Server
* Copyright (C) 2018 Filipe Coelho <falktx@falktx.com>
*
* This program 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 any later version.
*
* This program 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 more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

/* NOTE
* Even though Carla is GPL, restbed if AGPL.
* As such, the resulting binary will be AGPL.
* Take this into consideration before deploying it to any servers.
*/

#include "CarlaHost.h"
#include "CarlaUtils.h"
#include "CarlaUtils.hpp"

#include <cstring>
#include <restbed>

// #include <memory>
// #include <cstdlib>

// using namespace std;
using namespace restbed;

#if 0
void post_method_handler(const std::shared_ptr<Session> session)
{
const std::shared_ptr<const Request> request = session->get_request();

const string body = "Hello, " + request->get_path_parameter("id");
session->close(OK, body, { { "Content-Length", ::to_string( body.size( ) ) } } );
}
#endif

CARLA_BACKEND_START_NAMESPACE

enum {
kStrBufSize = 1023,
kJsonBufSize = 4095,
kSizeBufSize = 31,
};

// static buffer to returned content
static char strBuf[kStrBufSize+1];
static char jsonBuf[kJsonBufSize+1];

// static buffer to returned content size
static char sizeBuf[kSizeBufSize+1];

void prepare_size()
{
const std::size_t size = std::strlen(strBuf);
std::snprintf(sizeBuf, kSizeBufSize, P_SIZE, size);
sizeBuf[kSizeBufSize] = '\0';
}

void prepare_buffer_uint(const uint value)
{
std::snprintf(strBuf, kStrBufSize, "%u", value);
strBuf[kStrBufSize] = '\0';
}

void prepare_buffer_string(const char* const string)
{
std::strncpy(strBuf, string, kStrBufSize);
strBuf[kStrBufSize] = '\0';
}

void prepare_buffer_string_array(const char* const* const array)
{
size_t bytesRead = 0;
strBuf[0] = '\0';

for (int i=0; array[i] != nullptr && bytesRead < kStrBufSize; ++i)
{
const std::size_t size = std::strlen(array[i]);

if (bytesRead + size > kStrBufSize)
break;

std::strncpy(strBuf+bytesRead, array[i], kStrBufSize);
bytesRead += size;
strBuf[bytesRead] = '\n';
bytesRead += 1;
}

strBuf[bytesRead] = '\0';
}

char* prepare_buffer_json_start()
{
std::strcpy(jsonBuf, "{");
return jsonBuf + 1;
}

char* prepare_buffer_json_add_uint(char* bufPtr, const char* const key, const uint value)
{
prepare_buffer_uint(value);

if (bufPtr != jsonBuf+1)
{
*bufPtr = ',';
bufPtr += 1;
}

*bufPtr++ = '"';

std::strcpy(bufPtr, key);
bufPtr += std::strlen(key);

*bufPtr++ = '"';
*bufPtr++ = ':';

std::strcpy(bufPtr, strBuf);
bufPtr += std::strlen(strBuf);

return bufPtr;
}

void prepare_buffer_json_end(char* const bufPtr)
{
std::strcpy(bufPtr, "}");

const std::size_t size = std::strlen(jsonBuf);
std::snprintf(sizeBuf, kSizeBufSize, P_SIZE, size);
sizeBuf[kSizeBufSize] = '\0';
}

void handle_carla_get_complete_license_text(const std::shared_ptr<Session> session)
{
prepare_buffer_string(carla_get_complete_license_text());
prepare_size();
session->close(OK, strBuf, { { "Content-Length", sizeBuf } } );
}

void handle_carla_get_supported_file_extensions(const std::shared_ptr<Session> session)
{
prepare_buffer_string_array(carla_get_supported_file_extensions());
prepare_size();
session->close(OK, strBuf, { { "Content-Length", sizeBuf } } );
}

void handle_carla_get_supported_features(const std::shared_ptr<Session> session)
{
prepare_buffer_string_array(carla_get_supported_features());
prepare_size();
session->close(OK, strBuf, { { "Content-Length", sizeBuf } } );
}

void handle_carla_get_cached_plugin_count(const std::shared_ptr<Session> session)
{
PluginType ptype = PLUGIN_LV2;
const char* pluginPath = nullptr;

prepare_buffer_uint(carla_get_cached_plugin_count(ptype, pluginPath));
prepare_size();
session->close(OK, strBuf, { { "Content-Length", sizeBuf } } );
}

void handle_carla_get_cached_plugin_info(const std::shared_ptr<Session> session)
{
PluginType ptype = PLUGIN_LV2;
const uint index = 0;

// REMOVE THIS
carla_get_cached_plugin_count(ptype, nullptr);

const CarlaCachedPluginInfo* const info = carla_get_cached_plugin_info(ptype, index);

char* bufPtr;
bufPtr = prepare_buffer_json_start();
bufPtr = prepare_buffer_json_add_uint(bufPtr, "category", info->category);
bufPtr = prepare_buffer_json_add_uint(bufPtr, "hints", info->hints);
bufPtr = prepare_buffer_json_add_uint(bufPtr, "audioIns", info->audioIns);
bufPtr = prepare_buffer_json_add_uint(bufPtr, "audioOuts", info->audioOuts);
bufPtr = prepare_buffer_json_add_uint(bufPtr, "midiIns", info->midiIns);
bufPtr = prepare_buffer_json_add_uint(bufPtr, "midiOuts", info->midiOuts);
bufPtr = prepare_buffer_json_add_uint(bufPtr, "parameterIns", info->parameterIns);
bufPtr = prepare_buffer_json_add_uint(bufPtr, "parameterOuts", info->parameterOuts);

// const char* name;
// const char* label;
// const char* maker;
// const char* copyright;

prepare_buffer_json_end(bufPtr);

session->close(OK, jsonBuf, { { "Content-Length", sizeBuf } } );
}

// CARLA_EXPORT const CarlaCachedPluginInfo* carla_get_cached_plugin_info(PluginType ptype, uint index);

CARLA_BACKEND_END_NAMESPACE

void make_resource(Service& service,
const char* const path,
const std::function<void (const std::shared_ptr<Session>)>& callback)
{
std::shared_ptr<Resource> resource = std::make_shared<Resource>();
resource->set_path(path);
resource->set_method_handler("GET", callback);
service.publish(resource);
}

int main(int, const char**)
{
CARLA_BACKEND_USE_NAMESPACE;

Service service;
make_resource(service, "/get_complete_license_text", handle_carla_get_complete_license_text);
make_resource(service, "/get_supported_file_extensions", handle_carla_get_supported_file_extensions);
make_resource(service, "/get_supported_features", handle_carla_get_supported_features);
make_resource(service, "/get_cached_plugin_count", handle_carla_get_cached_plugin_count);
make_resource(service, "/get_cached_plugin_info", handle_carla_get_cached_plugin_info);

std::shared_ptr<Settings> settings = std::make_shared<Settings>();
settings->set_port(2228);
settings->set_default_header("Connection", "close");

carla_stdout("Carla REST-API Server started");
service.start(settings);
return 0;
}

Loading…
Cancel
Save