Finished version 0.1 of media server .. Jay !!!
[mediaserv.git] / Server / HTTPConnection.cc
diff --git a/Server/HTTPConnection.cc b/Server/HTTPConnection.cc
new file mode 100644 (file)
index 0000000..33a4e1c
--- /dev/null
@@ -0,0 +1,115 @@
+// $Id$
+//
+// Copyright (C) 2006 
+
+// Definition of non-inline non-template functions
+
+//#include "HTTPConnection.hh"
+//#include "HTTPConnection.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sstream>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include "Utils/membind.hh"
+
+#include "SimpleHTTPServer.hh"
+#include "StreamConnection.hh"
+#include "MimeTypes.hh"
+
+//#include "HTTPConnection.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ g0dil::mediaserv::HTTPConnection::HTTPConnection(ClientHandle client,
+                                                         SimpleHTTPServer & server,
+                                                         HTTPLogger & logger)
+    : client_(client), server_(server), logger_(logger), fileFd_(-1), bandwidth_(0)
+{
+    satcom::lib::ReadHelper<ClientHandle>
+       ::dispatch(client_, MaxRequestSize, satcom::lib::ReadUntil("\r\n\r\n"),
+                  satcom::lib::membind(&HTTPConnection::handleRequest,this));
+}
+
+prefix_ g0dil::mediaserv::HTTPConnection::~HTTPConnection()
+{
+//     if (client_.valid()) 
+//     client_.close();
+    if (fileFd_ != -1) 
+       ::close(fileFd_);
+}
+
+prefix_ void
+g0dil::mediaserv::HTTPConnection::handleRequest(satcom::lib::ReadHelper<ClientHandle>::ptr helper)
+{
+
+    try {
+       helper->throw_error();
+
+       request_.parseRequest(helper->handle(), helper->data());
+
+       boost::algorithm::split_iterator<std::string::const_iterator> 
+           i (request_.url(),boost::algorithm::first_finder("."));
+       boost::algorithm::split_iterator<std::string::const_iterator> i_end;
+       if (i == i_end || ++i == i_end) throw InvalidHTTPRequestException();
+       bandwidth_ = boost::lexical_cast<unsigned>(std::string(i->begin(),i->end()));
+       if (++i == i_end) throw InvalidHTTPRequestException();
+       std::string const & mimeType (MimeTypes::lookup(std::string(i->begin(), i->end())));
+       if (++i != i_end) throw InvalidHTTPRequestException();
+
+       fileFd_ = ::open(request_.url().c_str(),O_RDONLY);
+       if (fileFd_ < 0) throw satcom::lib::SystemException(errno);
+       struct ::stat s;
+       if (::fstat(fileFd_,&s) < 0) throw satcom::lib::SystemException(errno);
+       
+       std::ostringstream response;
+       response << request_.version() << (request_.version().empty() ? "" : " ") << "200 OK\r\n";
+       response << "Content-Type: " << mimeType << "\r\n";
+       response << "Content-Length: " << s.st_size << "\r\n\r\n";
+       
+       satcom::lib::WriteHelper<ClientHandle>
+           ::dispatch(client_, response.str(), 
+                      satcom::lib::membind(&HTTPConnection::startStream,this));
+
+    }
+    catch (std::exception const & ex) {
+       logger_.invalidRequest(ex.what());
+       server_.done(ptr(this));
+    }
+}
+
+prefix_ void
+g0dil::mediaserv::HTTPConnection::startStream(satcom::lib::WriteHelper<ClientHandle>::ptr helper)
+{
+    try {
+       helper->throw_error();
+       
+        connection_.reset(new StreamConnection(fileFd_, bandwidth_, client_, StreamBufferMSecs, 
+                                              boost::bind(&HTTPConnection::done,this)));
+       connection_->start();
+    }
+    catch (std::exception const & ex) {
+       logger_.failedRequest(request_, ex.what());
+       server_.done(ptr(this));
+    }
+}
+
+prefix_ void g0dil::mediaserv::HTTPConnection::done()
+{
+    logger_.request(request_, connection_->bytesSent());
+    server_.done(ptr(this));
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "HTTPConnection.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// End: