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