mirror of
https://github.com/clangen/musikcube.git
synced 2025-01-01 09:01:15 +00:00
All HTTP requests are now handled by plugins.
This commit is contained in:
parent
48b856d082
commit
7b72e40a4c
@ -544,3 +544,21 @@ void Track::SetThumbnail(const char *data,unsigned int size){
|
||||
TrackPtr Track::Copy(){
|
||||
return TrackPtr(new Track(this->id));
|
||||
}
|
||||
|
||||
bool Track::GetFileData(DBINT id,db::Connection &db){
|
||||
this->InitMeta(NULL);
|
||||
|
||||
this->id = id;
|
||||
|
||||
db::CachedStatement stmt("SELECT t.filename,t.filesize,t.filetime,p.path||f.relative_path||'/'||t.filename FROM tracks t,folders f,paths p WHERE t.folder_id=f.id AND f.path_id=p.id AND t.id=?",db);
|
||||
stmt.BindInt(0,id);
|
||||
|
||||
if(stmt.Step()==db::Row){
|
||||
this->SetValue("filename" ,stmt.ColumnTextUTF(0));
|
||||
this->SetValue("filesize" ,stmt.ColumnTextUTF(1));
|
||||
this->SetValue("filetime" ,stmt.ColumnTextUTF(2));
|
||||
this->SetValue("path" ,stmt.ColumnTextUTF(3));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -56,6 +56,9 @@ namespace musik{ namespace core{
|
||||
namespace db{
|
||||
class Connection;
|
||||
}
|
||||
namespace http{
|
||||
class Responder;
|
||||
}
|
||||
} }
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -144,6 +147,10 @@ class Track : public ITrack {
|
||||
bool Save(db::Connection &dbConnection,utfstring libraryDirectory,DBINT folderId);
|
||||
DBINT _GetGenre(db::Connection &dbConnection,utfstring genre,bool addRelation,bool aggregated=false);
|
||||
DBINT _GetArtist(db::Connection &dbConnection,utfstring artist,bool addRelation,bool aggregated=false);
|
||||
|
||||
private:
|
||||
friend class http::Responder;
|
||||
bool GetFileData(DBINT id,db::Connection &db);
|
||||
};
|
||||
|
||||
|
||||
|
@ -617,6 +617,18 @@
|
||||
<Filter
|
||||
Name="http"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\http\IRequestParser.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\http\IRequestPlugin.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\http\IResponder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\http\RequestParser.cpp"
|
||||
>
|
||||
@ -659,6 +671,14 @@
|
||||
RelativePath=".\http\Server.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\http\TrackSender.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\http\TrackSender.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
|
58
src/core/http/IRequestParser.h
Normal file
58
src/core/http/IRequestParser.h
Normal file
@ -0,0 +1,58 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2008, Daniel Önnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <core/config.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace musik{ namespace core{ namespace http{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class IRequestParser{
|
||||
public:
|
||||
virtual const char* Attribute(const char* key)=0;
|
||||
virtual const char* Path()=0;
|
||||
virtual const char* SubPath(int position)=0;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
} } } // musik::core:http
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
61
src/core/http/IRequestPlugin.h
Normal file
61
src/core/http/IRequestPlugin.h
Normal file
@ -0,0 +1,61 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2008, Daniel Önnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <core/config.h>
|
||||
#include <core/http/IResponder.h>
|
||||
#include <core/http/IRequestParser.h>
|
||||
#include <core/ITrack.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace musik{ namespace core{ namespace http{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class IRequestPlugin{
|
||||
public:
|
||||
virtual void Destroy()=0;
|
||||
virtual const char* WatchPath()=0;
|
||||
virtual void Execute(musik::core::http::IResponder* responder,const musik::core::http::IRequestParser* request,const musik::core::ITrack* track)=0;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
} } }
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
57
src/core/http/IResponder.h
Normal file
57
src/core/http/IResponder.h
Normal file
@ -0,0 +1,57 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2008, Daniel Önnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <core/config.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace musik{ namespace core{ namespace http{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class IResponder{
|
||||
public:
|
||||
virtual void SendContent(const char* buffer,const int bufferSize)=0;
|
||||
virtual bool Exited()=0;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
} } }
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -37,9 +37,7 @@
|
||||
#include "pch.hpp"
|
||||
|
||||
#include <core/http/RequestParser.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
using namespace musik::core::http;
|
||||
|
||||
@ -69,7 +67,8 @@ void RequestParser::Parse(const std::string &request){
|
||||
int questionMark( this->fullRequest.find("?") );
|
||||
|
||||
if(questionMark!=std::string::npos){
|
||||
this->path.assign(this->fullRequest.substr(questionMark));
|
||||
this->path.assign(this->fullRequest.substr(0,questionMark));
|
||||
this->ParseAttributes( this->fullRequest.substr(questionMark+1) );
|
||||
}else{
|
||||
this->path.assign(this->fullRequest);
|
||||
}
|
||||
@ -79,31 +78,58 @@ void RequestParser::Parse(const std::string &request){
|
||||
}
|
||||
|
||||
void RequestParser::SplitPath(){
|
||||
int startSearch(0);
|
||||
if(!this->path.empty()){
|
||||
boost::algorithm::split(this->splitPath,this->path,boost::algorithm::is_any_of("/"));
|
||||
}
|
||||
}
|
||||
|
||||
while(startSearch!=std::string::npos){
|
||||
int firstSlash( this->path.find("/",startSearch) );
|
||||
|
||||
if(firstSlash==std::string::npos){
|
||||
if(this->path.size()-startSearch!=0){
|
||||
std::string matchPath;
|
||||
matchPath.assign(this->path,startSearch,this->path.size()-startSearch);
|
||||
this->splitPath.push_back(matchPath);
|
||||
}
|
||||
startSearch = std::string::npos;
|
||||
}else{
|
||||
if(firstSlash-startSearch!=0){
|
||||
std::string matchPath;
|
||||
matchPath.assign(this->path,startSearch,firstSlash-startSearch);
|
||||
this->splitPath.push_back(matchPath);
|
||||
}
|
||||
startSearch = firstSlash+1;
|
||||
void RequestParser::ParseAttributes(std::string attributeString){
|
||||
StringVector attributes;
|
||||
boost::algorithm::split(attributes,attributeString,boost::algorithm::is_any_of("&"));
|
||||
|
||||
for(StringVector::iterator attribute=attributes.begin();attribute!=attributes.end();++attribute){
|
||||
std::string::size_type eqSign( attribute->find("=") );
|
||||
if(eqSign!=std::string::npos){
|
||||
this->attributes[ attribute->substr(0,eqSign) ] = attribute->substr(eqSign+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RequestParser::Clear(){
|
||||
this->path.clear();
|
||||
this->fullRequest.clear();
|
||||
this->splitPath.clear();
|
||||
}
|
||||
|
||||
const RequestParser::StringVector& RequestParser::SplitPaths() const{
|
||||
return this->splitPath;
|
||||
}
|
||||
|
||||
const char* RequestParser::Path(){
|
||||
return this->path.c_str();
|
||||
}
|
||||
|
||||
const RequestParser::AttributeMap& RequestParser::Attributes() const{
|
||||
return this->attributes;
|
||||
}
|
||||
|
||||
const char* RequestParser::Attribute(const char* key){
|
||||
if(key){
|
||||
AttributeMap::iterator attrib = this->attributes.find(key);
|
||||
if(attrib!=this->attributes.end()){
|
||||
return attrib->second.c_str();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* RequestParser::SubPath(int position){
|
||||
|
||||
if(position<this->splitPath.size()){
|
||||
return this->splitPath[position].c_str();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -37,9 +37,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <core/config.h>
|
||||
#include <core/http/IRequestParser.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -47,19 +49,31 @@ namespace musik{ namespace core{ namespace http{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class RequestParser{
|
||||
class RequestParser : public IRequestParser{
|
||||
public:
|
||||
RequestParser();
|
||||
void Parse(const std::string &request);
|
||||
~RequestParser();
|
||||
|
||||
std::string fullRequest;
|
||||
std::string path;
|
||||
std::vector<std::string> splitPath;
|
||||
virtual const char* Attribute(const char* key);
|
||||
virtual const char* Path();
|
||||
virtual const char* SubPath(int position);
|
||||
|
||||
typedef std::vector<std::string> StringVector;
|
||||
typedef std::map<std::string,std::string> AttributeMap;
|
||||
|
||||
const StringVector& SplitPaths() const;
|
||||
const AttributeMap& Attributes() const;
|
||||
|
||||
private:
|
||||
void SplitPath();
|
||||
void ParseAttributes(std::string attributeString);
|
||||
void Clear();
|
||||
|
||||
std::string fullRequest;
|
||||
std::string path;
|
||||
StringVector splitPath;
|
||||
AttributeMap attributes;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
using namespace musik::core::http;
|
||||
|
||||
@ -93,8 +94,46 @@ void Responder::ThreadLoop(){
|
||||
|
||||
// First, read request
|
||||
if(this->ReadRequest(request)){
|
||||
// Second, Find out what is requested.
|
||||
// Find out what is requested.
|
||||
requester.Parse(request);
|
||||
|
||||
// Check if there is a related Track
|
||||
musik::core::TrackPtr track;
|
||||
const char* trackId = requester.Attribute("track_id");
|
||||
if(trackId){
|
||||
try{
|
||||
track.reset(new musik::core::Track());
|
||||
if(!track->GetFileData( boost::lexical_cast<DBINT>(trackId),this->db)){
|
||||
track.reset();
|
||||
}
|
||||
}
|
||||
catch(...){
|
||||
// lexical cast fail
|
||||
track.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Lets see what plugin can handle the request
|
||||
std::string rootPath;
|
||||
if(requester.SubPath(0)){
|
||||
rootPath = requester.SubPath(0);
|
||||
}
|
||||
Server::PluginPathMap::iterator plugin = this->server.requestPlugins.find(rootPath);
|
||||
if(plugin!=this->server.requestPlugins.end()){
|
||||
|
||||
// Execute the plugin
|
||||
plugin->second->Execute(this,&requester,track.get());
|
||||
|
||||
}else{
|
||||
// Send 404 error
|
||||
std::string send("HTTP/1.1 404 OK\r\nContent-Type: text/html\r\n\r\n<html><body bgcolor=\"#ff0000\">ERROR: ");
|
||||
send += "<pre>";
|
||||
send += request;
|
||||
send += "</pre></body></html>";
|
||||
boost::asio::write(this->socket,boost::asio::buffer(send.c_str(),send.size()));
|
||||
}
|
||||
|
||||
/*
|
||||
utfstring fileName;
|
||||
int fileSize(0);
|
||||
|
||||
@ -134,7 +173,7 @@ void Responder::ThreadLoop(){
|
||||
send += "</pre></body></html>";
|
||||
|
||||
boost::asio::write(this->socket,boost::asio::buffer(send.c_str(),send.size()));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,10 +186,13 @@ void Responder::ThreadLoop(){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Responder::SendContent(const char* buffer,const int bufferSize){
|
||||
boost::asio::write(this->socket,boost::asio::buffer(buffer,bufferSize));
|
||||
}
|
||||
/*
|
||||
bool Responder::GetFileName(utfstring &fileName,int &fileSize,const RequestParser &request){
|
||||
if(request.splitPath.size()>0){
|
||||
std::string sRequestId = request.splitPath.front();
|
||||
if(request.SplitPaths().size()>0){
|
||||
std::string sRequestId = request.SplitPaths().front();
|
||||
int requestId = atoi(sRequestId.c_str());
|
||||
|
||||
musik::core::db::CachedStatement stmt("SELECT t.id,(p.path||f.relative_path||'/'||t.filename) AS file,t.filesize FROM tracks t,folders f,paths p WHERE t.id=? AND t.folder_id=f.id AND f.path_id=p.id",this->db);
|
||||
@ -166,7 +208,7 @@ bool Responder::GetFileName(utfstring &fileName,int &fileSize,const RequestParse
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
bool Responder::ReadRequest(std::string &request){
|
||||
char buffer[512];
|
||||
@ -194,13 +236,6 @@ bool Responder::ReadRequest(std::string &request){
|
||||
|
||||
void Responder::CloseSocket(){
|
||||
// Close socket
|
||||
/* int iError = shutdown(this->iSocket,SHUT_RDWR);
|
||||
ASSERT(iError==0);
|
||||
iError = closesocket(this->iSocket);
|
||||
ASSERT(iError==0);
|
||||
|
||||
this->iSocket = -1;
|
||||
*/
|
||||
this->socket.close();
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <core/config.h>
|
||||
#include <core/http/IResponder.h>
|
||||
#include <core/db/Connection.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
@ -65,22 +66,23 @@ namespace musik{ namespace core{ namespace http{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Responder : private boost::noncopyable{
|
||||
class Responder : public IResponder{
|
||||
public:
|
||||
Responder(Server &server,boost::asio::io_service &ioService,utfstring dbFilename);
|
||||
~Responder();
|
||||
|
||||
bool Startup();
|
||||
|
||||
virtual void SendContent(const char* buffer,const int bufferSize);
|
||||
virtual bool Exited();
|
||||
private:
|
||||
friend class Server;
|
||||
|
||||
void Exit();
|
||||
bool Exited();
|
||||
void ThreadLoop();
|
||||
bool ReadRequest(std::string &request);
|
||||
void CloseSocket();
|
||||
bool GetFileName(utfstring &fileName,int &fileSize,const RequestParser &request);
|
||||
// bool GetFileName(utfstring &fileName,int &fileSize,const RequestParser &request);
|
||||
|
||||
|
||||
bool exited;
|
||||
|
@ -38,11 +38,16 @@
|
||||
|
||||
#include <core/http/Server.h>
|
||||
#include <core/http/Responder.h>
|
||||
#include <core/http/Responder.h>
|
||||
#include <core/PluginFactory.h>
|
||||
#include <core/http/TrackSender.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
|
||||
using namespace musik::core::http;
|
||||
|
||||
|
||||
Server::Server(int port,utfstring dbFilename)
|
||||
:acceptor(ioService,boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
|
||||
,thread(NULL)
|
||||
@ -51,6 +56,24 @@ Server::Server(int port,utfstring dbFilename)
|
||||
,port(port)
|
||||
,dbFilename(dbFilename)
|
||||
{
|
||||
// Check for plugins
|
||||
typedef IRequestPlugin PluginType;
|
||||
typedef boost::shared_ptr<PluginType> PluginPtr;
|
||||
typedef PluginFactory::DestroyDeleter<PluginType> Deleter;
|
||||
typedef std::vector<PluginPtr> PluginVector;
|
||||
//
|
||||
PluginVector plugins = PluginFactory::Instance().QueryInterface<PluginType, Deleter>("GetHTTPRequestPlugin");
|
||||
|
||||
for(PluginVector::iterator plugin=plugins.begin();plugin!=plugins.end();++plugin){
|
||||
if((*plugin)->WatchPath()){
|
||||
this->requestPlugins[(*plugin)->WatchPath()] = *plugin;
|
||||
}else{
|
||||
this->requestPlugins[""] = *plugin;
|
||||
}
|
||||
}
|
||||
|
||||
// Lets always add the TrackSender
|
||||
this->requestPlugins["track"] = PluginPtr(new TrackSender());
|
||||
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
|
||||
#include <core/config.h>
|
||||
#include <core/http/Responder.h>
|
||||
#include <core/http/IRequestPlugin.h>
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
@ -94,6 +95,10 @@ class Server : private boost::noncopyable{
|
||||
friend class Responder;
|
||||
void FreeResponder(Responder *responder);
|
||||
|
||||
//
|
||||
typedef std::map<std::string,boost::shared_ptr<IRequestPlugin>> PluginPathMap;
|
||||
|
||||
PluginPathMap requestPlugins;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
88
src/core/http/TrackSender.cpp
Normal file
88
src/core/http/TrackSender.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2008, Daniel Önnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pch.hpp"
|
||||
#include <core/http/TrackSender.h>
|
||||
#include <core/Common.h>
|
||||
|
||||
|
||||
using namespace musik::core::http;
|
||||
|
||||
TrackSender::TrackSender()
|
||||
:watchPath("track")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const char* TrackSender::WatchPath(){
|
||||
return this->watchPath.c_str();
|
||||
}
|
||||
|
||||
void TrackSender::Execute(musik::core::http::IResponder* responder,const musik::core::http::IRequestParser* request,const musik::core::ITrack* track){
|
||||
#define BUFFER_SIZE 4096
|
||||
char buffer[BUFFER_SIZE];
|
||||
int buffersize(0);
|
||||
|
||||
// TODO: Should rewrite this in a multiplatform manner
|
||||
if(track && responder){
|
||||
FILE *file = _wfopen(track->GetValue("path"),UTF("rb"));
|
||||
|
||||
if(file){
|
||||
// Send header
|
||||
std::string header( "HTTP/1.1 200 OK\r\nContent-Type: audio/mpeg\r\nContent-Length: " );
|
||||
header.append( musik::core::ConvertUTF8(track->GetValue("filesize")) );
|
||||
header.append("\r\n\r\n");
|
||||
|
||||
responder->SendContent(header.c_str(),header.size());
|
||||
|
||||
while(!feof(file) && file && !responder->Exited()){
|
||||
buffersize=0;
|
||||
while(buffersize<BUFFER_SIZE && !feof(file)){
|
||||
buffersize += fread(buffer,sizeof(char),BUFFER_SIZE-buffersize,file);
|
||||
}
|
||||
|
||||
// send buffer
|
||||
responder->SendContent(buffer,buffersize);
|
||||
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TrackSender::Destroy(){
|
||||
delete this;
|
||||
}
|
63
src/core/http/TrackSender.h
Normal file
63
src/core/http/TrackSender.h
Normal file
@ -0,0 +1,63 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2008, Daniel Önnerby
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <core/config.h>
|
||||
#include <core/http/IRequestPlugin.h>
|
||||
#include <string>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace musik{ namespace core{ namespace http {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class TrackSender : public IRequestPlugin{
|
||||
public:
|
||||
TrackSender();
|
||||
|
||||
virtual void Destroy();
|
||||
virtual const char* WatchPath();
|
||||
virtual void Execute(musik::core::http::IResponder* responder,const musik::core::http::IRequestParser* request,const musik::core::ITrack* track);
|
||||
|
||||
private:
|
||||
std::string watchPath;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
} } } // musik::core::http
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user