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