31b546c7763676888c59ef9354bef22b544ce3ea
[mediaserv.git] / Server / HTTPRequest.cc
1 // $Id$
2 //
3 // Copyright (C) 2006 
4
5 // Definition of non-inline non-template functions
6
7 #include "HTTPRequest.hh"
8 //#include "HTTPRequest.ih"
9
10 // Custom includes
11 #include <boost/algorithm/string.hpp>
12 #include <boost/range.hpp>
13 #include "Socket/ClientSocketHandle.hh"
14 #include "Socket/INetAddressing.hh"
15 #include "Socket/CommunicationPolicy.hh"
16
17 //#include "HTTPRequest.mpp"
18 #define prefix_
19 ///////////////////////////////cc.p////////////////////////////////////////
20
21 prefix_ g0dil::mediaserv::HTTPRequest::HTTPRequest()
22 {}
23
24 prefix_ g0dil::mediaserv::HTTPRequest::HTTPRequest(senf::FileHandle handle,
25                                                    std::string const & request)
26 {
27     parseRequest(handle,request);
28 }
29
30 prefix_ void g0dil::mediaserv::HTTPRequest::parseRequest(senf::FileHandle handle,
31                                                          std::string const & request)
32 {
33     typedef senf::ClientSocketHandle< senf::MakeSocketPolicy< 
34         senf::INet4AddressingPolicy,
35         senf::ConnectedCommunicationPolicy >::policy> IPHandle;
36     try {
37         host_ = senf::dynamic_socket_cast<IPHandle>(handle).peer().host();
38     }
39     catch (std::bad_cast const *) {
40         host_ = "(unidentified address)";
41     }
42     boost::algorithm::split_iterator<std::string::const_iterator> 
43         line (request, boost::algorithm::first_finder("\n"));
44     boost::algorithm::split_iterator<std::string::const_iterator> line_end;
45     if (line == line_end) return;
46     parseRequestURL(*line);
47     for (++line; line != line_end; ++line)
48         parseRequestHeader(*line);
49 }
50
51 prefix_ void g0dil::mediaserv::HTTPRequest::
52 parseRequestURL(boost::iterator_range<std::string::const_iterator> line)
53 {
54     boost::algorithm::split_iterator<std::string::const_iterator> 
55         token (line, boost::algorithm::first_finder(" "));
56     boost::algorithm::split_iterator<std::string::const_iterator> token_end;
57
58     if (token == token_end)
59         throw InvalidHTTPRequestException();
60     method_ = std::string(token->begin(),token->end());
61     if (method_ != "GET")
62         throw InvalidHTTPRequestException();
63     if (++token == token_end)
64         throw InvalidHTTPRequestException();
65     url_ = std::string(token->begin(),token->end());
66     if (++token == token_end)
67         return;
68     version_ = std::string(token->begin(),token->end());
69     boost::trim(version_);
70     if (! boost::starts_with(version_,"HTTP/"))
71         throw InvalidHTTPRequestException();
72     if (++token != token_end)
73         throw InvalidHTTPRequestException();
74 }
75
76 prefix_ void g0dil::mediaserv::HTTPRequest::
77 parseRequestHeader(boost::iterator_range<std::string::const_iterator> line)
78 {
79     boost::iterator_range<std::string::const_iterator> i (boost::find_first(line,":"));
80     if (i.empty())
81         throw InvalidHTTPRequestException();
82     std::string key (line.begin(),i.begin());
83     std::string value (i.end(),line.end());
84     boost::to_lower(key);
85     boost::trim(value);
86     headers_.insert(std::make_pair(key,value));
87 }
88
89 prefix_ std::string const & g0dil::mediaserv::HTTPRequest::operator[](std::string const & key)
90     const
91 {
92     static std::string empty;
93     Headers::const_iterator i (headers_.find(key));
94     if (i == headers_.end()) return empty;
95     return i->second;
96 }
97
98 ///////////////////////////////cc.e////////////////////////////////////////
99 #undef prefix_
100 //#include "HTTPRequest.mpp"
101
102 \f
103 // Local Variables:
104 // mode: c++
105 // End: