1 /* This case tests multiple sessions. */
2 #include    "tx_api.h"
3 #include    "nx_api.h"
4 #include    "fx_api.h"
5 #include    "nx_web_http_client.h"
6 #include    "nx_web_http_server.h"
7 
8 extern void test_control_return(UINT);
9 
10 #if !defined(NX_DISABLE_IPV4)
11 
12 #include "test_device_cert.c"
13 #include "test_ca_cert.c"
14 #define ca_cert_der test_ca_cert_der
15 #define ca_cert_der_len test_ca_cert_der_len
16 
17 #define     DEMO_STACK_SIZE         4096
18 
19 /* Set up FileX and file memory resources. */
20 static CHAR             ram_disk_memory[4096];
21 static FX_MEDIA         ram_disk;
22 static UCHAR            media_memory[4096];
23 
24 static UCHAR            server_stack[16000];
25 
26 /* Define device drivers.  */
27 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
28 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
29 
30 /* Set up the HTTP client global variables. */
31 
32 #define         CLIENT_PACKET_SIZE  (NX_WEB_HTTP_CLIENT_MIN_PACKET_SIZE * 2)
33 
34 static TX_THREAD           client_thread;
35 static NX_PACKET_POOL      client_pool;
36 static NX_PACKET_POOL      client_pool_1;
37 static NX_WEB_HTTP_CLIENT  my_client;
38 static NX_WEB_HTTP_CLIENT  my_client_1;
39 static NX_IP               client_ip;
40 static NX_IP               client_ip_1;
41 static UINT                error_counter;
42 
43 /* Set up the HTTP server global variables */
44 
45 #define         SERVER_PACKET_SIZE  (NX_WEB_HTTP_SERVER_MIN_PACKET_SIZE * 2)
46 
47 static NX_WEB_HTTP_SERVER  my_server;
48 static NX_PACKET_POOL      server_pool;
49 static TX_THREAD           server_thread;
50 static NX_IP               server_ip;
51 static NXD_ADDRESS         server_ip_address;
52 static UINT                http_server_start = 0;
53 static UINT                http_client_stop = 0;
54 
55 static void thread_client_entry(ULONG thread_input);
56 static void thread_server_entry(ULONG thread_input);
57 
58 #define HTTP_SERVER_ADDRESS  IP_ADDRESS(1,2,3,4)
59 #define HTTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
60 #define HTTP_CLIENT_ADDRESS_1  IP_ADDRESS(1,2,3,6)
61 
62 #ifdef NX_WEB_HTTPS_ENABLE
63 static UINT                https_server_start = 0;
64 static UINT                https_client_stop = 0;
65 static UINT loop = 2;
66 extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;
67 static CHAR crypto_metadata_server[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
68 static CHAR crypto_metadata_client[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
69 static UCHAR tls_packet_buffer[18500];
70 static NX_SECURE_X509_CERT certificate;
71 static NX_SECURE_X509_CERT trusted_certificate;
72 static NX_SECURE_X509_CERT remote_certificate, remote_issuer;
73 static UCHAR remote_cert_buffer[2000];
74 static UCHAR remote_issuer_buffer[2000];
75 
76 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session);
77 #else
78 static UINT loop = 1;
79 #endif /* NX_WEB_HTTPS_ENABLE  */
80 
81 extern UINT _nx_web_http_client_send(NX_WEB_HTTP_CLIENT *client_ptr, NX_PACKET *packet_ptr, ULONG wait_option);
82 
83 static char pkt[] = {
84     0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0xb8, 0xca, /* .."3DW.. */
85     0x3a, 0x95, 0xdb, 0x0b, 0x08, 0x00, 0x45, 0x00, /* :.....E. */
86     0x00, 0xb0, 0x09, 0xb8, 0x40, 0x00, 0x80, 0x06, /* ....@... */
87     0x6e, 0x5b, 0xc0, 0xa8, 0x00, 0x69, 0xc0, 0xa8, /* n[...i.. */
88     0x00, 0x7b, 0xc4, 0x77, 0x00, 0x50, 0x51, 0x6d, /* .{.w.PQm */
89     0xbc, 0x22, 0x77, 0x7f, 0x23, 0xc7, 0x50, 0x18, /* ."w.#.P. */
90     0xfa, 0xf0, 0x20, 0x9c, 0x00, 0x00, 0x47, 0x45, /* .. ...GE */
91     0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, /* T /index */
92     0x2e, 0x68, 0x74, 0x6d, 0x20, 0x48, 0x54, 0x54, /* .htm HTT */
93     0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x55, /* P/1.1..U */
94     0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, /* ser-Agen */
95     0x74, 0x3a, 0x20, 0x63, 0x75, 0x72, 0x6c, 0x2f, /* t: curl/ */
96     0x37, 0x2e, 0x33, 0x32, 0x2e, 0x30, 0x0d, 0x0a, /* 7.32.0.. */
97     0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, /* Host: 19 */
98     0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, /* 2.168.0. */
99     0x31, 0x32, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, /* 123..Acc */
100     0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, /* ept:     */
101     0x0d, 0x0a, 0x49, 0x66, 0x2d, 0x4d, 0x6f, 0x64, /* ..If-Mod */
102     0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x53, 0x69, /* ified-Si */
103     0x6e, 0x63, 0x65, 0x3a, 0x20, 0x54, 0x75, 0x65, /* nce: Tue */
104     0x2c, 0x20, 0x30, 0x31, 0x20, 0x4a, 0x61, 0x6e, /* , 01 Jan */
105     0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x30, 0x30, /*  2013 00 */
106     0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x20, 0x47, /* :00:00 G */
107     0x4d, 0x54, 0x0d, 0x0a, 0x0d, 0x0a              /* MT.... */
108 };
109 
110 #ifdef CTEST
test_application_define(void * first_unused_memory)111 VOID test_application_define(void *first_unused_memory)
112 #else
113 void    netx_web_multiple_sessions_test_application_define(void *first_unused_memory)
114 #endif
115 {
116 CHAR    *pointer;
117 UINT    status;
118 
119 
120     error_counter = 0;
121 
122     /* Setup the working pointer.  */
123     pointer =  (CHAR *) first_unused_memory;
124 
125     /* Create a helper thread for the server. */
126     tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
127                      pointer, DEMO_STACK_SIZE,
128                      NX_WEB_HTTP_SERVER_PRIORITY, NX_WEB_HTTP_SERVER_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START);
129 
130     pointer =  pointer + DEMO_STACK_SIZE;
131 
132     /* Initialize the NetX system.  */
133     nx_system_initialize();
134 
135     /* Create the server packet pool.  */
136     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
137                                     pointer, SERVER_PACKET_SIZE*16);
138     pointer = pointer + SERVER_PACKET_SIZE * 16;
139     if (status)
140         error_counter++;
141 
142     /* Create an IP instance.  */
143     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
144                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
145                           pointer, 4096, 1);
146     pointer =  pointer + 4096;
147     if (status)
148         error_counter++;
149 
150     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
151     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
152     pointer = pointer + 1024;
153     if (status)
154         error_counter++;
155 
156 
157      /* Enable TCP traffic.  */
158     status = nx_tcp_enable(&server_ip);
159     if (status)
160         error_counter++;
161 
162     /* Create the HTTP Client thread. */
163     status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0,
164                               pointer, DEMO_STACK_SIZE,
165                               NX_WEB_HTTP_SERVER_PRIORITY + 2, NX_WEB_HTTP_SERVER_PRIORITY + 2, TX_NO_TIME_SLICE, TX_AUTO_START);
166     pointer =  pointer + DEMO_STACK_SIZE;
167     if (status)
168         error_counter++;
169 
170     /* Create the Client packet pool.  */
171     status =  nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
172                                     pointer, CLIENT_PACKET_SIZE*8);
173     pointer = pointer + CLIENT_PACKET_SIZE * 8;
174     if (status)
175         error_counter++;
176 
177     /* Create an IP instance.  */
178     status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
179                           0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
180                           pointer, 2048, 1);
181     pointer =  pointer + 2048;
182     if (status)
183         error_counter++;
184 
185     status  = nx_arp_enable(&client_ip, (void *) pointer, 1024);
186     pointer =  pointer + 2048;
187     if (status)
188         error_counter++;
189 
190      /* Enable TCP traffic.  */
191     status = nx_tcp_enable(&client_ip);
192     if (status)
193         error_counter++;
194 
195 
196     /* Create the Client packet pool.  */
197     status =  nx_packet_pool_create(&client_pool_1, "HTTP Client Packet Pool 1", CLIENT_PACKET_SIZE,
198                                     pointer, CLIENT_PACKET_SIZE*8);
199     pointer = pointer + CLIENT_PACKET_SIZE * 8;
200     if (status)
201         error_counter++;
202 
203     /* Create an IP instance.  */
204     status = nx_ip_create(&client_ip_1, "HTTP Client IP 1", HTTP_CLIENT_ADDRESS_1,
205                           0xFFFFFF00UL, &client_pool_1, _nx_ram_network_driver_1024,
206                           pointer, 2048, 1);
207     pointer =  pointer + 2048;
208     if (status)
209         error_counter++;
210 
211     status  = nx_arp_enable(&client_ip_1, (void *) pointer, 1024);
212     pointer =  pointer + 2048;
213     if (status)
214         error_counter++;
215 
216      /* Enable TCP traffic.  */
217     status = nx_tcp_enable(&client_ip_1);
218     if (status)
219         error_counter++;
220 }
221 
222 #ifdef NX_WEB_HTTPS_ENABLE
223 /* Define the TLS setup callback function.  */
tls_setup_callback(NX_WEB_HTTP_CLIENT * client_ptr,NX_SECURE_TLS_SESSION * tls_session)224 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session)
225 {
226 UINT status;
227 
228 
229     /* Initialize and create TLS session.  */
230     status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers, crypto_metadata_client, sizeof(crypto_metadata_client));
231 
232     /* Check status.  */
233     if (status)
234     {
235         return(status);
236     }
237 
238     /* Allocate space for packet reassembly.  */
239     status = nx_secure_tls_session_packet_buffer_set(&(client_ptr -> nx_web_http_client_tls_session), tls_packet_buffer, sizeof(tls_packet_buffer));
240 
241     /* Check status.  */
242     if (status)
243     {
244         return(status);
245     }
246 
247     /* Add a CA Certificate to our trusted store for verifying incoming server certificates.  */
248     nx_secure_x509_certificate_initialize(&trusted_certificate, ca_cert_der, ca_cert_der_len, NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
249     nx_secure_tls_trusted_certificate_add(&(client_ptr -> nx_web_http_client_tls_session), &trusted_certificate);
250 
251     /* Need to allocate space for the certificate coming in from the remote host.  */
252     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
253     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));
254 
255     return(NX_SUCCESS);
256 }
257 #endif /* NX_WEB_HTTPS_ENABLE  */
258 
thread_client_entry(ULONG thread_input)259 void thread_client_entry(ULONG thread_input)
260 {
261 UINT            i;
262 UINT            status;
263 NX_PACKET       *my_packet;
264 
265 
266     /* Give IP task and driver a chance to initialize the system.  */
267     tx_thread_sleep(NX_IP_PERIODIC_RATE);
268 
269     /* Set server IP address.  */
270     server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
271     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
272 
273     /* First loop test HTTP, second loop test HTTPS.  */
274     for (i = 0; i < loop ; i++)
275     {
276         if (i == 0)
277         {
278 
279             /* Wait HTTP server started.  */
280             while(!http_server_start)
281             {
282                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
283             }
284         }
285 #ifdef NX_WEB_HTTPS_ENABLE
286         else
287         {
288 
289             /* Wait HTTPS server started.  */
290             while(!https_server_start)
291             {
292                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
293             }
294         }
295 #endif /* NX_WEB_HTTPS_ENABLE  */
296 
297         /* Create an HTTP client instance.  */
298         status = nx_web_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1536);
299         status = nx_web_http_client_create(&my_client_1, "HTTP Client 1", &client_ip_1, &client_pool_1, 1536);
300 
301         /* Check status.  */
302         if (status)
303             error_counter++;
304 
305         /* Send a GET request.  */
306         if (i == 0)
307         {
308             status = nx_web_http_client_connect(&my_client, &server_ip_address, NX_WEB_HTTP_SERVER_PORT, NX_WAIT_FOREVER);
309 
310             /* Check status.  */
311             if (status)
312                 error_counter++;
313 
314             status = nx_web_http_client_connect(&my_client_1, &server_ip_address, NX_WEB_HTTP_SERVER_PORT, NX_WAIT_FOREVER);
315 
316             /* Check status.  */
317             if (status)
318                 error_counter++;
319         }
320 #ifdef NX_WEB_HTTPS_ENABLE
321         else
322         {
323             status = nx_web_http_client_secure_connect(&my_client, &server_ip_address, NX_WEB_HTTPS_SERVER_PORT, tls_setup_callback, NX_WAIT_FOREVER);
324 
325             /* Check status.  */
326             if (status)
327                 error_counter++;
328 
329             status = nx_web_http_client_secure_connect(&my_client_1, &server_ip_address, NX_WEB_HTTPS_SERVER_PORT, tls_setup_callback, NX_WAIT_FOREVER);
330 
331             /* Check status.  */
332             if (status)
333                 error_counter++;
334         }
335 #endif /* NX_WEB_HTTPS_ENABLE  */
336 
337         /* Check status.  */
338         if (status)
339             error_counter++;
340 
341         /* Allocate a packet.  */
342         status = nx_web_http_client_request_packet_allocate(&my_client, &my_packet, 1 * NX_IP_PERIODIC_RATE);
343         if(status)
344             error_counter++;
345 
346         /* Write Get packet into the packet payload.  */
347         status = nx_packet_data_append(my_packet, &pkt[54] , (sizeof(pkt) - 54), &client_pool, 1 * NX_IP_PERIODIC_RATE);
348         if(status)
349             error_counter++;
350 
351         /* Send the packet out.  */
352         status = _nx_web_http_client_send(&my_client, my_packet, 1 * NX_IP_PERIODIC_RATE);
353         if(status)
354         {
355             nx_packet_release(my_packet);
356             error_counter++;
357         }
358 
359         /* Allocate a packet.  */
360         status = nx_web_http_client_request_packet_allocate(&my_client_1, &my_packet, 1 * NX_IP_PERIODIC_RATE);
361         if(status)
362             error_counter++;
363 
364         /* Write Get packet into the packet payload.  */
365         status = nx_packet_data_append(my_packet, &pkt[54] , (sizeof(pkt) - 54), &client_pool_1, 1 * NX_IP_PERIODIC_RATE);
366         if(status)
367             error_counter++;
368 
369         /* Send the packet out.  */
370         status = _nx_web_http_client_send(&my_client_1, my_packet, 1 * NX_IP_PERIODIC_RATE);
371         if(status)
372         {
373             nx_packet_release(my_packet);
374             error_counter++;
375         }
376 
377         status = nx_web_http_client_delete(&my_client);
378         if (status)
379             error_counter++;
380 
381         status = nx_web_http_client_delete(&my_client_1);
382         if (status)
383             error_counter++;
384 
385         /* Set the flag.  */
386         if (i == 0)
387         {
388             http_client_stop = 1;
389         }
390 #ifdef NX_WEB_HTTPS_ENABLE
391         else
392         {
393             https_client_stop = 1;
394         }
395 #endif /* NX_WEB_HTTPS_ENABLE  */
396     }
397 }
398 
399 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)400 void    thread_server_entry(ULONG thread_input)
401 {
402 UINT            i;
403 UINT            status;
404 FX_FILE         my_file;
405 UINT            server_port = NX_WEB_HTTP_SERVER_PORT;
406 
407 
408     /* Print out test information banner.  */
409     printf("NetX Test:   Web Multiple Sessions Test................................");
410 
411     /* Check for earlier error.  */
412     if(error_counter)
413     {
414         printf("ERROR!\n");
415         test_control_return(1);
416     }
417 
418     fx_media_format(&ram_disk,
419                     _fx_ram_driver,               // Driver entry
420                     ram_disk_memory,              // RAM disk memory pointer
421                     media_memory,                 // Media buffer pointer
422                     sizeof(media_memory),         // Media buffer size
423                     "MY_RAM_DISK",                // Volume Name
424                     1,                            // Number of FATs
425                     32,                           // Directory Entries
426                     0,                            // Hidden sectors
427                     256,                          // Total sectors
428                     512,                          // Sector size
429                     8,                            // Sectors per cluster
430                     1,                            // Heads
431                     1);                           // Sectors per track
432 
433     /* Open the RAM disk.  */
434     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
435     status += fx_file_create(&ram_disk, "TEST.TXT");
436     status += fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
437     status += fx_file_write(&my_file, "https server", 12);
438     status += fx_file_close(&my_file);
439     if(status)
440         error_counter++;
441 
442     /* Give NetX a chance to initialize the system.  */
443     tx_thread_sleep(NX_IP_PERIODIC_RATE);
444 
445     /* First loop test HTTP, second loop test HTTPS.  */
446     for (i = 0; i < loop; i++)
447     {
448 
449         if (i == 1)
450         {
451             server_port = NX_WEB_HTTPS_SERVER_PORT;
452         }
453 
454         /* Create the HTTP Server. */
455         status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
456                                            &server_stack, sizeof(server_stack), &server_pool,
457                                            NX_NULL, NX_NULL);
458         if (status)
459             error_counter++;
460 
461 #ifdef NX_WEB_HTTPS_ENABLE
462         /* Set TLS for HTTPS.  */
463         if (i == 1)
464         {
465             /* Initialize device certificate (used for all sessions in HTTPS server).  */
466             memset(&certificate, 0, sizeof(certificate));
467             nx_secure_x509_certificate_initialize(&certificate, test_device_cert_der, test_device_cert_der_len, NX_NULL, 0, test_device_cert_key_der, test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER);
468 
469             /* Setup TLS session data for the TCP server.  */
470             status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
471                                                          crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
472                                                          &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
473             if (status)
474                 error_counter++;
475         }
476 #endif /* NX_WEB_HTTPS_ENABLE  */
477 
478         /* OK to start the HTTP Server.  */
479         status = nx_web_http_server_start(&my_server);
480         if (status)
481             error_counter++;
482 
483         /* Set the flag.  */
484         if (i == 0)
485         {
486             http_server_start = 1;
487 
488             /* Wait HTTP test finished.  */
489             while(!http_client_stop)
490             {
491                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
492             }
493         }
494 #ifdef NX_WEB_HTTPS_ENABLE
495         else
496         {
497             https_server_start = 1;
498 
499             /* Wait HTTPS test finished.  */
500             while(!https_client_stop)
501             {
502                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
503             }
504         }
505 #endif /* NX_WEB_HTTPS_ENABLE  */
506 
507         status = nx_web_http_server_delete(&my_server);
508         if (status)
509             error_counter++;
510     }
511 
512     /* Check packet pool.  */
513     if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
514     {
515         error_counter++;
516     }
517 
518     if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total)
519     {
520         error_counter++;
521     }
522 
523     if(error_counter)
524     {
525         printf("ERROR!\n");
526         test_control_return(1);
527     }
528     else
529     {
530         printf("SUCCESS!\n");
531         test_control_return(0);
532     }
533 }
534 #else
535 
536 #ifdef CTEST
test_application_define(void * first_unused_memory)537 VOID test_application_define(void *first_unused_memory)
538 #else
539 void    netx_web_multiple_sessions_test_application_define(void *first_unused_memory)
540 #endif
541 {
542 
543     /* Print out test information banner.  */
544     printf("NetX Test:   Web Multiple Sessions Test................................N/A\n");
545 
546     test_control_return(3);
547 }
548 #endif
549 
550