1 /* This case tests server getting chunked content.  */
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) && !defined(NX_DISABLE_PACKET_CHAIN)
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(192,168,0,105)
56 #define HTTP_CLIENT_ADDRESS  IP_ADDRESS(192,168,0,123)
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 = 2;
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 = 1;
73 #endif /* NX_WEB_HTTPS_ENABLE  */
74 
75 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr);
76 
77 static char pkt[] = {
78 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
79 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
80 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
81 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
82 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
83 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
84 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
85 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
86 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
87 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
88 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
89 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
90 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
91 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
92 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
93 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
94 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
95 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
96 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
97 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
98 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
99 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
100 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
101 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
102 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
103 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
104 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
105 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
106 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
107 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
108 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
109 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
110 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
111 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
112 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
113 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, /* testtest */
114 };
115 
116 static UINT test_chunk[] = {20, 120, 19, 34};
117 static UINT test_num = sizeof(test_chunk)/sizeof(UINT);
118 
119 #define HEADER_CONTAIN_CONTENT 1
120 
121 #ifdef CTEST
test_application_define(void * first_unused_memory)122 VOID test_application_define(void *first_unused_memory)
123 #else
124 void    netx_web_server_chunked_content_process_test_application_define(void *first_unused_memory)
125 #endif
126 {
127 CHAR    *pointer;
128 UINT    status;
129 
130 
131     error_counter = 0;
132 
133     /* Setup the working pointer.  */
134     pointer =  (CHAR *) first_unused_memory;
135 
136     /* Create a helper thread for the server. */
137     tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
138                      pointer, DEMO_STACK_SIZE,
139                      NX_WEB_HTTP_SERVER_PRIORITY, NX_WEB_HTTP_SERVER_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START);
140 
141     pointer =  pointer + DEMO_STACK_SIZE;
142 
143     /* Initialize the NetX system.  */
144     nx_system_initialize();
145 
146     /* Create the server packet pool.  */
147     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
148                                     pointer, SERVER_PACKET_SIZE*16);
149     pointer = pointer + SERVER_PACKET_SIZE * 16;
150     if (status)
151         error_counter++;
152 
153     /* Create an IP instance.  */
154     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
155                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
156                           pointer, 4096, 1);
157     pointer =  pointer + 4096;
158     if (status)
159         error_counter++;
160 
161     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
162     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
163     pointer = pointer + 1024;
164     if (status)
165         error_counter++;
166 
167      /* Enable TCP traffic.  */
168     status = nx_tcp_enable(&server_ip);
169     if (status)
170         error_counter++;
171 
172     /* Create the HTTP Client thread. */
173     status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0,
174                               pointer, DEMO_STACK_SIZE,
175                               NX_WEB_HTTP_SERVER_PRIORITY + 2, NX_WEB_HTTP_SERVER_PRIORITY + 2, TX_NO_TIME_SLICE, TX_AUTO_START);
176     pointer =  pointer + DEMO_STACK_SIZE;
177     if (status)
178         error_counter++;
179 
180     /* Create the Client packet pool.  */
181     status =  nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
182                                     pointer, CLIENT_PACKET_SIZE*16);
183     pointer = pointer + CLIENT_PACKET_SIZE * 16;
184     if (status)
185         error_counter++;
186 
187     /* Create an IP instance.  */
188     status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
189                           0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
190                           pointer, 2048, 1);
191     pointer =  pointer + 2048;
192     if (status)
193         error_counter++;
194 
195     status  = nx_arp_enable(&client_ip, (void *) pointer, 1024);
196     pointer =  pointer + 2048;
197     if (status)
198         error_counter++;
199 
200      /* Enable TCP traffic.  */
201     status = nx_tcp_enable(&client_ip);
202     if (status)
203         error_counter++;
204 }
205 
206 #ifdef NX_WEB_HTTPS_ENABLE
207 /* Define the TLS setup callback function.  */
tls_setup_callback(NX_WEB_HTTP_CLIENT * client_ptr,NX_SECURE_TLS_SESSION * tls_session)208 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session)
209 {
210 UINT status;
211 
212 
213     /* Initialize and create TLS session.  */
214     status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers, crypto_metadata_client, sizeof(crypto_metadata_client));
215 
216     /* Check status.  */
217     if (status)
218     {
219         return(status);
220     }
221 
222     /* Allocate space for packet reassembly.  */
223     status = nx_secure_tls_session_packet_buffer_set(&(client_ptr -> nx_web_http_client_tls_session), tls_packet_buffer, sizeof(tls_packet_buffer));
224 
225     /* Check status.  */
226     if (status)
227     {
228         return(status);
229     }
230 
231     /* Add a CA Certificate to our trusted store for verifying incoming server certificates.  */
232     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);
233     nx_secure_tls_trusted_certificate_add(&(client_ptr -> nx_web_http_client_tls_session), &trusted_certificate);
234 
235     /* Need to allocate space for the certificate coming in from the remote host.  */
236     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
237     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));
238 
239     return(NX_SUCCESS);
240 }
241 #endif /* NX_WEB_HTTPS_ENABLE  */
242 
thread_client_entry(ULONG thread_input)243 void thread_client_entry(ULONG thread_input)
244 {
245 UINT            i, j;
246 UINT            status;
247 NX_PACKET      *send_packet, *recv_packet;
248 UINT            chunk_size = 0;
249 CHAR           *put_test;
250 UINT            more_data;
251 
252 
253     /* Give IP task and driver a chance to initialize the system. */
254     tx_thread_sleep(NX_IP_PERIODIC_RATE);
255 
256     /* Set server IP address.  */
257     server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
258     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
259 
260     /* First loop test HTTP, second loop test HTTPS.  */
261     for (i = 0; i < loop ; i++)
262     {
263         if (i == 0)
264         {
265 
266             /* Wait HTTP server started.  */
267             while(!http_server_start)
268             {
269                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
270             }
271         }
272 #ifdef NX_WEB_HTTPS_ENABLE
273         else
274         {
275 
276             /* Wait HTTPS server started.  */
277             while(!https_server_start)
278             {
279                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
280             }
281         }
282 #endif /* NX_WEB_HTTPS_ENABLE  */
283 
284 
285         /* Create an HTTP client instance.  */
286         status = nx_web_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1536);
287 
288         /* Check status.  */
289         if (status)
290             error_counter++;
291 
292 
293         /* Check status.  */
294         if (status)
295             error_counter++;
296 
297         /* Test chunked PUT request.  */
298         /* Connect to server.  */
299         if (i == 0)
300         {
301             status = nx_web_http_client_connect(&my_client, &server_ip_address, NX_WEB_HTTP_SERVER_PORT, NX_WAIT_FOREVER);
302             put_test = "http_put_test.html";
303         }
304 #ifdef NX_WEB_HTTPS_ENABLE
305         else
306         {
307             status = nx_web_http_client_secure_connect(&my_client, &server_ip_address, NX_WEB_HTTPS_SERVER_PORT,
308                                                        tls_setup_callback, NX_WAIT_FOREVER);
309             put_test = "https_put_test.html";
310         }
311 #endif /* NX_WEB_HTTPS_ENABLE  */
312 
313         /* Check status.  */
314         if (status)
315             error_counter++;
316 
317         /* Initialize the request.  */
318         status = nx_web_http_client_request_initialize(&my_client, NX_WEB_HTTP_METHOD_PUT, put_test, "www.abc.com",
319                                                        0, NX_TRUE, "name", "password", NX_WAIT_FOREVER);
320 
321         /* Check status.  */
322         if (status)
323             error_counter++;
324 
325 #if HEADER_CONTAIN_CONTENT
326 
327         /* For test, append chunked data to the header packet.  */
328         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, "\r\n19\r\n", 6, my_client.nx_web_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
329         nx_packet_data_append(my_client.nx_web_http_client_request_packet_ptr, pkt, 25, my_client.nx_web_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
330 #endif
331 
332         /* Send the request.  */
333         status = nx_web_http_client_request_send(&my_client, NX_WAIT_FOREVER);
334 
335         /* Check status.  */
336         if (status)
337             error_counter++;
338 
339         for (j = 0; j < test_num; j++)
340         {
341 
342             if (j != (test_num - 1))
343             {
344                 more_data = NX_TRUE;
345             }
346             else
347             {
348                 more_data = NX_FALSE;
349             }
350 
351             chunk_size = test_chunk[j];
352 
353             status = nx_web_http_client_request_packet_allocate(&my_client, &send_packet, NX_WAIT_FOREVER);
354             if (status)
355                 error_counter++;
356 
357             status = nx_web_http_client_request_chunked_set(&my_client, chunk_size, send_packet);
358             if (status)
359                 error_counter++;
360 
361             nx_packet_data_append(send_packet, pkt, chunk_size, my_client.nx_web_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
362 
363             status = nx_web_http_client_request_packet_send(&my_client, send_packet, more_data, 1 * NX_IP_PERIODIC_RATE);
364             if (status)
365             {
366                 nx_packet_release(send_packet);
367                 error_counter++;
368             }
369         }
370 
371         /* Get response from server.  */
372         while (1)
373         {
374             status = nx_web_http_client_response_body_get(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
375 
376             if (status)
377             {
378                 break;
379             }
380             else
381             {
382                 nx_packet_release(recv_packet);
383             }
384         }
385 
386         /* Check status.  */
387         if (status != NX_WEB_HTTP_GET_DONE)
388             error_counter++;
389         else
390             nx_packet_release(recv_packet);
391 
392         status = nx_web_http_client_delete(&my_client);
393         if (status)
394            error_counter++;
395 
396         /* Set the flag.  */
397         if (i == 0)
398         {
399             http_client_stop = 1;
400         }
401 #ifdef NX_WEB_HTTPS_ENABLE
402         else
403         {
404             https_client_stop = 1;
405         }
406 #endif /* NX_WEB_HTTPS_ENABLE  */
407     }
408 
409     if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
410     {
411         error_counter++;
412     }
413 }
414 
415 
416 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)417 void    thread_server_entry(ULONG thread_input)
418 {
419 UINT            i;
420 UINT            status;
421 FX_FILE         my_file;
422 UINT            server_port = NX_WEB_HTTP_SERVER_PORT;
423 
424 
425     /* Print out test information banner.  */
426     printf("NetX Test:   Web Server Chunked Content Process Test...................");
427 
428     /* Check for earlier error. */
429     if(error_counter)
430     {
431         printf("ERROR!\n");
432         test_control_return(1);
433     }
434 
435     fx_media_format(&ram_disk,
436                     _fx_ram_driver,               // Driver entry
437                     ram_disk_memory,              // RAM disk memory pointer
438                     media_memory,                 // Media buffer pointer
439                     sizeof(media_memory),         // Media buffer size
440                     "MY_RAM_DISK",                // Volume Name
441                     1,                            // Number of FATs
442                     32,                           // Directory Entries
443                     0,                            // Hidden sectors
444                     256,                          // Total sectors
445                     512,                          // Sector size
446                     8,                            // Sectors per cluster
447                     1,                            // Heads
448                     1);                           // Sectors per track
449 
450     /* Open the RAM disk.  */
451     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
452     status += fx_file_create(&ram_disk, "index.htm");
453     status += fx_file_open(&ram_disk, &my_file, "index.htm", FX_OPEN_FOR_WRITE);
454     status += fx_file_write(&my_file, "https server", 12);
455     status += fx_file_close(&my_file);
456     if(status)
457         error_counter++;
458 
459     /* Give NetX a chance to initialize the system. */
460     tx_thread_sleep(NX_IP_PERIODIC_RATE);
461 
462     /* First loop test HTTP, second loop test HTTPS.  */
463     for (i = 0; i < loop; i++)
464     {
465 
466         if (i == 1)
467         {
468             server_port = NX_WEB_HTTPS_SERVER_PORT;
469         }
470 
471         /* Create the HTTP Server. */
472         status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
473                                            &server_stack, sizeof(server_stack), &server_pool,
474                                            NX_NULL, server_request_callback);
475         if (status)
476             error_counter++;
477 
478 #ifdef NX_WEB_HTTPS_ENABLE
479         /* Set TLS for HTTPS.  */
480         if (i == 1)
481         {
482             /* Initialize device certificate (used for all sessions in HTTPS server). */
483             memset(&certificate, 0, sizeof(certificate));
484             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);
485 
486             /* Setup TLS session data for the TCP server. */
487             status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
488                                                          crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
489                                                          &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
490             if (status)
491                 error_counter++;
492         }
493 #endif /* NX_WEB_HTTPS_ENABLE  */
494 
495         /* OK to start the HTTP Server.   */
496         status = nx_web_http_server_start(&my_server);
497         if (status)
498             error_counter++;
499 
500         /* Set the flag.  */
501         if (i == 0)
502         {
503             http_server_start = 1;
504 
505             /* Wait HTTP test finished.  */
506             while(!http_client_stop)
507             {
508                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
509             }
510         }
511 #ifdef NX_WEB_HTTPS_ENABLE
512         else
513         {
514             https_server_start = 1;
515 
516             /* Wait HTTPS test finished.  */
517             while(!https_client_stop)
518             {
519                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
520             }
521         }
522 #endif /* NX_WEB_HTTPS_ENABLE  */
523 
524         status = nx_web_http_server_delete(&my_server);
525         if (status)
526             error_counter++;
527     }
528 
529     /* Check packet pool.  */
530     if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
531     {
532         error_counter++;
533     }
534 
535     if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total)
536     {
537         error_counter++;
538     }
539 
540     if(error_counter)
541     {
542         printf("ERROR!\n");
543         test_control_return(1);
544     }
545     else
546     {
547         printf("SUCCESS!\n");
548         test_control_return(0);
549     }
550 }
551 
552 /* Define the server request callback function.  */
server_request_callback(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,NX_PACKET * packet_ptr)553 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr)
554 {
555 NX_PACKET   *response_pkt;
556 UINT         status;
557 UINT         i = 0;
558 UINT         content_length = 0;
559 UINT         total_length = 0;
560 UCHAR        buffer[4000];
561 UINT         length;
562 
563     /* Process content.  */
564     if(request_type == NX_WEB_HTTP_SERVER_PUT_REQUEST)
565     {
566 
567         for (i = 0; i < test_num; i++)
568         {
569             total_length += test_chunk[i];
570         }
571 
572 #if HEADER_CONTAIN_CONTENT
573         total_length += 0x19;
574 #endif
575 
576         while (1)
577         {
578 
579             status = nx_web_http_server_content_get(server_ptr, packet_ptr, content_length, buffer, sizeof(buffer), &length);
580 
581             if (status)
582             {
583                 break;
584             }
585             else
586             {
587                 content_length += length;
588             }
589 
590             status = nx_web_http_server_content_get_extended(server_ptr, packet_ptr, content_length, buffer, sizeof(buffer), &length);
591 
592             if (status)
593             {
594                 break;
595             }
596             else
597             {
598                 content_length += length;
599             }
600         }
601 
602         if (content_length != total_length)
603         {
604             error_counter++;
605         }
606 
607         status = nx_web_http_server_packet_content_find(server_ptr, &packet_ptr, (ULONG *)&length);
608 
609         /* Release the received content packet.  */
610         nx_packet_release(packet_ptr);
611 
612         if (length != content_length)
613         {
614             error_counter++;
615         }
616 
617        /* Generate HTTP header.  */
618         status = nx_web_http_server_callback_generate_response_header(server_ptr,
619                                                                       &response_pkt, NX_WEB_HTTP_STATUS_OK, 0, "text/html",
620                                                                       NX_NULL);
621         if (status)
622         {
623             return(status);
624         }
625 
626         status = nx_web_http_server_callback_packet_send(server_ptr, response_pkt);
627         if (status)
628         {
629             nx_packet_release(response_pkt);
630             return(status);
631         }
632     }
633     else
634     {
635         /* Indicate we have not processed the response to client yet.  */
636         return(NX_SUCCESS);
637     }
638 
639     /* Indicate the response to client is transmitted.  */
640     return(NX_WEB_HTTP_CALLBACK_COMPLETED);
641 }
642 
643 #else
644 
645 #ifdef CTEST
test_application_define(void * first_unused_memory)646 VOID test_application_define(void *first_unused_memory)
647 #else
648 void    netx_web_server_chunked_content_process_test_application_define(void *first_unused_memory)
649 #endif
650 {
651 
652     /* Print out test information banner.  */
653     printf("NetX Test:   Web Server Chunked Content Process Test...................N/A\n");
654 
655     test_control_return(3);
656 }
657 #endif
658