1 //
2 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 //   Free Software Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 
19 #ifdef HAVE_CONFIG_H
20 #include "gnashconfig.h"
21 #endif
22 
23 #ifdef HAVE_DEJAGNU_H
24 
25 #include <string>
26 
27 #include "GnashSystemIOHeaders.h"
28 #ifdef HAVE_GETOPT_H
29 # include <getopt.h>
30 #endif
31 
32 #ifndef __GNUC__
33 extern int optind, getopt(int, char *const *, const char *);
34 #endif
35 
36 #include <sys/types.h>
37 #include <iostream>
38 #include <string>
39 #include <vector>
40 #include <regex.h>
41 #include <ctime>            // std::time
42 
43 #include <boost/random/uniform_int.hpp>
44 #include <boost/random/mersenne_twister.hpp>
45 
46 #include "log.h"
47 #include "http.h"
48 #include "dejagnu.h"
49 #include "network.h"
50 #include "amf.h"
51 #include "buffer.h"
52 #include "GnashNumeric.h"
53 
54 using namespace gnash;
55 using namespace cygnal;
56 using namespace std;
57 
58 static void usage (void);
59 static void tests (void);
60 static void test_post (void);
61 // static void test_rtmpt (void);
62 
63 static TestState runtest;
64 
65 LogFile& dbglogfile = LogFile::getDefaultInstance();
66 
67 // Uncommenting this enables test cases that attempt to handle
68 // corrupted packets by randomly trashing data. These are not
69 // enabled by default, as they aren't valgrind clean by definition
70 // These tests primary function is to make sure HTTP, RTMPT, and
71 // AMF parsing is as stable as possible, and can handle some of the
72 // without crashing.
73 //#define CORRUPT_MEMORY_TESTS 1
74 
75 int
main(int argc,char * argv[])76 main(int argc, char *argv[])
77 {
78     int c;
79 
80     while ((c = getopt (argc, argv, "hdvsm:")) != -1) {
81         switch (c) {
82           case 'h':
83               usage ();
84               break;
85 
86           case 'v':
87               dbglogfile.setVerbosity();
88               break;
89 
90           default:
91               usage ();
92               break;
93         }
94     }
95 
96     tests();
97     test_post();
98 //    test_rtmpt();
99 }
100 
101 
102 void
tests()103 tests()
104 {
105     HTTP http;
106 
107     http.clearHeader();
108     http.formatDate();
109 //    cerr << "FIXME: " << http.getHeader() << endl;
110 
111 //     amf::Buffer &buf = http.getBuffer();
112 //     cerr << "STREAM: " << http.getHeader() << endl;
113 //     char *ptr = (char *)buf.reference();
114 //     cerr << "BUFFER: " << buf.reference() << endl;
115 
116     regex_t regex_pat;
117 
118     // Check the Date field
119     // The date should look something like this:
120     //     Date: Mon, 10 Dec 2007  GMT
121     //     Date: Tue, 1 Apr 2008 19:52:16 GMT\r\n
122     regcomp (&regex_pat, "Date: [A-Z][a-z]*, [0-9]* [A-Z][a-z]* [0-9]* [0-9:]* *GMT.*$",
123              REG_NOSUB|REG_NEWLINE);
124     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
125         runtest.fail ("HTTP::formatDate()");
126         cerr << http.getHeader() << endl;
127     } else {
128         runtest.pass ("HTTP::formatDate()");
129     }
130     regfree(&regex_pat);
131 
132     // Check the Content-Length field
133     // Content-Length: 12345\r\n"
134     http.clearHeader();
135     http.formatContentLength(12345);
136 
137 //    cerr << "FIXME: " << http.getHeader() << endl;
138     regcomp (&regex_pat, "Content-Length: [0-9]*.*$",
139              REG_NOSUB|REG_NEWLINE);
140     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
141         runtest.fail ("HTTP::formatContentLength()");
142     } else {
143         runtest.pass ("HTTP::formatContentLength()");
144     }
145     regfree(&regex_pat);
146 
147 
148     // Check the Connection field
149 //     bool formatConnection(const char *data);
150     http.clearHeader();
151     const char *data = "Keep-Alive";
152     http.formatConnection(data);
153 //    cerr << "FIXME: " << http.getHeader() << endl;
154     regcomp (&regex_pat, "Connection: [A-Za-z-]*",
155              REG_NOSUB|REG_NEWLINE);
156     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
157         runtest.fail ("HTTP::formatConnection()");
158     } else {
159         runtest.pass ("HTTP::formatConnection()");
160     }
161     regfree(&regex_pat);
162 
163     // Check the Server field
164     http.clearHeader();
165     http.formatServer();
166 //    cerr << "FIXME: " << http.getHeader() << endl;
167     regcomp (&regex_pat, "Server: Cygnal (GNU/Linux).*$",
168              REG_NOSUB|REG_NEWLINE);
169     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
170         runtest.fail ("HTTP::formatServer()");
171     } else {
172         runtest.pass ("HTTP::formatServer()");
173     }
174     regfree(&regex_pat);
175 
176     // Check the Host field
177 //     bool formatHost(const char *data);
178     http.clearHeader();
179     data = "localhost:4080";
180     http.formatHost(data);
181 //    cerr << "FIXME: " << http.getHeader() << endl;
182     regcomp (&regex_pat, "Host: [A-Za-z-]*:[0-9]*.*$",
183              REG_NOSUB|REG_NEWLINE);
184     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
185         runtest.fail ("HTTP::formatHost()");
186     } else {
187         runtest.pass ("HTTP::formatHost()");
188     }
189     regfree(&regex_pat);
190 
191 // Check the Language field
192 //     bool formatLanguage(const char *data);
193     http.clearHeader();
194     data = "en-US,en;q=0.9";
195     http.formatLanguage(data);
196 //    cerr << "FIXME: " << http.getHeader() << endl;
197     regcomp (&regex_pat, "Accept-Language: en-US,en;q=0.9.*$",
198              REG_NOSUB|REG_NEWLINE);
199     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
200         runtest.fail ("HTTP::formatLanguage()");
201     } else {
202         runtest.pass ("HTTP::formatLanguage()");
203     }
204     regfree(&regex_pat);
205 
206 //     bool formatCharset(const char *data);
207 // Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r
208     http.clearHeader();
209     data = "iso-8859-1, utf-8, utf-16, *;q=0.1";
210     http.formatCharset(data);
211 //    cerr << "FIXME: " << http.getHeader() << endl;
212     regcomp (&regex_pat, "Accept-Charset: iso-8859-1.*$",
213              REG_NOSUB|REG_NEWLINE);
214     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
215         runtest.fail ("HTTP::formatCharset()");
216     } else {
217         runtest.pass ("HTTP::formatCharset()");
218     }
219     regfree(&regex_pat);
220 
221 //     bool formatEncoding(const char *data);
222     http.clearHeader();
223     data = "deflate, gzip, x-gzip, identity, *;q=0";
224     http.formatEncoding(data);
225 //    cerr << "FIXME: " << http.getHeader() << endl;
226     regcomp (&regex_pat, "Accept-Encoding: deflate, gzip.*$",
227              REG_NOSUB|REG_NEWLINE);
228     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
229         runtest.fail ("HTTP::formatEncoding()");
230     } else {
231         runtest.pass ("HTTP::formatEncoding()");
232     }
233     regfree(&regex_pat);
234 
235 
236 //     bool formatTE(const char *data);
237     http.clearHeader();
238     data = "deflate, gzip, chunked, identity, trailers";
239     http.formatTE(data);
240 //    cerr << "FIXME: " << http.getHeader() << endl;
241     regcomp (&regex_pat, "TE: deflate, gzip,.*$",
242              REG_NOSUB|REG_NEWLINE);
243     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
244         runtest.fail ("HTTP::formatTE()");
245     } else {
246         runtest.pass ("HTTP::formatTE()");
247     }
248     regfree(&regex_pat);
249 
250 //     bool formatAgent(const char *data);
251     http.clearHeader();
252     data = "Gnash 0.8.1-cvs (X11; Linux i686; U; en)";
253     http.formatAgent(data);
254 //    cerr << "FIXME: " << http.getHeader() << endl;
255     regcomp (&regex_pat, "User-Agent: Gnash 0.8.1-cvs.*$",
256              REG_NOSUB|REG_NEWLINE);
257     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
258         runtest.fail ("HTTP::formatAgent()");
259     } else {
260         runtest.pass ("HTTP::formatAgent()");
261     }
262     regfree(&regex_pat);
263 
264     // Check the Content Type field. First we check with a
265     // specified field, then next to see if the default works.
266 //     bool formatContentType();
267     http.clearHeader();
268     http.formatContentType(DiskStream::FILETYPE_SWF);
269 //    cerr << "FIXME: " << http.getHeader() << endl;
270     regcomp (&regex_pat, "Content-Type: application/x-shockwave-flash.*$",
271              REG_NOSUB|REG_NEWLINE);
272     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
273         runtest.fail ("HTTP::formatContentType(type)");
274     } else {
275         runtest.pass ("HTTP::formatContentType(type)");
276     }
277     regfree(&regex_pat);
278 
279     http.clearHeader();
280     http.formatContentType();
281 //    cerr << "FIXME: " << http.getHeader() << endl;
282     regcomp (&regex_pat, "Content-Type: text/html.*$",
283              REG_NOSUB|REG_NEWLINE);
284     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
285         runtest.fail ("HTTP::formatContentType()");
286     } else {
287         runtest.pass ("HTTP::formatContenType()");
288     }
289     regfree(&regex_pat);
290 
291 //     bool formatReferer(const char *data);
292     http.clearHeader();
293     data = "http://localhost/software/gnash/tests/index.html";
294     http.formatReferer(data);
295 //    cerr << "FIXME: " << http.getHeader() << endl;
296     regcomp (&regex_pat, "Referer: http://localhost.*index.html.*$",
297              REG_NOSUB|REG_NEWLINE);
298     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
299         runtest.fail ("HTTP::formatReferer()");
300     } else {
301         runtest.pass ("HTTP::formatReferer()");
302     }
303     regfree(&regex_pat);
304 
305     // Check formatHeader()
306     // HTTP/1.1 200 OK\r\nDate: Tue, 1 Apr 2008 19:58:40 GMT\r\nServer: Cygnal (GNU/Linux)\r\nLast-Modified: Tue, 1 Apr 2008 19:58:40 GMT\r\nEtag: 24103b9-1c54-ec8632c0\r\nAccept-Ranges: bytes\r\nContent-Length: 0\r\nKeep
307     http.clearHeader();
308     http.formatHeader(HTTP::OK);
309 //    cerr << "FIXME: " << http.getHeader() << endl;
310     regcomp (&regex_pat, "HTTP/[0-9].[0-9] 200 OK.*Date:.*Server:.*:.*-Length.*-Type:.*$",
311              REG_NOSUB);        // note that we do want to look for NL
312     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
313         runtest.fail ("HTTP::formatHeader(port)");
314     } else {
315         runtest.pass ("HTTP::formatheader(port)");
316     }
317     regfree(&regex_pat);
318 
319 #if 0
320     // FIXME: should be moved to server side only test case
321     // Check the Server field
322     http.clearHeader();
323     HTTPServer https;
324     https.formatErrorResponse(HTTP::NOT_FOUND);
325 //    cerr << "FIXME: " << http.getHeader() << endl;
326 //    cerr << "FIXME: " << http.getBody() << endl;
327     regcomp (&regex_pat, "Date:.*Server:.*Content-Length:.*Connection:.*Content-Type:.*$",
328              REG_NOSUB);        // note that we do want to look for NL
329     if (regexec (&regex_pat, reinterpret_cast<const char*>(http.getHeader()), 0, (regmatch_t *)0, 0)) {
330         runtest.fail ("HTTP::formatErrorResponse(header)");
331     } else {
332         runtest.pass ("HTTP::formatErrorResponse(header)");
333     }
334     regfree(&regex_pat);
335 #endif
336 
337 # if 0
338     regfree(&regex_pat);
339     regcomp (&regex_pat, "DOCTYPE.*<title>404 Not Found</title>.*$",
340              REG_NOSUB);        // note that we do want to look for NL
341     if (regexec (&regex_pat, http.getBody().c_str(), 0, (regmatch_t *)0, 0)) {
342         runtest.fail ("HTTP::formatErrorResponse(body)");
343     } else {
344         runtest.pass ("HTTP::formatErrorResponse(body)");
345     }
346     regfree(&regex_pat);
347 #endif
348 
349     //
350     // Decoding tests for HTTP
351     //
352     http.clearHeader();
353 #if 0
354     std::uint8_t *buffer = (std::uint8_t *)"GET /software/gnash/tests/flvplayer.swf?file=http://localhost/software/gnash/tests/Ouray_Ice_Festival_Climbing_Competition.flv HTTP/1.1\r\n"
355 "User-Agent: Gnash/0.8.1-cvs (X11; Linux i686; U; en)\r\n"
356 "Host: localhost:4080\r\n"
357 "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1\r\n"
358 "Accept-Language: en-US,en;q=0.9\r\n"
359 "Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n"
360 "Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0\r\n"
361 "If-Modified-Since: Mon, 10 Dec 2007 02:26:31 GMT\r\n"
362 "If-None-Match: \"4cc434-e266-52ff63c0\"\r\n"
363 "Connection: Keep-Alive, TE\r\n"
364 "Referer: http://localhost/software/gnash/tests/index.html\r\n"
365 "TE: deflate, gzip, chunked, identity, trailers\r\n"
366 "\r\n";
367 #endif
368 
369 // GET /software/gnash/tests/ HTTP/1.1
370 // Host: localhost:4080
371 // User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.5) Gecko/20070718 Fedora/2.0.0.5-1.fc7 Firefox/2.0.0.5
372 // Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
373 // Accept-Language: en-us,en;q=0.5
374 // Accept-Encoding: gzip,deflate
375 // Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
376 // Keep-Alive: 300
377 // Connection: keep-alive
378 
379 // User Agent: Lynx/2.8.6rel.2 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/0.9.8b
380 
381 
382 #if 0
383     // FIXME: should be moved to server side only test case
384     // Check the Server field
385     Buffer field1;
386     field1 = "GET /index.html HTTP/1.1";
387     //    std::uint8_t *field1 = (std::uint8_t *)"GET /index.html HTTP/1.1";
388     HTTP http1;
389     //    http1.extractCommand(field1);
390     http1.extractCommand(field1);
391     if ((http1.getVersion()->minor == 1) && (http1.getFilespec() == "/index.html")) {
392         runtest.pass ("HTTP::extractCommand(HTTP/1.1)");
393     } else {
394         runtest.fail ("HTTP::extractCommand(HTTP/1.1)");
395     }
396 
397     Buffer field2;
398     field2 = "GET /index.html HTTP/1.0";
399     HTTP http2;
400     http2.extractCommand(field2);
401     if ((http2.getVersion()->minor == 0) && (http2.getFilespec() == "/index.html")) {
402         runtest.pass ("HTTP::extractCommand(HTTP/1.0)");
403     } else {
404         runtest.fail ("HTTP::extractCommand(HTTP/1.0)");
405     }
406 
407     Buffer field3;
408     field3 = "GET /software/gnash/tests/flvplayer.swf?file=http://localhost/software/gnash/tests/Ouray_Ice_Festival_Climbing_Competition.flv HTTP/1.1\r\n";
409     HTTP http3;
410     http3.extractCommand(field3);
411     if (http3.getFilespec() == "/software/gnash/tests/flvplayer.swf") {
412         runtest.pass ("HTTP::extractCommand(filespec)");
413     } else {
414         runtest.fail ("HTTP::extractCommand(params)");
415     }
416     if (http3.getParams() == "file=http://localhost/software/gnash/tests/Ouray_Ice_Festival_Climbing_Competition.flv") {
417         runtest.pass ("HTTP::extractCommand(params)");
418     } else {
419         runtest.fail ("HTTP::extractCommand(params)");
420     }
421 #endif
422 
423 #if 0
424     std::uint8_t *field3 = (std::uint8_t *) "Keep-Alive: 300";
425     HTTP http3;
426     http3.extractKeepAlive(field3);
427     if ((http3.keepAlive() == true) && (http3.getMaxRequests() == 300)) {
428         runtest.pass ("HTTP::extractKeepAlive(300)");
429     } else {
430         runtest.fail ("HTTP::extractKeepAlive(300)");
431     }
432 
433     std::uint8_t *field4 = (std::uint8_t *) "Keep-Alive: On";
434     HTTP http4;
435     http4.extractKeepAlive(field4);
436     if (http4.keepAlive() == true) {
437         runtest.pass ("HTTP::extractKeepAlive(On)");
438     } else {
439         runtest.fail ("HTTP::extractKeepAlive(On)");
440     }
441 
442     std::uint8_t *field5 = (std::uint8_t *) "Keep-Alive: Off";
443     HTTP http5;
444     http5.extractKeepAlive(field5);
445     if (http5.keepAlive() == false) {
446         runtest.pass ("HTTP::extractKeepAlive(Off)");
447     } else {
448         runtest.fail ("HTTP::extractKeepAlive(Off)");
449     }
450 
451 // Some browsers have a different synatax, of course, to keep things
452 // interesting.
453     std::uint8_t *buffer2 = (std::uint8_t *)"GET /software/gnash/tests/flvplayer.swf?file=http://localhost/software/gnash/tests/Ouray_Ice_Festival_Climbing_Competition.flv HTTP/1.1\r\n)"
454 "Content-Language: en-US,en;q=0.9\r\n"
455 "Content-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n"
456 "Content-Encoding: deflate, gzip, x-gzip, identity, *;q=0\r\n";
457 //    http.extractCommand(buffer);
458     string result;
459     result = http.extractReferer(buffer);
460     if (result == "http://localhost/software/gnash/tests/index.html") {
461         runtest.fail ("HTTP::extractReferer()");
462     } else {
463         runtest.pass ("HTTP::extractReferer()");
464     }
465     result = http.extractHost(buffer);
466     if (result == "localhost:4080") {
467         runtest.fail ("HTTP::extractHost()");
468     } else {
469         runtest.pass ("HTTP::extractHost()");
470     }
471 
472     result = http.extractAgent(buffer);
473     if (result == "Gnash/0.8.1-cvs (X11; Linux i686; U; en)") {
474         runtest.fail ("HTTP::extractAgent()");
475     } else {
476         runtest.pass ("HTTP::extractAgent()");
477     }
478 
479     int count;
480     count = http.extractLanguage(buffer);
481     std::vector<std::string> language = http.getLanguage();
482     if ((count > 2) &&
483         (language[0] == "en-US") &&
484         (language[1] == "en")) {
485         runtest.fail ("HTTP::extractLanguage(Accept-)");
486     } else {
487         runtest.pass ("HTTP::extractLanguage(Accept-)");
488     }
489     count = http.extractLanguage(buffer2);
490     language = http.getLanguage();
491 
492     if ((count == 2) &&
493         (language[0] == "en-US") &&
494         (language[1] == "en")) {
495         runtest.fail ("HTTP::extractLanguage(Content-)");
496     } else {
497         runtest.pass ("HTTP::extractLanguage(Content-)");
498     }
499 
500     count = http.extractCharset(buffer);
501     std::vector<std::string> charsets = http.getCharset();
502 
503     if ((count == 3) &&
504         (charsets[0] == "iso-8859-1") &&
505         (charsets[1] == "utf-8") &&
506         (charsets[2] == "utf-16")) {
507         runtest.fail ("HTTP::extractCharset(Accept-)");
508     } else {
509         runtest.pass ("HTTP::extractCharset(Accept-)");
510     }
511     count = http.extractCharset(buffer2);
512     charsets = http.getCharset();
513     if ((count == 3) &&
514         (charsets[0] == "iso-8859-1") &&
515         (charsets[1] == "utf-8") &&
516         (charsets[2] == "utf-16")) {
517         runtest.fail ("HTTP::extractCharset(Content-)");
518     } else {
519         runtest.pass ("HTTP::extractCharset(Content-)");
520     }
521 
522     count = http.extractConnection(buffer);
523     std::vector<std::string> connections = http.getConnection();
524     if ((count == 2) &&
525         (connections[0] == "Keep-Alive") &&
526         (connections[1] == "TE")) {
527         runtest.pass ("HTTP::extractConnection()");
528     } else {
529         runtest.fail ("HTTP::extractConnection()");
530     }
531 
532     count = http.extractEncoding(buffer);
533     std::vector<std::string> encoding = http.getEncoding();
534     if ((count == 4) &&
535         (encoding[0] == "deflate") &&
536         (encoding[1] == "gzip") &&
537         (encoding[2] == "chunked") &&
538         (encoding[3] == "identity")) {
539         runtest.fail ("HTTP::extractEncoding(Accept-)");
540     } else{
541         runtest.pass ("HTTP::extractEncoding(Accept-)");
542     }
543 
544     count = http.extractTE(buffer);
545     std::vector<std::string> te = http.getTE();
546     if ((count == 5) &&
547         (te[0] == "deflate") &&
548         (te[1] == "gzip") &&
549         (te[2] == "chunked") &&
550         (te[3] == "identity") &&
551         (te[4] == "trailers")) {
552         runtest.pass ("HTTP::extractTE()");
553     } else {
554         runtest.fail ("HTTP::extractTE()");
555     }
556 #endif
557 
558 //     http.formatHeader(666, RTMP);
559 //     http.formatRequest("http://localhost:4080", HTTP::GET);
560 
561 //     bool formatMethod(const char *data);
562 
563 
564 //     void *out = amf_obj.encodeNumber(*num);
565 
566 //     if (memcmp(out, buf, 9) == 0) {
567 //         runtest.pass("Encoded AMF Number");
568 //     } else {
569 //         runtest.fail("Encoded AMF Number");
570 //     }
571 
572 //    delete num;
573 
574 
575     if (dbglogfile.getVerbosity() > 0) {
576         http.dump();
577     }
578 }
579 
580 void
test_post()581 test_post()
582 {
583 
584     HTTP http;
585 
586     std::shared_ptr<cygnal::Buffer> encstr = AMF::encodeString("Hello World!");
587     std::shared_ptr<cygnal::Buffer> encnum = AMF::encodeNumber(1.2345);
588 
589     cygnal::Buffer ptr1;
590     ptr1 = "POST /echo/gateway HTTP/1.1\r\n";
591     ptr1 += "User-Agent: Opera/9.62 (X11; Linux i686; U; en) Presto/2.1.1\r\n";
592     ptr1 += "Host: localhost:4080\r\n";
593     ptr1 += "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap;q=0.1\r\n";
594     ptr1 += "Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0\r\n";
595     ptr1 += "Referer: http://localhost:5080/demos/echo_test.swf\r\n";
596     ptr1 += "Connection: Keep-Alive, TE\r\n";
597     ptr1 += "Content-Length: 15\r\n";
598     ptr1 += "Content-Type: application/x-amf\r\n";
599     ptr1 += "\r\n";
600     ptr1 += *encstr;
601     ptr1.resize();              // shrink the buffer to be the exact size of the data
602 
603 #if 1
604     // FIXME: should be moved to server side only test case
605     // Check the Server field
606     AMF amf;
607     std::uint8_t *data1 = http.processHeaderFields(&ptr1);
608     std::shared_ptr<cygnal::Element> el1 = amf.extractAMF(data1, data1 + 15);
609     string str1 = el1->to_string();
610 
611     if ((http.getField("host") == "localhost:4080")
612         && (str1 == "Hello World!")
613         && (http.getField("content-length") == "15")) {
614         runtest.pass("HTTP::processHeaderFields(POST) + STRING");
615     } else {
616         runtest.fail("HTTP::processHeaderFields(POST) + STRING");
617     }
618 
619     cygnal::Buffer ptr2;
620     ptr2 += "POST /echo/gateway HTTP/1.1\r\n";
621     ptr2 += "User-Agent: Opera/9.62.(X11;.Linux.i686;.U;.en) Presto/2.1.1\r\n";
622     ptr2 += "Host: localhost:5080\r\n";
623     ptr2 += "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap\r\n";
624     ptr2 += "Keep-Alive: 300\r\n";
625     ptr2 += "Accept-Language: en\r\n";
626     ptr2 += "Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n";
627     ptr2 += "Accept-Encoding: deflate, gzip,.x-gzip, identity, *;q=0\r\n";
628     ptr2 += "Referer: http://localhost:5080/demos/echo_test.swf\r\n";
629     ptr2 += "Connection: Keep-Alive, TE. TE: deflate, gzip, chunked, identity, trailers\r\n";
630     ptr2 += "Content-Length:.9\r\n";
631     ptr2 += "Content-Type: application/x-amf\r\n";
632     ptr2 += "\r\n";
633     ptr2 += *encnum;
634     ptr2.resize();              // shrink the buffer to be the exact size of the data
635 
636     std::uint8_t *data2 = http.processHeaderFields(&ptr2);
637     std::shared_ptr<cygnal::Element> el2 = amf.extractAMF(data2, data2 + 15);
638     if ((http.getField("host") == "localhost:5080")
639         && (el2->to_number() == 1.2345)
640         && (http.getField("content-length") == "9")) {
641         runtest.pass("HTTP::processHeaderFields(POST) + NUMBER");
642     } else {
643         runtest.fail("HTTP::processHeaderFields(POST) + NUMBER");
644     }
645 
646     std::shared_ptr<std::vector<std::string> > item2 = http.getFieldItem("accept");
647     if (!item2) {
648         runtest.unresolved("HTTP::getFieldItem(Accept)");
649     } else {
650         if (item2->at(2) == "application/xhtml+xml") {
651             runtest.pass("HTTP::getFieldItem(Accept)");
652         } else {
653             runtest.fail("HTTP::getFieldItem(Accept)");
654         }
655     }
656 
657     std::shared_ptr<std::vector<std::string> > item3 = http.getFieldItem("connection");
658     if (!item3) {
659         runtest.unresolved("HTTP::getFieldItem(POST)");
660     } else {
661         if (item3->at(0) == "keep-alive") {
662             runtest.pass("HTTP::getFieldItem(Connection)");
663         } else {
664             runtest.fail("HTTP::getFieldItem(Connection)");
665         }
666     }
667 
668 #if 0
669     // Make sure we can parse the Red5 echo_test client messages.
670     std::shared_ptr<Buffer> hex1(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 32 00 00 00 14 0a 00 00 00 01 02 00 0c 48 65 6c 6c 6f 20 77 6f 72 6c 64 21"));
671     std::shared_ptr<Buffer> hex2(new Buffer("00 00 00 00 00 01 00 0b 2f 32 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 02 00 0c 48 65 6c 6c 6f 20 77 6f 72 6c 64 21"));
672 //    http.clearFields();
673     vector<std::shared_ptr<cygnal::Element> > headers = http.parseEchoRequest(*hex1);
674 
675     if ((strncmp(headers[0]->getName(), "echo", 4) == 0)
676         && (strncmp(headers[1]->getName(), "/2", 2) == 0)
677         && (strncmp(headers[3]->to_string(), "Hello world!", 12) == 0)) {
678         runtest.pass("HTTP::parseEchoRequest()");
679     } else {
680         runtest.fail("HTTP::parseEchoRequest()");
681     }
682 
683     cygnal::Buffer &buff = http.formatEchoResponse(headers[1]->getName(), *headers[3]);
684     string head(reinterpret_cast<const char *>(buff.reference()));
685     const char *ptr3 = reinterpret_cast<const char *>(hex2->reference());
686     const char *ptr4 = reinterpret_cast<const char *>(buff.reference()) + head.size();
687 
688     if (memcmp(ptr3, ptr4, hex2->allocated()) == 0) {
689         runtest.pass("HTTP::formatEchoResponse()");
690     } else {
691         runtest.fail("HTTP::formatEchoResponse()");
692     }
693 #endif
694 #endif
695 
696     if (dbglogfile.getVerbosity() > 0) {
697         http.dump();
698     }
699 }
700 
701 #if 0
702 void
703 test_rtmpt (void)
704 {
705     HTTP http;
706 
707     // Boolean True request
708     std::shared_ptr<Buffer> hex_req1(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 31 00 00 00 07 0a 00 00 00 01 01 01"));
709     vector<std::shared_ptr<cygnal::Element> > headers1 = http.parseEchoRequest(*hex_req1);
710     if ((strncmp(headers1[0]->getName(), "echo", 4) == 0)
711         && (strncmp(headers1[1]->getName(), "/1", 2) == 0)
712         && (headers1[3]->getType() == Element::BOOLEAN_AMF0)
713         && (headers1[3]->to_bool() == true)) {
714         runtest.pass("HTTP::parseEchoRequest(Boolean TRUE)");
715     } else {
716         runtest.fail("HTTP::parseEchoRequest(Boolean TRUE)");
717     }
718 //    hex_req1->corrupt();
719 
720     // Boolean True response
721     std::shared_ptr<Buffer> hex_res1(new Buffer("00 00 00 00 00 01 00 0b 2f 31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 01 01"));
722     cygnal::Buffer &buf1 = http.formatEchoResponse(headers1[1]->getName(), *headers1[3]);
723     string head1(reinterpret_cast<const char *>(buf1.reference()));
724     const char *ptr1a = reinterpret_cast<const char *>(hex_res1->reference());
725     const char *ptr1b = reinterpret_cast<const char *>(buf1.reference()) + head1.size();
726     if (memcmp(ptr1a, ptr1b, hex_res1->allocated()-1) == 0) {
727         runtest.pass("HTTP::formatEchoResponse(Boolean TRUE)");
728     } else {
729         runtest.fail("HTTP::formatEchoResponse(Boolean TRUE)");
730     }
731 
732 
733     // Boolean false request
734     std::shared_ptr<Buffer> hex_req2(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 32 00 00 00 07 0a 00 00 00 01 01 00"));
735     vector<std::shared_ptr<cygnal::Element> > headers2 = http.parseEchoRequest(*hex_req2);
736     if ((strncmp(headers2[0]->getName(), "echo", 4) == 0)
737         && (strncmp(headers2[1]->getName(), "/2", 2) == 0)
738         && (headers2[3]->getType() == Element::BOOLEAN_AMF0)
739         && (headers2[3]->to_bool() == false)) {
740         runtest.pass("HTTP::parseEchoRequest(Boolean FALSE)");
741     } else {
742         runtest.fail("HTTP::parseEchoRequest(Boolean FALSE)");
743     }
744     // Boolean False response
745     std::shared_ptr<Buffer> hex_res2(new Buffer("00 00 00 00 00 01 00 0b 2f 32 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 01 00"));
746     cygnal::Buffer &buf2 = http.formatEchoResponse(headers2[1]->getName(), *headers2[3]);
747     string head2(reinterpret_cast<const char *>(buf2.reference()));
748     const char *ptr2a = reinterpret_cast<const char *>(hex_res2->reference());
749     const char *ptr2b = reinterpret_cast<const char *>(buf2.reference()) + head2.size();
750     if (memcmp(ptr2a, ptr2b, hex_res2->allocated()-1) == 0) {
751         runtest.pass("HTTP::formatEchoResponse(Boolean FALSE)");
752     } else {
753         runtest.fail("HTTP::formatEchoResponse(Boolean FALSE)");
754     }
755 
756     // NULL Object request
757     std::shared_ptr<Buffer> hex_req3(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 31 00 00 00 06 0a 00 00 00 01 05"));
758     vector<std::shared_ptr<cygnal::Element> > headers3 = http.parseEchoRequest(*hex_req3);
759     if ((strncmp(headers3[0]->getName(), "echo", 4) == 0)
760         && (strncmp(headers3[1]->getName(), "/1", 2) == 0)
761         && (headers3[3]->getType() == Element::NULL_AMF0)) {
762         runtest.pass("HTTP::parseEchoRequest(NULL Object)");
763     } else {
764         runtest.fail("HTTP::parseEchoRequest(NULL Object)");
765     }
766     // NULL Object response
767     std::shared_ptr<Buffer> hex_res3(new Buffer("00 00 00 00 00 01 00 0b 2f 31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 05"));
768     cygnal::Buffer &buf3 = http.formatEchoResponse(headers3[1]->getName(), *headers3[3]);
769     string head3(reinterpret_cast<const char *>(buf3.reference()));
770     const char *ptr3a = reinterpret_cast<const char *>(hex_res3->reference());
771     const char *ptr3b = reinterpret_cast<const char *>(buf3.reference()) + head3.size();
772     if (memcmp(ptr3a, ptr3b, hex_res3->allocated()) == 0) {
773         runtest.pass("HTTP::formatEchoResponse(NULL Object)");
774     } else {
775         runtest.fail("HTTP::formatEchoResponse(NULL Object)");
776     }
777 
778     // UNDEFINED Object request
779     std::shared_ptr<Buffer> hex_req4(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 31 00 00 00 06 0a 00 00 00 01 06"));
780     vector<std::shared_ptr<cygnal::Element> > headers4 = http.parseEchoRequest(*hex_req4);
781     if ((strncmp(headers4[0]->getName(), "echo", 4) == 0)
782         && (strncmp(headers4[1]->getName(), "/1", 2) == 0)
783         && (headers4[3]->getType() == Element::UNDEFINED_AMF0)) {
784         runtest.pass("HTTP::parseEchoRequest(UNDEFINED Object)");
785     } else {
786         runtest.fail("HTTP::parseEchoRequest(UNDEFINED Object)");
787     }
788     // UNDEFINED Object response
789     std::shared_ptr<Buffer> hex_res4(new Buffer("00 00 00 00 00 01 00 0b 2f 31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 05"));
790     cygnal::Buffer &buf4 = http.formatEchoResponse(headers4[1]->getName(), *headers4[3]);
791     string head4(reinterpret_cast<const char *>(buf4.reference()));
792     const char *ptr4a = reinterpret_cast<const char *>(hex_res4->reference());
793     const char *ptr4b = reinterpret_cast<const char *>(buf4.reference()) + head4.size();
794     if (memcmp(ptr4a, ptr4b, hex_res4->allocated()) == 0) {
795         runtest.pass("HTTP::formatEchoResponse(UNDEFINED Object, NULL response)");
796     } else {
797         runtest.fail("HTTP::formatEchoResponse(UNDEFINED Object, NULL response)");
798     }
799 
800     // Date Object request
801     std::shared_ptr<Buffer> hex_req5(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 31 00 00 00 10 0a 00 00 00 01 0b 42 71 e4 ca 4e 32 d0 00 01 a4"));
802     vector<std::shared_ptr<cygnal::Element> > headers5 = http.parseEchoRequest(*hex_req5);
803     if (headers5[3] == 0) {
804         runtest.unresolved("HTTP::parseEchoRequest(DATE Object)");
805     } else {
806         double swapped = *reinterpret_cast<const double*>(headers5[3]->to_reference());
807         swapBytes(&swapped, amf::AMF0_NUMBER_SIZE);
808         if ((strncmp(headers5[0]->getName(), "echo", 4) == 0)
809             && (strncmp(headers5[1]->getName(), "/1", 2) == 0)
810             && (headers5[3]->getType() == Element::DATE_AMF0)
811             && (headers5[3]->getDataSize() > 0 )
812             && (memcmp(hex_req5->reference()+26, &swapped, amf::AMF0_NUMBER_SIZE) == 0)) {
813             runtest.pass("HTTP::parseEchoRequest(DATE Object)");
814         } else {
815             runtest.fail("HTTP::parseEchoRequest(DATE Object)");
816         }
817     }
818     // Date Object response
819     std::shared_ptr<Buffer> hex_res5(new Buffer("00 00 00 00 00 01 00 0b 2f 31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 0b 42 71 e4 ca 4e 32 d0 00 fe 5c"));
820     if (headers5[3] == 0) {
821         runtest.unresolved("HTTP::formatEchoResponse(DATE Object)");
822     } else {
823         cygnal::Buffer &buf5 = http.formatEchoResponse(headers5[1]->getName(), *headers5[3]);
824         string head5(reinterpret_cast<const char *>(buf5.reference()));
825         const char *ptr5a = reinterpret_cast<const char *>(hex_res5->reference()+30);
826         const char *ptr5b = reinterpret_cast<const char *>(buf5.reference() + 124);
827         if (memcmp(ptr5a, ptr5b, amf::AMF0_NUMBER_SIZE) == 0) {
828             runtest.pass("HTTP::formatEchoResponse(DATE Object)");
829         } else {
830             runtest.fail("HTTP::formatEchoResponse(DATE Object)");
831         }
832     }
833 
834     // Date Array request
835     std::shared_ptr<Buffer> hex_req6(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 32 00 00 00 18 0a 00 00 00 01 0a 00 00 00 02 0b 42 71 e4 ca 4e 32 d0 00 01 a4 07 00 01"));
836     vector<std::shared_ptr<cygnal::Element> > headers6 = http.parseEchoRequest(*hex_req6);
837     if (headers6[3] == 0) {
838         runtest.unresolved("HTTP::parseEchoRequest(DATE Array)");
839     } else {
840         if ((strncmp(headers6[0]->getName(), "echo", 4) == 0)
841             && (strncmp(headers6[1]->getName(), "/2", 2) == 0)
842             && (headers6[3]->getType() == Element::STRICT_ARRAY_AMF0)) {
843             runtest.pass("HTTP::parseEchoRequest(DATE Array)");
844         } else {
845             runtest.fail("HTTP::parseEchoRequest(DATE Array)");
846         }
847     }
848     // Date Array response
849     std::shared_ptr<Buffer> hex_res6(new Buffer("00 00 00 00 00 01 00 0b 2f 32 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 0a 00 00 00 02 0b 42 71 e4 ca 4e 32 d0 00 fe 5c 0b 42 71 e4 ca 4e 32 d0 00 fe 5c"));
850 
851     // Undefined Array request
852     std::shared_ptr<Buffer> hex_req7(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 31 00 00 00 0a 0a 00 00 00 01 0a 00 00 00 00"));
853     vector<std::shared_ptr<cygnal::Element> > headers7 = http.parseEchoRequest(*hex_req7);
854     if ((strncmp(headers7[0]->getName(), "echo", 4) == 0)
855         && (strncmp(headers7[1]->getName(), "/1", 2) == 0)
856         && (headers7[3]->getType() == Element::STRICT_ARRAY_AMF0)) {
857         runtest.pass("HTTP::parseEchoRequest(Undefined Strict Array)");
858     } else {
859         runtest.fail("HTTP::parseEchoRequest(Undefined Strict Array)");
860     }
861     // Undefined Array response
862     std::shared_ptr<Buffer> hex_res7(new Buffer("00 00 00 00 00 01 00 0b 2f 31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 0a 00 00 00 00"));
863     cygnal::Buffer &buf7 = http.formatEchoResponse(headers7[1]->getName(), *headers7[3]);
864 
865     //    cerr << hexify(hex_res7->reference(), hex_res7->allocated(), false) << endl;
866     string head7(reinterpret_cast<const char *>(buf7.reference()));
867     const char *ptr7a = reinterpret_cast<const char *>(hex_res7->reference());
868     const char *ptr7b = reinterpret_cast<const char *>(buf7.reference()) + head7.size();
869     //    cerr << hexify(buf7.reference() + head7.size(), buf7.allocated() - head7.size(), false) << endl;
870     if (memcmp(ptr7a, ptr7b, hex_res7->allocated()-1) == 0) {
871         runtest.pass("HTTP::formatEchoResponse(Undefined Strict Array)");
872     } else {
873         runtest.fail("HTTP::formatEchoResponse(Undefined Strict Array)");
874     }
875 
876     // Number 1
877     // Array request
878     std::shared_ptr<Buffer> hex_req8(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 32 00 00 00 13 0a 00 00 00 01 0a 00 00 00 01 00 3f f0 00 00 00 00 00 00"));
879     vector<std::shared_ptr<cygnal::Element> > headers8 = http.parseEchoRequest(*hex_req8);
880     if (headers8[3] == 0) {
881         runtest.unresolved("HTTP::parseEchoRequest(Simple Strict Array of Numbers, 1 item)");
882     } else {
883         if (headers8[3]->propertySize() > 0) {
884             std::vector<std::shared_ptr<cygnal::Element> > props8 = headers8[3]->getProperties();
885             if ((strncmp(headers8[0]->getName(), "echo", 4) == 0)
886                 && (strncmp(headers8[1]->getName(), "/2", 2) == 0)
887                 && (headers8[3]->getType() == Element::STRICT_ARRAY_AMF0)
888                 && (props8[0]->getType() == Element::NUMBER_AMF0)
889                 && (props8[0]->to_number() == 1)
890                 ) {
891                 runtest.pass("HTTP::parseEchoRequest(Simple Strict Array of Numbers. 1 item)");
892             } else {
893                 runtest.fail("HTTP::parseEchoRequest(Simple Strict Array of Numbers, 1 item)");
894             }
895         } else {
896             runtest.fail("HTTP::parseEchoRequest(Simple Strict Array of Numbers, 1 item)");
897         }
898     }
899     // Undefined Array response
900     std::shared_ptr<Buffer> hex_res8(new Buffer("00 00 00 00 00 01 00 0b 2f 32 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 0a 00 00 00 01 00 3f f0 00 00 00 00 00 00"));
901     cygnal::Buffer &buf8 = http.formatEchoResponse(headers8[1]->getName(), *headers8[3]);
902     //    cerr << hexify(hex_res8->reference()+30, amf::AMF0_NUMBER_SIZE, false) << endl;
903     //    cerr << hexify(buf8.reference() + 124, amf::AMF0_NUMBER_SIZE, false) << endl;
904     string head8(reinterpret_cast<const char *>(buf8.reference()));
905     const char *ptr8a = reinterpret_cast<const char *>(hex_res8->reference());
906     const char *ptr8b = reinterpret_cast<const char *>(buf8.reference()) + head8.size();
907     if (memcmp(ptr8a, ptr8b, hex_res8->allocated()-1) == 0) {
908         runtest.pass("HTTP::formatEchoResponse(Simple Strict Array of Numbers, 1 item)");
909     } else {
910         runtest.fail("HTTP::formatEchoResponse(Simple Strict Array of Numbers, 1 item)");
911     }
912 
913     // Number 1,2
914     // Array request
915     std::shared_ptr<Buffer> hex_req9(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 33 00 00 00 1c 0a 00 00 00 01 0a 00 00 00 02 00 3f f0 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00"));
916     vector<std::shared_ptr<cygnal::Element> > headers9 = http.parseEchoRequest(*hex_req9);
917     if ((strncmp(headers9[0]->getName(), "echo", 4) == 0)
918         && (strncmp(headers9[1]->getName(), "/3", 2) == 0)
919         && (headers9[3]->getType() == Element::STRICT_ARRAY_AMF0)) {
920         runtest.pass("HTTP::parseEchoRequest(Simple Strict Array of Numbers, 2 items)");
921     } else {
922 
923         runtest.fail("HTTP::parseEchoRequest(Simple Strict Array of Numbers, 2 items)");
924     }
925     // Undefined Array response
926     std::shared_ptr<Buffer> hex_res9(new Buffer("00 00 00 00 00 01 00 0b 2f 33 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 0a 00 00 00 02 00 3f f0 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00"));
927     cygnal::Buffer &buf9 = http.formatEchoResponse(headers9[1]->getName(), *headers9[3]);
928     string head9(reinterpret_cast<const char *>(buf9.reference()));
929     const char *ptr9a = reinterpret_cast<const char *>(hex_res9->reference());
930     const char *ptr9b = reinterpret_cast<const char *>(buf9.reference()) + head9.size();
931     if (memcmp(ptr9a, ptr9b, hex_res9->allocated()-1) == 0) {
932         runtest.pass("HTTP::formatEchoResponse(Simple Strict Array of Numbers, 2 items)");
933     } else {
934         runtest.fail("HTTP::formatEchoResponse(Simple Strict Array of Numbers, 2 items)");
935     }
936 
937     // Number 1,2,3
938     // Array request
939     std::shared_ptr<Buffer> hex_req10(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 34 00 00 00 25 0a 00 00 00 01 0a 00 00 00 03 00 3f f0 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 40 08 00 00 00 00 00 00"));
940     vector<std::shared_ptr<cygnal::Element> > headers10 = http.parseEchoRequest(*hex_req10);
941     if ((strncmp(headers10[0]->getName(), "echo", 4) == 0)
942         && (strncmp(headers10[1]->getName(), "/4", 2) == 0)
943         && (headers10[3]->getType() == Element::STRICT_ARRAY_AMF0)) {
944         runtest.pass("HTTP::parseEchoRequest(Simple Strict Array of Numbers, 3 items)");
945     } else {
946 
947         runtest.fail("HTTP::parseEchoRequest(Simple Strict Array of Numbers, 3 items)");
948     }
949     // Undefined Array response
950     std::shared_ptr<Buffer> hex_res10(new Buffer("00 00 00 00 00 01 00 0b 2f 34 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 0a 00 00 00 03 00 3f f0 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 40 08 00 00 00 00 00 00"));
951     cygnal::Buffer &buf10 = http.formatEchoResponse(headers10[1]->getName(), *headers10[3]);
952     string head10(reinterpret_cast<const char *>(buf10.reference()));
953     const char *ptr10a = reinterpret_cast<const char *>(hex_res10->reference());
954     const char *ptr10b = reinterpret_cast<const char *>(buf10.reference()) + head10.size();
955     if (memcmp(ptr10a, ptr10b, hex_res10->allocated()-1) == 0) {
956         runtest.pass("HTTP::formatEchoResponse(Simple Strict Array of Numbers, 3 items)");
957     } else {
958         runtest.fail("HTTP::formatEchoResponse(Simple Strict Array of Numbers, 3 items)");
959     }
960 
961     // Number 0 Request
962     std::shared_ptr<Buffer> hex_req11(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 31 00 00 00 0e 0a 00 00 00 01 00 00 00 00 00 00 00 00 00"));
963     vector<std::shared_ptr<cygnal::Element> > headers11 = http.parseEchoRequest(*hex_req11);
964     if ((strncmp(headers11[0]->getName(), "echo", 4) == 0)
965         && (strncmp(headers11[1]->getName(), "/1", 2) == 0)
966         && (headers11[3]->getType() == Element::NUMBER_AMF0)
967         && (headers11[3]->to_number() == 0)) {
968         runtest.pass("HTTP::parseEchoRequest(Number 0)");
969     } else {
970         runtest.fail("HTTP::parseEchoRequest(Number 0)");
971     }
972     // Number 0 Response
973     std::shared_ptr<Buffer> hex_res11(new Buffer("00 00 00 00 00 01 00 0b 2f 31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 00 00 00 00 00 00 00 00"));
974     cygnal::Buffer &buf11 = http.formatEchoResponse(headers11[1]->getName(), *headers11[3]);
975     string head11(reinterpret_cast<const char *>(buf11.reference()));
976     const char *ptr11a = reinterpret_cast<const char *>(hex_res11->reference());
977     const char *ptr11b = reinterpret_cast<const char *>(buf11.reference()) + head11.size();
978     if (memcmp(ptr11a, ptr11b, hex_res11->allocated()-11) == 0) {
979         runtest.pass("HTTP::formatEchoResponse(Number 0)");
980     } else {
981         runtest.fail("HTTP::formatEchoResponse(Number 0)");
982     }
983 
984     // Number 1 Request
985     std::shared_ptr<Buffer> hex_req12(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 32 00 00 00 0e 0a 00 00 00 01 00 3f f0 00 00 00 00 00 00"));
986     vector<std::shared_ptr<cygnal::Element> > headers12 = http.parseEchoRequest(*hex_req12);
987     if ((strncmp(headers12[0]->getName(), "echo", 4) == 0)
988         && (strncmp(headers12[1]->getName(), "/2", 2) == 0)
989         && (headers12[3]->getType() == Element::NUMBER_AMF0)
990         && (headers12[3]->to_number() == 1)) {
991         runtest.pass("HTTP::parseEchoRequest(Number 1)");
992     } else {
993         runtest.fail("HTTP::parseEchoRequest(Number 1)");
994     }
995     // Number 1 Response
996     std::shared_ptr<Buffer> hex_res12(new Buffer("00 00 00 00 00 01 00 0b 2f 32 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 3f f0 00 00 00 00 00 00"));
997     cygnal::Buffer &buf12 = http.formatEchoResponse(headers12[1]->getName(), *headers12[3]);
998     string head12(reinterpret_cast<const char *>(buf12.reference()));
999     const char *ptr12a = reinterpret_cast<const char *>(hex_res12->reference());
1000     const char *ptr12b = reinterpret_cast<const char *>(buf12.reference()) + head12.size();
1001     if (memcmp(ptr12a, ptr12b, hex_res12->allocated()-11) == 0) {
1002         runtest.pass("HTTP::formatEchoResponse(Number 1)");
1003     } else {
1004         runtest.fail("HTTP::formatEchoResponse(Number 1)");
1005     }
1006 
1007     // Number -1 Request
1008     std::shared_ptr<Buffer> hex_req13(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 33 00 00 00 0e 0a 00 00 00 01 00 bf f0 00 00 00 00 00 00"));
1009     vector<std::shared_ptr<cygnal::Element> > headers13 = http.parseEchoRequest(*hex_req13);
1010     if ((strncmp(headers13[0]->getName(), "echo", 4) == 0)
1011         && (strncmp(headers13[1]->getName(), "/3", 2) == 0)
1012         && (headers13[3]->getType() == Element::NUMBER_AMF0)
1013         && (headers13[3]->to_number() == -1)) {
1014         runtest.pass("HTTP::parseEchoRequest(Number -1)");
1015     } else {
1016         runtest.fail("HTTP::parseEchoRequest(Number -1)");
1017     }
1018     // Number -1 Response
1019     std::shared_ptr<Buffer> hex_res13(new Buffer("00 00 00 00 00 01 00 0b 2f 33 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 bf f0 00 00 00 00 00 00"));
1020     cygnal::Buffer &buf13 = http.formatEchoResponse(headers13[1]->getName(), *headers13[3]);
1021     string head13(reinterpret_cast<const char *>(buf13.reference()));
1022     const char *ptr13a = reinterpret_cast<const char *>(hex_res13->reference());
1023     const char *ptr13b = reinterpret_cast<const char *>(buf13.reference()) + head13.size();
1024     if (memcmp(ptr13a, ptr13b, hex_res13->allocated()-11) == 0) {
1025         runtest.pass("HTTP::formatEchoResponse(Number -1)");
1026     } else {
1027         runtest.fail("HTTP::formatEchoResponse(Number -1)");
1028     }
1029 
1030     // Number 256 Request
1031     std::shared_ptr<Buffer> hex_req14(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 34 00 00 00 0e 0a 00 00 00 01 00 40 70 00 00 00 00 00 00"));
1032     vector<std::shared_ptr<cygnal::Element> > headers14 = http.parseEchoRequest(*hex_req14);
1033     if ((strncmp(headers14[0]->getName(), "echo", 4) == 0)
1034         && (strncmp(headers14[1]->getName(), "/4", 2) == 0)
1035         && (headers14[3]->getType() == Element::NUMBER_AMF0)
1036         && (headers14[3]->to_number() == 256)) {
1037         runtest.pass("HTTP::parseEchoRequest(Number 256)");
1038     } else {
1039         runtest.fail("HTTP::parseEchoRequest(Number 256)");
1040     }
1041     // Number 256 Response
1042     std::shared_ptr<Buffer> hex_res14(new Buffer("00 00 00 00 00 01 00 0b 2f 34 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 40 70 00 00 00 00 00 00"));
1043     cygnal::Buffer &buf14 = http.formatEchoResponse(headers14[1]->getName(), *headers14[3]);
1044     string head14(reinterpret_cast<const char *>(buf14.reference()));
1045     const char *ptr14a = reinterpret_cast<const char *>(hex_res14->reference());
1046     const char *ptr14b = reinterpret_cast<const char *>(buf14.reference()) + head14.size();
1047     if (memcmp(ptr14a, ptr14b, AMF0_NUMBER_SIZE) == 0) {
1048         runtest.pass("HTTP::formatEchoResponse(Number 256)");
1049     } else {
1050         runtest.fail("HTTP::formatEchoResponse(Number 256)");
1051     }
1052 
1053     // Number -256 Request
1054     std::shared_ptr<Buffer> hex_req15(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 35 00 00 00 0e 0a 00 00 00 01 00 c0 70 00 00 00 00 00 00"));
1055     vector<std::shared_ptr<cygnal::Element> > headers15 = http.parseEchoRequest(*hex_req15);
1056     if ((strncmp(headers15[0]->getName(), "echo", 4) == 0)
1057         && (strncmp(headers15[1]->getName(), "/5", 2) == 0)
1058         && (headers15[3]->getType() == Element::NUMBER_AMF0)
1059         && (headers15[3]->to_number() == -256)) {
1060         runtest.pass("HTTP::parseEchoRequest(Number -256)");
1061     } else {
1062         runtest.fail("HTTP::parseEchoRequest(Number -256)");
1063     }
1064     // Number -256 Response
1065     std::shared_ptr<Buffer> hex_res15(new Buffer("00 00 00 00 00 01 00 0b 2f 35 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 c0 70 00 00 00 00 00 00"));
1066     cygnal::Buffer &buf15 = http.formatEchoResponse(headers15[1]->getName(), *headers15[3]);
1067     string head15(reinterpret_cast<const char *>(buf15.reference()));
1068     const char *ptr15a = reinterpret_cast<const char *>(hex_res15->reference());
1069     const char *ptr15b = reinterpret_cast<const char *>(buf15.reference()) + head15.size();
1070     if (memcmp(ptr15a, ptr15b, hex_res15->allocated()-11) == 0) {
1071         runtest.pass("HTTP::formatEchoResponse(Number -256)");
1072     } else {
1073         runtest.fail("HTTP::formatEchoResponse(Number -256)");
1074     }
1075 
1076     // Number 65536 Request
1077     std::shared_ptr<Buffer> hex_req16(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 36 00 00 00 0e 0a 00 00 00 01 00 40 f0 00 00 00 00 00 00"));
1078     vector<std::shared_ptr<cygnal::Element> > headers16 = http.parseEchoRequest(*hex_req16);
1079     if ((strncmp(headers16[0]->getName(), "echo", 4) == 0)
1080         && (strncmp(headers16[1]->getName(), "/6", 2) == 0)
1081         && (headers16[3]->getType() == Element::NUMBER_AMF0)
1082         && (headers16[3]->to_number() == 65536)) {
1083         runtest.pass("HTTP::parseEchoRequest(Number 65536)");
1084     } else {
1085         runtest.fail("HTTP::parseEchoRequest(Number 65536)");
1086     }
1087     // Number 65536 Response
1088     std::shared_ptr<Buffer> hex_res16(new Buffer("00 00 00 00 00 01 00 0b 2f 36 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 40 f0 00 00 00 00 00 00"));
1089     cygnal::Buffer &buf16 = http.formatEchoResponse(headers16[1]->getName(), *headers16[3]);
1090     string head16(reinterpret_cast<const char *>(buf16.reference()));
1091     const char *ptr16a = reinterpret_cast<const char *>(hex_res16->reference());
1092     const char *ptr16b = reinterpret_cast<const char *>(buf16.reference()) + head16.size();
1093     if (memcmp(ptr16a, ptr16b, hex_res16->allocated()-11) == 0) {
1094         runtest.pass("HTTP::formatEchoResponse(Number 65536)");
1095     } else {
1096         runtest.fail("HTTP::formatEchoResponse(Number 65536)");
1097     }
1098 
1099     // Number -655536 Request
1100     std::shared_ptr<Buffer> hex_req16x(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 37 00 00 00 0e 0a 00 00 00 01 00 c0 f0 00 00 00 00 00 00"));
1101     vector<std::shared_ptr<cygnal::Element> > headers16x = http.parseEchoRequest(*hex_req16x);
1102     if ((strncmp(headers16x[0]->getName(), "echo", 4) == 0)
1103         && (strncmp(headers16x[1]->getName(), "/7", 2) == 0)
1104         && (headers16x[3]->getType() == Element::NUMBER_AMF0)
1105         && (headers16x[3]->to_number() == -65536)) {
1106         runtest.pass("HTTP::parseEchoRequest(Number -65536)");
1107     } else {
1108         runtest.fail("HTTP::parseEchoRequest(Number -65536)");
1109     }
1110     // Number -655536 Response
1111     std::shared_ptr<Buffer> hex_res17(new Buffer("00 00 00 00 00 01 00 0b 2f 37 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 c0 f0 00 00 00 00 00 00"));
1112     cygnal::Buffer &buf17 = http.formatEchoResponse(headers16x[1]->getName(), *headers16x[3]);
1113     string head17(reinterpret_cast<const char *>(buf17.reference()));
1114     const char *ptr17a = reinterpret_cast<const char *>(hex_res17->reference());
1115     const char *ptr17b = reinterpret_cast<const char *>(buf17.reference()) + head17.size();
1116     if (memcmp(ptr17a, ptr17b, hex_res17->allocated()-11) == 0) {
1117         runtest.pass("HTTP::formatEchoResponse(Number -65536)");
1118     } else {
1119         runtest.fail("HTTP::formatEchoResponse(Number -65536)");
1120     }
1121 
1122     // Number 0 Request
1123     std::shared_ptr<Buffer> hex_req18(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 38 00 00 00 0e 0a 00 00 00 01 00 00 00 00 00 00 00 00 00"));
1124     vector<std::shared_ptr<cygnal::Element> > headers18 = http.parseEchoRequest(*hex_req18);
1125     if ((strncmp(headers18[0]->getName(), "echo", 4) == 0)
1126         && (strncmp(headers18[1]->getName(), "/8", 2) == 0)
1127         && (headers18[3]->getType() == Element::NUMBER_AMF0)
1128         && (headers18[3]->to_number() == 0)) {
1129         runtest.pass("HTTP::parseEchoRequest(Number 0)");
1130     } else {
1131         runtest.fail("HTTP::parseEchoRequest(Number 0)");
1132     }
1133     // Number 0 Response
1134     std::shared_ptr<Buffer> hex_res18(new Buffer("00 00 00 00 00 01 00 0b 2f 38 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 00 00 00 00 00 00 00 00"));
1135     cygnal::Buffer &buf18 = http.formatEchoResponse(headers18[1]->getName(), *headers18[3]);
1136     string head18(reinterpret_cast<const char *>(buf18.reference()));
1137     const char *ptr18a = reinterpret_cast<const char *>(hex_res18->reference());
1138     const char *ptr18b = reinterpret_cast<const char *>(buf18.reference()) + head18.size();
1139     if (memcmp(ptr18a, ptr18b, hex_res18->allocated()-11) == 0) {
1140         runtest.pass("HTTP::formatEchoResponse(Number 0)");
1141     } else {
1142         runtest.fail("HTTP::formatEchoResponse(Number 0)");
1143     }
1144 
1145     // Number 1.5 Request
1146     std::shared_ptr<Buffer> hex_req19(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 39 00 00 00 0e 0a 00 00 00 01 00 3f f8 00 00 00 00 00 00"));
1147     vector<std::shared_ptr<cygnal::Element> > headers19 = http.parseEchoRequest(*hex_req19);
1148     if ((strncmp(headers19[0]->getName(), "echo", 4) == 0)
1149         && (strncmp(headers19[1]->getName(), "/9", 2) == 0)
1150         && (headers19[3]->getType() == Element::NUMBER_AMF0)
1151         && (headers19[3]->to_number() == 1.5)) {
1152         runtest.pass("HTTP::parseEchoRequest(Number 1.5)");
1153     } else {
1154         runtest.fail("HTTP::parseEchoRequest(Number 1.5)");
1155     }
1156     // Number 1.5 Response
1157     std::shared_ptr<Buffer> hex_res19(new Buffer("00 00 00 00 00 01 00 0b 2f 39 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 3f f8 00 00 00 00 00 00"));
1158     cygnal::Buffer &buf19 = http.formatEchoResponse(headers19[1]->getName(), *headers19[3]);
1159     string head19(reinterpret_cast<const char *>(buf19.reference()));
1160     const char *ptr19a = reinterpret_cast<const char *>(hex_res19->reference());
1161     const char *ptr19b = reinterpret_cast<const char *>(buf19.reference()) + head19.size();
1162     if (memcmp(ptr19a, ptr19b, hex_res19->allocated()-11) == 0) {
1163         runtest.pass("HTTP::formatEchoResponse(Number 1.5");
1164     } else {
1165         runtest.fail("HTTP::formatEchoResponse(Number 1.5");
1166     }
1167 
1168     // Number -1.5 Request
1169     std::shared_ptr<Buffer> hex_req20(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 03 2f 31 30 00 00 00 0e 0a 00 00 00 01 00 bf f8 00 00 00 00 00 00"));
1170     vector<std::shared_ptr<cygnal::Element> > headers20 = http.parseEchoRequest(*hex_req20);
1171     if ((strncmp(headers20[0]->getName(), "echo", 4) == 0)
1172         && (strncmp(headers20[1]->getName(), "/10", 2) == 0)
1173         && (headers20[3]->getType() == Element::NUMBER_AMF0)
1174         && (headers20[3]->to_number() == -1.5)) {
1175         runtest.pass("HTTP::parseEchoRequest(Number -1.5)");
1176     } else {
1177         runtest.fail("HTTP::parseEchoRequest(Number -1.5)");
1178     }
1179     // Number -1.5 Response
1180     std::shared_ptr<Buffer> hex_res20(new Buffer("00 00 00 00 00 01 00 0c 2f 31 30 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 bf f8 00 00 00 00 00 00"));
1181     cygnal::Buffer &buf20 = http.formatEchoResponse(headers20[1]->getName(), *headers20[3]);
1182     string head20(reinterpret_cast<const char *>(buf20.reference()));
1183     const char *ptr20a = reinterpret_cast<const char *>(hex_res20->reference());
1184     const char *ptr20b = reinterpret_cast<const char *>(buf20.reference()) + head20.size();
1185     if (memcmp(ptr20a, ptr20b, hex_res20->allocated()-11) == 0) {
1186         runtest.pass("HTTP::formatEchoResponse(Number -1.5");
1187     } else {
1188         runtest.fail("HTTP::formatEchoResponse(Number -1.5");
1189     }
1190 
1191     // Number NaN Request
1192     std::shared_ptr<Buffer> hex_req21(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 03 2f 31 31 00 00 00 0e 0a 00 00 00 01 00 ff f8 00 00 00 00 00 00"));
1193     vector<std::shared_ptr<cygnal::Element> > headers21 = http.parseEchoRequest(*hex_req21);
1194     if ((strncmp(headers21[0]->getName(), "echo", 4) == 0)
1195         && (strncmp(headers21[1]->getName(), "/11", 2) == 0)
1196         && (headers21[3]->getType() == Element::NUMBER_AMF0)
1197         && (isnan(headers21[3]->to_number()))) {
1198         runtest.pass("HTTP::parseEchoRequest(Number NaN)");
1199     } else {
1200         runtest.fail("HTTP::parseEchoRequest(Number Nan)");
1201     }
1202     // Number NaN Response
1203     std::shared_ptr<Buffer> hex_res21(new Buffer("00 00 00 00 00 01 00 0c 2f 31 31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 ff f8 00 00 00 00 00 00"));
1204     cygnal::Buffer &buf21 = http.formatEchoResponse(headers21[1]->getName(), *headers21[3]);
1205     string head21(reinterpret_cast<const char *>(buf21.reference()));
1206     const char *ptr21a = reinterpret_cast<const char *>(hex_res21->reference());
1207     const char *ptr21b = reinterpret_cast<const char *>(buf21.reference()) + head21.size();
1208     if (memcmp(ptr21a, ptr21b, hex_res21->allocated()-11) == 0) {
1209         runtest.pass("HTTP::formatEchoResponse(Number Nan");
1210     } else {
1211         runtest.fail("HTTP::formatEchoResponse(Number Nan");
1212     }
1213 
1214     // Number -Infinity Request
1215     std::shared_ptr<Buffer> hex_req22(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 03 2f 31 32 00 00 00 0e 0a 00 00 00 01 00 ff f0 00 00 00 00 00 00"));
1216 
1217     // Number Infinity Request
1218     std::shared_ptr<Buffer> hex_req22x(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 03 2f 31 34 00 00 00 0e 0a 00 00 00 01 00 7f ef ff ff ff ff ff ff"));
1219     vector<std::shared_ptr<cygnal::Element> > headers22x = http.parseEchoRequest(*hex_req22x);
1220     if ((strncmp(headers22x[0]->getName(), "echo", 4) == 0)
1221         && (strncmp(headers22x[1]->getName(), "/14", 2) == 0)
1222         && (headers22x[3]->getType() == Element::NUMBER_AMF0)
1223         && (isFinite(headers22x[3]->to_number()))) {
1224         runtest.pass("HTTP::parseEchoRequest(Number Infinity)");
1225     } else {
1226         runtest.fail("HTTP::parseEchoRequest(Number Infinity)");
1227     }
1228     // Number Infinity Response
1229     std::shared_ptr<Buffer> hex_res23(new Buffer("00 00 00 00 00 01 00 0c 2f 31 33 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 7f f0 00 00 00 00 00 00"));
1230 #if 0
1231     cygnal::Buffer &buf23 = http.formatEchoResponse(headers22x[1]->getName(), *headers22x[3]);
1232     string head23(reinterpret_cast<const char *>(buf23.reference()));
1233     const char *ptr23a = reinterpret_cast<const char *>(hex_res23->reference());
1234     const char *ptr23b = reinterpret_cast<const char *>(buf23.reference()) + head23.size();
1235     if (memcmp(ptr23a, ptr23b, hex_res23->allocated()-11) == 0) {
1236         runtest.pass("HTTP::formatEchoResponse(Number Infinity)");
1237     } else {
1238         runtest.fail("HTTP::formatEchoResponse(Number Infinity)");
1239     }
1240 #endif
1241 
1242     // Number 1.79769313486231e+308 Request
1243     std::shared_ptr<Buffer> hex_req24(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 03 2f 31 35 00 00 00 0e 0a 00 00 00 01 00 00 00 00 00 00 00 00 01"));
1244     // Number 1.79769313486231e+308 Response
1245     std::shared_ptr<Buffer> hex_res24(new Buffer("00 00 00 00 00 01 00 0c 2f 31 34 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 7f ef ff ff ff ff ff ff"));
1246 
1247     // Number 4.940656484124654e-324 Request
1248     std::shared_ptr<Buffer> hex_req25(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 03 2f 31 36 00 00 00 0e 0a 00 00 00 01 00 00 00 00 00 00 00 00 00"));
1249     // Number 4.940656484124654e-324 Response
1250     std::shared_ptr<Buffer> hex_res25(new Buffer("00 00 00 00 00 01 00 0c 2f 31 35 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 00 00 00 00 00 00 00 00 01"));
1251 
1252     // Number 1,2,1,2
1253     // Array request
1254     std::shared_ptr<Buffer> hex_req26(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 35 00 00 00 33 0a 00 00 00 01 0a 00 00 00 03 00 3f f0 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 0a 00 00 00 02 00 3f f0 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00"));
1255     vector<std::shared_ptr<cygnal::Element> > headers26 = http.parseEchoRequest(*hex_req26);
1256     std::vector<std::shared_ptr<cygnal::Element> > props26 = headers26[3]->getProperties();
1257     std::vector<std::shared_ptr<cygnal::Element> > props26a = props26[2]->getProperties();
1258     if ((strncmp(headers26[0]->getName(), "echo", 4) == 0)
1259         && (strncmp(headers26[1]->getName(), "/5", 2) == 0)
1260         && (headers26[3]->getType() == Element::STRICT_ARRAY_AMF0)
1261 	&& (props26[0]->getType() == Element::NUMBER_AMF0)
1262 	&& (props26[0]->to_number() == 1)
1263 	&& (props26[2]->getType() == Element::STRICT_ARRAY_AMF0)
1264 	&& (props26a[1]->getType() == Element::NUMBER_AMF0)
1265 	&& (props26a[1]->to_number() == 2)
1266 	) {
1267         runtest.pass("HTTP::parseEchoRequest(Strict Array of Numbers, 3 items)");
1268     } else {
1269         runtest.fail("HTTP::parseEchoRequest(Strict Array of Numbers, 3 items)");
1270     }
1271     // Undefined Array response
1272     std::shared_ptr<Buffer> hex_res26(new Buffer("00 00 00 00 00 01 00 0b 2f 35 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 0a 00 00 00 03 00 3f f0 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 0a 00 00 00 02 00 3f f0 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00"));
1273     cygnal::Buffer &buf26 = http.formatEchoResponse(headers26[1]->getName(), *headers26[3]);
1274     string head26(reinterpret_cast<const char *>(buf26.reference()));
1275     //    cerr << hexify(hex_res26->reference()+30, amf::AMF0_NUMBER_SIZE, false) << endl;
1276     const char *ptr26a = reinterpret_cast<const char *>(hex_res26->reference());
1277     //    cerr << hexify(buf26.reference() + 124, amf::AMF0_NUMBER_SIZE, false) << endl;
1278     const char *ptr26b = reinterpret_cast<const char *>(buf26.reference()) + head26.size();
1279     if (memcmp(ptr26a, ptr26b, hex_res26->allocated()-1) == 0) {
1280         runtest.pass("HTTP::formatEchoResponse(Strict Array of Numbers, 3 items)");
1281     } else {
1282         runtest.fail("HTTP::formatEchoResponse(Strict Array of Numbers, 3 items)");
1283     }
1284 
1285     // Number 1,,,,,,,100
1286     // Array request
1287     std::shared_ptr<Buffer> hex_req27(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 36 00 00 00 7f 0a 00 00 00 01 0a 00 00 00 65 00 3f f0 00 00 00 00 00 00 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 06 00 40 59 00 00 00 00 00 00"));
1288     vector<std::shared_ptr<cygnal::Element> > headers27 = http.parseEchoRequest(*hex_req27);
1289     std::vector<std::shared_ptr<cygnal::Element> > props27 = headers27[3]->getProperties();
1290     if ((strncmp(headers27[0]->getName(), "echo", 4) == 0)
1291         && (strncmp(headers27[1]->getName(), "/6", 2) == 0)
1292         && (headers27[3]->getType() == Element::STRICT_ARRAY_AMF0)
1293         && (props27[0]->to_number() == 1)
1294         && (props27[1]->getType() == Element::UNDEFINED_AMF0)
1295         && (props27[0]->getType() == Element::NUMBER_AMF0)
1296         && (props27[0]->to_number() == 1)
1297         && (props27[100]->to_number() == 100)
1298         ) { // FIXME: add test for array values
1299         runtest.pass("HTTP::parseEchoRequest(Strict Array - Number, undefines, Number)");
1300     } else {
1301         runtest.fail("HTTP::parseEchoRequest(Strict Array - Number, undefines, Number)");
1302     }
1303     // Undefined Array response
1304     std::shared_ptr<Buffer> hex_res27(new Buffer("00 00 00 00 00 01 00 0b 2f 36 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 08 00 00 00 66 00 01 30 00 3f f0 00 00 00 00 00 00 00 03 31 30 30 00 40 59 00 00 00 00 00 00 00 06 6c 65 6e 67 74 68 00 40 59 80 00 00 00 00 00 00 00 09"));
1305 #if 0
1306     cygnal::Buffer &buf27 = http.formatEchoResponse(headers27[1]->getName(), *headers27[3]);
1307     string head27(reinterpret_cast<const char *>(buf27.reference()));
1308     cerr << hexify(hex_res27->reference()+29, hex_res27->allocated()-29 , false) << endl;
1309     cerr << hexify(buf27.reference() + 123, buf27.allocated()-123, false) << endl;
1310     const char *ptr27a = reinterpret_cast<const char *>(hex_res27->reference());
1311     const char *ptr27b = reinterpret_cast<const char *>(buf27.reference()) + head27.size();
1312     if (memcmp(ptr27a, ptr27b, hex_res27->allocated()-1) == 0) {
1313         runtest.pass("HTTP::formatEchoResponse(Strict Array - Number, undefines, Number)");
1314     } else {
1315         runtest.fail("HTTP::formatEchoResponse(Strict Array  - Number, undefines, Number)");
1316     }
1317 #endif
1318 
1319 #if 0
1320     // Array request
1321     std::shared_ptr<Buffer> hex_req28(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 37 00 00 00 38 0a 00 00 00 01 08 00 00 00 01 00 06 6c 65 6e 67 74 68 00 3f f0 00 00 00 00 00 00 00 01 30 00 3f f0 00 00 00 00 00 00 00 03 6f 6e 65 00 3f f0 00 00 00 00 00 00 00 00 09"));
1322     vector<std::shared_ptr<cygnal::Element> > headers28 = http.parseEchoRequest(*hex_req28);
1323     std::vector<std::shared_ptr<cygnal::Element> > props28 = headers28[3]->getProperties();
1324     if ((strncmp(headers28[0]->getName(), "echo", 4) == 0)
1325         && (strncmp(headers28[1]->getName(), "/7", 2) == 0)
1326         && (headers28[3]->getType() == Element::ECMA_ARRAY_AMF0)
1327         && (props28[0]->getType() == Element::NUMBER_AMF0)
1328         && (strcmp(props28[0]->getName(), "length") == 0)
1329         && (props28[0]->to_number() == 1)
1330         && (props28[2]->getType() == Element::NUMBER_AMF0)
1331         && (strcmp(props28[2]->getName(), "one") == 0)
1332         && (props28[2]->to_number() == 1)
1333         ) {
1334         runtest.pass("HTTP::parseEchoRequest(ECMA Array, 2 Numbers)");
1335     } else {
1336         runtest.fail("HTTP::parseEchoRequest(ECMA Array, 2 Numbers)");
1337     }
1338 
1339     // Undefined Array response
1340     std::shared_ptr<Buffer> hex_res28(new Buffer("00 00 00 00 00 01 00 0b 2f 37 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 08 00 00 00 01 00 03 6f 6e 65 00 3f f0 00 00 00 00 00 00 00 01 30 00 3f f0 00 00 00 00 00 00 00 06 6c 65 6e 67 74 68 00 3f f0 00 00 00 00 00 00 00 00 09"));
1341     cygnal::Buffer &buf28 = http.formatEchoResponse(headers28[1]->getName(), *headers28[3]);
1342 //     cerr << hexify(hex_res28->reference()+30, hex_res28->allocated()-30, false) << endl;
1343 //     cerr << hexify(buf28.reference() + 124, buf28.allocated() - 124, false) << endl;
1344     string head28(reinterpret_cast<const char *>(buf28.reference()));
1345     const char *ptr28a = reinterpret_cast<const char *>(hex_res28->reference());
1346     const char *ptr28b = reinterpret_cast<const char *>(buf28.reference()) + head28.size();
1347     if (memcmp(ptr28a, ptr28b, hex_res28->allocated()-1) == 0) {
1348         runtest.pass("HTTP::formatEchoResponse(ECMA Array, 2 Numbers)");
1349     } else {
1350         runtest.fail("HTTP::formatEchoResponse(ECMA Array, 2 Numbers)");
1351     }
1352 #endif
1353 
1354     // NULL String request, ie.. no data
1355     std::shared_ptr<Buffer> hex_req29(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 31 00 00 00 08 0a 00 00 00 01 02 00 00"));
1356     vector<std::shared_ptr<cygnal::Element> > headers29 = http.parseEchoRequest(*hex_req29);
1357     if ((strncmp(headers29[0]->getName(), "echo", 4) == 0)
1358         && (strncmp(headers29[1]->getName(), "/1", 2) == 0)
1359         && (headers29[3]->getType() == Element::STRING_AMF0)
1360         && (headers29[3]->to_string() == 0)) {
1361         runtest.pass("HTTP::parseEchoRequest(NULL String)");
1362     } else {
1363         runtest.fail("HTTP::parseEchoRequest(NULL String)");
1364     }
1365     // NULL String response
1366     std::shared_ptr<Buffer> hex_res29(new Buffer("00 00 00 00 00 01 00 0b 2f 31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 02 00 00"));
1367 #if 0                           // FIXME: why does this core dump ?
1368     cygnal::Buffer &buf29 = http.formatEchoResponse(headers29[1]->getName(), *headers29[3]);
1369     string head29(reinterpret_cast<const char *>(buf29.reference()));
1370     const char *ptr29a = reinterpret_cast<const char *>(hex_res29->reference());
1371     const char *ptr29b = reinterpret_cast<const char *>(buf29.reference()) + head29.size();
1372     if (memcmp(ptr29a, ptr29b, hex_res29->allocated()-1) == 0) {
1373         runtest.pass("HTTP::formatEchoResponse(NULL String)");
1374     } else {
1375         runtest.fail("HTTP::formatEchoResponse(NULL String)");
1376     }
1377 #endif
1378 
1379     // String request
1380     // "Hello world!"
1381     std::shared_ptr<Buffer> hex_req30(new Buffer(" 00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 32 00 00 00 14 0a 00 00 00 01 02 00 0c 48 65 6c 6c 6f 20 77 6f 72 6c 64 21"));
1382     vector<std::shared_ptr<cygnal::Element> > headers30 = http.parseEchoRequest(*hex_req30);
1383     if ((strncmp(headers30[0]->getName(), "echo", 4) == 0)
1384         && (strncmp(headers30[1]->getName(), "/2", 2) == 0)
1385         && (headers30[3]->getType() == Element::STRING_AMF0)
1386         && (strcmp(headers30[3]->to_string(), "Hello world!") == 0)) {
1387         runtest.pass("HTTP::parseEchoRequest(Simple String)");
1388     } else {
1389         runtest.fail("HTTP::parseEchoRequest(Simple String)");
1390     }
1391     // String response
1392     std::shared_ptr<Buffer> hex_res30(new Buffer("00 00 00 00 00 01 00 0b 2f 32 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 02 00 0c 48 65 6c 6c 6f 20 77 6f 72 6c 64 21"));
1393     cygnal::Buffer &buf30 = http.formatEchoResponse(headers30[1]->getName(), *headers30[3]);
1394     string head30(reinterpret_cast<const char *>(buf30.reference()));
1395     const char *ptr30a = reinterpret_cast<const char *>(hex_res30->reference());
1396     const char *ptr30b = reinterpret_cast<const char *>(buf30.reference()) + head30.size();
1397     if (memcmp(ptr30a, ptr30b, hex_res30->allocated()-1) == 0) {
1398         runtest.pass("HTTP::formatEchoResponse(Simple String)");
1399     } else {
1400         runtest.fail("HTTP::formatEchoResponse(Simple String)");
1401     }
1402 
1403     // Array of Strings request
1404     // test1,test2,test3,test4
1405     std::shared_ptr<Buffer> hex_req31(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 33 00 00 00 2a 0a 00 00 00 01 0a 00 00 00 04 02 00 05 74 65 73 74 31 02 00 05 74 65 73 74 32 02 00 05 74 65 73 74 33 02 00 05 74 65 73 74 34"));
1406     vector<std::shared_ptr<cygnal::Element> > headers31 = http.parseEchoRequest(*hex_req31);
1407     if (headers31.size() == 0) {
1408         runtest.unresolved("HTTP::parseEchoRequest(Simple String Array)");
1409     } else {
1410 
1411         std::vector<std::shared_ptr<cygnal::Element> > props31 = headers31[3]->getProperties();
1412         if ((strncmp(headers31[0]->getName(), "echo", 4) == 0)
1413             && (strncmp(headers31[1]->getName(), "/3", 2) == 0)
1414             && (headers31[3]->getType() == Element::STRICT_ARRAY_AMF0)
1415             && (strcmp(props31[0]->to_string(), "test1") == 0)
1416             && (strcmp(props31[1]->to_string(), "test2") == 0)
1417             && (strcmp(props31[2]->to_string(), "test3") == 0)
1418             && (strcmp(props31[3]->to_string(), "test4") == 0)
1419             ) {
1420             runtest.pass("HTTP::parseEchoRequest(Simple String Array)");
1421         } else {
1422             runtest.fail("HTTP::parseEchoRequest(Simple String Array)");
1423         }
1424     }
1425 
1426     // Array of Strings response
1427     std::shared_ptr<Buffer> hex_res31(new Buffer("00 00 00 00 00 01 00 0b 2f 33 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 0a 00 00 00 04 02 00 05 74 65 73 74 31 02 00 05 74 65 73 74 32 02 00 05 74 65 73 74 33 02 00 05 74 65 73 74 34"));
1428     cygnal::Buffer &buf31 = http.formatEchoResponse(headers31[1]->getName(), *headers31[3]);
1429     string head31(reinterpret_cast<const char *>(buf31.reference()));
1430     const char *ptr31a = reinterpret_cast<const char *>(hex_res31->reference());
1431     const char *ptr31b = reinterpret_cast<const char *>(buf31.reference()) + head31.size();
1432     if (memcmp(ptr31a, ptr31b, hex_res31->allocated()-1) == 0) {
1433         runtest.pass("HTTP::formatEchoResponse(Simple String Array)");
1434     } else {
1435         runtest.fail("HTTP::formatEchoResponse(Simple String Array)");
1436     }
1437 
1438     // Custom class Request
1439     // [object EchoClass]                    [object.Object]
1440     std::shared_ptr<Buffer> hex_req40(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 31 00 00 00 26 0a 00 00 00 01 03 00 05 61 74 74 72 32 00 3f f0 00 00 00 00 00 00 00 05 61 74 74 72 31 02 00 03 6f 6e 65 00 00 09"));
1441     vector<std::shared_ptr<cygnal::Element> > headers40 = http.parseEchoRequest(*hex_req40);
1442     if (headers40[3] == 0) {
1443         runtest.unresolved("HTTP::parseEchoRequest(object CustomClass)");
1444     } else {
1445         std::vector<std::shared_ptr<cygnal::Element> > props40 = headers40[3]->getProperties();
1446         if ((strncmp(headers40[0]->getName(), "echo", 4) == 0)
1447             && (strncmp(headers40[1]->getName(), "/1", 2) == 0)
1448             && (headers40[3]->getType() == Element::OBJECT_AMF0)
1449             && (strcmp(props40[0]->getName(), "attr2") == 0)
1450             && (props40[0]->to_number() == 1)
1451             && (strcmp(props40[1]->getName(), "attr1") == 0)
1452             && (strcmp(props40[1]->to_string(), "one") == 0)) {
1453             runtest.pass("HTTP::parseEchoRequest(object CustomClass)");
1454         } else {
1455             runtest.fail("HTTP::parseEchoRequest(object CustomClass)");
1456         }
1457     }
1458     std::shared_ptr<Buffer> hex_res40(new Buffer("00 00 00 00 00 01 00 0b 2f 31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 03 00 05 61 74 74 72 32 00 3f f0 00 00 00 00 00 00 00 05 61 74 74 72 31 02 00 03 6f 6e 65 00 00 09"));
1459     cygnal::Buffer &buf40 = http.formatEchoResponse(headers40[1]->getName(), *headers40[3]);
1460 
1461     string head40(reinterpret_cast<const char *>(buf40.reference()));
1462     const char *ptr40a = reinterpret_cast<const char *>(hex_res40->reference());
1463     const char *ptr40b = reinterpret_cast<const char *>(buf40.reference()) + head40.size();
1464     if (memcmp(ptr40a, ptr40b, hex_res40->allocated()-1) == 0) {
1465         runtest.pass("HTTP::formatEchoResponse(object CustomClass)");
1466     } else {
1467         runtest.fail("HTTP::formatEchoResponse(object CustomClass)");
1468     }
1469 
1470     // [object EchoClass],[object EchoClass] [object.Object],[object.Object]
1471     std::shared_ptr<Buffer> hex_req41(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 32 00 00 00 2e 0a 00 00 00 01 0a 00 00 00 02 03 00 05 61 74 74 72 32 00 3f f0 00 00 00 00 00 00 00 05 61 74 74 72 31 02 00 03 6f 6e 65 00 00 09 07 00 01"));
1472     vector<std::shared_ptr<cygnal::Element> > headers41 = http.parseEchoRequest(*hex_req41);
1473     if (headers41[3] == 0) {
1474         runtest.unresolved("HTTP::parseEchoRequest(object CustomClass Array)");
1475     } else {
1476         if ((headers41[3]->getType() == Element::STRICT_ARRAY_AMF0)
1477 	    && (headers41[3]->propertySize() == 2)) {
1478             runtest.pass("HTTP::parseEchoRequest(object CustomClass Array)");
1479         } else {
1480             runtest.fail("HTTP::parseEchoRequest(object CustomClass Array)");
1481         }
1482     }
1483     std::shared_ptr<Buffer> hex_res41(new Buffer("00 00 00 00 00 01 00 0b 2f 32 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 0a 00 00 00 02 03 00 05 61 74 74 72 32 00 3f f0 00 00 00 00 00 00 00 05 61 74 74 72 31 02 00 03 6f 6e 65 00 00 09 07 00 01"));
1484     cygnal::Buffer &buf41 = http.formatEchoResponse(headers41[1]->getName(), *headers41[3]);
1485     string head41(reinterpret_cast<const char *>(buf41.reference()));
1486     const char *ptr41a = reinterpret_cast<const char *>(hex_res41->reference());
1487     const char *ptr41b = reinterpret_cast<const char *>(buf41.reference()) + head41.size();
1488     if (memcmp(ptr41a, ptr41b, hex_res41->allocated()-4) == 0) {
1489         runtest.pass("HTTP::formatEchoResponse(object CustomClass Array)");
1490     } else {
1491         runtest.fail("HTTP::formatEchoResponse(object CustomClass Array)");
1492     }
1493 
1494     // Remote Class
1495     // [object RemoteClass]                      [object RemoteClass]
1496     std::shared_ptr<Buffer> hex_req42(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 31 00 00 00 59 0a 00 00 00 01 10 00 27 6f 72 67 2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 32 00 40 00 00 00 00 00 00 00 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 03 6f 6e 65 00 00 09"));
1497     vector<std::shared_ptr<cygnal::Element> > headers42 = http.parseEchoRequest(*hex_req42);
1498     if (headers42[3] == 0) {
1499         runtest.unresolved("HTTP::parseEchoRequest(Remote Class)");
1500     } else {
1501         if ((strncmp(headers42[0]->getName(), "echo", 4) == 0)
1502             && (strncmp(headers42[1]->getName(), "/1", 2) == 0)
1503             && (headers42[3]->getType() == Element::TYPED_OBJECT_AMF0)
1504             && (headers42[3]->propertySize() == 2)) {
1505             runtest.pass("HTTP::parseEchoRequest(object RemoteClass)");
1506         } else {
1507             runtest.fail("HTTP::parseEchoRequest(object RemoteClass)");
1508         }
1509     }
1510 
1511     std::shared_ptr<Buffer> hex_res42(new Buffer("00 00 00 00 00 01 00 0b 2f 31 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 10 00 27 6f 72 67 2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 03 6f 6e 65 00 0a 61 74 74 72 69 62 75 74 65 32 00 40 00 00 00 00 00 00 00 00 00 09"));
1512     cygnal::Buffer &buf42 = http.formatEchoResponse(headers42[1]->getName(), *headers42[3]);
1513     string head42(reinterpret_cast<const char *>(buf42.reference()));
1514     const char *ptr42a = reinterpret_cast<const char *>(hex_res42->reference());
1515     const char *ptr42b = reinterpret_cast<const char *>(buf42.reference()) + head42.size();
1516     if (memcmp(ptr42a, ptr42b, hex_res42->allocated()-1) == 0) {
1517         runtest.pass("HTTP::formatEchoResponse(object RemoteClass)");
1518     } else {
1519         runtest.fail("HTTP::formatEchoResponse(object RemoteClass)");
1520     }
1521 
1522     // An array of RemoteClass objects
1523     // org.red5.server.webapp.echo.RemoteClass
1524     // [object RemoteClass],[object RemoteClass] [object RemoteClass],[object RemoteClass]
1525     std::shared_ptr<Buffer> hex_req43(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 32 00 00 00 b2 0a 00 00 00 01 0a 00 00 00 02 10 00 27 6f 72 67 2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 32 00 3f f0 00 00 00 00 00 00 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 03 6f 6e 65 00 00 09 10 00 27 6f 72 67 2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 32 00 40 00 00 00 00 00 00 00 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 03 74 77 6f 00 00 09"));
1526     vector<std::shared_ptr<cygnal::Element> > headers43 = http.parseEchoRequest(*hex_req43);
1527     if (headers43[3] == 0) {
1528         runtest.unresolved("HTTP::parseEchoRequest(object RemoteClass Array, 2 items)");
1529     } else {
1530 	std::vector<std::shared_ptr<cygnal::Element> > props43 = headers43[3]->getProperties();
1531 	std::vector<std::shared_ptr<cygnal::Element> > props43a = props43[0]->getProperties();
1532 	std::vector<std::shared_ptr<cygnal::Element> > props43b = props43[1]->getProperties();
1533         if ((strncmp(headers43[0]->getName(), "echo", 4) == 0)
1534             && (strncmp(headers43[1]->getName(), "/2", 2) == 0)
1535             && (headers43[3]->getType() == Element::STRICT_ARRAY_AMF0)
1536 	    && (props43[0]->getType() == Element::TYPED_OBJECT_AMF0)
1537 	    && (props43a[0]->getType() == Element::NUMBER_AMF0)
1538 	    && (props43[1]->getType() == Element::TYPED_OBJECT_AMF0)
1539 	    && (props43a[1]->getType() == Element::STRING_AMF0)
1540             && (strncmp(props43a[0]->getName(), "attribute2", 10) == 0)
1541             && (props43a[0]->to_number() == 1)
1542             && (strncmp(props43a[1]->getName(), "attribute1", 10) == 0)
1543             && (strncmp(props43a[1]->to_string(), "one", 3) == 0)
1544             && (strncmp(props43b[0]->getName(), "attribute2", 10) == 0)
1545             && (props43b[0]->to_number() == 2)
1546             && (strncmp(props43b[1]->getName(), "attribute1", 10) == 0)
1547             && (strncmp(props43b[1]->to_string(), "two", 3) == 0)
1548 	    ) {
1549             runtest.pass("HTTP::parseEchoRequest(object RemoteClass Array, 2 items)");
1550         } else {
1551             runtest.fail("HTTP::parseEchoRequest(object RemoteClass Array, 2 items)");
1552         }
1553     }
1554     std::shared_ptr<Buffer> hex_res43(new Buffer("00 00 00 00 00 01 00 0b 2f 32 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 0a 00 00 00 02 10 00 27 6f 72 67 2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 03 6f 6e 65 00 0a 61 74 74 72 69 62 75 74 65 32 00 3f f0 00 00 00 00 00 00 00 00 09 10 00 27 6f 72 67 2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 03 74 77 6f 00 0a 61 74 74 72 69 62 75 74 65 32 00 40 00 00 00 00 00 00 00 00 00 09"));
1555     cygnal::Buffer &buf43 = http.formatEchoResponse(headers43[1]->getName(), *headers43[3]);
1556     std::vector<std::shared_ptr<cygnal::Element> > props43 = headers43[3]->getProperties();
1557     //    std::vector<std::shared_ptr<cygnal::Element> > props43a = props43[0]->getProperties();
1558 //     cerr << hexify(hex_res43->reference()+29, hex_res43->allocated()-29 , false) << endl;
1559 //     cerr << hexify(buf43.reference(), buf43.allocated(), true) << endl;
1560 //     cerr << hexify(buf43.reference() + 124, buf43.allocated()-124, false) << endl;
1561     string head43(reinterpret_cast<const char *>(buf43.reference()));
1562     const char *ptr43a = reinterpret_cast<const char *>(hex_res43->reference());
1563     const char *ptr43b = reinterpret_cast<const char *>(buf43.reference()) + head43.size();
1564 #if 0
1565     if (memcmp(ptr43a, ptr43b, hex_res43->allocated()-4) == 0) {
1566         runtest.xpass("HTTP::formatEchoResponse(object RemoteClass Array, 2 items)");
1567     } else {
1568         runtest.xfail("HTTP::formatEchoResponse(object RemoteClass Array, 2 items)");
1569     }
1570 #endif
1571 
1572     // [object RemoteClass]                      [object RemoteClass]
1573     std::shared_ptr<Buffer> hex_req44(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 33 00 00 00 5b 0a 00 00 00 01 10 00 27 6f 72 67 2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 32 00 41 d2 65 80 b4 80 00 00 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 05 74 68 72 65 65 00 00 09"));
1574     vector<std::shared_ptr<cygnal::Element> > headers44 = http.parseEchoRequest(*hex_req44);
1575     if (headers44[3] == 0) {
1576         runtest.unresolved("HTTP::parseEchoRequest(object RemoteClass Array)");
1577     } else {
1578         if ((strncmp(headers44[0]->getName(), "echo", 4) == 0)
1579             && (strncmp(headers44[1]->getName(), "/3", 2) == 0)
1580             && (headers44[3]->getType() == Element::TYPED_OBJECT_AMF0)) {
1581             runtest.pass("HTTP::parseEchoRequest(object RemoteClass Array, 2 items)");
1582         } else {
1583             runtest.fail("HTTP::parseEchoRequest(object RemoteClass Array, 2 items)");
1584         }
1585     }
1586     std::shared_ptr<Buffer> hex_res44(new Buffer("00 00 00 00 00 01 00 0b 2f 33 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 10 00 27 6f 72 67 2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 05 74 68 72 65 65 00 0a 61 74 74 72 69 62 75 74 65 32 00 41 d2 65 80 b4 80 00 00 00 00 09"));
1587     cygnal::Buffer &buf44 = http.formatEchoResponse(headers44[1]->getName(), *headers44[3]);
1588     string head44(reinterpret_cast<const char *>(buf44.reference()));
1589     const char *ptr44a = reinterpret_cast<const char *>(hex_res44->reference());
1590     const char *ptr44b = reinterpret_cast<const char *>(buf44.reference()) + head44.size();
1591     if (memcmp(ptr44a, ptr44b, hex_res44->allocated()-1) == 0) {
1592         runtest.pass("HTTP::formatEchoResponse(object RemoteClass)");
1593     } else {
1594         runtest.fail("HTTP::formatEchoResponse(object RemoteClass)");
1595     }
1596 
1597 #if 0
1598     // [object RemoteClass]                      [object RemoteClass]
1599     std::shared_ptr<Buffer> hex_req45(new Buffer("00 00 00 00 00 01 00 04 65 63 68 6f 00 02 2f 34 00 00 00 5a 0a 00 00 00 01 10 00 27 6f 72 67 2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 32 00 42 71 3f 8f 4d 00 00 00 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 04 66 6f 75 72 00 00 09"));
1600     vector<std::shared_ptr<cygnal::Element> > headers45 = http.parseEchoRequest(*hex_req45);
1601     if (headers45[3] == 0) {
1602         runtest.unresolved("HTTP::parseEchoRequest(object RemoteClass Array)");
1603     } else {
1604 	std::vector<std::shared_ptr<cygnal::Element> > props45 = headers45[3]->getProperties();
1605         if (props45.size() == 2) {
1606             if ((strncmp(headers45[0]->getName(), "echo", 4) == 0)
1607                 && (strncmp(headers45[1]->getName(), "/4", 2) == 0)
1608                 && (headers45[3]->getType() == Element::TYPED_OBJECT_AMF0)
1609                 && (strcmp(headers45[3]->getName(), "org.red5.server.webapp.echo.RemoteClass") == 0)
1610                 && (props45[0]->getType() == Element::NUMBER_AMF0)
1611                 && (strncmp(props45[0]->getName(), "attribute2", 10) == 0)
1612                 && (props45[1]->getType() == Element::STRING_AMF0)
1613                 && (strncmp(props45[1]->getName(), "attribute1", 10) == 0)
1614                 && (strncmp(props45[1]->to_string(), "four", 4) == 0)
1615                 ) {
1616                 runtest.pass("HTTP::parseEchoRequest(object RemoteClass)");
1617             } else {
1618                 runtest.fail("HTTP::parseEchoRequest(object RemoteClass)");
1619             }
1620         } else {
1621             runtest.untested("HTTP::parseEchoRequest(object RemoteClass)");
1622         }
1623     }
1624 
1625     std::shared_ptr<Buffer> hex_res45(new Buffer("00 00 00 00 00 01 00 0b 2f 34 2f 6f 6e 52 65 73 75 6c 74 00 04 6e 75 6c 6c ff ff ff ff 10 00 27 6f 72 67 2e 72 65 64 35 2e 73 65 72 76 65 72 2e 77 65 62 61 70 70 2e 65 63 68 6f 2e 52 65 6d 6f 74 65 43 6c 61 73 73 00 0a 61 74 74 72 69 62 75 74 65 31 02 00 04 66 6f 75 72 00 0a 61 74 74 72 69 62 75 74 65 32 00 c1 9c 2c c0 00 00 00 00 00 00 09"));
1626     cygnal::Buffer &buf45 = http.formatEchoResponse(headers45[1]->getName(), *headers45[3]);
1627     string head45(reinterpret_cast<const char *>(buf45.reference()));
1628     const char *ptr45a = reinterpret_cast<const char *>(hex_res45->reference());
1629     const char *ptr45b = reinterpret_cast<const char *>(buf45.reference()) + head45.size();
1630 //     cerr << hexify(hex_res45->reference()+29, hex_res45->allocated()-29 , false) << endl;
1631 //     cerr << hexify(buf45.reference()+124, buf45.allocated()-124, true) << endl;
1632 //     cerr << hexify(buf45.reference()+123, buf45.allocated()-123, false) << endl;
1633     if (memcmp(ptr45a, ptr45b, hex_res45->allocated()-11) == 0) {
1634         runtest.pass("HTTP::formatEchoResponse(object RemoteClass)");
1635     } else {
1636         runtest.fail("HTTP::formatEchoResponse(object RemoteClass)");
1637     }
1638 #endif
1639 
1640     // String test with 40000 characters
1641     // String test with 70000 characters
1642     // String test with 1000000 characters
1643 
1644 #ifdef CORRUPT_MEMORY_TESTS
1645     // Use the existing binary data and see if we can survive decoding corupted
1646     // packets. While the data may be bogus in the returned Elements, we shouldn't
1647     // ever crash,. so these are primarily a stress test.
1648 //    cerr << hexify(hex_req1->reference(), hex_req1->allocated(), false) << endl;
1649     hex_req1->corrupt(6);
1650 //    cerr << hexify(hex_req1->reference(), hex_req1->allocated(), false) << endl;
1651     vector<std::shared_ptr<cygnal::Element> > corrupt1 = http.parseEchoRequest(*hex_req1);
1652     if (corrupt1.size()) {
1653         runtest.pass("Corrupted HTTP::parseEchoRequest(Boolean TRUE)");
1654     } else {
1655         runtest.fail("Corrupted HTTP::parseEchoRequest(Boolean TRUE)");
1656     }
1657 
1658 //    cerr << hexify(hex_req2->reference(), hex_req2->allocated(), false) << endl;
1659     hex_req2->corrupt(4);
1660 //    cerr << hexify(hex_req2->reference(), hex_req2->allocated(), false) << endl;
1661     vector<std::shared_ptr<cygnal::Element> > corrupt2 = http.parseEchoRequest(*hex_req2);
1662     if (corrupt2.size()) {
1663         runtest.pass("Corrupted HTTP::parseEchoRequest(Boolean FALSE)");
1664     } else {
1665         runtest.fail("Corrupted HTTP::parseEchoRequest(Boolean FALSE)");
1666     }
1667 
1668 //    cerr << hexify(hex_req3->reference(), hex_req3->allocated(), false) << endl;
1669     hex_req3->corrupt(3);
1670 //    cerr << hexify(hex_req3->reference(), hex_req3->allocated(), false) << endl;
1671     vector<std::shared_ptr<cygnal::Element> > corrupt3 = http.parseEchoRequest(*hex_req3);
1672     if (corrupt3.size()) {
1673         runtest.pass("Corrupted HTTP::parseEchoRequest(NULL Object)");
1674     } else {
1675         runtest.fail("Corrupted HTTP::parseEchoRequest(NULL Object)");
1676     }
1677 
1678 //    cerr << hexify(hex_req4->reference(), hex_req4->allocated(), false) << endl;
1679     hex_req4->corrupt(7);
1680 //    cerr << hexify(hex_req4->reference(), hex_req4->allocated(), false) << endl;
1681     vector<std::shared_ptr<cygnal::Element> > corrupt4 = http.parseEchoRequest(*hex_req4);
1682     if (corrupt4.size()) {
1683         runtest.pass("Corrupted HTTP::parseEchoRequest(UNDEFINED Object)");
1684     } else {
1685         runtest.fail("Corrupted HTTP::parseEchoRequest(UNDEFINED Object)");
1686     }
1687 
1688     cerr << hexify(hex_req5->reference(), hex_req5->allocated(), false) << endl;
1689     hex_req5->corrupt(5);
1690     cerr << hexify(hex_req5->reference(), hex_req5->allocated(), false) << endl;
1691     vector<std::shared_ptr<cygnal::Element> > corrupt5 = http.parseEchoRequest(*hex_req5);
1692     if (corrupt5.size()) {
1693         runtest.pass("Corrupted HTTP::parseEchoRequest(DATE Object)");
1694     } else {
1695         runtest.fail("Corrupted HTTP::parseEchoRequest(DATE Object)");
1696     }
1697 
1698 //    cerr << hexify(hex_req6->reference(), hex_req6->allocated(), false) << endl;
1699     hex_req6->corrupt(7);
1700 //    cerr << hexify(hex_req6->reference(), hex_req6->allocated(), false) << endl;
1701     vector<std::shared_ptr<cygnal::Element> > corrupt6 = http.parseEchoRequest(*hex_req6);
1702     if (corrupt6.size()) {
1703         runtest.pass("Corrupted HTTP::parseEchoRequest(DATE Array)");
1704     } else {
1705         runtest.fail("Corrupted HTTP::parseEchoRequest(DATE Array)");
1706     }
1707 
1708 //    cerr << hexify(hex_req7->reference(), hex_req7->allocated(), false) << endl;
1709     hex_req7->corrupt(5);
1710 //    cerr << hexify(hex_req7->reference(), hex_req7->allocated(), false) << endl;
1711     vector<std::shared_ptr<cygnal::Element> > corrupt7 = http.parseEchoRequest(*hex_req7);
1712     if (corrupt7.size()) {
1713         runtest.pass("Corrupted HTTP::parseEchoRequest(Undefined Strict Array)");
1714     } else {
1715         runtest.fail("Corrupted HTTP::parseEchoRequest(Undefined Strict Array)");
1716     }
1717 
1718 //    cerr << hexify(hex_req8->reference(), hex_req8->allocated(), false) << endl;
1719     hex_req8->corrupt(2);
1720 //    cerr << hexify(hex_req8->reference(), hex_req8->allocated(), false) << endl;
1721     vector<std::shared_ptr<cygnal::Element> > corrupt8 = http.parseEchoRequest(*hex_req8);
1722     if (corrupt8.size()) {
1723         runtest.pass("Corrupted HTTP::parseEchoRequest(Simple Strict Array of Numbers. 1 item)");
1724     } else {
1725         runtest.fail("Corrupted HTTP::parseEchoRequest(Simple Strict Array of Numbers. 1 item)");
1726     }
1727 
1728 //    cerr << hexify(hex_req9->reference(), hex_req9->allocated(), false) << endl;
1729     hex_req9->corrupt(3);
1730 //    cerr << hexify(hex_req9->reference(), hex_req9->allocated(), false) << endl;
1731     vector<std::shared_ptr<cygnal::Element> > corrupt9 = http.parseEchoRequest(*hex_req9);
1732     if (corrupt9.size()) {
1733         runtest.pass("Corrupted HTTP::parseEchoRequest(Simple Strict Array of Numbers. 2 items)");
1734     } else {
1735         runtest.fail("Corrupted HTTP::parseEchoRequest(Simple Strict Array of Numbers. 2 items)");
1736     }
1737 
1738 //    cerr << hexify(hex_req10->reference(), hex_req10->allocated(), false) << endl;
1739     hex_req10->corrupt(2);
1740 //    cerr << hexify(hex_req10->reference(), hex_req10->allocated(), false) << endl;
1741     vector<std::shared_ptr<cygnal::Element> > corrupt10 = http.parseEchoRequest(*hex_req10);
1742     if (corrupt10.size()) {
1743         runtest.pass("Corrupted HTTP::parseEchoRequest(Simple Strict Array of Numbers. 3 items)");
1744     } else {
1745         runtest.fail("Corrupted HTTP::parseEchoRequest(Simple Strict Array of Numbers. 3 items)");
1746     }
1747 
1748 //    cerr << hexify(hex_req11->reference(), hex_req11->allocated(), false) << endl;
1749     hex_req11->corrupt(2);
1750 //    cerr << hexify(hex_req11->reference(), hex_req11->allocated(), false) << endl;
1751     vector<std::shared_ptr<cygnal::Element> > corrupt11 = http.parseEchoRequest(*hex_req11);
1752     if (corrupt11.size()) {
1753         runtest.pass("Corrupted HTTP::parseEchoRequest(Number 0)");
1754     } else {
1755         runtest.fail("Corrupted HTTP::parseEchoRequest(Number 0)");
1756     }
1757 
1758 //    cerr << hexify(hex_req12->reference(), hex_req12->allocated(), false) << endl;
1759     hex_req12->corrupt(4);
1760 //    cerr << hexify(hex_req12->reference(), hex_req12->allocated(), false) << endl;
1761     vector<std::shared_ptr<cygnal::Element> > corrupt12 = http.parseEchoRequest(*hex_req12);
1762     if (corrupt12.size()) {
1763         runtest.pass("Corrupted HTTP::parseEchoRequest(Number 1)");
1764     } else {
1765         runtest.fail("Corrupted HTTP::parseEchoRequest(Number 1)");
1766     }
1767 
1768 //    cerr << hexify(hex_req13->reference(), hex_req13->allocated(), false) << endl;
1769     hex_req13->corrupt(1);
1770 //    cerr << hexify(hex_req13->reference(), hex_req13->allocated(), false) << endl;
1771     vector<std::shared_ptr<cygnal::Element> > corrupt13 = http.parseEchoRequest(*hex_req13);
1772     if (corrupt13.size()) {
1773         runtest.pass("Corrupted HTTP::parseEchoRequest(Number -1)");
1774     } else {
1775         runtest.fail("Corrupted HTTP::parseEchoRequest(Number -1)");
1776     }
1777 
1778 //    cerr << hexify(hex_req14->reference(), hex_req14->allocated(), false) << endl;
1779     hex_req14->corrupt(5);
1780 //    cerr << hexify(hex_req14->reference(), hex_req14->allocated(), false) << endl;
1781     vector<std::shared_ptr<cygnal::Element> > corrupt14 = http.parseEchoRequest(*hex_req14);
1782     if (corrupt14.size()) {
1783         runtest.pass("Corrupted HTTP::parseEchoRequest(Number 256)");
1784     } else {
1785         runtest.fail("Corrupted HTTP::parseEchoRequest(Number 256)");
1786     }
1787 
1788 //    cerr << hexify(hex_req15->reference(), hex_req15->allocated(), false) << endl;
1789     hex_req15->corrupt(5);
1790 //    cerr << hexify(hex_req15->reference(), hex_req15->allocated(), false) << endl;
1791     vector<std::shared_ptr<cygnal::Element> > corrupt15 = http.parseEchoRequest(*hex_req15);
1792     if (corrupt15.size()) {
1793         runtest.pass("Corrupted HTTP::parseEchoRequest(Number -256)");
1794     } else {
1795         runtest.fail("Corrupted HTTP::parseEchoRequest(Number -256)");
1796     }
1797 
1798 //    cerr << hexify(hex_req16->reference(), hex_req16->allocated(), false) << endl;
1799     hex_req16->corrupt(2);
1800 //    cerr << hexify(hex_req16->reference(), hex_req16->allocated(), false) << endl;
1801     vector<std::shared_ptr<cygnal::Element> > corrupt16 = http.parseEchoRequest(*hex_req16);
1802     if (corrupt16.size()) {
1803         runtest.pass("Corrupted HTTP::parseEchoRequest(Number 65536)");
1804     } else {
1805         runtest.fail("Corrupted HTTP::parseEchoRequest(Number 65536)");
1806     }
1807 
1808 //    cerr << hexify(hex_req17->reference(), hex_req17->allocated(), false) << endl;
1809     hex_req16x->corrupt(6);
1810 //    cerr << hexify(hex_req17->reference(), hex_req17->allocated(), false) << endl;
1811     vector<std::shared_ptr<cygnal::Element> > corrupt17 = http.parseEchoRequest(*hex_req16x);
1812     if (corrupt17.size()) {
1813         runtest.pass("Corrupted HTTP::parseEchoRequest(Number -65536)");
1814     } else {
1815         runtest.fail("Corrupted HTTP::parseEchoRequest(Number -65536)");
1816     }
1817 
1818 //    cerr << hexify(hex_req19->reference(), hex_req19->allocated(), false) << endl;
1819     hex_req19->corrupt(1);
1820 //    cerr << hexify(hex_req19->reference(), hex_req19->allocated(), false) << endl;
1821     vector<std::shared_ptr<cygnal::Element> > corrupt19 = http.parseEchoRequest(*hex_req19);
1822     if (corrupt19.size()) {
1823         runtest.pass("Corrupted HTTP::parseEchoRequest(Number 1.5)");
1824     } else {
1825         runtest.fail("Corrupted HTTP::parseEchoRequest(Number 1.5)");
1826     }
1827 
1828 //    cerr << hexify(hex_req20->reference(), hex_req20->allocated(), false) << endl;
1829     hex_req20->corrupt(4);
1830 //    cerr << hexify(hex_req20->reference(), hex_req20->allocated(), false) << endl;
1831     vector<std::shared_ptr<cygnal::Element> > corrupt20 = http.parseEchoRequest(*hex_req20);
1832     if (corrupt20.size()) {
1833         runtest.pass("Corrupted HTTP::parseEchoRequest(Number -1.5)");
1834     } else {
1835         runtest.fail("Corrupted HTTP::parseEchoRequest(Number -1.5)");
1836     }
1837 
1838 //    cerr << hexify(hex_req21->reference(), hex_req21->allocated(), false) << endl;
1839     hex_req21->corrupt(8);
1840 //    cerr << hexify(hex_req21->reference(), hex_req21->allocated(), false) << endl;
1841     vector<std::shared_ptr<cygnal::Element> > corrupt21 = http.parseEchoRequest(*hex_req21);
1842     if (corrupt21.size()) {
1843         runtest.pass("Corrupted HTTP::parseEchoRequest(Number NaN)");
1844     } else {
1845         runtest.fail("Corrupted HTTP::parseEchoRequest(Number NaN)");
1846     }
1847 
1848 //    cerr << hexify(hex_req22->reference(), hex_req22->allocated(), false) << endl;
1849     hex_req22->corrupt(1);
1850 //    cerr << hexify(hex_req22->reference(), hex_req22->allocated(), false) << endl;
1851     vector<std::shared_ptr<cygnal::Element> > corrupt22 = http.parseEchoRequest(*hex_req22);
1852     if (corrupt22.size()) {
1853         runtest.pass("Corrupted HTTP::parseEchoRequest(Number Infinity)");
1854     } else {
1855         runtest.fail("Corrupted HTTP::parseEchoRequest(Number Infinity)");
1856     }
1857 
1858 //    cerr << hexify(hex_req26->reference(), hex_req26->allocated(), false) << endl;
1859     hex_req26->corrupt(5);
1860 //    cerr << hexify(hex_req26->reference(), hex_req26->allocated(), false) << endl;
1861     vector<std::shared_ptr<cygnal::Element> > corrupt26 = http.parseEchoRequest(*hex_req26);
1862     if (corrupt26.size()) {
1863         runtest.pass("Corrupted HTTP::parseEchoRequest(Strict Array of Numbers, 3 items)");
1864     } else {
1865         runtest.fail("Corrupted HTTP::parseEchoRequest(Strict Array of Numbers, 3 items)");
1866     }
1867 
1868 //    cerr << hexify(hex_req27->reference(), hex_req27->allocated(), false) << endl;
1869     hex_req27->corrupt(3);
1870 //    cerr << hexify(hex_req27->reference(), hex_req27->allocated(), false) << endl;
1871     vector<std::shared_ptr<cygnal::Element> > corrupt27 = http.parseEchoRequest(*hex_req27);
1872     if (corrupt27.size()) {
1873         runtest.pass("Corrupted HTTP::parseEchoRequest(Strict Array - Number, undefines, Number)");
1874     } else {
1875         runtest.fail("Corrupted HTTP::parseEchoRequest(Strict Array - Number, undefines, Number)");
1876     }
1877 
1878 //    cerr << hexify(hex_req29->reference(), hex_req29->allocated(), false) << endl;
1879     hex_req29->corrupt(8);
1880 //    cerr << hexify(hex_req29->reference(), hex_req29->allocated(), false) << endl;
1881     vector<std::shared_ptr<cygnal::Element> > corrupt29 = http.parseEchoRequest(*hex_req29);
1882     if (corrupt29.size()) {
1883         runtest.pass("Corrupted HTTP::parseEchoRequest(NULL String)");
1884     } else {
1885         runtest.fail("Corrupted HTTP::parseEchoRequest(NULL String)");
1886     }
1887 
1888 //    cerr << hexify(hex_req30->reference(), hex_req30->allocated(), false) << endl;
1889     hex_req30->corrupt(7);
1890 //    cerr << hexify(hex_req30->reference(), hex_req30->allocated(), false) << endl;
1891     vector<std::shared_ptr<cygnal::Element> > corrupt30 = http.parseEchoRequest(*hex_req30);
1892     if (corrupt30.size()) {
1893         runtest.pass("Corrupted HTTP::parseEchoRequest(Simple String)");
1894     } else {
1895         runtest.fail("Corrupted HTTP::parseEchoRequest(Simple String)");
1896     }
1897 
1898 //    cerr << hexify(hex_req31->reference(), hex_req31->allocated(), false) << endl;
1899     hex_req31->corrupt(2);
1900 //    cerr << hexify(hex_req31->reference(), hex_req31->allocated(), false) << endl;
1901     vector<std::shared_ptr<cygnal::Element> > corrupt31 = http.parseEchoRequest(*hex_req31);
1902     if (corrupt31.size()) {
1903         runtest.pass("Corrupted HTTP::parseEchoRequest(Simple String Array)");
1904     } else {
1905         runtest.fail("Corrupted HTTP::parseEchoRequest(Simple String Array)");
1906     }
1907 
1908 //    cerr << hexify(hex_req40->reference(), hex_req40->allocated(), false) << endl;
1909     hex_req40->corrupt(6);
1910 //    cerr << hexify(hex_req40->reference(), hex_req40->allocated(), false) << endl;
1911     vector<std::shared_ptr<cygnal::Element> > corrupt40 = http.parseEchoRequest(*hex_req40);
1912     if (corrupt40.size()) {
1913         runtest.pass("Corrupted HTTP::parseEchoRequest(object CustomClass)");
1914     } else {
1915         runtest.fail("Corrupted HTTP::parseEchoRequest(object CustomClass)");
1916     }
1917 
1918 //    cerr << hexify(hex_req41->reference(), hex_req41->allocated(), false) << endl;
1919     hex_req41->corrupt(1);
1920 //    cerr << hexify(hex_req41->reference(), hex_req41->allocated(), false) << endl;
1921     vector<std::shared_ptr<cygnal::Element> > corrupt41 = http.parseEchoRequest(*hex_req41);
1922     if (corrupt41.size()) {
1923         runtest.pass("Corrupted HTTP::parseEchoRequest(object CustomClass Array)");
1924     } else {
1925         runtest.fail("Corrupted HTTP::parseEchoRequest(object CustomClass Array)");
1926     }
1927 
1928 //    cerr << hexify(hex_req42->reference(), hex_req42->allocated(), false) << endl;
1929     hex_req42->corrupt(2);
1930 //    cerr << hexify(hex_req42->reference(), hex_req42->allocated(), false) << endl;
1931     vector<std::shared_ptr<cygnal::Element> > corrupt42 = http.parseEchoRequest(*hex_req42);
1932     if (corrupt42.size()) {
1933         runtest.pass("Corrupted HTTP::parseEchoRequest(object RemoteClass)");
1934     } else {
1935         runtest.fail("Corrupted HTTP::parseEchoRequest(object RemoteClass)");
1936     }
1937 
1938 //    cerr << hexify(hex_req43->reference(), hex_req43->allocated(), false) << endl;
1939     hex_req43->corrupt(4);
1940 //    cerr << hexify(hex_req43->reference(), hex_req43->allocated(), false) << endl;
1941     vector<std::shared_ptr<cygnal::Element> > corrupt43 = http.parseEchoRequest(*hex_req43);
1942     if (corrupt43.size()) {
1943         runtest.pass("Corrupted HTTP::parseEchoRequest(object RemoteClass Array, 2 items)");
1944     } else {
1945         runtest.fail("Corrupted HTTP::parseEchoRequest(object RemoteClass Array, 2 items)");
1946     }
1947 
1948 //    cerr << hexify(hex_req44->reference(), hex_req44->allocated(), false) << endl;
1949     hex_req44->corrupt(3);
1950 //    cerr << hexify(hex_req44->reference(), hex_req44->allocated(), false) << endl;
1951     vector<std::shared_ptr<cygnal::Element> > corrupt44 = http.parseEchoRequest(*hex_req44);
1952     if (corrupt44.size()) {
1953         runtest.pass("Corrupted HTTP::parseEchoRequest(object RemoteClass");
1954     } else {
1955         runtest.fail("Corrupted HTTP::parseEchoRequest(object RemoteClass");
1956     }
1957 #endif
1958 
1959 //    cerr << hexify(hex_req45->reference(), hex_req45->allocated(), false) << endl;
1960 #if 0
1961     hex_req45->corrupt(6);
1962 //    cerr << hexify(hex_req45->reference(), hex_req45->allocated(), false) << endl;
1963     vector<std::shared_ptr<cygnal::Element> > corrupt45 = http.parseEchoRequest(*hex_req45);
1964     if (corrupt45.size()) {
1965         runtest.pass("Corrupted HTTP::parseEchoRequest(object RemoteClass");
1966     } else {
1967         runtest.fail("Corrupted HTTP::parseEchoRequest(object RemoteClass");
1968     }
1969 #endif
1970 }
1971 #endif
1972 
1973 static void
usage(void)1974 usage (void)
1975 {
1976     cerr << "This program tests HTTP protocol support." << endl;
1977     cerr << "Usage: test_http [hv]" << endl;
1978     cerr << "-h\tHelp" << endl;
1979     cerr << "-v\tVerbose" << endl;
1980     exit (-1);
1981 }
1982 
1983 #else  // no DejaGnu support
1984 
1985 int
main(int,char **)1986 main(int /*argc*/, char**)
1987 {
1988   // nop
1989   return 0;
1990 }
1991 
1992 #endif
1993