All HTTP requests are now handled by plugins.

This commit is contained in:
Daniel Önnerby 2008-08-26 12:03:32 +00:00
parent 48b856d082
commit 7b72e40a4c
14 changed files with 518 additions and 41 deletions

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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>

View 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
//////////////////////////////////////////////////////////////////////////////

View 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;
};
//////////////////////////////////////////////////////////////////////////////
} } }
//////////////////////////////////////////////////////////////////////////////

View 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;
};
//////////////////////////////////////////////////////////////////////////////
} } }
//////////////////////////////////////////////////////////////////////////////

View File

@ -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;
}

View File

@ -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;
};
//////////////////////////////////////////////////////////////////////////////

View File

@ -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();
}

View File

@ -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;

View File

@ -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());
}

View File

@ -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;
};
//////////////////////////////////////////////////////////////////////////////

View 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;
}

View 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
//////////////////////////////////////////////////////////////////////////////