1 /* This case tests abnormal cases. */
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 #ifdef NX_WEB_HTTPS_ENABLE
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 #endif /* NX_WEB_HTTPS_ENABLE  */
18 
19 #define     DEMO_STACK_SIZE         4096
20 
21 /* Set up FileX and file memory resources. */
22 static CHAR             ram_disk_memory[4096];
23 static FX_MEDIA         ram_disk;
24 static UCHAR            media_memory[4096];
25 
26 static UCHAR            server_stack[16000];
27 
28 /* Define device drivers.  */
29 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
30 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
31 
32 /* Set up the HTTP client global variables. */
33 
34 #define         CLIENT_PACKET_SIZE  (NX_WEB_HTTP_CLIENT_MIN_PACKET_SIZE * 2)
35 
36 static TX_THREAD           client_thread;
37 static NX_PACKET_POOL      client_pool;
38 static NX_WEB_HTTP_CLIENT  my_client;
39 static NX_IP               client_ip;
40 static UINT                error_counter;
41 
42 /* Set up the HTTP server global variables */
43 
44 #define         SERVER_PACKET_SIZE  (NX_WEB_HTTP_SERVER_MIN_PACKET_SIZE * 2)
45 
46 static NX_WEB_HTTP_SERVER  my_server;
47 static NX_PACKET_POOL      server_pool;
48 static TX_THREAD           server_thread;
49 static NX_IP               server_ip;
50 static NXD_ADDRESS         server_ip_address;
51 
52 static void thread_client_entry(ULONG thread_input);
53 static void thread_server_entry(ULONG thread_input);
54 
55 #define HTTP_SERVER_ADDRESS  IP_ADDRESS(1,2,3,4)
56 #define HTTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
57 
58 #ifdef NX_WEB_HTTPS_ENABLE
59 static UINT loop = 2;
60 extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;
61 static CHAR crypto_metadata_server[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
62 static CHAR crypto_metadata_client[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
63 static UCHAR tls_packet_buffer[18500];
64 static NX_SECURE_X509_CERT certificate;
65 static NX_SECURE_X509_CERT trusted_certificate;
66 static NX_SECURE_X509_CERT remote_certificate, remote_issuer;
67 static UCHAR remote_cert_buffer[2000];
68 static UCHAR remote_issuer_buffer[2000];
69 
70 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session);
71 #else
72 static UINT loop = 1;
73 #endif /* NX_WEB_HTTPS_ENABLE  */
74 
75 static TX_SEMAPHORE semaphore_server_start;
76 static TX_SEMAPHORE semaphore_client_stop;
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_send_fail_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     tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0);
101     tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0);
102 
103     /* Initialize the NetX system.  */
104     nx_system_initialize();
105 
106     /* Create the server packet pool.  */
107     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
108                                     pointer, SERVER_PACKET_SIZE*8);
109     pointer = pointer + SERVER_PACKET_SIZE * 8;
110     if (status)
111         error_counter++;
112 
113     /* Create an IP instance.  */
114     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
115                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
116                           pointer, 4096, 1);
117     pointer =  pointer + 4096;
118     if (status)
119         error_counter++;
120 
121     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
122     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
123     pointer = pointer + 1024;
124     if (status)
125         error_counter++;
126 
127 
128      /* Enable TCP traffic.  */
129     status = nx_tcp_enable(&server_ip);
130     if (status)
131         error_counter++;
132 
133     /* Create the HTTP Client thread. */
134     status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0,
135                               pointer, DEMO_STACK_SIZE,
136                               NX_WEB_HTTP_SERVER_PRIORITY + 2, NX_WEB_HTTP_SERVER_PRIORITY + 2, TX_NO_TIME_SLICE, TX_AUTO_START);
137     pointer =  pointer + DEMO_STACK_SIZE;
138     if (status)
139         error_counter++;
140 
141     /* Create the Client packet pool.  */
142     status =  nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
143                                     pointer, CLIENT_PACKET_SIZE*8);
144     pointer = pointer + CLIENT_PACKET_SIZE * 8;
145     if (status)
146         error_counter++;
147 
148     /* Create an IP instance.  */
149     status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
150                           0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
151                           pointer, 2048, 1);
152     pointer =  pointer + 2048;
153     if (status)
154         error_counter++;
155 
156     status  = nx_arp_enable(&client_ip, (void *) pointer, 1024);
157     pointer =  pointer + 2048;
158     if (status)
159         error_counter++;
160 
161      /* Enable TCP traffic.  */
162     status = nx_tcp_enable(&client_ip);
163     if (status)
164         error_counter++;
165 }
166 
167 #ifdef NX_WEB_HTTPS_ENABLE
168 /* Define the TLS setup callback function.  */
tls_setup_callback(NX_WEB_HTTP_CLIENT * client_ptr,NX_SECURE_TLS_SESSION * tls_session)169 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session)
170 {
171 UINT status;
172 
173 
174     /* Initialize and create TLS session.  */
175     status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers, crypto_metadata_client, sizeof(crypto_metadata_client));
176 
177     /* Check status.  */
178     if (status)
179     {
180         return(status);
181     }
182 
183     /* Allocate space for packet reassembly.  */
184     status = nx_secure_tls_session_packet_buffer_set(&(client_ptr -> nx_web_http_client_tls_session), tls_packet_buffer, sizeof(tls_packet_buffer));
185 
186     /* Check status.  */
187     if (status)
188     {
189         return(status);
190     }
191 
192     /* Add a CA Certificate to our trusted store for verifying incoming server certificates.  */
193     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);
194     nx_secure_tls_trusted_certificate_add(&(client_ptr -> nx_web_http_client_tls_session), &trusted_certificate);
195 
196     /* Need to allocate space for the certificate coming in from the remote host.  */
197     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
198     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));
199 
200     return(NX_SUCCESS);
201 }
202 #endif /* NX_WEB_HTTPS_ENABLE  */
203 
thread_client_entry(ULONG thread_input)204 void thread_client_entry(ULONG thread_input)
205 {
206 UINT            i, j;
207 UINT            status;
208 NX_PACKET       *recv_packet;
209 ULONG           temp;
210 
211 
212     /* Give IP task and driver a chance to initialize the system.  */
213     tx_thread_sleep(NX_IP_PERIODIC_RATE);
214 
215     /* Set server IP address.  */
216     server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
217     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
218 
219     /* First loop test HTTP, second loop test HTTPS.  */
220     for (i = 0; i < loop ; i++)
221     {
222 
223         /* Create an HTTP client instance.  */
224         status = nx_web_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1536);
225 
226         /* Check status.  */
227         if (status)
228             error_counter++;
229 
230         tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER);
231 
232         for (j = 0; j < 2; j++)
233         {
234 
235             /* Connect to server.  */
236             if (i == 0)
237             {
238                 status = nx_web_http_client_connect(&my_client, &server_ip_address, NX_WEB_HTTP_SERVER_PORT, NX_WAIT_FOREVER);
239             }
240 #ifdef NX_WEB_HTTPS_ENABLE
241             else
242             {
243                 status = nx_web_http_client_secure_connect(&my_client, &server_ip_address, NX_WEB_HTTPS_SERVER_PORT,
244                                                            tls_setup_callback, NX_WAIT_FOREVER);
245             }
246 #endif /* NX_WEB_HTTPS_ENABLE  */
247 
248             /* Check status.  */
249             if (status)
250                 error_counter++;
251 
252             /* Initialize the request.  */
253             status = nx_web_http_client_request_initialize(&my_client, NX_WEB_HTTP_METHOD_GET, "/test.txt", "1.2.3.4",
254                                                            0, NX_FALSE, "name", "password", NX_WAIT_FOREVER);
255 
256             /* Check status.  */
257             if (status)
258                 error_counter++;
259 
260             if (j == 0)
261             {
262                 temp = my_client.nx_web_http_client_socket.nx_tcp_socket_connect_mss;
263                 my_client.nx_web_http_client_socket.nx_tcp_socket_connect_mss = 1;
264 
265                 /* Send the request.  */
266                 status = nx_web_http_client_request_send(&my_client, NX_NO_WAIT);
267 
268                 if (!status)
269                     error_counter++;
270 
271                 my_client.nx_web_http_client_socket.nx_tcp_socket_connect_mss = temp;
272 
273                 continue;
274             }
275 
276             /* Send the request.  */
277             status = nx_web_http_client_request_send(&my_client, NX_IP_PERIODIC_RATE);
278 
279             if (status)
280                 error_counter++;
281 
282             /* Get response from server.  */
283             while (1)
284             {
285                 status = nx_web_http_client_response_body_get(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
286 
287                 if (status)
288                     break;
289                 else
290                     nx_packet_release(recv_packet);
291             }
292 
293             /* Check status.  */
294             if (status != NX_WEB_HTTP_GET_DONE)
295                 error_counter++;
296             else
297                 nx_packet_release(recv_packet);
298         }
299 
300         status = nx_web_http_client_delete(&my_client);
301         if (status)
302             error_counter++;
303 
304         tx_semaphore_put(&semaphore_client_stop);
305     }
306 }
307 
308 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)309 void    thread_server_entry(ULONG thread_input)
310 {
311 UINT            i;
312 UINT            status;
313 FX_FILE         my_file;
314 UINT            server_port = NX_WEB_HTTP_SERVER_PORT;
315 
316 
317     /* Print out test information banner.  */
318     printf("NetX Test:   Web Client Send Fail Test.................................");
319 
320     /* Check for earlier error.  */
321     if(error_counter)
322     {
323         printf("ERROR!\n");
324         test_control_return(1);
325     }
326 
327     fx_media_format(&ram_disk,
328                     _fx_ram_driver,               // Driver entry
329                     ram_disk_memory,              // RAM disk memory pointer
330                     media_memory,                 // Media buffer pointer
331                     sizeof(media_memory),         // Media buffer size
332                     "MY_RAM_DISK",                // Volume Name
333                     1,                            // Number of FATs
334                     32,                           // Directory Entries
335                     0,                            // Hidden sectors
336                     256,                          // Total sectors
337                     512,                          // Sector size
338                     8,                            // Sectors per cluster
339                     1,                            // Heads
340                     1);                           // Sectors per track
341 
342     /* Open the RAM disk.  */
343     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
344     status += fx_file_create(&ram_disk, "TEST.TXT");
345     status += fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
346     status += fx_file_write(&my_file, "https server", 12);
347     status += fx_file_close(&my_file);
348     if(status)
349         error_counter++;
350 
351     /* Give NetX a chance to initialize the system.  */
352     tx_thread_sleep(NX_IP_PERIODIC_RATE);
353 
354     /* First loop test HTTP, second loop test HTTPS.  */
355     for (i = 0; i < loop; i++)
356     {
357 
358         if (i == 1)
359         {
360             server_port = NX_WEB_HTTPS_SERVER_PORT;
361         }
362 
363         /* Create the HTTP Server. */
364         status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
365                                            &server_stack, sizeof(server_stack), &server_pool,
366                                            NX_NULL, NX_NULL);
367         if (status)
368             error_counter++;
369 
370 #ifdef NX_WEB_HTTPS_ENABLE
371         /* Set TLS for HTTPS.  */
372         if (i == 1)
373         {
374             /* Initialize device certificate (used for all sessions in HTTPS server).  */
375             memset(&certificate, 0, sizeof(certificate));
376             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);
377 
378             /* Setup TLS session data for the TCP server.  */
379             status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
380                                                          crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
381                                                          &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
382             if (status)
383                 error_counter++;
384         }
385 #endif /* NX_WEB_HTTPS_ENABLE  */
386 
387         /* OK to start the HTTP Server.  */
388         status = nx_web_http_server_start(&my_server);
389         if (status)
390             error_counter++;
391 
392         tx_semaphore_put(&semaphore_server_start);
393 
394         tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER);
395 
396         status = nx_web_http_server_stop(&my_server);
397         if (status)
398             error_counter++;
399 
400         status = nx_web_http_server_delete(&my_server);
401         if (status)
402             error_counter++;
403     }
404 
405     /* Check packet pool.  */
406     if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
407     {
408         error_counter++;
409     }
410 
411     if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total)
412     {
413         error_counter++;
414     }
415 
416     if(error_counter)
417     {
418         printf("ERROR!\n");
419         test_control_return(1);
420     }
421     else
422     {
423         printf("SUCCESS!\n");
424         test_control_return(0);
425     }
426 }
427 #else
428 
429 #ifdef CTEST
test_application_define(void * first_unused_memory)430 VOID test_application_define(void *first_unused_memory)
431 #else
432 void    netx_web_client_send_fail_test_application_define(void *first_unused_memory)
433 #endif
434 {
435 
436     /* Print out test information banner.  */
437     printf("NetX Test:   Web Client Send Fail Test.................................N/A\n");
438 
439     test_control_return(3);
440 }
441 #endif
442 
443