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