fixed typo
[anytun.git] / Sockets / AjpBaseSocket.cpp
blob3b54dd00096712c544013d24e61cce45e82cc816
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 "AjpBaseSocket.h"
27 #include "ajp13.h"
29 #ifdef SOCKETS_NAMESPACE
30 namespace SOCKETS_NAMESPACE {
31 #endif
33 #ifdef _DEBUG
34 #define DEB(x) x
35 #else
36 #define DEB(x)
37 #endif
40 // ---------------------------------------------------------------------------
41 AjpBaseSocket::Initializer AjpBaseSocket::Init;
44 // ---------------------------------------------------------------------------
45 AjpBaseSocket::Initializer::Initializer()
48 Header[HTTP_REQUEST_ACCEPT] = "accept";
49 Header[HTTP_REQUEST_ACCEPT_CHARSET] = "accept-charset";
50 Header[HTTP_REQUEST_ACCEPT_ENCODING] = "accept-encoding";
51 Header[HTTP_REQUEST_ACCEPT_LANGUAGE] = "accept-language";
52 Header[HTTP_REQUEST_AUTHORIZATION] = "authorization";
53 Header[HTTP_REQUEST_CONNECTION] = "connection";
54 Header[HTTP_REQUEST_CONTENT_TYPE] = "content-type";
55 Header[HTTP_REQUEST_CONTENT_LENGTH] = "content-length";
56 Header[HTTP_REQUEST_COOKIE] = "cookie";
57 Header[HTTP_REQUEST_COOKIE2] = "cookie2";
58 Header[HTTP_REQUEST_HOST] = "host";
59 Header[HTTP_REQUEST_PRAGMA] = "pragma";
60 Header[HTTP_REQUEST_REFERER] = "referer";
61 Header[HTTP_REQUEST_USER_AGENT] = "user-agent";
63 Method[HTTP_METHOD_OPTIONS] = "OPTIONS";
64 Method[HTTP_METHOD_GET] = "GET";
65 Method[HTTP_METHOD_HEAD] = "HEAD";
66 Method[HTTP_METHOD_POST] = "POST";
67 Method[HTTP_METHOD_PUT] = "PUT";
68 Method[HTTP_METHOD_DELETE] = "DELETE";
69 Method[HTTP_METHOD_TRACE] = "TRACE";
70 Method[HTTP_METHOD_PROPFIND] = "PROPFIND";
71 Method[HTTP_METHOD_PROPPATCH] = "PROPPATCH";
72 Method[HTTP_METHOD_MKCOL] = "MKCOL";
73 Method[HTTP_METHOD_COPY] = "COPY";
74 Method[HTTP_METHOD_MOVE] = "MOVE";
75 Method[HTTP_METHOD_LOCK] = "LOCK";
76 Method[HTTP_METHOD_UNLOCK] = "UNLOCK";
77 Method[HTTP_METHOD_ACL] = "ACL";
78 Method[HTTP_METHOD_REPORT] = "REPORT";
79 Method[HTTP_METHOD_VERSION_CONTROL] = "VERSION_CONTROL"; // with a dash "VERSION-CONTROL"
80 Method[HTTP_METHOD_CHECKIN] = "CHECKIN";
81 Method[HTTP_METHOD_CHECKOUT] = "CHECKOUT";
82 Method[HTTP_METHOD_UNCHECKOUT] = "UNCHECKOUT";
83 Method[HTTP_METHOD_SEARCH] = "SEARCH";
84 Method[HTTP_METHOD_MKWORKSPACE] = "MKWORKSPACE";
85 Method[HTTP_METHOD_UPDATE] = "UPDATE";
86 Method[HTTP_METHOD_LABEL] = "LABEL";
87 Method[HTTP_METHOD_MERGE] = "MERGE";
88 Method[HTTP_METHOD_BASELINE_CONTROL] = "BASELINE_CONTROL";
89 Method[HTTP_METHOD_MKACTIVITY] = "MKACTIVITY";
91 Attribute[ATTR_CONTEXT] = "context";
92 Attribute[ATTR_SERVLET_PATH] = "servlet_path";
93 Attribute[ATTR_REMOTE_USER] = "remote_user";
94 Attribute[ATTR_AUTH_TYPE] = "auth_type";
95 Attribute[ATTR_QUERY_STRING] = "query_string";
96 Attribute[ATTR_ROUTE] = "route";
97 Attribute[ATTR_SSL_CERT] = "ssl_cert";
98 Attribute[ATTR_SSL_CIPHER] = "ssl_cipher";
99 Attribute[ATTR_SSL_SESSION] = "ssl_session";
100 Attribute[ATTR_SSL_KEY_SIZE] = "ssl_key_size";
101 Attribute[ATTR_SECRET] = "secret";
102 Attribute[ATTR_STORED_METHOD] = "stored_method";
104 ResponseHeader["content-type"] = 0xa001;
105 ResponseHeader["content-language"] = 0xa002;
106 ResponseHeader["content-length"] = 0xa003;
107 ResponseHeader["date"] = 0xa004;
108 ResponseHeader["last-modified"] = 0xa005;
109 ResponseHeader["location"] = 0xa006;
110 ResponseHeader["set-cookie"] = 0xa007;
111 ResponseHeader["set-cookie2"] = 0xa008;
112 ResponseHeader["servlet-engine"] = 0xa009;
113 ResponseHeader["status"] = 0xa00a;
114 ResponseHeader["www-authenticate"] = 0xa00b;
118 // ---------------------------------------------------------------------------
119 AjpBaseSocket::AjpBaseSocket(ISocketHandler& h) : TcpSocket(h)
120 , m_state(0)
121 , m_length(4)
122 , m_ptr(0)
127 // ---------------------------------------------------------------------------
128 void AjpBaseSocket::OnRawData(const char *buf, size_t sz)
130 DEB(fprintf(stderr, "OnRawData: %d bytes\n", sz);)
131 size_t ptr = 0;
132 while (true)
134 size_t left = sz - ptr;
135 DEB(fprintf(stderr, " left: %d bytes\n", left);
136 fprintf(stderr, " state: %d\n", m_state);)
137 switch (m_state)
139 case 0:
141 size_t missing = m_length - m_ptr;
142 short len = (short)(missing < left ? missing : left);
143 memcpy(m_message + m_ptr, buf + ptr, len);
144 m_ptr += len;
145 ptr += len;
146 if (m_ptr < m_length)
148 return; // read more
150 int p = 0;
151 short id = get_integer(m_message, p);
152 short length = get_integer(m_message, p);
153 OnHeader(id, length);
154 m_state = 1;
155 m_length = length;
156 m_ptr = 0; // bytes in m_message
158 break;
159 case 1:
161 size_t missing = m_length - m_ptr;
162 short len = (short)(missing < left ? missing : left);
163 memcpy(m_message + m_ptr, buf + ptr, len);
164 m_ptr += len;
165 ptr += len;
166 if (m_ptr < m_length)
168 return; // read more
170 OnPacket(m_message, m_ptr);
171 m_state = 0;
172 m_length = 4;
173 m_ptr = 0;
175 break;
181 // ---------------------------------------------------------------------------
182 unsigned char AjpBaseSocket::get_byte(const char *buf, int& ptr)
184 return (unsigned char)buf[ptr++];
188 // ---------------------------------------------------------------------------
189 bool AjpBaseSocket::get_boolean(const char *buf, int& ptr)
191 return ( (unsigned char)buf[ptr++] & 1) == 1 ? true : false;
195 // ---------------------------------------------------------------------------
196 short AjpBaseSocket::get_integer(const char *buf, int& ptr)
198 short n;
199 memcpy(&n, buf + ptr, 2);
200 ptr += 2;
201 return ntohs(n);
205 // ---------------------------------------------------------------------------
206 std::string AjpBaseSocket::get_string(const char *buf, int& ptr)
208 short len = get_integer(buf, ptr);
209 if (len != -1)
211 std::string tmp = buf + ptr;
212 ptr += len;
213 ptr++; // skip trailing 0x0
214 tmp.resize(len);
215 return tmp;
217 return "";
221 // ---------------------------------------------------------------------------
222 void AjpBaseSocket::put_byte(char *buf, int& ptr, unsigned char zz)
224 buf[ptr++] = zz;
228 // ---------------------------------------------------------------------------
229 void AjpBaseSocket::put_boolean(char *buf, int& ptr, bool zz)
231 buf[ptr++] = zz ? 1 : 0;
235 // ---------------------------------------------------------------------------
236 void AjpBaseSocket::put_integer(char *buf, int& ptr, short zz)
238 short tmp = htons(zz);
239 memcpy(buf + ptr, &tmp, 2);
240 ptr += 2;
244 // ---------------------------------------------------------------------------
245 void AjpBaseSocket::put_string(char *buf, int& ptr, const std::string& zz)
247 put_integer(buf, ptr, (short)zz.size() );
248 memcpy(buf + ptr, zz.c_str(), zz.size());
249 ptr += (int)zz.size();
250 put_byte(buf, ptr, 0);
254 #ifdef SOCKETS_NAMESPACE
255 } // namespace SOCKETS_NAMESPACE {
256 #endif