fixed typo
[anytun.git] / Sockets / HttpBaseSocket.cpp
blob6f05b2eac6bd138f8abae68819cfde20662e0b1c
1 /**
2 ** \file AjpBaseSocket.cpp
3 ** \date 2007-10-05
4 ** \author grymse@alhem.net
5 **/
6 /*
7 Copyright (C) 2007 Anders Hedstrom
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #ifdef _MSC_VER
24 #pragma warning(disable:4786)
25 #endif
26 #include "HttpBaseSocket.h"
27 #include "IFile.h"
28 #include "Utility.h"
29 #include "HttpResponse.h"
31 #ifdef SOCKETS_NAMESPACE
32 namespace SOCKETS_NAMESPACE {
33 #endif
35 #ifdef _DEBUG
36 #define DEB(x) x
37 #else
38 #define DEB(x)
39 #endif
42 HttpBaseSocket::HttpBaseSocket(ISocketHandler& h)
43 :HTTPSocket(h)
44 ,m_res_file(NULL)
45 ,m_b_keepalive(false)
50 HttpBaseSocket::~HttpBaseSocket()
55 void HttpBaseSocket::OnFirst()
57 DEB(fprintf(stderr, " %s %s %s\n", GetMethod().c_str(), GetUri().c_str(), GetHttpVersion().c_str());)
58 m_req.SetHttpMethod( GetMethod() );
59 m_req.SetUri( GetUri() );
60 m_req.SetHttpVersion( GetHttpVersion() );
62 m_req.SetAttribute("query_string", GetQueryString() );
64 m_req.SetRemoteAddr( GetRemoteAddress() );
65 m_req.SetRemoteHost( "" ); // %!
66 m_req.SetServerName( GetSockAddress() );
67 m_req.SetServerPort( GetSockPort() );
71 void HttpBaseSocket::OnHeader(const std::string& key,const std::string& value)
73 DEB(fprintf(stderr, " (request)OnHeader %s: %s\n", key.c_str(), value.c_str());)
74 if (Utility::ToLower(key) == "cookie")
75 m_req.AddCookie(value);
76 else
77 m_req.SetHeader(key, value);
81 void HttpBaseSocket::OnHeaderComplete()
83 m_body_size_left = atol( m_req.Header("content-length").c_str() );
84 if (m_body_size_left > 0)
86 m_req.InitBody( m_body_size_left );
88 else
90 // execute
91 Execute();
96 void HttpBaseSocket::OnData(const char *buf,size_t sz)
98 m_req.Write( buf, sz );
99 m_body_size_left -= sz;
100 if (!m_body_size_left)
102 m_req.CloseBody();
104 // execute
105 Execute();
110 // --------------------------------------------------------------------------------------
111 void HttpBaseSocket::Execute()
113 // parse form data / query_string and cookie header if available
114 m_req.ParseBody();
116 // prepare page
117 OnExec( m_req );
119 DEB(printf(" *** http version: %s\n", m_req.HttpVersion().c_str());
120 printf(" *** connection: %s\n", m_req.Header("connection").c_str());)
121 if ( !(m_req.HttpVersion().size() > 4 && m_req.HttpVersion().substr(m_req.HttpVersion().size() - 4) == "/1.1") ||
122 m_req.Header("connection") == "close")
124 m_b_keepalive = false;
125 DEB(printf(" *** keepalive: false\n");)
127 else
129 m_b_keepalive = true;
130 DEB(printf(" *** keepalive: true\n");)
132 m_req.Reset();
133 Reset();
137 // --------------------------------------------------------------------------------------
138 void HttpBaseSocket::Respond(const HttpResponse& res)
140 // res.SetHeader("connection", "close");
142 SetHttpVersion( res.HttpVersion() );
143 SetStatus( Utility::l2string(res.HttpStatusCode()) );
144 SetStatusText( res.HttpStatusMsg() );
146 if (!ResponseHeaderIsSet("content-length"))
148 AddResponseHeader( "content-length", Utility::l2string( res.GetFile().size() ) );
150 for (std::map<std::string, std::string>::const_iterator it = res.Headers().begin(); it != res.Headers().end(); ++it)
152 AddResponseHeader( it -> first, it -> second );
154 std::list<std::string> vec = res.CookieNames();
155 for (std::list<std::string>::iterator it2 = vec.begin(); it2 != vec.end(); it2++)
157 AppendResponseHeader( "set-cookie", res.Cookie(*it2) );
159 SendResponse();
161 m_res_file = &res.GetFile();
163 OnTransferLimit();
167 // --------------------------------------------------------------------------------------
168 void HttpBaseSocket::OnTransferLimit()
170 char msg[32768];
171 size_t n = m_res_file -> fread(msg, 1, 32768);
172 while (n > 0)
174 SendBuf( msg, n );
175 if (GetOutputLength() > 1)
177 SetTransferLimit( 1 );
178 break;
180 n = m_res_file -> fread(msg, 1, 32768);
182 if (!GetOutputLength())
184 if (!m_b_keepalive)
186 SetCloseAndDelete();
192 // --------------------------------------------------------------------------------------
193 void HttpBaseSocket::Reset()
195 HTTPSocket::Reset();
196 m_body_size_left = 0;
200 #ifdef SOCKETS_NAMESPACE
201 } // namespace SOCKETS_NAMESPACE {
202 #endif