diff -ruN httptnt.new/cds_scpd.cpp httptnt/cds_scpd.cpp --- 1/httptnt.new/cds_scpd.cpp 1970-01-01 01:00:00.000000000 +0100 +++ 2/httptnt/cds_scpd.cpp 2013-05-01 16:43:04.937505028 +0200 @@ -0,0 +1,136 @@ +//////////////////////////////////////////////////////////////////////// +// cds_scpd.cpp +// generated with ecppc +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +log_define("component.cds_scpd") + +// <%pre> +// + +namespace +{ +class _component_ : public tnt::EcppComponent +{ + _component_& main() { return *this; } + + protected: + ~_component_(); + + public: + _component_(const tnt::Compident& ci, const tnt::Urlmapper& um, tnt::Comploader& cl); + + unsigned operator() (tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparam); +}; + +static tnt::ComponentFactoryImpl<_component_> Factory("cds_scpd"); + +static const char* rawData = "\034\000\000\000F\000\000\000G\000\000\000H\000\000\000%\015\000\000j\024\000\000\212\024" + "\000\000<\?xml version = \"1.0\" encoding = \"utf-8\"\?>\n\n\n\n <" + "specVersion>\n 1\n 0\n \n \n \n " + " Browse\n \n \n ObjectID\n " + " in\n A_ARG_TYPE_ObjectID\n \n \n BrowseFlag\n in\n A_ARG_TYPE_BrowseFlag\n \n \n Filter\n in\n " + " A_ARG_TYPE_Filter\n \n \n StartingIndex\n in\n A_ARG_TYPE_Index\n \n \n RequestedCount\n in\n A_ARG_TYPE_C" + "ount\n \n \n SortCriteria\n in\n A_ARG_TYPE_SortCriteria\n \n \n Result\n out\n A_ARG_TYPE_Result\n \n \n NumberReturned\n out\n A_ARG_TYPE_Count\n \n " + " \n TotalMatches\n out\n A_ARG_TYPE_Count\n \n \n " + " UpdateID\n out\n A_ARG_" + "TYPE_UpdateID\n \n \n \n \n GetSearchCapabilities\n \n \n SearchCaps\n out\n SearchCapabilit" + "ies\n \n \n \n \n " + " GetSortCapabilities\n \n \n SortCaps<" + "/name>\n out\n SortCapabilities\n \n \n \n \n GetSys" + "temUpdateID\n\n \n \n Id\n " + "out\n SystemUpdateID\n <" + "/argument>\n \n \n\n \n \n \n A_ARG_TYPE_BrowseFlag\n string\n \n BrowseMetadata\n BrowseDirectChildren\n \n \n \n SystemUpdateID\n ui4\n \n \n ContainerUpdateIDs\n string\n \n " + " \n A_ARG_TYPE_Count\n ui4\n " + " \n \n A_ARG_TYPE_SortCriteria\n " + " string\n \n \n SortCap" + "abilities\n string\n \n \n A_ARG_TYPE_Index\n ui4\n \n \n A_ARG_TYPE_ObjectID\n string\n \n \n A_ARG_TYPE_UpdateID\n ui4\n \n \n A_ARG_TYPE_Result\n string\n \n \n " + " SearchCapabilities\n string\n \n \n A_ARG_TYPE_Filter\n string\n \n\n \n"; + +// <%shared> +// + +// <%config> +// + +#define SET_LANG(lang) \ + do \ + { \ + request.setLang(lang); \ + reply.setLocale(request.getLocale()); \ + } while (false) + +_component_::_component_(const tnt::Compident& ci, const tnt::Urlmapper& um, tnt::Comploader& cl) + : EcppComponent(ci, um, cl) +{ + // <%init> + // +} + +_component_::~_component_() +{ + // <%cleanup> + // +} + +unsigned _component_::operator() (tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparam) +{ + log_trace("cds_scpd " << qparam.getUrl()); + + tnt::DataChunks data(rawData); + + // <%args> + // + + // <%cpp> + reply.out() << data[0]; // <\?xml version = "1.0" encoding = "utf-8"\?> + reply.out() << data[1]; // \n + reply.out() << data[2]; // \n +#line 9 "cds_scpd.ecpp" + reply.setContentType("text/xml"); + reply.out() << data[3]; // \n\n \n 1\n 0\n \n \n \n Browse\n \n \n ObjectID\n in\n A_ARG_TYPE_ObjectID\n \n \n BrowseFlag\n in\n A_ARG_TYPE_BrowseFlag\n \n \n Filter\n in\n A_ARG_TYPE_Filter\n \n \n StartingIndex\n in\n A_ARG_TYPE_Index\n \n \n RequestedCount\n in\n A_ARG_TYPE_Count\n \n \n SortCriteria\n in\n A_ARG_TYPE_SortCriteria\n \n \n Result\n out\n A_ARG_TYPE_Result\n \n \n NumberReturned\n out\n A_ARG_TYPE_Count\n \n \n TotalMatches\n out\n A_ARG_TYPE_Count\n \n \n UpdateID\n out\n A_ARG_TYPE_UpdateID\n \n \n \n \n GetSearchCapabilities\n \n \n SearchCaps\n out\n SearchCapabilities\n \n \n \n \n GetSortCapabilities\n \n \n SortCaps\n out\n SortCapabilities\n \n \n \n \n GetSystemUpdateID\n\n \n \n Id\n out\n SystemUpdateID\n \n \n \n + reply.out() << data[4]; // \n \n \n \n A_ARG_TYPE_BrowseFlag\n string\n \n BrowseMetadata\n BrowseDirectChildren\n \n \n \n SystemUpdateID\n ui4\n \n \n ContainerUpdateIDs\n string\n \n \n A_ARG_TYPE_Count\n ui4\n \n \n A_ARG_TYPE_SortCriteria\n string\n \n \n SortCapabilities\n string\n \n \n A_ARG_TYPE_Index\n ui4\n \n \n A_ARG_TYPE_ObjectID\n string\n \n \n A_ARG_TYPE_UpdateID\n ui4\n \n \n A_ARG_TYPE_Result\n string\n \n \n SearchCapabilities\n string\n \n \n A_ARG_TYPE_Filter\n string\n \n + reply.out() << data[5]; // \n \n + // <%/cpp> + return HTTP_OK; +} + +} // namespace diff -ruN httptnt.new/cms_scpd.cpp httptnt/cms_scpd.cpp --- 1/httptnt.new/cms_scpd.cpp 1970-01-01 01:00:00.000000000 +0100 +++ 2/httptnt/cms_scpd.cpp 2013-05-01 16:43:13.149505312 +0200 @@ -0,0 +1,137 @@ +//////////////////////////////////////////////////////////////////////// +// cms_scpd.cpp +// generated with ecppc +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +log_define("component.cms_scpd") + +// <%pre> +// + +namespace +{ +class _component_ : public tnt::EcppComponent +{ + _component_& main() { return *this; } + + protected: + ~_component_(); + + public: + _component_(const tnt::Compident& ci, const tnt::Urlmapper& um, tnt::Comploader& cl); + + unsigned operator() (tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparam); +}; + +static tnt::ComponentFactoryImpl<_component_> Factory("cms_scpd"); + +static const char* rawData = "\024\000\000\000:\000\000\000;\000\000\000<\000\000\000L\026\000\000<\?xml version=\"1.0" + "\" encoding=\"UTF-8\"\?>\n\n\n\n \n 1" + "\n 0\n \n \n \n Get" + "ProtocolInfo\n \n \n Sou" + "rce\n out\n Sourc" + "eProtocolInfo\n \n \n " + " Sink\n out\n SinkProtocolInfo\n \n " + "\n \n \n GetCurrentConnectionIDs\n \n \n ConnectionIDs\n <" + "direction>out\n CurrentConnectionIDs" + "\n \n \n \n \n " + " GetCurrentConnectionInfo\n \n \n " + " ConnectionID\n in\n " + "A_ARG_TYPE_ConnectionID\n \n " + " \n RcsID\n out\n " + " A_ARG_TYPE_RcsID\n \n \n AVTransportID\n out\n A_ARG_TYPE_AVTransportID\n \n \n ProtocolInfo\n out\n A_ARG_TYPE_Pro" + "tocolInfo\n \n \n " + " PeerConnectionManager\n out\n " + " A_ARG_TYPE_ConnectionManager\n \n " + " \n PeerConnectionID\n out\n A_ARG_TYPE_ConnectionID\n " + " \n \n Direction\n " + " out\n A_ARG_TYPE_Direction\n \n \n Status\n out\n A" + "_ARG_TYPE_ConnectionStatus\n \n \n " + " \n \n \n \n " + " SourceProtocolInfo\n string\n \n " + " \n SinkProtocolInfo\n string\n \n \n CurrentConnec" + "tionIDs\n string\n \n \n A_ARG_TYPE_ConnectionStatus\n string\n " + " \n OK\n Conte" + "ntFormatMismatch\n InsufficientBandwidth\n " + " UnreliableChannel\n Unknown\n " + " \n \n \n " + " A_ARG_TYPE_ConnectionManager\n string\n \n " + " \n A_ARG_TYPE_Direction\n s" + "tring\n \n Input\n " + " Output\n \n \n " + " \n A_ARG_TYPE_ProtocolInfo\n st" + "ring\n \n \n A_ARG_T" + "YPE_ConnectionID\n i4\n \n \n A_ARG_TYPE_AVTransportID\n i4\n " + " \n \n A_ARG_TYPE_RcsID\n " + " i4\n \n \n\n"; + +// <%shared> +// + +// <%config> +// + +#define SET_LANG(lang) \ + do \ + { \ + request.setLang(lang); \ + reply.setLocale(request.getLocale()); \ + } while (false) + +_component_::_component_(const tnt::Compident& ci, const tnt::Urlmapper& um, tnt::Comploader& cl) + : EcppComponent(ci, um, cl) +{ + // <%init> + // +} + +_component_::~_component_() +{ + // <%cleanup> + // +} + +unsigned _component_::operator() (tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparam) +{ + log_trace("cms_scpd " << qparam.getUrl()); + + tnt::DataChunks data(rawData); + + // <%args> + // + + // <%cpp> + reply.out() << data[0]; // <\?xml version="1.0" encoding="UTF-8"\?> + reply.out() << data[1]; // \n + reply.out() << data[2]; // \n +#line 9 "cms_scpd.ecpp" + reply.setContentType("text/xml"); + reply.out() << data[3]; // \n\n \n 1\n 0\n \n \n \n GetProtocolInfo\n \n \n Source\n out\n SourceProtocolInfo\n \n \n Sink\n out\n SinkProtocolInfo\n \n \n \n \n GetCurrentConnectionIDs\n \n \n ConnectionIDs\n out\n CurrentConnectionIDs\n \n \n \n \n GetCurrentConnectionInfo\n \n \n ConnectionID\n in\n A_ARG_TYPE_ConnectionID\n \n \n RcsID\n out\n A_ARG_TYPE_RcsID\n \n \n AVTransportID\n out\n A_ARG_TYPE_AVTransportID\n \n \n ProtocolInfo\n out\n A_ARG_TYPE_ProtocolInfo\n \n \n PeerConnectionManager\n out\n A_ARG_TYPE_ConnectionManager\n \n \n PeerConnectionID\n out\n A_ARG_TYPE_ConnectionID\n \n \n Direction\n out\n A_ARG_TYPE_Direction\n \n \n Status\n out\n A_ARG_TYPE_ConnectionStatus\n \n \n \n \n \n \n SourceProtocolInfo\n string\n \n \n SinkProtocolInfo\n string\n \n \n CurrentConnectionIDs\n string\n \n \n A_ARG_TYPE_ConnectionStatus\n string\n \n OK\n ContentFormatMismatch\n InsufficientBandwidth\n UnreliableChannel\n Unknown\n \n \n \n A_ARG_TYPE_ConnectionManager\n string\n \n \n A_ARG_TYPE_Direction\n string\n \n Input\n Output\n \n \n \n A_ARG_TYPE_ProtocolInfo\n string\n \n \n A_ARG_TYPE_ConnectionID\n i4\n \n \n A_ARG_TYPE_AVTransportID\n i4\n \n \n A_ARG_TYPE_RcsID\n i4\n \n \n\n + // <%/cpp> + return HTTP_OK; +} + +} // namespace diff -ruN httptnt.new/deviceDescription.cpp httptnt/deviceDescription.cpp --- 1/httptnt.new/deviceDescription.cpp 1970-01-01 01:00:00.000000000 +0100 +++ 2/httptnt/deviceDescription.cpp 2013-05-01 16:43:19.597505533 +0200 @@ -0,0 +1,220 @@ +//////////////////////////////////////////////////////////////////////// +// deviceDescription.cpp +// generated with ecppc +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +log_define("component.deviceDescription") + +// <%pre> +#line 9 "deviceDescription.ecpp" + +#include +#include +#include "../include/tools.h" +#include "../include/server.h" +#include "../include/service.h" +#include "../include/webserver.h" +#include "../include/config.h" + +using namespace upnp; + +// + +namespace +{ +class _component_ : public tnt::EcppComponent +{ + _component_& main() { return *this; } + + protected: + ~_component_(); + + public: + _component_(const tnt::Compident& ci, const tnt::Urlmapper& um, tnt::Comploader& cl); + + unsigned operator() (tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparam); +}; + +static tnt::ComponentFactoryImpl<_component_> Factory("deviceDescription"); + +static const char* rawData = "t\000\000\000\236\000\000\000\237\000\000\000\240\000\000\000\262\001\000\000\325\001\000" + "\000\373\001\000\000%\002\000\000I\002\000\000h\002\000\000\206\002\000\000\245\002\000\000\277\002\000\000\334\002" + "\000\0001\003\000\000V\003\000\000x\003\000\000\226\003\000\000\265\003\000\000\330\003\000\000\370\003\000\000\032" + "\004\000\0009\004\000\000T\004\000\000m\004\000\000\206\004\000\000\234\004\000\000\261\004\000\000\326\004\000\000<" + "\?xml version = \"1.0\" encoding = \"utf-8\"\?>\n\n \n \n 1 \n 0 \n \n " + " \n urn:schemas-upnp-org:device:MediaServer:1 \n " + " \n \n \n \n \n \n \n \n \n \n DMS-1.50 \n \n \n \n \n " + " \n \n \n " + "\n \n \n \n \n \n <" + "height>\n \n \n \n \n \n" + "\n"; + +// <%shared> +// + +// <%config> +// + +#define SET_LANG(lang) \ + do \ + { \ + request.setLang(lang); \ + reply.setLocale(request.getLocale()); \ + } while (false) + +_component_::_component_(const tnt::Compident& ci, const tnt::Urlmapper& um, tnt::Comploader& cl) + : EcppComponent(ci, um, cl) +{ + // <%init> + // +} + +_component_::~_component_() +{ + // <%cleanup> + // +} + +unsigned _component_::operator() (tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparam) +{ + log_trace("deviceDescription " << qparam.getUrl()); + + tnt::DataChunks data(rawData); + + // <%args> + // + + // <%cpp> + reply.out() << data[0]; // <\?xml version = "1.0" encoding = "utf-8"\?> + reply.out() << data[1]; // \n + reply.out() << data[2]; // \n +#line 20 "deviceDescription.ecpp" + + upnp::cMediaServer* server = cMediaServer::GetInstance(); + const upnp::cWebserver& webserver = server->GetWebserver(); + + const upnp::cMediaServer::Description& serverDescription = server->GetServerDescription(); + std::string deviceUUID = server->GetDeviceUUID(); + std::string presentationUrl = webserver.GetPresentationUrl(); + std::string staticContentUrl = webserver.GetStaticContentUrl(); + + std::string serviceUrl = webserver.GetServiceUrl(); + std::string controlUrl = webserver.GetControlUrl(); + + reply.setContentType("text/xml"); + + + reply.out() << data[3]; // \n \n 1 \n 0 \n \n \n urn:schemas-upnp-org:device:MediaServer:1 \n +#line 42 "deviceDescription.ecpp" + reply.sout() << ( serverDescription.friendlyName ); + reply.out() << data[4]; // \n +#line 43 "deviceDescription.ecpp" + reply.sout() << ( serverDescription.manufacturer ); + reply.out() << data[5]; // \n +#line 44 "deviceDescription.ecpp" + reply.sout() << ( serverDescription.manufacturerURL ); + reply.out() << data[6]; // \n +#line 45 "deviceDescription.ecpp" + reply.sout() << ( serverDescription.modelDescription ); + reply.out() << data[7]; // \n +#line 46 "deviceDescription.ecpp" + reply.sout() << ( serverDescription.modelName ); + reply.out() << data[8]; // \n +#line 47 "deviceDescription.ecpp" + reply.sout() << ( serverDescription.modelNumber ); + reply.out() << data[9]; // \n +#line 48 "deviceDescription.ecpp" + reply.sout() << ( serverDescription.modelURL ); + reply.out() << data[10]; // \n +#line 49 "deviceDescription.ecpp" + reply.sout() << ( serverDescription.serialNumber ); + reply.out() << data[11]; // \n +#line 50 "deviceDescription.ecpp" + reply.sout() << ( deviceUUID ); + reply.out() << data[12]; // \n +#line 51 "deviceDescription.ecpp" + reply.sout() << ( presentationUrl ); + reply.out() << data[13]; // \n DMS-1.50 \n \n +#line 54 "deviceDescription.ecpp" + + const cMediaServer::serviceMap& services = server->GetServices(); + + for(cMediaServer::serviceMap::const_iterator it = services.begin(); it != services.end(); ++it){ + const cUPnPService::Description& serviceDescription = (*it).second->GetServiceDescription(); + + reply.out() << data[14]; // \n +#line 61 "deviceDescription.ecpp" + reply.sout() << ( serviceDescription.serviceType ); + reply.out() << data[15]; // \n +#line 62 "deviceDescription.ecpp" + reply.sout() << ( serviceDescription.serviceID ); + reply.out() << data[16]; // \n +#line 63 "deviceDescription.ecpp" + reply.sout() << ( serviceUrl ); +#line 63 "deviceDescription.ecpp" + reply.sout() << ( serviceDescription.SCPDXML ); + reply.out() << data[17]; // \n +#line 64 "deviceDescription.ecpp" + reply.sout() << ( controlUrl ); +#line 64 "deviceDescription.ecpp" + reply.sout() << ( serviceDescription.controlDescriptor ); + reply.out() << data[18]; // \n +#line 65 "deviceDescription.ecpp" + reply.sout() << ( controlUrl ); +#line 65 "deviceDescription.ecpp" + reply.sout() << ( serviceDescription.eventSubscriberDescriptor ); + reply.out() << data[19]; // \n \n +#line 67 "deviceDescription.ecpp" + + }; + + reply.out() << data[20]; // \n \n +#line 72 "deviceDescription.ecpp" + + const cMediaServer::iconList& icons = server->GetServerIcons(); + + for(cMediaServer::iconList::const_iterator it = icons.begin(); it != icons.end(); ++it){ + + reply.out() << data[21]; // \n +#line 78 "deviceDescription.ecpp" + reply.sout() << ( (*it).profile.mime ); + reply.out() << data[22]; // \n +#line 79 "deviceDescription.ecpp" + reply.sout() << ( (*it).profile.width ); + reply.out() << data[23]; // \n +#line 80 "deviceDescription.ecpp" + reply.sout() << ( (*it).profile.height ); + reply.out() << data[24]; // \n +#line 81 "deviceDescription.ecpp" + reply.sout() << ( (int)(*it).profile.bitDepth ); + reply.out() << data[25]; // \n +#line 82 "deviceDescription.ecpp" + reply.sout() << ( staticContentUrl ); +#line 82 "deviceDescription.ecpp" + reply.sout() << ( (*it).filename ); + reply.out() << data[26]; // \n \n +#line 84 "deviceDescription.ecpp" + + }; + + reply.out() << data[27]; // \n \n\n + // <%/cpp> + return HTTP_OK; +} + +} // namespace diff -ruN httptnt.new/resourceStreamer.cpp httptnt/resourceStreamer.cpp --- 1/httptnt.new/resourceStreamer.cpp 1970-01-01 01:00:00.000000000 +0100 +++ 2/httptnt/resourceStreamer.cpp 2013-05-01 16:43:24.029505690 +0200 @@ -0,0 +1,191 @@ +//////////////////////////////////////////////////////////////////////// +// resourceStreamer.cpp +// generated with ecppc +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +log_define("component.resourceStreamer") + +// <%pre> +#line 5 "resourceStreamer.ecpp" + +#include +#include +#include +#include +#include "../include/tools.h" +#include "../include/media/mediaManager.h" +#include "../include/server.h" +#include "../include/media/requestCounter.h" + +using namespace upnp; + +// + +namespace +{ +class _component_ : public tnt::EcppComponent +{ + _component_& main() { return *this; } + + protected: + ~_component_(); + + public: + _component_(const tnt::Compident& ci, const tnt::Urlmapper& um, tnt::Comploader& cl); + + unsigned operator() (tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparam); +}; + +static tnt::ComponentFactoryImpl<_component_> Factory("resourceStreamer"); + +// <%shared> +// + +// <%config> +// + +#define SET_LANG(lang) \ + do \ + { \ + request.setLang(lang); \ + reply.setLocale(request.getLocale()); \ + } while (false) + +_component_::_component_(const tnt::Compident& ci, const tnt::Urlmapper& um, tnt::Comploader& cl) + : EcppComponent(ci, um, cl) +{ + // <%init> + // +} + +_component_::~_component_() +{ + // <%cleanup> + // +} + +unsigned _component_::operator() (tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparam) +{ + log_trace("resourceStreamer " << qparam.getUrl()); + + + // <%args> +std::string objectID = qparam.param("objectID"); +int resourceID = qparam.has("resourceID") ? tnt::stringToWithDefault(qparam.param("resourceID"), ( 0), reply.out().getloc()) : ( 0); + // + +#line 18 "resourceStreamer.ecpp" + typedef boost::shared_ptr streamer_type; + TNT_REQUEST_COMPONENT_VAR(streamer_type, streamer, "streamer", ()); // <%request> boost::shared_ptr streamer +#line 19 "resourceStreamer.ecpp" + typedef request_counter_t counter_type; + TNT_REQUEST_COMPONENT_VAR(counter_type, counter, "counter", ()); // <%request> request_counter_t counter + // <%cpp> +#line 21 "resourceStreamer.ecpp" + + _unused(counter); + + if(objectID.empty()){ + reply.out() << "Object ID missing"; + return HTTP_BAD_REQUEST; + } + + cMediaServer* server = cMediaServer::GetInstance(); + cMediaManager& manager = server->GetManager(); + streamer = boost::shared_ptr(manager.GetResourceStreamer(objectID, resourceID)); + + if(!streamer.get()){ + reply.out() << "Object ID not found or invalid"; + return HTTP_NOT_FOUND; + } + + int code = HTTP_OK; + string codeText = "OK"; + + reply.setContentType(streamer->GetContentType()); + reply.setHeader("friendlyName.dlna.org ", server->GetServerDescription().friendlyName); + reply.setHeader("contentFeatures.dlna.org ", streamer->GetContentFeatures()); + reply.setHeader("transferMode.dlna.org ", streamer->GetTransferMode(reply.getHeader("transferMode.dlna.org"))); + + size_t from = 0, to = 0, contentLength = streamer->GetContentLength(), length = contentLength; + bool hasRange = false; + + if(contentLength > 0){ + reply.setContentLengthHeader(contentLength); + if(streamer->Seekable()){ + reply.setHeader("Accept-Ranges ", "bytes"); + if(request.hasHeader("getAvailableSeekRange.dlna.org:")){ + std::stringstream availableRangeHeader; + availableRangeHeader << "1 bytes=0-" << contentLength; + reply.setHeader("availableSeekRange.dlna.org ", availableRangeHeader.str()); + } + } + + if(request.hasHeader("Range:")){ + std::string rangeRequest = request.getHeader("Range:"); + if(rangeRequest.find("bytes=",0) == 0){ + unsigned int minus = rangeRequest.find_first_of('-',6); + if(minus != std::string::npos){ + from = atol(rangeRequest.substr(6, minus - 6).c_str()); + to = atol(rangeRequest.substr(minus + 1).c_str()); + if(from){ + // If range is off the road, reset it to correct values. + if(from <= 0 || from > contentLength) from = 0; + if(to <= 0 || to > contentLength) to = contentLength; + length = to - from; + hasRange = true; + + std::stringstream contentRangeHeader; + contentRangeHeader << "bytes " << from << "-" << to << "/" << contentLength; + reply.setHeader("Content-Range ", contentRangeHeader.str()); + reply.setContentLengthHeader(length); + + } + } + } + } + } + + if(!request.isMethodHEAD()){ + if(!streamer->Open()){ + return HTTP_INTERNAL_SERVER_ERROR; + } + + if(hasRange && streamer->Seekable() && contentLength > 0){ + if(!streamer->Seek(from, SEEK_SET)){ + return HTTP_INTERNAL_SERVER_ERROR; + } + code = HTTP_PARTIAL_CONTENT; + codeText = "Partial Content"; + } + + reply.setDirectMode(code, codeText.c_str()); + + size_t bytesRead = 0; + char buffer[KB(16)]; + while ((bytesRead = streamer->Read(buffer, KB(16))) > 0 && length) { + if(!(reply.out().write(buffer, bytesRead))) break; + length -= bytesRead; + request.touch(); + } + } + + reply.out() << std::flush; + return code; + + // <%/cpp> + return HTTP_OK; +} + +} // namespace diff -ruN httptnt.new/x_mrr_scpd.cpp httptnt/x_mrr_scpd.cpp --- 1/httptnt.new/x_mrr_scpd.cpp 1970-01-01 01:00:00.000000000 +0100 +++ 2/httptnt/x_mrr_scpd.cpp 2013-05-01 16:43:29.553505885 +0200 @@ -0,0 +1,103 @@ +//////////////////////////////////////////////////////////////////////// +// x_mrr_scpd.cpp +// generated with ecppc +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +log_define("component.x_mrr_scpd") + +// <%pre> +// + +namespace +{ +class _component_ : public tnt::EcppComponent +{ + _component_& main() { return *this; } + + protected: + ~_component_(); + + public: + _component_(const tnt::Compident& ci, const tnt::Urlmapper& um, tnt::Comploader& cl); + + unsigned operator() (tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparam); +}; + +static tnt::ComponentFactoryImpl<_component_> Factory("x_mrr_scpd"); + +static const char* rawData = "\034\000\000\000F\000\000\000G\000\000\000H\000\000\000&\003\000\000x\004\000\000\322\005" + "\000\000<\?xml version = \"1.0\" encoding = \"utf-8\"\?>\n\n\n\n " + "\n 1\n 0\n \n \n \n IsAuthorized\n \n \n " + " DeviceID\n in\n A" + "_ARG_TYPE_DeviceID\n \n \n " + " Result\n out\n A_A" + "RG_TYPE_Result\n \n \n \n" + "\n \n \n \n A_ARG_TYPE" + "_DeviceID\n string\n \n \n A_ARG_TYPE_Result\n int\n " + "\n\n \n AuthorizationGrantedUpdateID\n ui4\n \n \n Autho" + "rizationDeniedUpdateID\n ui4\n \n \n"; + +// <%shared> +// + +// <%config> +// + +#define SET_LANG(lang) \ + do \ + { \ + request.setLang(lang); \ + reply.setLocale(request.getLocale()); \ + } while (false) + +_component_::_component_(const tnt::Compident& ci, const tnt::Urlmapper& um, tnt::Comploader& cl) + : EcppComponent(ci, um, cl) +{ + // <%init> + // +} + +_component_::~_component_() +{ + // <%cleanup> + // +} + +unsigned _component_::operator() (tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparam) +{ + log_trace("x_mrr_scpd " << qparam.getUrl()); + + tnt::DataChunks data(rawData); + + // <%args> + // + + // <%cpp> + reply.out() << data[0]; // <\?xml version = "1.0" encoding = "utf-8"\?> + reply.out() << data[1]; // \n + reply.out() << data[2]; // \n +#line 9 "x_mrr_scpd.ecpp" + reply.setContentType("text/xml"); + reply.out() << data[3]; // \n\n \n 1\n 0\n \n \n \n IsAuthorized\n \n \n DeviceID\n in\n A_ARG_TYPE_DeviceID\n \n \n Result\n out\n A_ARG_TYPE_Result\n \n \n \n + reply.out() << data[4]; // \n \n \n \n A_ARG_TYPE_DeviceID\n string\n \n \n A_ARG_TYPE_Result\n int\n \n + reply.out() << data[5]; // \n \n AuthorizationGrantedUpdateID\n ui4\n \n \n AuthorizationDeniedUpdateID\n ui4\n \n \n + // <%/cpp> + return HTTP_OK; +} + +} // namespace