1 /* This case tests server send chunked packet to external client and process chunked packet from external client.  */
2 #include    "tx_api.h"
3 #include    "nx_api.h"
4 #include    "fx_api.h"
5 #include    "nx_web_http_server.h"
6 
7 extern void test_control_return(UINT);
8 
9 #if !defined(NX_DISABLE_IPV4)
10 
11 #include "test_device_cert.c"
12 #include "test_ca_cert.c"
13 #define ca_cert_der test_ca_cert_der
14 #define ca_cert_der_len test_ca_cert_der_len
15 
16 #define     DEMO_STACK_SIZE         4096
17 
18 /* Set up FileX and file memory resources. */
19 static CHAR             ram_disk_memory[4096];
20 static FX_MEDIA         ram_disk;
21 static UCHAR            media_memory[4096];
22 
23 static UCHAR            server_stack[16000];
24 
25 /* Define device drivers.  */
26 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
27 extern  void _nx_pcap_network_driver(NX_IP_DRIVER*);
28 
29 static UINT                error_counter;
30 
31 /* Set up the HTTP server global variables */
32 
33 #define         SERVER_PACKET_SIZE  (NX_WEB_HTTP_SERVER_MIN_PACKET_SIZE * 2)
34 
35 static NX_WEB_HTTP_SERVER  my_server;
36 static NX_PACKET_POOL      server_pool;
37 static TX_THREAD           server_thread;
38 static NX_IP               server_ip;
39 static NXD_ADDRESS         server_ip_address;
40 
41 static void thread_server_entry(ULONG thread_input);
42 
43 #define HTTP_SERVER_ADDRESS  IP_ADDRESS(192,168,100,22)
44 
45 #ifdef NX_WEB_HTTPS_ENABLE
46 static UINT loop = 2;
47 extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;
48 static CHAR crypto_metadata_server[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
49 static UCHAR tls_packet_buffer[18500];
50 static NX_SECURE_X509_CERT certificate;
51 static NX_SECURE_X509_CERT trusted_certificate;
52 static NX_SECURE_X509_CERT remote_certificate, remote_issuer;
53 static UCHAR remote_cert_buffer[2000];
54 static UCHAR remote_issuer_buffer[2000];
55 #else
56 static UINT loop = 1;
57 #endif /* NX_WEB_HTTPS_ENABLE  */
58 
59 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr);
60 
61 #ifdef CTEST
test_application_define(void * first_unused_memory)62 VOID test_application_define(void *first_unused_memory)
63 #else
64 void    netx_web_external_client_test_application_define(void *first_unused_memory)
65 #endif
66 {
67 CHAR    *pointer;
68 UINT    status;
69 
70 
71     error_counter = 0;
72 
73     /* Setup the working pointer.  */
74     pointer =  (CHAR *) first_unused_memory;
75 
76     /* Create a helper thread for the server. */
77     tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
78                      pointer, DEMO_STACK_SIZE,
79                      NX_WEB_HTTP_SERVER_PRIORITY, NX_WEB_HTTP_SERVER_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START);
80 
81     pointer =  pointer + DEMO_STACK_SIZE;
82 
83     /* Initialize the NetX system.  */
84     nx_system_initialize();
85 
86     /* Create the server packet pool.  */
87     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
88                                     pointer, SERVER_PACKET_SIZE*16);
89     pointer = pointer + SERVER_PACKET_SIZE * 16;
90     if (status)
91         error_counter++;
92 
93     /* Create an IP instance.  */
94     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
95                           0xFFFFFF00UL, &server_pool, _nx_pcap_network_driver,
96                           pointer, 4096, 1);
97     pointer =  pointer + 4096;
98     if (status)
99         error_counter++;
100 
101     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
102     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
103     pointer = pointer + 1024;
104     if (status)
105         error_counter++;
106 
107      /* Enable TCP traffic.  */
108     status = nx_tcp_enable(&server_ip);
109     if (status)
110         error_counter++;
111 
112     /* Enable ICMP.  */
113     status = nx_icmp_enable(&server_ip);
114     if (status)
115         error_counter++;
116 }
117 
118 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)119 void    thread_server_entry(ULONG thread_input)
120 {
121 UINT            i;
122 UINT            status;
123 FX_FILE         my_file;
124 UINT            server_port = NX_WEB_HTTP_SERVER_PORT;
125 
126 
127     /* Print out test information banner.  */
128     printf("NetX Test:   Web External Client Test..................................");
129 
130     /* Check for earlier error. */
131     if(error_counter)
132     {
133         printf("ERROR!\n");
134         test_control_return(1);
135     }
136 
137     fx_media_format(&ram_disk,
138                     _fx_ram_driver,               // Driver entry
139                     ram_disk_memory,              // RAM disk memory pointer
140                     media_memory,                 // Media buffer pointer
141                     sizeof(media_memory),         // Media buffer size
142                     "MY_RAM_DISK",                // Volume Name
143                     1,                            // Number of FATs
144                     32,                           // Directory Entries
145                     0,                            // Hidden sectors
146                     256,                          // Total sectors
147                     512,                          // Sector size
148                     8,                            // Sectors per cluster
149                     1,                            // Heads
150                     1);                           // Sectors per track
151 
152     /* Open the RAM disk.  */
153     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
154     status += fx_file_create(&ram_disk, "index.htm");
155     status += fx_file_open(&ram_disk, &my_file, "index.htm", FX_OPEN_FOR_WRITE);
156     status += fx_file_write(&my_file, "https server", 12);
157     status += fx_file_close(&my_file);
158     if(status)
159         error_counter++;
160 
161     /* Give NetX a chance to initialize the system. */
162     tx_thread_sleep(NX_IP_PERIODIC_RATE);
163 
164     /* First loop test HTTP, second loop test HTTPS.  */
165     for (i = 0; i < loop; i++)
166     {
167 
168         if (i == 1)
169         {
170             server_port = NX_WEB_HTTPS_SERVER_PORT;
171         }
172 
173         /* Create the HTTP Server. */
174         status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
175                                            &server_stack, sizeof(server_stack), &server_pool,
176                                            NX_NULL, server_request_callback);
177         if (status)
178             error_counter++;
179 
180 #ifdef NX_WEB_HTTPS_ENABLE
181         /* Set TLS for HTTPS.  */
182         if (i == 1)
183         {
184             /* Initialize device certificate (used for all sessions in HTTPS server). */
185             memset(&certificate, 0, sizeof(certificate));
186             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);
187 
188             /* Setup TLS session data for the TCP server. */
189             status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
190                                                          crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
191                                                          &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
192             if (status)
193                 error_counter++;
194         }
195 #endif /* NX_WEB_HTTPS_ENABLE  */
196 
197         /* OK to start the HTTP Server.   */
198         status = nx_web_http_server_start(&my_server);
199         if (status)
200             error_counter++;
201 
202         tx_thread_sleep(600 * NX_IP_PERIODIC_RATE);
203 
204         status = nx_web_http_server_delete(&my_server);
205         if (status)
206             error_counter++;
207     }
208 
209     if(error_counter)
210     {
211         printf("ERROR!\n");
212         test_control_return(1);
213     }
214     else
215     {
216         printf("SUCCESS!\n");
217         test_control_return(0);
218     }
219 }
220 
221 /* Define the server request callback function.  */
server_request_callback(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,NX_PACKET * packet_ptr)222 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr)
223 {
224 NX_PACKET   *response_pkt;
225 UINT         status;
226 UINT         content_length = 0, length = 0;
227 UCHAR        buffer[4000];
228 
229     /* Process request.  */
230     if(request_type == NX_WEB_HTTP_SERVER_GET_REQUEST)
231     {
232 
233        /* Generate HTTP header.  */
234         status = nx_web_http_server_callback_generate_response_header(server_ptr,
235                                                                       &response_pkt, NX_WEB_HTTP_STATUS_OK, 6, "application/octet-stream",
236                                                                       NX_NULL);
237         if (status)
238         {
239             return(status);
240         }
241 
242         nx_packet_data_append(response_pkt, "abcdef", 6, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
243 
244         status = nx_web_http_server_callback_packet_send(server_ptr, response_pkt);
245         if (status)
246         {
247             nx_packet_release(response_pkt);
248             return(status);
249         }
250 
251     }
252     else if(request_type == NX_WEB_HTTP_SERVER_POST_REQUEST)
253     {
254 
255        /* Generate HTTP header.  */
256         status = nx_web_http_server_callback_generate_response_header(server_ptr,
257                                                                       &response_pkt, NX_WEB_HTTP_STATUS_OK, 0, "text/htm",
258                                                                       "Transfer-Encoding: chunked\r\n");
259         if (status)
260         {
261             return(status);
262         }
263 
264         status = nx_web_http_server_callback_packet_send(server_ptr, response_pkt);
265         if (status)
266         {
267             nx_packet_release(response_pkt);
268             return(status);
269         }
270 
271         while (1)
272         {
273             status = nx_web_http_server_content_get(server_ptr, packet_ptr, content_length, buffer, sizeof(buffer), &length);
274 
275             if (status)
276             {
277                 break;
278             }
279 
280             status = nx_web_http_server_response_packet_allocate(server_ptr, &response_pkt, NX_WAIT_FOREVER);
281             if (status)
282             {
283                 return(status);
284             }
285 
286             status = nx_web_http_server_response_chunked_set(server_ptr, length, response_pkt);
287             if (status)
288             {
289                 return(status);
290             }
291 
292             nx_packet_data_append(response_pkt, buffer, length, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
293 
294             status = nx_web_http_server_callback_packet_send(server_ptr, response_pkt);
295             if (status)
296             {
297                 nx_packet_release(response_pkt);
298                 return(status);
299             }
300 
301             content_length += length;
302         }
303 
304 
305         status = nx_web_http_server_response_packet_allocate(server_ptr, &response_pkt, NX_WAIT_FOREVER);
306         if (status)
307         {
308             return(status);
309         }
310 
311         status = nx_web_http_server_response_chunked_set(server_ptr, 16, response_pkt);
312         if (status)
313         {
314            return(status);
315        }
316 
317        nx_packet_data_append(response_pkt, "NETX HTTP SERVER", 16, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
318 
319        status = nx_web_http_server_callback_packet_send(server_ptr, response_pkt);
320        if (status)
321        {
322            nx_packet_release(response_pkt);
323            return(status);
324        }
325     }
326     else
327     {
328         /* Indicate we have not processed the response to client yet.  */
329         return(NX_SUCCESS);
330     }
331 
332     /* Indicate the response to client is transmitted.  */
333     return(NX_WEB_HTTP_CALLBACK_COMPLETED);
334 }
335 
336 #else
337 
338 #ifdef CTEST
test_application_define(void * first_unused_memory)339 VOID test_application_define(void *first_unused_memory)
340 #else
341 void    netx_web_external_client_test_application_define(void *first_unused_memory)
342 #endif
343 {
344 
345     /* Print out test information banner.  */
346     printf("NetX Test:   Web External Client Test..................................N/A\n");
347 
348     test_control_return(3);
349 }
350 #endif
351