annotate 3rdparty/vmime/tests/net/smtp/SMTPTransportTestUtils.hpp @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
rev   line source
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
ferencd@0 25 /** Accepts connection and fails on greeting.
ferencd@0 26 */
ferencd@0 27 class greetingErrorSMTPTestSocket : public lineBasedTestSocket
ferencd@0 28 {
ferencd@0 29 public:
ferencd@0 30
ferencd@0 31 void onConnected()
ferencd@0 32 {
ferencd@0 33 localSend("421 test.vmime.org Service not available, closing transmission channel\r\n");
ferencd@0 34 disconnect();
ferencd@0 35 }
ferencd@0 36
ferencd@0 37 void processCommand()
ferencd@0 38 {
ferencd@0 39 if (!haveMoreLines())
ferencd@0 40 return;
ferencd@0 41
ferencd@0 42 getNextLine();
ferencd@0 43
ferencd@0 44 localSend("502 Command not implemented\r\n");
ferencd@0 45 processCommand();
ferencd@0 46 }
ferencd@0 47 };
ferencd@0 48
ferencd@0 49
ferencd@0 50 /** SMTP test server 1.
ferencd@0 51 *
ferencd@0 52 * Test send().
ferencd@0 53 * Ensure MAIL and RCPT commands are sent correctly.
ferencd@0 54 */
ferencd@0 55 class MAILandRCPTSMTPTestSocket : public lineBasedTestSocket
ferencd@0 56 {
ferencd@0 57 public:
ferencd@0 58
ferencd@0 59 MAILandRCPTSMTPTestSocket()
ferencd@0 60 {
ferencd@0 61 m_recipients.insert("recipient1@test.vmime.org");
ferencd@0 62 m_recipients.insert("recipient2@test.vmime.org");
ferencd@0 63 m_recipients.insert("recipient3@test.vmime.org");
ferencd@0 64
ferencd@0 65 m_state = STATE_NOT_CONNECTED;
ferencd@0 66 m_ehloSent = m_heloSent = m_mailSent = m_rcptSent = m_dataSent = m_quitSent = false;
ferencd@0 67 }
ferencd@0 68
ferencd@0 69 ~MAILandRCPTSMTPTestSocket()
ferencd@0 70 {
ferencd@0 71 VASSERT("Client must send the DATA command", m_dataSent);
ferencd@0 72 VASSERT("Client must send the QUIT command", m_quitSent);
ferencd@0 73 }
ferencd@0 74
ferencd@0 75 void onConnected()
ferencd@0 76 {
ferencd@0 77 localSend("220 test.vmime.org Service ready\r\n");
ferencd@0 78 processCommand();
ferencd@0 79
ferencd@0 80 m_state = STATE_COMMAND;
ferencd@0 81 }
ferencd@0 82
ferencd@0 83 void processCommand()
ferencd@0 84 {
ferencd@0 85 if (!haveMoreLines())
ferencd@0 86 return;
ferencd@0 87
ferencd@0 88 vmime::string line = getNextLine();
ferencd@0 89 std::istringstream iss(line);
ferencd@0 90
ferencd@0 91 switch (m_state)
ferencd@0 92 {
ferencd@0 93 case STATE_NOT_CONNECTED:
ferencd@0 94
ferencd@0 95 localSend("451 Requested action aborted: invalid state\r\n");
ferencd@0 96 break;
ferencd@0 97
ferencd@0 98 case STATE_COMMAND:
ferencd@0 99 {
ferencd@0 100 std::string cmd;
ferencd@0 101 iss >> cmd;
ferencd@0 102
ferencd@0 103 if (cmd.empty())
ferencd@0 104 {
ferencd@0 105 localSend("500 Syntax error, command unrecognized\r\n");
ferencd@0 106 }
ferencd@0 107 else if (cmd == "EHLO")
ferencd@0 108 {
ferencd@0 109 localSend("502 Command not implemented\r\n");
ferencd@0 110
ferencd@0 111 m_ehloSent = true;
ferencd@0 112 }
ferencd@0 113 else if (cmd == "HELO")
ferencd@0 114 {
ferencd@0 115 VASSERT("Client must send the EHLO command before HELO", m_ehloSent);
ferencd@0 116
ferencd@0 117 localSend("250 OK\r\n");
ferencd@0 118
ferencd@0 119 m_heloSent = true;
ferencd@0 120 }
ferencd@0 121 else if (cmd == "MAIL")
ferencd@0 122 {
ferencd@0 123 VASSERT("Client must send the HELO command", m_heloSent);
ferencd@0 124 VASSERT("The MAIL command must be sent only one time", !m_mailSent);
ferencd@0 125
ferencd@0 126 VASSERT_EQ("MAIL", std::string("MAIL FROM:<expeditor@test.vmime.org>"), line);
ferencd@0 127
ferencd@0 128 localSend("250 OK\r\n");
ferencd@0 129
ferencd@0 130 m_mailSent = true;
ferencd@0 131 }
ferencd@0 132 else if (cmd == "RCPT")
ferencd@0 133 {
ferencd@0 134 const vmime::size_t lt = line.find('<');
ferencd@0 135 const vmime::size_t gt = line.find('>');
ferencd@0 136
ferencd@0 137 VASSERT("RCPT <", lt != vmime::string::npos);
ferencd@0 138 VASSERT("RCPT >", gt != vmime::string::npos);
ferencd@0 139 VASSERT("RCPT ><", gt >= lt);
ferencd@0 140
ferencd@0 141 const vmime::string recip = vmime::string
ferencd@0 142 (line.begin() + lt + 1, line.begin() + gt);
ferencd@0 143
ferencd@0 144 std::set <vmime::string>::iterator it =
ferencd@0 145 m_recipients.find(recip);
ferencd@0 146
ferencd@0 147 VASSERT(std::string("Recipient not found: '") + recip + "'",
ferencd@0 148 it != m_recipients.end());
ferencd@0 149
ferencd@0 150 m_recipients.erase(it);
ferencd@0 151
ferencd@0 152 localSend("250 OK, recipient accepted\r\n");
ferencd@0 153
ferencd@0 154 m_rcptSent = true;
ferencd@0 155 }
ferencd@0 156 else if (cmd == "DATA")
ferencd@0 157 {
ferencd@0 158 VASSERT("Client must send the MAIL command", m_mailSent);
ferencd@0 159 VASSERT("Client must send the RCPT command", m_rcptSent);
ferencd@0 160 VASSERT("All recipients", m_recipients.empty());
ferencd@0 161
ferencd@0 162 localSend("354 Ready to accept data; end with <CRLF>.<CRLF>\r\n");
ferencd@0 163
ferencd@0 164 m_state = STATE_DATA;
ferencd@0 165 m_msgData.clear();
ferencd@0 166
ferencd@0 167 m_dataSent = true;
ferencd@0 168 }
ferencd@0 169 else if (cmd == "NOOP")
ferencd@0 170 {
ferencd@0 171 localSend("250 Completed\r\n");
ferencd@0 172 }
ferencd@0 173 else if (cmd == "QUIT")
ferencd@0 174 {
ferencd@0 175 m_quitSent = true;
ferencd@0 176
ferencd@0 177 localSend("221 test.vmime.org Service closing transmission channel\r\n");
ferencd@0 178 }
ferencd@0 179 else
ferencd@0 180 {
ferencd@0 181 localSend("502 Command not implemented\r\n");
ferencd@0 182 }
ferencd@0 183
ferencd@0 184 break;
ferencd@0 185 }
ferencd@0 186 case STATE_DATA:
ferencd@0 187 {
ferencd@0 188 if (line == ".")
ferencd@0 189 {
ferencd@0 190 VASSERT_EQ("Data", "Message data\r\n", m_msgData);
ferencd@0 191
ferencd@0 192 localSend("250 Message accepted for delivery\r\n");
ferencd@0 193 m_state = STATE_COMMAND;
ferencd@0 194 }
ferencd@0 195 else
ferencd@0 196 {
ferencd@0 197 m_msgData += line + "\r\n";
ferencd@0 198 }
ferencd@0 199
ferencd@0 200 break;
ferencd@0 201 }
ferencd@0 202
ferencd@0 203 }
ferencd@0 204
ferencd@0 205 processCommand();
ferencd@0 206 }
ferencd@0 207
ferencd@0 208 private:
ferencd@0 209
ferencd@0 210 enum State
ferencd@0 211 {
ferencd@0 212 STATE_NOT_CONNECTED,
ferencd@0 213 STATE_COMMAND,
ferencd@0 214 STATE_DATA
ferencd@0 215 };
ferencd@0 216
ferencd@0 217 int m_state;
ferencd@0 218
ferencd@0 219 std::set <vmime::string> m_recipients;
ferencd@0 220
ferencd@0 221 std::string m_msgData;
ferencd@0 222
ferencd@0 223 bool m_ehloSent, m_heloSent, m_mailSent, m_rcptSent,
ferencd@0 224 m_dataSent, m_quitSent;
ferencd@0 225 };
ferencd@0 226
ferencd@0 227
ferencd@0 228
ferencd@0 229 /** SMTP test server 2.
ferencd@0 230 *
ferencd@0 231 * Test CHUNKING extension/BDAT command.
ferencd@0 232 */
ferencd@0 233 class chunkingSMTPTestSocket : public testSocket
ferencd@0 234 {
ferencd@0 235 public:
ferencd@0 236
ferencd@0 237 chunkingSMTPTestSocket()
ferencd@0 238 {
ferencd@0 239 m_state = STATE_NOT_CONNECTED;
ferencd@0 240 m_bdatChunkCount = 0;
ferencd@0 241 m_ehloSent = m_mailSent = m_rcptSent = m_quitSent = false;
ferencd@0 242 }
ferencd@0 243
ferencd@0 244 ~chunkingSMTPTestSocket()
ferencd@0 245 {
ferencd@0 246 VASSERT_EQ("BDAT chunk count", 3, m_bdatChunkCount);
ferencd@0 247 VASSERT("Client must send the QUIT command", m_quitSent);
ferencd@0 248 }
ferencd@0 249
ferencd@0 250 void onConnected()
ferencd@0 251 {
ferencd@0 252 localSend("220 test.vmime.org Service ready\r\n");
ferencd@0 253 processCommand();
ferencd@0 254
ferencd@0 255 m_state = STATE_COMMAND;
ferencd@0 256 }
ferencd@0 257
ferencd@0 258 void onDataReceived()
ferencd@0 259 {
ferencd@0 260 if (m_state == STATE_DATA)
ferencd@0 261 {
ferencd@0 262 if (m_bdatChunkReceived != m_bdatChunkSize)
ferencd@0 263 {
ferencd@0 264 const size_t remaining = m_bdatChunkSize - m_bdatChunkReceived;
ferencd@0 265 const size_t received = localReceiveRaw(NULL, remaining);
ferencd@0 266
ferencd@0 267 m_bdatChunkReceived += received;
ferencd@0 268 }
ferencd@0 269
ferencd@0 270 if (m_bdatChunkReceived == m_bdatChunkSize)
ferencd@0 271 {
ferencd@0 272 m_state = STATE_COMMAND;
ferencd@0 273 }
ferencd@0 274 }
ferencd@0 275
ferencd@0 276 processCommand();
ferencd@0 277 }
ferencd@0 278
ferencd@0 279 void processCommand()
ferencd@0 280 {
ferencd@0 281 vmime::string line;
ferencd@0 282
ferencd@0 283 if (!localReceiveLine(line))
ferencd@0 284 return;
ferencd@0 285
ferencd@0 286 std::istringstream iss(line);
ferencd@0 287
ferencd@0 288 switch (m_state)
ferencd@0 289 {
ferencd@0 290 case STATE_NOT_CONNECTED:
ferencd@0 291
ferencd@0 292 localSend("451 Requested action aborted: invalid state\r\n");
ferencd@0 293 break;
ferencd@0 294
ferencd@0 295 case STATE_COMMAND:
ferencd@0 296 {
ferencd@0 297 std::string cmd;
ferencd@0 298 iss >> cmd;
ferencd@0 299
ferencd@0 300 if (cmd == "EHLO")
ferencd@0 301 {
ferencd@0 302 localSend("250-test.vmime.org says hello\r\n");
ferencd@0 303 localSend("250 CHUNKING\r\n");
ferencd@0 304
ferencd@0 305 m_ehloSent = true;
ferencd@0 306 }
ferencd@0 307 else if (cmd == "HELO")
ferencd@0 308 {
ferencd@0 309 VASSERT("Client must not send the HELO command, as EHLO succeeded", false);
ferencd@0 310 }
ferencd@0 311 else if (cmd == "MAIL")
ferencd@0 312 {
ferencd@0 313 VASSERT("The MAIL command must be sent only one time", !m_mailSent);
ferencd@0 314
ferencd@0 315 localSend("250 OK\r\n");
ferencd@0 316
ferencd@0 317 m_mailSent = true;
ferencd@0 318 }
ferencd@0 319 else if (cmd == "RCPT")
ferencd@0 320 {
ferencd@0 321 localSend("250 OK, recipient accepted\r\n");
ferencd@0 322
ferencd@0 323 m_rcptSent = true;
ferencd@0 324 }
ferencd@0 325 else if (cmd == "DATA")
ferencd@0 326 {
ferencd@0 327 VASSERT("BDAT must be used here!", false);
ferencd@0 328 }
ferencd@0 329 else if (cmd == "BDAT")
ferencd@0 330 {
ferencd@0 331 VASSERT("Client must send the MAIL command", m_mailSent);
ferencd@0 332 VASSERT("Client must send the RCPT command", m_rcptSent);
ferencd@0 333
ferencd@0 334 unsigned long chunkSize = 0;
ferencd@0 335 iss >> chunkSize;
ferencd@0 336
ferencd@0 337 std::string last;
ferencd@0 338 iss >> last;
ferencd@0 339
ferencd@0 340 if (m_bdatChunkCount == 0)
ferencd@0 341 {
ferencd@0 342 VASSERT_EQ("BDAT chunk1 size", 262144, chunkSize);
ferencd@0 343 VASSERT_EQ("BDAT chunk1 last", "", last);
ferencd@0 344 }
ferencd@0 345 else if (m_bdatChunkCount == 1)
ferencd@0 346 {
ferencd@0 347 VASSERT_EQ("BDAT chunk2 size", 262144, chunkSize);
ferencd@0 348 VASSERT_EQ("BDAT chunk2 last", "", last);
ferencd@0 349 }
ferencd@0 350 else if (m_bdatChunkCount == 2)
ferencd@0 351 {
ferencd@0 352 VASSERT_EQ("BDAT chunk3 size", 4712, chunkSize);
ferencd@0 353 VASSERT_EQ("BDAT chunk3 last", "LAST", last);
ferencd@0 354 }
ferencd@0 355 else
ferencd@0 356 {
ferencd@0 357 VASSERT("No more BDAT command should be issued!", false);
ferencd@0 358 }
ferencd@0 359
ferencd@0 360 m_bdatChunkSize = chunkSize;
ferencd@0 361 m_bdatChunkReceived = 0;
ferencd@0 362 m_bdatChunkCount++;
ferencd@0 363 m_state = STATE_DATA;
ferencd@0 364
ferencd@0 365 localSend("250 chunk received\r\n");
ferencd@0 366 }
ferencd@0 367 else if (cmd == "NOOP")
ferencd@0 368 {
ferencd@0 369 localSend("250 Completed\r\n");
ferencd@0 370 }
ferencd@0 371 else if (cmd == "QUIT")
ferencd@0 372 {
ferencd@0 373 localSend("221 test.vmime.org Service closing transmission channel\r\n");
ferencd@0 374
ferencd@0 375 m_quitSent = true;
ferencd@0 376 }
ferencd@0 377 else
ferencd@0 378 {
ferencd@0 379 localSend("502 Command not implemented\r\n");
ferencd@0 380 }
ferencd@0 381
ferencd@0 382 break;
ferencd@0 383 }
ferencd@0 384
ferencd@0 385 }
ferencd@0 386
ferencd@0 387 processCommand();
ferencd@0 388 }
ferencd@0 389
ferencd@0 390 private:
ferencd@0 391
ferencd@0 392 enum State
ferencd@0 393 {
ferencd@0 394 STATE_NOT_CONNECTED,
ferencd@0 395 STATE_COMMAND,
ferencd@0 396 STATE_DATA
ferencd@0 397 };
ferencd@0 398
ferencd@0 399 int m_state;
ferencd@0 400 int m_bdatChunkCount;
ferencd@0 401 int m_bdatChunkSize, m_bdatChunkReceived;
ferencd@0 402
ferencd@0 403 bool m_ehloSent, m_mailSent, m_rcptSent, m_quitSent;
ferencd@0 404 };
ferencd@0 405
ferencd@0 406
ferencd@0 407 class SMTPTestMessage : public vmime::message
ferencd@0 408 {
ferencd@0 409 public:
ferencd@0 410
ferencd@0 411 vmime::size_t getChunkBufferSize() const
ferencd@0 412 {
ferencd@0 413 static vmime::net::smtp::SMTPChunkingOutputStreamAdapter chunkStream(vmime::null, 0, NULL);
ferencd@0 414 return chunkStream.getBlockSize();
ferencd@0 415 }
ferencd@0 416
ferencd@0 417 const std::vector <vmime::string>& getChunks() const
ferencd@0 418 {
ferencd@0 419 static std::vector <vmime::string> chunks;
ferencd@0 420
ferencd@0 421 if (chunks.size() == 0)
ferencd@0 422 {
ferencd@0 423 chunks.push_back(vmime::string(1000, 'A'));
ferencd@0 424 chunks.push_back(vmime::string(3000, 'B'));
ferencd@0 425 chunks.push_back(vmime::string(500000, 'C'));
ferencd@0 426 chunks.push_back(vmime::string(25000, 'D'));
ferencd@0 427 }
ferencd@0 428
ferencd@0 429 return chunks;
ferencd@0 430 }
ferencd@0 431
ferencd@0 432 void generateImpl
ferencd@0 433 (const vmime::generationContext& /* ctx */, vmime::utility::outputStream& outputStream,
ferencd@0 434 const size_t /* curLinePos */ = 0, size_t* /* newLinePos */ = NULL) const
ferencd@0 435 {
ferencd@0 436 for (unsigned int i = 0, n = getChunks().size() ; i < n ; ++i)
ferencd@0 437 {
ferencd@0 438 const vmime::string& chunk = getChunks()[i];
ferencd@0 439 outputStream.write(chunk.data(), chunk.size());
ferencd@0 440 }
ferencd@0 441 }
ferencd@0 442 };
ferencd@0 443
ferencd@0 444
ferencd@0 445
ferencd@0 446 /** SMTP test server 3.
ferencd@0 447 *
ferencd@0 448 * Test SIZE extension.
ferencd@0 449 */
ferencd@0 450 template <bool WITH_CHUNKING>
ferencd@0 451 class bigMessageSMTPTestSocket : public testSocket
ferencd@0 452 {
ferencd@0 453 public:
ferencd@0 454
ferencd@0 455 bigMessageSMTPTestSocket()
ferencd@0 456 {
ferencd@0 457 m_state = STATE_NOT_CONNECTED;
ferencd@0 458 m_ehloSent = m_mailSent = m_rcptSent = m_quitSent = false;
ferencd@0 459 }
ferencd@0 460
ferencd@0 461 ~bigMessageSMTPTestSocket()
ferencd@0 462 {
ferencd@0 463 VASSERT("Client must send the QUIT command", m_quitSent);
ferencd@0 464 }
ferencd@0 465
ferencd@0 466 void onConnected()
ferencd@0 467 {
ferencd@0 468 localSend("220 test.vmime.org Service ready\r\n");
ferencd@0 469 processCommand();
ferencd@0 470
ferencd@0 471 m_state = STATE_COMMAND;
ferencd@0 472 }
ferencd@0 473
ferencd@0 474 void onDataReceived()
ferencd@0 475 {
ferencd@0 476 processCommand();
ferencd@0 477 }
ferencd@0 478
ferencd@0 479 void processCommand()
ferencd@0 480 {
ferencd@0 481 vmime::string line;
ferencd@0 482
ferencd@0 483 if (!localReceiveLine(line))
ferencd@0 484 return;
ferencd@0 485
ferencd@0 486 std::istringstream iss(line);
ferencd@0 487
ferencd@0 488 switch (m_state)
ferencd@0 489 {
ferencd@0 490 case STATE_NOT_CONNECTED:
ferencd@0 491
ferencd@0 492 localSend("451 Requested action aborted: invalid state\r\n");
ferencd@0 493 break;
ferencd@0 494
ferencd@0 495 case STATE_COMMAND:
ferencd@0 496 {
ferencd@0 497 std::string cmd;
ferencd@0 498 iss >> cmd;
ferencd@0 499
ferencd@0 500 if (cmd == "EHLO")
ferencd@0 501 {
ferencd@0 502 localSend("250-test.vmime.org says hello\r\n");
ferencd@0 503
ferencd@0 504 if (WITH_CHUNKING)
ferencd@0 505 localSend("250-CHUNKING\r\n");
ferencd@0 506
ferencd@0 507 localSend("250 SIZE 1000000\r\n");
ferencd@0 508
ferencd@0 509 m_ehloSent = true;
ferencd@0 510 }
ferencd@0 511 else if (cmd == "HELO")
ferencd@0 512 {
ferencd@0 513 VASSERT("Client must not send the HELO command, as EHLO succeeded", false);
ferencd@0 514 }
ferencd@0 515 else if (cmd == "MAIL")
ferencd@0 516 {
ferencd@0 517 VASSERT("The MAIL command must be sent only one time", !m_mailSent);
ferencd@0 518
ferencd@0 519 std::string address;
ferencd@0 520 iss >> address;
ferencd@0 521
ferencd@0 522 VASSERT_EQ("MAIL/address", "FROM:<expeditor@test.vmime.org>", address);
ferencd@0 523
ferencd@0 524 std::string option;
ferencd@0 525 iss >> option;
ferencd@0 526
ferencd@0 527 VASSERT_EQ("MAIL/size", "SIZE=4194304", option);
ferencd@0 528
ferencd@0 529 localSend("552 Channel size limit exceeded\r\n");
ferencd@0 530
ferencd@0 531 m_mailSent = true;
ferencd@0 532 }
ferencd@0 533 else if (cmd == "NOOP")
ferencd@0 534 {
ferencd@0 535 localSend("250 Completed\r\n");
ferencd@0 536 }
ferencd@0 537 else if (cmd == "QUIT")
ferencd@0 538 {
ferencd@0 539 localSend("221 test.vmime.org Service closing transmission channel\r\n");
ferencd@0 540
ferencd@0 541 m_quitSent = true;
ferencd@0 542 }
ferencd@0 543 else
ferencd@0 544 {
ferencd@0 545 VASSERT("No other command should be sent", false);
ferencd@0 546
ferencd@0 547 localSend("502 Command not implemented\r\n");
ferencd@0 548 }
ferencd@0 549
ferencd@0 550 break;
ferencd@0 551 }
ferencd@0 552
ferencd@0 553 }
ferencd@0 554
ferencd@0 555 processCommand();
ferencd@0 556 }
ferencd@0 557
ferencd@0 558 private:
ferencd@0 559
ferencd@0 560 enum State
ferencd@0 561 {
ferencd@0 562 STATE_NOT_CONNECTED,
ferencd@0 563 STATE_COMMAND,
ferencd@0 564 STATE_DATA
ferencd@0 565 };
ferencd@0 566
ferencd@0 567 int m_state;
ferencd@0 568
ferencd@0 569 bool m_ehloSent, m_mailSent, m_rcptSent, m_quitSent;
ferencd@0 570 };
ferencd@0 571
ferencd@0 572
ferencd@0 573 template <unsigned long SIZE>
ferencd@0 574 class SMTPBigTestMessage : public vmime::message
ferencd@0 575 {
ferencd@0 576 public:
ferencd@0 577
ferencd@0 578 size_t getGeneratedSize(const vmime::generationContext& /* ctx */)
ferencd@0 579 {
ferencd@0 580 return SIZE;
ferencd@0 581 }
ferencd@0 582
ferencd@0 583 void generateImpl(const vmime::generationContext& /* ctx */,
ferencd@0 584 vmime::utility::outputStream& outputStream,
ferencd@0 585 const vmime::size_t /* curLinePos */ = 0,
ferencd@0 586 vmime::size_t* /* newLinePos */ = NULL) const
ferencd@0 587 {
ferencd@0 588 for (unsigned int i = 0, n = SIZE ; i < n ; ++i)
ferencd@0 589 outputStream.write("X", 1);
ferencd@0 590 }
ferencd@0 591 };
ferencd@0 592
ferencd@0 593 typedef SMTPBigTestMessage <4194304> SMTPBigTestMessage4MB;