mirror of
https://github.com/clangen/musikcube.git
synced 2025-01-01 09:01:15 +00:00
Added http::Server to musik::core::Server. Fixed some issues in the Remote Library.
This commit is contained in:
parent
7b72e40a4c
commit
22a2f0caaf
@ -628,3 +628,7 @@ void Library::Base::CreateDatabase(db::Connection &db){
|
||||
|
||||
db.Execute("ANALYZE");
|
||||
}
|
||||
|
||||
utfstring Library::Base::BasePath(){
|
||||
return UTF("");
|
||||
}
|
||||
|
@ -130,6 +130,8 @@ class Base : boost::noncopyable{
|
||||
|
||||
virtual musik::core::Indexer *Indexer();
|
||||
|
||||
virtual utfstring BasePath();
|
||||
|
||||
bool Exited();
|
||||
|
||||
const utfstring& Identifier();
|
||||
|
@ -188,6 +188,9 @@ void Library::Remote::ReadThread(){
|
||||
boost::mutex::scoped_lock lock(this->libraryMutex);
|
||||
currentQuery->status |= Query::Base::Status::Canceled | Query::Base::Status::Ended;
|
||||
}
|
||||
|
||||
this->waitCondition.notify_all();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -293,3 +296,13 @@ void Library::Remote::Exit(){
|
||||
}
|
||||
this->waitCondition.notify_all();
|
||||
}
|
||||
|
||||
utfstring Library::Remote::BasePath(){
|
||||
utfstring path(UTF("http://"));
|
||||
boost::asio::ip::tcp::endpoint endPoint = this->socket.remote_endpoint();
|
||||
boost::asio::ip::address address = endPoint.address();
|
||||
|
||||
path += musik::core::ConvertUTF16(address.to_string());
|
||||
path += UTF(":") + musik::core::ConvertUTF16(this->port) + UTF("/");
|
||||
return path;
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ class Remote : public Library::Base{
|
||||
|
||||
bool Startup();
|
||||
utfstring GetInfo();
|
||||
virtual utfstring BasePath();
|
||||
|
||||
protected:
|
||||
void CancelCurrentQuery( );
|
||||
|
@ -396,6 +396,9 @@ bool TrackMetadata::SendResults(musik::core::xml::WriterNode &queryNode,Library:
|
||||
if( !resultCopy.empty() ){
|
||||
try{
|
||||
for(TrackVector::iterator track=resultCopy.begin();track!=resultCopy.end();++track){
|
||||
// Erase the path.. is translated in the RecieveResults
|
||||
(*track)->ClearValue("path");
|
||||
|
||||
musik::core::xml::WriterNode trackNode(queryNode,"t");
|
||||
trackNode.Attributes()["id"] = boost::lexical_cast<std::string>( (*track)->id );
|
||||
|
||||
@ -426,6 +429,9 @@ bool TrackMetadata::SendResults(musik::core::xml::WriterNode &queryNode,Library:
|
||||
|
||||
bool TrackMetadata::RecieveResults(musik::core::xml::ParserNode &queryNode,Library::Base *library){
|
||||
|
||||
bool requestPath( this->requestedFields.find("path")!=this->requestedFields.end() );
|
||||
utfstring pathPrefix(library->BasePath()+UTF("track/?track_id="));
|
||||
|
||||
while(musik::core::xml::ParserNode trackNode=queryNode.ChildNode("t") ){
|
||||
try{
|
||||
DBINT trackId( boost::lexical_cast<DBINT>(trackNode.Attributes()["id"]) );
|
||||
@ -453,6 +459,13 @@ bool TrackMetadata::RecieveResults(musik::core::xml::ParserNode &queryNode,Libra
|
||||
currentTrack->SetValue( metadataNode.Attributes()["k"].c_str(),ConvertUTF16(metadataNode.Content()).c_str());
|
||||
}
|
||||
|
||||
// Special case for the "path" when connecting to a webserver
|
||||
if(requestPath){
|
||||
utfstring path(pathPrefix);
|
||||
path += boost::lexical_cast<utfstring>(currentTrack->id);
|
||||
currentTrack->SetValue("path",path.c_str());
|
||||
}
|
||||
|
||||
{
|
||||
boost::mutex::scoped_lock oLock(library->oResultMutex);
|
||||
this->aResultTracks.push_back(currentTrack);
|
||||
@ -460,7 +473,7 @@ bool TrackMetadata::RecieveResults(musik::core::xml::ParserNode &queryNode,Libra
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
return false;
|
||||
// return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,9 +47,10 @@
|
||||
using namespace musik::core;
|
||||
|
||||
|
||||
Server::Server(unsigned int port)
|
||||
Server::Server(unsigned int port,unsigned int httpPort)
|
||||
:exitThread(false)
|
||||
,acceptor(ioService,boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
|
||||
,httpServer(httpPort)
|
||||
{
|
||||
this->acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
|
||||
}
|
||||
@ -77,6 +78,7 @@ bool Server::Exited(){
|
||||
bool Server::Startup(){
|
||||
// Start the server thread
|
||||
this->threads.create_thread(boost::bind(&Server::ThreadLoop,this));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -88,6 +90,8 @@ void Server::ThreadLoop(){
|
||||
utfstring directory( musik::core::GetDataDirectory()+UTF("server/") );
|
||||
utfstring database(directory+UTF("musik.db"));
|
||||
|
||||
this->httpServer.Startup(database);
|
||||
|
||||
{
|
||||
// Create database
|
||||
db::Connection db;
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <core/server/Connection.h>
|
||||
|
||||
#include <core/Indexer.h>
|
||||
#include <core/http/Server.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
@ -53,12 +54,13 @@ namespace musik{ namespace core{
|
||||
class Server{
|
||||
public:
|
||||
// Methods
|
||||
Server(unsigned int port);
|
||||
Server(unsigned int port,unsigned int httpPort);
|
||||
~Server(void);
|
||||
bool Startup();
|
||||
|
||||
public:
|
||||
Indexer indexer;
|
||||
http::Server httpServer;
|
||||
|
||||
private:
|
||||
// Methods
|
||||
|
@ -125,6 +125,12 @@ void Track::SetValue(const char* metakey,const utfchar* value){
|
||||
}
|
||||
}
|
||||
|
||||
void Track::ClearValue(const char* metakey){
|
||||
if(this->meta){
|
||||
this->meta->ClearValue(metakey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Track::ClearMeta(){
|
||||
if(this->meta){
|
||||
|
@ -113,6 +113,7 @@ class Track : public ITrack {
|
||||
const utfchar* GetValue(const char* metakey) const;
|
||||
void SetValue(const char* metakey,const utfchar* value);
|
||||
void SetThumbnail(const char *data,unsigned int size);
|
||||
void ClearValue(const char* metakey);
|
||||
|
||||
|
||||
void InitMeta(Library::Base *library);
|
||||
|
@ -135,6 +135,11 @@ void TrackMeta::SetValue(const TrackMeta::Key &key,const TrackMeta::Value &value
|
||||
}
|
||||
}
|
||||
|
||||
void TrackMeta::ClearValue(const TrackMeta::Key &key){
|
||||
this->tags.erase(key);
|
||||
}
|
||||
|
||||
|
||||
const TrackMeta::Value& TrackMeta::_GetValue(const TrackMeta::Key &key) const{
|
||||
|
||||
TrackMeta::TagMap::const_iterator oKeyValue = this->tags.find(key);
|
||||
|
@ -77,6 +77,7 @@ class TrackMeta : boost::noncopyable{
|
||||
const utfstring& GetValue(const Key &key) const;
|
||||
TrackMeta::TagMapIteratorPair GetValues(const char* metakey) const;
|
||||
void SetValue(const Key &key,const Value &value);
|
||||
void ClearValue(const Key &key);
|
||||
const utfchar* GetValue(const char* metakey) const;
|
||||
|
||||
Library::Base *library;
|
||||
|
@ -81,6 +81,14 @@ void RequestParser::SplitPath(){
|
||||
if(!this->path.empty()){
|
||||
boost::algorithm::split(this->splitPath,this->path,boost::algorithm::is_any_of("/"));
|
||||
}
|
||||
// Remove empty paths
|
||||
for(StringVector::iterator path=this->splitPath.begin();path!=this->splitPath.end();){
|
||||
if(path->empty()){
|
||||
path = this->splitPath.erase(path);
|
||||
}else{
|
||||
++path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,6 +56,7 @@ Responder::Responder(Server &server,boost::asio::io_service &ioService,utfstring
|
||||
:socket(ioService)
|
||||
,thread(NULL)
|
||||
,server(server)
|
||||
,exited(false)
|
||||
{
|
||||
this->db.Open(dbFilename,0,256);
|
||||
}
|
||||
@ -133,47 +134,6 @@ void Responder::ThreadLoop(){
|
||||
boost::asio::write(this->socket,boost::asio::buffer(send.c_str(),send.size()));
|
||||
}
|
||||
|
||||
/*
|
||||
utfstring fileName;
|
||||
int fileSize(0);
|
||||
|
||||
if(this->GetFileName(fileName,fileSize,requester)){
|
||||
char buffer[1024];
|
||||
int buffersize(0);
|
||||
|
||||
|
||||
FILE *file = _wfopen(fileName.c_str(),UTF("rb"));
|
||||
|
||||
// Send header
|
||||
std::string header( boost::str( boost::format("HTTP/1.1 200 OK\r\nContent-Type: audio/mpeg\r\nContent-Length: %1%\r\n\r\n")%fileSize ));
|
||||
|
||||
//send(this->iSocket,sHeader.c_str(),sHeader.size(),0);
|
||||
try{
|
||||
boost::asio::write(this->socket,boost::asio::buffer(header.c_str(),header.size()));
|
||||
}
|
||||
catch(...){
|
||||
}
|
||||
|
||||
while(!feof(file) && file && !this->Exited()){
|
||||
buffersize=0;
|
||||
while(buffersize<1024 && !feof(file)){
|
||||
buffersize += fread(buffer,sizeof(char),1024-buffersize,file);
|
||||
}
|
||||
// send buffer
|
||||
// send(this->iSocket,buffer,iBuffersize,0);
|
||||
boost::asio::write(this->socket,boost::asio::buffer(buffer,buffersize));
|
||||
|
||||
}
|
||||
fclose(file);
|
||||
}else{
|
||||
std::string send("HTTP/1.1 404 OK\r\nContent-Type: text/html\r\n\r\n<html><body bgcolor=\"#ff0000\">testar: ");
|
||||
send += musik::core::ConvertUTF8(fileName);
|
||||
send += "<br><pre>";
|
||||
send += request;
|
||||
send += "</pre></body></html>";
|
||||
|
||||
boost::asio::write(this->socket,boost::asio::buffer(send.c_str(),send.size()));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,13 +48,12 @@
|
||||
using namespace musik::core::http;
|
||||
|
||||
|
||||
Server::Server(int port,utfstring dbFilename)
|
||||
Server::Server(int port)
|
||||
:acceptor(ioService,boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
|
||||
,thread(NULL)
|
||||
,timer(ioService)
|
||||
,exited(false)
|
||||
,port(port)
|
||||
,dbFilename(dbFilename)
|
||||
{
|
||||
// Check for plugins
|
||||
typedef IRequestPlugin PluginType;
|
||||
@ -85,7 +84,9 @@ Server::~Server(){
|
||||
}
|
||||
}
|
||||
|
||||
bool Server::Startup(){
|
||||
bool Server::Startup(utfstring dbFilename){
|
||||
|
||||
this->dbFilename = dbFilename;
|
||||
|
||||
// start the thread
|
||||
this->thread = new boost::thread(boost::bind(&Server::ThreadLoop,this));
|
||||
@ -165,10 +166,14 @@ ResponderPtr Server::GetResponder(){
|
||||
void Server::FreeResponder(Responder *responder){
|
||||
boost::mutex::scoped_lock lock(this->mutex);
|
||||
|
||||
ResponderSet::iterator foundResponder = this->busyResponders.find(ResponderPtr(responder));
|
||||
if(foundResponder!=this->busyResponders.end()){
|
||||
this->freeResponders.push(*foundResponder);
|
||||
this->busyResponders.erase(foundResponder);
|
||||
ResponderSet::iterator tempResponder=this->busyResponders.begin();
|
||||
while(tempResponder!=this->busyResponders.end()){
|
||||
if(tempResponder->get()==responder){
|
||||
this->freeResponders.push(*tempResponder);
|
||||
tempResponder = this->busyResponders.erase(tempResponder);
|
||||
}else{
|
||||
++tempResponder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,10 +56,10 @@ namespace musik{ namespace core{ namespace http {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class Server : private boost::noncopyable{
|
||||
public:
|
||||
Server(int port,utfstring dbFilename);
|
||||
Server(int port);
|
||||
~Server();
|
||||
|
||||
bool Startup();
|
||||
bool Startup(utfstring dbFilename);
|
||||
|
||||
int port;
|
||||
|
||||
@ -70,12 +70,6 @@ class Server : private boost::noncopyable{
|
||||
void Exit();
|
||||
bool Exited();
|
||||
|
||||
typedef std::set<ResponderPtr> ResponderSet;
|
||||
typedef std::queue<ResponderPtr> ResponderQueue;
|
||||
ResponderSet busyResponders;
|
||||
ResponderQueue freeResponders;
|
||||
ResponderPtr waitingResponder;
|
||||
|
||||
ResponderPtr GetResponder();
|
||||
|
||||
void initAccept();
|
||||
@ -99,6 +93,12 @@ class Server : private boost::noncopyable{
|
||||
typedef std::map<std::string,boost::shared_ptr<IRequestPlugin>> PluginPathMap;
|
||||
|
||||
PluginPathMap requestPlugins;
|
||||
|
||||
typedef std::set<ResponderPtr> ResponderSet;
|
||||
typedef std::queue<ResponderPtr> ResponderQueue;
|
||||
ResponderSet busyResponders;
|
||||
ResponderQueue freeResponders;
|
||||
ResponderPtr waitingResponder;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -43,7 +43,7 @@ using namespace musik::core;
|
||||
|
||||
int main(int argc, utfchar* argv[]){
|
||||
|
||||
Server server(10543);
|
||||
Server server(10543,10544);
|
||||
|
||||
server.Startup();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user