1 /* This case tests the cleanup function.
2  */
3 #include    "tx_api.h"
4 #include    "nx_api.h"
5 #include    "fx_api.h"
6 #include    "nx_web_http_client.h"
7 #include    "nx_web_http_server.h"
8 
9 extern void test_control_return(UINT);
10 
11 #if !defined(NX_DISABLE_IPV4)
12 
13 #include "test_device_cert.c"
14 #include "test_ca_cert.c"
15 #define ca_cert_der test_ca_cert_der
16 #define ca_cert_der_len test_ca_cert_der_len
17 
18 #define     DEMO_STACK_SIZE         4096
19 
20 /* Set up FileX and file memory resources. */
21 static CHAR             ram_disk_memory[4096];
22 static FX_MEDIA         ram_disk;
23 static UCHAR            media_memory[4096];
24 
25 static UCHAR            server_stack[16000];
26 
27 /* Define device drivers.  */
28 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
29 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
30 
31 /* Set up the HTTP client global variables. */
32 
33 #define         CLIENT_PACKET_SIZE  (NX_WEB_HTTP_CLIENT_MIN_PACKET_SIZE * 2)
34 
35 static TX_THREAD           client_thread;
36 static NX_PACKET_POOL      client_pool;
37 static NX_WEB_HTTP_CLIENT  my_client;
38 static NX_IP               client_ip;
39 static UINT                error_counter;
40 
41 /* Set up the HTTP server global variables */
42 
43 #define         SERVER_PACKET_SIZE  (NX_WEB_HTTP_SERVER_MIN_PACKET_SIZE * 2)
44 
45 static NX_WEB_HTTP_SERVER  my_server;
46 static NX_PACKET_POOL      server_pool;
47 static TX_THREAD           server_thread;
48 static NX_IP               server_ip;
49 static NXD_ADDRESS         server_ip_address;
50 static UINT                http_server_start = 0;
51 static UINT                http_client_stop = 0;
52 
53 static void thread_client_entry(ULONG thread_input);
54 static void thread_server_entry(ULONG thread_input);
55 
56 #define HTTP_SERVER_ADDRESS  IP_ADDRESS(1,2,3,4)
57 #define HTTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
58 
59 #ifdef NX_WEB_HTTPS_ENABLE
60 static UINT                https_server_start = 0;
61 static UINT                https_client_stop = 0;
62 static UINT loop = 2;
63 extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;
64 static CHAR crypto_metadata_server[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
65 static CHAR crypto_metadata_client[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
66 static UCHAR tls_packet_buffer[18500];
67 static NX_SECURE_X509_CERT certificate;
68 static NX_SECURE_X509_CERT trusted_certificate;
69 static NX_SECURE_X509_CERT remote_certificate, remote_issuer;
70 static UCHAR remote_cert_buffer[2000];
71 static UCHAR remote_issuer_buffer[2000];
72 #else
73 static UINT loop = 1;
74 #endif /* NX_WEB_HTTPS_ENABLE  */
75 
76 extern VOID _nx_web_http_client_error_exit(NX_WEB_HTTP_CLIENT *client_ptr, UINT wait_option);
77 
78 #ifdef CTEST
test_application_define(void * first_unused_memory)79 VOID test_application_define(void *first_unused_memory)
80 #else
81 void    netx_web_client_cleanup_test_application_define(void *first_unused_memory)
82 #endif
83 {
84 CHAR    *pointer;
85 UINT    status;
86 
87 
88     error_counter = 0;
89 
90     /* Setup the working pointer.  */
91     pointer =  (CHAR *) first_unused_memory;
92 
93     /* Create a helper thread for the server. */
94     tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
95                      pointer, DEMO_STACK_SIZE,
96                      NX_WEB_HTTP_SERVER_PRIORITY, NX_WEB_HTTP_SERVER_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START);
97 
98     pointer =  pointer + DEMO_STACK_SIZE;
99 
100     /* Initialize the NetX system.  */
101     nx_system_initialize();
102 
103     /* Create the server packet pool.  */
104     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
105                                     pointer, SERVER_PACKET_SIZE*8);
106     pointer = pointer + SERVER_PACKET_SIZE * 8;
107     if (status)
108         error_counter++;
109 
110     /* Create an IP instance.  */
111     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
112                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
113                           pointer, 4096, 1);
114     pointer =  pointer + 4096;
115     if (status)
116         error_counter++;
117 
118     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
119     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
120     pointer = pointer + 1024;
121     if (status)
122         error_counter++;
123 
124      /* Enable TCP traffic.  */
125     status = nx_tcp_enable(&server_ip);
126     if (status)
127         error_counter++;
128 
129     /* Create the HTTP Client thread. */
130     status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0,
131                               pointer, DEMO_STACK_SIZE,
132                               NX_WEB_HTTP_SERVER_PRIORITY + 2, NX_WEB_HTTP_SERVER_PRIORITY + 2, TX_NO_TIME_SLICE, TX_AUTO_START);
133     pointer =  pointer + DEMO_STACK_SIZE;
134     if (status)
135         error_counter++;
136 
137     /* Create the Client packet pool.  */
138     status =  nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
139                                     pointer, CLIENT_PACKET_SIZE*8);
140     pointer = pointer + CLIENT_PACKET_SIZE * 8;
141     if (status)
142         error_counter++;
143 
144     /* Create an IP instance.  */
145     status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
146                           0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
147                           pointer, 2048, 1);
148     pointer =  pointer + 2048;
149     if (status)
150         error_counter++;
151 
152     status  = nx_arp_enable(&client_ip, (void *) pointer, 1024);
153     pointer =  pointer + 2048;
154     if (status)
155         error_counter++;
156 
157      /* Enable TCP traffic.  */
158     status = nx_tcp_enable(&client_ip);
159     if (status)
160         error_counter++;
161 }
162 
163 #ifdef NX_WEB_HTTPS_ENABLE
164 /* Define the TLS setup callback function.  */
tls_setup_callback(NX_WEB_HTTP_CLIENT * client_ptr,NX_SECURE_TLS_SESSION * tls_session)165 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session)
166 {
167 UINT status;
168 
169 
170     /* Initialize and create TLS session.  */
171     status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers, crypto_metadata_client, sizeof(crypto_metadata_client));
172 
173     /* Check status.  */
174     if (status)
175     {
176         return(status);
177     }
178 
179     /* Allocate space for packet reassembly.  */
180     status = nx_secure_tls_session_packet_buffer_set(&(client_ptr -> nx_web_http_client_tls_session), tls_packet_buffer, sizeof(tls_packet_buffer));
181 
182     /* Check status.  */
183     if (status)
184     {
185         return(status);
186     }
187 
188     /* Add a CA Certificate to our trusted store for verifying incoming server certificates.  */
189     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);
190     nx_secure_tls_trusted_certificate_add(&(client_ptr -> nx_web_http_client_tls_session), &trusted_certificate);
191 
192     /* Need to allocate space for the certificate coming in from the remote host.  */
193     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
194     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));
195 
196     return(NX_SUCCESS);
197 }
198 #endif /* NX_WEB_HTTPS_ENABLE  */
199 
thread_client_entry(ULONG thread_input)200 void thread_client_entry(ULONG thread_input)
201 {
202 UINT            i;
203 UINT            status;
204 NX_PACKET       *send_packet;
205 NX_PACKET       *recv_packet;
206 UINT            recv_length = 0;
207 
208 
209     /* Give IP task and driver a chance to initialize the system. */
210     tx_thread_sleep(NX_IP_PERIODIC_RATE);
211 
212     /* Set server IP address.  */
213     server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
214     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
215 
216     /* First loop test HTTP, second loop test HTTPS.  */
217     for (i = 0; i < loop; i++)
218     {
219         if (i == 0)
220         {
221 
222             /* Wait HTTP server started.  */
223             while(!http_server_start)
224             {
225                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
226             }
227         }
228 #ifdef NX_WEB_HTTPS_ENABLE
229         else
230         {
231 
232             /* Wait HTTPS server started.  */
233             while(!https_server_start)
234             {
235                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
236             }
237         }
238 #endif /* NX_WEB_HTTPS_ENABLE  */
239 
240         /* Create an HTTP client instance.  */
241         status = nx_web_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1536);
242 
243         /* Check status.  */
244         if (status)
245             error_counter++;
246 
247 
248         /* Send PUT request.  */
249         if (i == 0)
250         {
251 
252             status = nx_web_http_client_put_start(&my_client, &server_ip_address,
253                                                   NX_WEB_HTTP_SERVER_PORT, "http://www.abc.com/client_test.htm",
254                                                   "www.abc.com", "name", "password", 103, NX_WAIT_FOREVER);
255         }
256 #ifdef NX_WEB_HTTPS_ENABLE
257         else
258         {
259 
260             status = nx_web_http_client_put_secure_start(&my_client, &server_ip_address,
261                                                          NX_WEB_HTTPS_SERVER_PORT, "https://www.abc.com/client_test1.htm",
262                                                          "www.abc.com", "name", "password", 103, tls_setup_callback, NX_WAIT_FOREVER);
263         }
264 #endif /* NX_WEB_HTTPS_ENABLE  */
265 
266         /* Check status.  */
267         if (status)
268         {
269             error_counter++;
270             break;
271         }
272 
273         /* Allocate a packet.  */
274         status = nx_web_http_client_request_packet_allocate(&my_client, &send_packet, NX_WAIT_FOREVER);
275 
276         /* Check status.  */
277         if (status)
278             error_counter++;
279 
280         /* Build a simple 103-byte HTML page.  */
281         nx_packet_data_append(send_packet, "<HTML>\r\n", 8,
282                               &client_pool, NX_WAIT_FOREVER);
283         nx_packet_data_append(send_packet,
284                               "<HEAD><TITLE>NetX HTTP Test</TITLE></HEAD>\r\n", 44,
285                               &client_pool, NX_WAIT_FOREVER);
286         nx_packet_data_append(send_packet, "<BODY>\r\n", 8,
287                               &client_pool, NX_WAIT_FOREVER);
288         nx_packet_data_append(send_packet, "<H1>Another NetX Test Page!</H1>\r\n", 25,
289                               &client_pool, NX_WAIT_FOREVER);
290         nx_packet_data_append(send_packet, "</BODY>\r\n", 9,
291                               &client_pool, NX_WAIT_FOREVER);
292         nx_packet_data_append(send_packet, "</HTML>\r\n", 9,
293                               &client_pool, NX_WAIT_FOREVER);
294 
295         /* Complete the PUT by writing the total length.  */
296         status = nx_web_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE);
297         if (status)
298         {
299             nx_packet_release(send_packet);
300             error_counter++;
301         }
302 
303         /* Disconnect with server.  */
304         _nx_web_http_client_error_exit(&my_client, 1 * NX_IP_PERIODIC_RATE);
305 
306         /* Reconnect with server, the client should clean up the temporary variables and reset the state.  */
307         /* Send a GET request.  */
308         if (i == 0)
309         {
310             status = nx_web_http_client_get_start(&my_client, &server_ip_address,
311                                                   NX_WEB_HTTP_SERVER_PORT, "http://www.abc.com/client_test.htm",
312                                                   "www.abc.com", "name", "password", NX_WAIT_FOREVER);
313         }
314 #ifdef NX_WEB_HTTPS_ENABLE
315         else
316         {
317             status = nx_web_http_client_get_secure_start(&my_client, &server_ip_address,
318                                                          NX_WEB_HTTPS_SERVER_PORT, "https://www.abc.com/client_test1.htm",
319                                                          "www.abc.com", "name", "password",
320                                                          tls_setup_callback, NX_WAIT_FOREVER);
321         }
322 #endif /* NX_WEB_HTTPS_ENABLE  */
323 
324         /* Check status.  */
325         if (status)
326             error_counter++;
327 
328         /* Reset the receive length.  */
329         recv_length = 0;
330 
331         /* Get response from server.  */
332         while (1)
333         {
334             status = nx_web_http_client_response_body_get(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
335 
336             if (status)
337                 break;
338             else
339             {
340                 recv_length += recv_packet -> nx_packet_length;
341                 nx_packet_release(recv_packet);
342             }
343         }
344 
345         /* Check status.  */
346         if (status != NX_WEB_HTTP_GET_DONE)
347             error_counter++;
348         else
349         {
350             recv_length += recv_packet -> nx_packet_length;
351             nx_packet_release(recv_packet);
352         }
353 
354         if (recv_length != 103)
355             error_counter++;
356 
357         status = nx_web_http_client_delete(&my_client);
358         if (status)
359             error_counter++;
360 
361         /* Set the flag.  */
362         if (i == 0)
363         {
364             http_client_stop = 1;
365         }
366 #ifdef NX_WEB_HTTPS_ENABLE
367         else
368         {
369             https_client_stop = 1;
370         }
371 #endif /* NX_WEB_HTTPS_ENABLE  */
372     }
373 }
374 
375 
376 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)377 void    thread_server_entry(ULONG thread_input)
378 {
379 UINT            i;
380 UINT            status;
381 FX_FILE         my_file;
382 UINT            server_port = NX_WEB_HTTP_SERVER_PORT;
383 
384 
385     /* Print out test information banner.  */
386     printf("NetX Test:   Web Client Cleanup Test...................................");
387 
388     /* Check for earlier error. */
389     if(error_counter)
390     {
391         printf("ERROR!\n");
392         test_control_return(1);
393     }
394 
395     fx_media_format(&ram_disk,
396                     _fx_ram_driver,               // Driver entry
397                     ram_disk_memory,              // RAM disk memory pointer
398                     media_memory,                 // Media buffer pointer
399                     sizeof(media_memory),         // Media buffer size
400                     "MY_RAM_DISK",                // Volume Name
401                     1,                            // Number of FATs
402                     32,                           // Directory Entries
403                     0,                            // Hidden sectors
404                     256,                          // Total sectors
405                     512,                          // Sector size
406                     8,                            // Sectors per cluster
407                     1,                            // Heads
408                     1);                           // Sectors per track
409 
410     /* Open the RAM disk.  */
411     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
412     status += fx_file_create(&ram_disk, "TEST.TXT");
413     status += fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
414     status += fx_file_write(&my_file, "https server", 12);
415     status += fx_file_close(&my_file);
416     if(status)
417         error_counter++;
418 
419     /* Give NetX a chance to initialize the system. */
420     tx_thread_sleep(NX_IP_PERIODIC_RATE);
421 
422     /* First loop test HTTP, second loop test HTTPS.  */
423     for (i = 0; i < loop; i++)
424     {
425 
426         if (i == 1)
427         {
428             server_port = NX_WEB_HTTPS_SERVER_PORT;
429         }
430 
431         /* Create the HTTP Server. */
432         status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
433                                            &server_stack, sizeof(server_stack), &server_pool,
434                                            NX_NULL, NX_NULL);
435         if (status)
436             error_counter++;
437 
438 #ifdef NX_WEB_HTTPS_ENABLE
439         /* Set TLS for HTTPS.  */
440         if (i == 1)
441         {
442             /* Initialize device certificate (used for all sessions in HTTPS server). */
443             memset(&certificate, 0, sizeof(certificate));
444             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);
445 
446             /* Setup TLS session data for the TCP server. */
447             status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
448                                                          crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
449                                                          &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
450             if (status)
451                 error_counter++;
452         }
453 #endif /* NX_WEB_HTTPS_ENABLE  */
454 
455         /* OK to start the HTTP Server.   */
456         status = nx_web_http_server_start(&my_server);
457         if (status)
458             error_counter++;
459 
460         /* Set the flag.  */
461         if (i == 0)
462         {
463             http_server_start = 1;
464 
465             /* Wait HTTP test finished.  */
466             while(!http_client_stop)
467             {
468                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
469             }
470         }
471 #ifdef NX_WEB_HTTPS_ENABLE
472         else
473         {
474             https_server_start = 1;
475 
476             /* Wait HTTPS test finished.  */
477             while(!https_client_stop)
478             {
479                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
480             }
481         }
482 #endif /* NX_WEB_HTTPS_ENABLE  */
483 
484         status = nx_web_http_server_delete(&my_server);
485         if (status)
486             error_counter++;
487     }
488 
489     /* Check packet pool.  */
490     if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
491     {
492         error_counter++;
493     }
494 
495     if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total)
496     {
497         error_counter++;
498     }
499 
500     if(error_counter)
501     {
502         printf("ERROR!\n");
503         test_control_return(1);
504     }
505     else
506     {
507         printf("SUCCESS!\n");
508         test_control_return(0);
509     }
510 }
511 #else
512 
513 #ifdef CTEST
test_application_define(void * first_unused_memory)514 VOID test_application_define(void *first_unused_memory)
515 #else
516 void    netx_web_client_cleanup_test_application_define(void *first_unused_memory)
517 #endif
518 {
519 
520     /* Print out test information banner.  */
521     printf("NetX Test:   Web Client Cleanup Test...................................N/A\n");
522 
523     test_control_return(3);
524 }
525 #endif
526