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