Emacs/cc-ide: More robust function movement
[mediaserv.git] / Server / HTTPConnection.cc
1 // $Id$
2 //
3 // Copyright (C) 2006 
4
5 // Definition of non-inline non-template functions
6
7 //#include "HTTPConnection.hh"
8 //#include "HTTPConnection.ih"
9
10 // Custom includes
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <sstream>
15
16 #include <boost/lexical_cast.hpp>
17 #include <boost/algorithm/string.hpp>
18
19 #include "Utils/membind.hh"
20
21 #include "SimpleHTTPServer.hh"
22 #include "StreamConnection.hh"
23 #include "MimeTypes.hh"
24
25 //#include "HTTPConnection.mpp"
26 #define prefix_
27 ///////////////////////////////cc.p////////////////////////////////////////
28
29 prefix_ g0dil::mediaserv::HTTPConnection::HTTPConnection(ClientHandle client,
30                                                          SimpleHTTPServer & server,
31                                                          HTTPLogger & logger)
32     : client_(client), server_(server), logger_(logger), fileFd_(-1), bandwidth_(0)
33 {
34     senf::ReadHelper<ClientHandle>
35         ::dispatch(client_, MaxRequestSize, senf::ReadUntil("\r\n\r\n"),
36                    senf::membind(&HTTPConnection::handleRequest,this));
37 }
38
39 prefix_ g0dil::mediaserv::HTTPConnection::~HTTPConnection()
40 {
41 //     if (client_.valid()) 
42 //      client_.close();
43     if (fileFd_ != -1) 
44         ::close(fileFd_);
45 }
46
47 prefix_ void
48 g0dil::mediaserv::HTTPConnection::handleRequest(senf::ReadHelper<ClientHandle>::ptr helper)
49 {
50
51     try {
52         helper->throw_error();
53
54         request_.parseRequest(helper->handle(), helper->data());
55
56         boost::algorithm::split_iterator<std::string::const_iterator> 
57             i (request_.url(),boost::algorithm::first_finder("."));
58         boost::algorithm::split_iterator<std::string::const_iterator> i_end;
59         if (i == i_end || ++i == i_end) throw InvalidHTTPRequestException();
60         bandwidth_ = boost::lexical_cast<unsigned>(std::string(i->begin(),i->end()));
61         if (++i == i_end) throw InvalidHTTPRequestException();
62         std::string const & mimeType (MimeTypes::lookup(std::string(i->begin(), i->end())));
63         if (++i != i_end) throw InvalidHTTPRequestException();
64
65         fileFd_ = ::open(request_.url().c_str(),O_RDONLY);
66         if (fileFd_ < 0) throw senf::SystemException(errno);
67         struct ::stat s;
68         if (::fstat(fileFd_,&s) < 0) throw senf::SystemException(errno);
69         
70         std::ostringstream response;
71         response << request_.version() << (request_.version().empty() ? "" : " ") << "200 OK\r\n";
72         response << "Content-Type: " << mimeType << "\r\n";
73         response << "Content-Length: " << s.st_size << "\r\n\r\n";
74         
75         senf::WriteHelper<ClientHandle>
76             ::dispatch(client_, response.str(), 
77                        senf::membind(&HTTPConnection::startStream,this));
78
79     }
80     catch (std::exception const & ex) {
81         logger_.invalidRequest(ex.what());
82         server_.done(ptr(this));
83     }
84 }
85
86 prefix_ void
87 g0dil::mediaserv::HTTPConnection::startStream(senf::WriteHelper<ClientHandle>::ptr helper)
88 {
89     try {
90         helper->throw_error();
91         
92         connection_.reset(new StreamConnection(fileFd_, bandwidth_, client_, StreamBufferMSecs, 
93                                                boost::bind(&HTTPConnection::done,this)));
94         connection_->start();
95     }
96     catch (std::exception const & ex) {
97         logger_.failedRequest(request_, ex.what());
98         server_.done(ptr(this));
99     }
100 }
101
102 prefix_ void g0dil::mediaserv::HTTPConnection::done()
103 {
104     logger_.request(request_, connection_->bytesSent());
105     server_.done(ptr(this));
106 }
107
108 ///////////////////////////////cc.e////////////////////////////////////////
109 #undef prefix_
110 //#include "HTTPConnection.mpp"
111
112 \f
113 // Local Variables:
114 // mode: c++
115 // End: