|
ferencd@0
|
1 //
|
|
ferencd@0
|
2 // VMime library (http://www.vmime.org)
|
|
ferencd@0
|
3 // Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
|
ferencd@0
|
4 //
|
|
ferencd@0
|
5 // This program is free software; you can redistribute it and/or
|
|
ferencd@0
|
6 // modify it under the terms of the GNU General Public License as
|
|
ferencd@0
|
7 // published by the Free Software Foundation; either version 3 of
|
|
ferencd@0
|
8 // the License, or (at your option) any later version.
|
|
ferencd@0
|
9 //
|
|
ferencd@0
|
10 // This program is distributed in the hope that it will be useful,
|
|
ferencd@0
|
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
ferencd@0
|
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
ferencd@0
|
13 // General Public License for more details.
|
|
ferencd@0
|
14 //
|
|
ferencd@0
|
15 // You should have received a copy of the GNU General Public License along
|
|
ferencd@0
|
16 // with this program; if not, write to the Free Software Foundation, Inc.,
|
|
ferencd@0
|
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
ferencd@0
|
18 //
|
|
ferencd@0
|
19 // Linking this library statically or dynamically with other modules is making
|
|
ferencd@0
|
20 // a combined work based on this library. Thus, the terms and conditions of
|
|
ferencd@0
|
21 // the GNU General Public License cover the whole combination.
|
|
ferencd@0
|
22 //
|
|
ferencd@0
|
23
|
|
ferencd@0
|
24 #include "testUtils.hpp"
|
|
ferencd@0
|
25
|
|
ferencd@0
|
26 #include "vmime/utility/stringUtils.hpp"
|
|
ferencd@0
|
27
|
|
ferencd@0
|
28 #include <cstring>
|
|
ferencd@0
|
29
|
|
ferencd@0
|
30
|
|
ferencd@0
|
31
|
|
ferencd@0
|
32 // testSocket
|
|
ferencd@0
|
33
|
|
ferencd@0
|
34 void testSocket::connect(const vmime::string& address, const vmime::port_t port)
|
|
ferencd@0
|
35 {
|
|
ferencd@0
|
36 m_address = address;
|
|
ferencd@0
|
37 m_port = port;
|
|
ferencd@0
|
38 m_connected = true;
|
|
ferencd@0
|
39
|
|
ferencd@0
|
40 onConnected();
|
|
ferencd@0
|
41 }
|
|
ferencd@0
|
42
|
|
ferencd@0
|
43
|
|
ferencd@0
|
44 void testSocket::disconnect()
|
|
ferencd@0
|
45 {
|
|
ferencd@0
|
46 m_address.clear();
|
|
ferencd@0
|
47 m_port = 0;
|
|
ferencd@0
|
48 m_connected = false;
|
|
ferencd@0
|
49 }
|
|
ferencd@0
|
50
|
|
ferencd@0
|
51
|
|
ferencd@0
|
52 bool testSocket::isConnected() const
|
|
ferencd@0
|
53 {
|
|
ferencd@0
|
54 return m_connected;
|
|
ferencd@0
|
55 }
|
|
ferencd@0
|
56
|
|
ferencd@0
|
57
|
|
ferencd@0
|
58 vmime::size_t testSocket::getBlockSize() const
|
|
ferencd@0
|
59 {
|
|
ferencd@0
|
60 return 16384;
|
|
ferencd@0
|
61 }
|
|
ferencd@0
|
62
|
|
ferencd@0
|
63
|
|
ferencd@0
|
64 unsigned int testSocket::getStatus() const
|
|
ferencd@0
|
65 {
|
|
ferencd@0
|
66 return 0;
|
|
ferencd@0
|
67 }
|
|
ferencd@0
|
68
|
|
ferencd@0
|
69
|
|
ferencd@0
|
70 const vmime::string testSocket::getPeerName() const
|
|
ferencd@0
|
71 {
|
|
ferencd@0
|
72 return "test.vmime.org";
|
|
ferencd@0
|
73 }
|
|
ferencd@0
|
74
|
|
ferencd@0
|
75
|
|
ferencd@0
|
76 const vmime::string testSocket::getPeerAddress() const
|
|
ferencd@0
|
77 {
|
|
ferencd@0
|
78 return "127.0.0.1";
|
|
ferencd@0
|
79 }
|
|
ferencd@0
|
80
|
|
ferencd@0
|
81
|
|
ferencd@0
|
82 vmime::shared_ptr <vmime::net::timeoutHandler> testSocket::getTimeoutHandler()
|
|
ferencd@0
|
83 {
|
|
ferencd@0
|
84 return vmime::null;
|
|
ferencd@0
|
85 }
|
|
ferencd@0
|
86
|
|
ferencd@0
|
87
|
|
ferencd@0
|
88 void testSocket::setTracer(vmime::shared_ptr <vmime::net::tracer> tracer)
|
|
ferencd@0
|
89 {
|
|
ferencd@0
|
90 }
|
|
ferencd@0
|
91
|
|
ferencd@0
|
92
|
|
ferencd@0
|
93 vmime::shared_ptr <vmime::net::tracer> testSocket::getTracer()
|
|
ferencd@0
|
94 {
|
|
ferencd@0
|
95 return vmime::null;
|
|
ferencd@0
|
96 }
|
|
ferencd@0
|
97
|
|
ferencd@0
|
98
|
|
ferencd@0
|
99 bool testSocket::waitForRead(const int msecs)
|
|
ferencd@0
|
100 {
|
|
ferencd@0
|
101 return true;
|
|
ferencd@0
|
102 }
|
|
ferencd@0
|
103
|
|
ferencd@0
|
104
|
|
ferencd@0
|
105 bool testSocket::waitForWrite(const int msecs)
|
|
ferencd@0
|
106 {
|
|
ferencd@0
|
107 return true;
|
|
ferencd@0
|
108 }
|
|
ferencd@0
|
109
|
|
ferencd@0
|
110
|
|
ferencd@0
|
111 void testSocket::receive(vmime::string& buffer)
|
|
ferencd@0
|
112 {
|
|
ferencd@0
|
113 buffer = m_inBuffer;
|
|
ferencd@0
|
114 m_inBuffer.clear();
|
|
ferencd@0
|
115 }
|
|
ferencd@0
|
116
|
|
ferencd@0
|
117
|
|
ferencd@0
|
118 void testSocket::send(const vmime::string& buffer)
|
|
ferencd@0
|
119 {
|
|
ferencd@0
|
120 m_outBuffer += buffer;
|
|
ferencd@0
|
121
|
|
ferencd@0
|
122 onDataReceived();
|
|
ferencd@0
|
123 }
|
|
ferencd@0
|
124
|
|
ferencd@0
|
125
|
|
ferencd@0
|
126 void testSocket::send(const char* str)
|
|
ferencd@0
|
127 {
|
|
ferencd@0
|
128 sendRaw(reinterpret_cast <const vmime::byte_t*>(str), strlen(str));
|
|
ferencd@0
|
129 }
|
|
ferencd@0
|
130
|
|
ferencd@0
|
131
|
|
ferencd@0
|
132 vmime::size_t testSocket::receiveRaw(vmime::byte_t* buffer, const size_t count)
|
|
ferencd@0
|
133 {
|
|
ferencd@0
|
134 const size_t n = std::min(count, static_cast <size_t>(m_inBuffer.size()));
|
|
ferencd@0
|
135
|
|
ferencd@0
|
136 std::copy(m_inBuffer.begin(), m_inBuffer.begin() + n, buffer);
|
|
ferencd@0
|
137 m_inBuffer.erase(m_inBuffer.begin(), m_inBuffer.begin() + n);
|
|
ferencd@0
|
138
|
|
ferencd@0
|
139 return n;
|
|
ferencd@0
|
140 }
|
|
ferencd@0
|
141
|
|
ferencd@0
|
142
|
|
ferencd@0
|
143 void testSocket::sendRaw(const vmime::byte_t* buffer, const size_t count)
|
|
ferencd@0
|
144 {
|
|
ferencd@0
|
145 send(vmime::utility::stringUtils::makeStringFromBytes(buffer, count));
|
|
ferencd@0
|
146 }
|
|
ferencd@0
|
147
|
|
ferencd@0
|
148
|
|
ferencd@0
|
149 vmime::size_t testSocket::sendRawNonBlocking(const vmime::byte_t* buffer, const size_t count)
|
|
ferencd@0
|
150 {
|
|
ferencd@0
|
151 sendRaw(buffer, count);
|
|
ferencd@0
|
152 return count;
|
|
ferencd@0
|
153 }
|
|
ferencd@0
|
154
|
|
ferencd@0
|
155
|
|
ferencd@0
|
156 void testSocket::localSend(const vmime::string& buffer)
|
|
ferencd@0
|
157 {
|
|
ferencd@0
|
158 m_inBuffer += buffer;
|
|
ferencd@0
|
159 }
|
|
ferencd@0
|
160
|
|
ferencd@0
|
161
|
|
ferencd@0
|
162 void testSocket::localReceive(vmime::string& buffer)
|
|
ferencd@0
|
163 {
|
|
ferencd@0
|
164 buffer = m_outBuffer;
|
|
ferencd@0
|
165 m_outBuffer.clear();
|
|
ferencd@0
|
166 }
|
|
ferencd@0
|
167
|
|
ferencd@0
|
168
|
|
ferencd@0
|
169 bool testSocket::localReceiveLine(vmime::string& line)
|
|
ferencd@0
|
170 {
|
|
ferencd@0
|
171 vmime::size_t eol;
|
|
ferencd@0
|
172
|
|
ferencd@0
|
173 if ((eol = m_outBuffer.find('\n')) != vmime::string::npos)
|
|
ferencd@0
|
174 {
|
|
ferencd@0
|
175 line = vmime::string(m_outBuffer.begin(), m_outBuffer.begin() + eol);
|
|
ferencd@0
|
176
|
|
ferencd@0
|
177 if (!line.empty() && line[line.length() - 1] == '\r')
|
|
ferencd@0
|
178 line.erase(line.end() - 1, line.end());
|
|
ferencd@0
|
179
|
|
ferencd@0
|
180 m_outBuffer.erase(m_outBuffer.begin(), m_outBuffer.begin() + eol + 1);
|
|
ferencd@0
|
181
|
|
ferencd@0
|
182 return true;
|
|
ferencd@0
|
183 }
|
|
ferencd@0
|
184
|
|
ferencd@0
|
185 return false;
|
|
ferencd@0
|
186 }
|
|
ferencd@0
|
187
|
|
ferencd@0
|
188
|
|
ferencd@0
|
189 vmime::size_t testSocket::localReceiveRaw(vmime::byte_t* buffer, const size_t count)
|
|
ferencd@0
|
190 {
|
|
ferencd@0
|
191 const size_t received = std::min(count, static_cast <size_t>(m_outBuffer.size()));
|
|
ferencd@0
|
192
|
|
ferencd@0
|
193 if (received != 0)
|
|
ferencd@0
|
194 {
|
|
ferencd@0
|
195 if (buffer != NULL)
|
|
ferencd@0
|
196 std::copy(m_outBuffer.begin(), m_outBuffer.begin() + received, buffer);
|
|
ferencd@0
|
197
|
|
ferencd@0
|
198 m_outBuffer.erase(m_outBuffer.begin(), m_outBuffer.begin() + received);
|
|
ferencd@0
|
199 }
|
|
ferencd@0
|
200
|
|
ferencd@0
|
201 return received;
|
|
ferencd@0
|
202 }
|
|
ferencd@0
|
203
|
|
ferencd@0
|
204
|
|
ferencd@0
|
205 void testSocket::onDataReceived()
|
|
ferencd@0
|
206 {
|
|
ferencd@0
|
207 // Override
|
|
ferencd@0
|
208 }
|
|
ferencd@0
|
209
|
|
ferencd@0
|
210
|
|
ferencd@0
|
211 void testSocket::onConnected()
|
|
ferencd@0
|
212 {
|
|
ferencd@0
|
213 // Override
|
|
ferencd@0
|
214 }
|
|
ferencd@0
|
215
|
|
ferencd@0
|
216
|
|
ferencd@0
|
217 // lineBasedTestSocket
|
|
ferencd@0
|
218
|
|
ferencd@0
|
219 void lineBasedTestSocket::onDataReceived()
|
|
ferencd@0
|
220 {
|
|
ferencd@0
|
221 vmime::string chunk;
|
|
ferencd@0
|
222 localReceive(chunk);
|
|
ferencd@0
|
223
|
|
ferencd@0
|
224 m_buffer += chunk;
|
|
ferencd@0
|
225
|
|
ferencd@0
|
226 vmime::size_t eol;
|
|
ferencd@0
|
227
|
|
ferencd@0
|
228 while ((eol = m_buffer.find('\n')) != vmime::string::npos)
|
|
ferencd@0
|
229 {
|
|
ferencd@0
|
230 vmime::string line(std::string(m_buffer.begin(), m_buffer.begin() + eol));
|
|
ferencd@0
|
231
|
|
ferencd@0
|
232 if (!line.empty() && line[line.length() - 1] == '\r')
|
|
ferencd@0
|
233 line.erase(line.end() - 1, line.end());
|
|
ferencd@0
|
234
|
|
ferencd@0
|
235 m_lines.push_back(line);
|
|
ferencd@0
|
236 m_buffer.erase(m_buffer.begin(), m_buffer.begin() + eol + 1);
|
|
ferencd@0
|
237 }
|
|
ferencd@0
|
238
|
|
ferencd@0
|
239 while (!m_lines.empty())
|
|
ferencd@0
|
240 processCommand();
|
|
ferencd@0
|
241 }
|
|
ferencd@0
|
242
|
|
ferencd@0
|
243
|
|
ferencd@0
|
244 const vmime::string lineBasedTestSocket::getNextLine()
|
|
ferencd@0
|
245 {
|
|
ferencd@0
|
246 const vmime::string line = m_lines.front();
|
|
ferencd@0
|
247 m_lines.erase(m_lines.begin(), m_lines.begin() + 1);
|
|
ferencd@0
|
248 return line;
|
|
ferencd@0
|
249 }
|
|
ferencd@0
|
250
|
|
ferencd@0
|
251 bool lineBasedTestSocket::haveMoreLines() const
|
|
ferencd@0
|
252 {
|
|
ferencd@0
|
253 return !m_lines.empty();
|
|
ferencd@0
|
254 }
|
|
ferencd@0
|
255
|
|
ferencd@0
|
256
|
|
ferencd@0
|
257 // testTimeoutHandler
|
|
ferencd@0
|
258
|
|
ferencd@0
|
259 testTimeoutHandler::testTimeoutHandler(const unsigned long delay)
|
|
ferencd@0
|
260 : m_delay(delay), m_start(0)
|
|
ferencd@0
|
261 {
|
|
ferencd@0
|
262 }
|
|
ferencd@0
|
263
|
|
ferencd@0
|
264
|
|
ferencd@0
|
265 bool testTimeoutHandler::isTimeOut()
|
|
ferencd@0
|
266 {
|
|
ferencd@0
|
267 return (vmime::platform::getHandler()->getUnixTime() - m_start) >= m_delay;
|
|
ferencd@0
|
268 }
|
|
ferencd@0
|
269
|
|
ferencd@0
|
270
|
|
ferencd@0
|
271 void testTimeoutHandler::resetTimeOut()
|
|
ferencd@0
|
272 {
|
|
ferencd@0
|
273 m_start = vmime::platform::getHandler()->getUnixTime();
|
|
ferencd@0
|
274 }
|
|
ferencd@0
|
275
|
|
ferencd@0
|
276
|
|
ferencd@0
|
277 bool testTimeoutHandler::handleTimeOut()
|
|
ferencd@0
|
278 {
|
|
ferencd@0
|
279 return false;
|
|
ferencd@0
|
280 }
|
|
ferencd@0
|
281
|
|
ferencd@0
|
282
|
|
ferencd@0
|
283 // testTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory
|
|
ferencd@0
|
284
|
|
ferencd@0
|
285 vmime::shared_ptr <vmime::net::timeoutHandler> testTimeoutHandlerFactory::create()
|
|
ferencd@0
|
286 {
|
|
ferencd@0
|
287 return vmime::make_shared <testTimeoutHandler>();
|
|
ferencd@0
|
288 }
|
|
ferencd@0
|
289
|
|
ferencd@0
|
290
|
|
ferencd@0
|
291
|
|
ferencd@0
|
292 // Exception helper
|
|
ferencd@0
|
293 std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
|
|
ferencd@0
|
294 {
|
|
ferencd@0
|
295 os << "* vmime::exceptions::" << e.name() << std::endl;
|
|
ferencd@0
|
296 os << " what = " << e.what() << std::endl;
|
|
ferencd@0
|
297
|
|
ferencd@0
|
298 // More information for special exceptions
|
|
ferencd@0
|
299 if (dynamic_cast <const vmime::exceptions::command_error*>(&e))
|
|
ferencd@0
|
300 {
|
|
ferencd@0
|
301 const vmime::exceptions::command_error& cee =
|
|
ferencd@0
|
302 dynamic_cast <const vmime::exceptions::command_error&>(e);
|
|
ferencd@0
|
303
|
|
ferencd@0
|
304 os << " command = " << cee.command() << std::endl;
|
|
ferencd@0
|
305 os << " response = " << cee.response() << std::endl;
|
|
ferencd@0
|
306 }
|
|
ferencd@0
|
307
|
|
ferencd@0
|
308 if (dynamic_cast <const vmime::exceptions::invalid_response*>(&e))
|
|
ferencd@0
|
309 {
|
|
ferencd@0
|
310 const vmime::exceptions::invalid_response& ir =
|
|
ferencd@0
|
311 dynamic_cast <const vmime::exceptions::invalid_response&>(e);
|
|
ferencd@0
|
312
|
|
ferencd@0
|
313 os << " response = " << ir.response() << std::endl;
|
|
ferencd@0
|
314 }
|
|
ferencd@0
|
315
|
|
ferencd@0
|
316 if (dynamic_cast <const vmime::exceptions::connection_greeting_error*>(&e))
|
|
ferencd@0
|
317 {
|
|
ferencd@0
|
318 const vmime::exceptions::connection_greeting_error& cgee =
|
|
ferencd@0
|
319 dynamic_cast <const vmime::exceptions::connection_greeting_error&>(e);
|
|
ferencd@0
|
320
|
|
ferencd@0
|
321 os << " response = " << cgee.response() << std::endl;
|
|
ferencd@0
|
322 }
|
|
ferencd@0
|
323
|
|
ferencd@0
|
324 if (dynamic_cast <const vmime::exceptions::authentication_error*>(&e))
|
|
ferencd@0
|
325 {
|
|
ferencd@0
|
326 const vmime::exceptions::authentication_error& aee =
|
|
ferencd@0
|
327 dynamic_cast <const vmime::exceptions::authentication_error&>(e);
|
|
ferencd@0
|
328
|
|
ferencd@0
|
329 os << " response = " << aee.response() << std::endl;
|
|
ferencd@0
|
330 }
|
|
ferencd@0
|
331
|
|
ferencd@0
|
332 if (dynamic_cast <const vmime::exceptions::filesystem_exception*>(&e))
|
|
ferencd@0
|
333 {
|
|
ferencd@0
|
334 const vmime::exceptions::filesystem_exception& fse =
|
|
ferencd@0
|
335 dynamic_cast <const vmime::exceptions::filesystem_exception&>(e);
|
|
ferencd@0
|
336
|
|
ferencd@0
|
337 os << " path = " << vmime::platform::getHandler()->
|
|
ferencd@0
|
338 getFileSystemFactory()->pathToString(fse.path()) << std::endl;
|
|
ferencd@0
|
339 }
|
|
ferencd@0
|
340
|
|
ferencd@0
|
341 if (e.other() != NULL)
|
|
ferencd@0
|
342 os << *e.other();
|
|
ferencd@0
|
343
|
|
ferencd@0
|
344 return os;
|
|
ferencd@0
|
345 }
|
|
ferencd@0
|
346
|
|
ferencd@0
|
347
|
|
ferencd@0
|
348 const vmime::string toHex(const vmime::string str)
|
|
ferencd@0
|
349 {
|
|
ferencd@0
|
350 static const char hexChars[] = "0123456789abcdef";
|
|
ferencd@0
|
351
|
|
ferencd@0
|
352 vmime::string res = "\n";
|
|
ferencd@0
|
353
|
|
ferencd@0
|
354 for (size_t i = 0 ; i < str.length() ; i += 16)
|
|
ferencd@0
|
355 {
|
|
ferencd@0
|
356 size_t r = std::min
|
|
ferencd@0
|
357 (static_cast <size_t>(16), str.length() - i);
|
|
ferencd@0
|
358
|
|
ferencd@0
|
359 vmime::string hex;
|
|
ferencd@0
|
360 vmime::string chr;
|
|
ferencd@0
|
361
|
|
ferencd@0
|
362 for (size_t j = 0 ; j < r ; ++j)
|
|
ferencd@0
|
363 {
|
|
ferencd@0
|
364 const unsigned char c = str[i + j];
|
|
ferencd@0
|
365
|
|
ferencd@0
|
366 hex += hexChars[c / 16];
|
|
ferencd@0
|
367 hex += hexChars[c % 16];
|
|
ferencd@0
|
368 hex += " ";
|
|
ferencd@0
|
369
|
|
ferencd@0
|
370 if (c >= 32 && c <= 127)
|
|
ferencd@0
|
371 chr += c;
|
|
ferencd@0
|
372 else
|
|
ferencd@0
|
373 chr += '.';
|
|
ferencd@0
|
374 }
|
|
ferencd@0
|
375
|
|
ferencd@0
|
376 for (size_t j = r ; j < 16 ; ++j)
|
|
ferencd@0
|
377 hex += " ";
|
|
ferencd@0
|
378
|
|
ferencd@0
|
379 res += hex + " " + chr + "\n";
|
|
ferencd@0
|
380 }
|
|
ferencd@0
|
381
|
|
ferencd@0
|
382 return res;
|
|
ferencd@0
|
383 }
|