1 /* This case tests Host field. */
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 = 2;
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 = 1;
77 #endif /* NX_WEB_HTTPS_ENABLE */
78
79 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr);
80 extern UINT _nx_web_http_server_field_value_get(NX_PACKET *packet_ptr, UCHAR *field_name, ULONG name_length, UCHAR *field_value, ULONG field_value_size);
81 static CHAR *host_test = "express_logic";
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_host_field_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
thread_client_entry(ULONG thread_input)206 void thread_client_entry(ULONG thread_input)
207 {
208 UINT i;
209 UINT status;
210 NX_PACKET *recv_packet;
211
212
213 /* Give IP task and driver a chance to initialize the system. */
214 tx_thread_sleep(NX_IP_PERIODIC_RATE);
215
216 /* Set server IP address. */
217 server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
218 server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
219
220 /* First loop test HTTP, second loop test HTTPS. */
221 for (i = 0; i < loop ; i++)
222 {
223 if (i == 0)
224 {
225
226 /* Wait HTTP server started. */
227 while(!http_server_start)
228 {
229 tx_thread_sleep(NX_IP_PERIODIC_RATE);
230 }
231 }
232 #ifdef NX_WEB_HTTPS_ENABLE
233 else
234 {
235
236 /* Wait HTTPS server started. */
237 while(!https_server_start)
238 {
239 tx_thread_sleep(NX_IP_PERIODIC_RATE);
240 }
241 }
242 #endif
243
244 /* Create an HTTP client instance. */
245 status = nx_web_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1536);
246
247 /* Check status. */
248 if (status)
249 error_counter++;
250
251 /* Send a GET request. */
252 if (i == 0)
253 {
254 status = nx_web_http_client_get_start(&my_client, &server_ip_address,
255 NX_WEB_HTTP_SERVER_PORT, "/test.txt",
256 host_test, "name", "password", NX_WAIT_FOREVER);
257 }
258 #ifdef NX_WEB_HTTPS_ENABLE
259 else
260 {
261 status = nx_web_http_client_get_secure_start(&my_client, &server_ip_address,
262 NX_WEB_HTTPS_SERVER_PORT, "/test.txt",
263 host_test, "name", "password",
264 tls_setup_callback, NX_WAIT_FOREVER);
265 }
266 #endif /* NX_WEB_HTTPS_ENABLE */
267
268 /* Check status. */
269 if (status)
270 error_counter++;
271
272 /* Get response from server. */
273 while(1)
274 {
275 status = nx_web_http_client_response_body_get(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
276
277 if (status)
278 break;
279 else
280 nx_packet_release(recv_packet);
281 }
282
283 /* Check status. */
284 if (status != NX_WEB_HTTP_GET_DONE)
285 error_counter++;
286 else
287 nx_packet_release(recv_packet);
288
289 status = nx_web_http_client_delete(&my_client);
290 if (status)
291 error_counter++;
292
293 /* Set the flag. */
294 if (i == 0)
295 {
296 http_client_stop = 1;
297 }
298 #ifdef NX_WEB_HTTPS_ENABLE
299 else
300 {
301 https_client_stop = 1;
302 }
303 #endif /* NX_WEB_HTTPS_ENABLE */
304 }
305 }
306
307 /* Define the helper HTTP server thread. */
thread_server_entry(ULONG thread_input)308 void thread_server_entry(ULONG thread_input)
309 {
310 UINT i;
311 UINT status;
312 FX_FILE my_file;
313 UINT server_port = NX_WEB_HTTP_SERVER_PORT;
314
315
316 /* Print out test information banner. */
317 printf("NetX Test: Web Host Field Test.......................................");
318
319 /* Check for earlier error. */
320 if(error_counter)
321 {
322 printf("ERROR!\n");
323 test_control_return(1);
324 }
325
326 fx_media_format(&ram_disk,
327 _fx_ram_driver, // Driver entry
328 ram_disk_memory, // RAM disk memory pointer
329 media_memory, // Media buffer pointer
330 sizeof(media_memory), // Media buffer size
331 "MY_RAM_DISK", // Volume Name
332 1, // Number of FATs
333 32, // Directory Entries
334 0, // Hidden sectors
335 256, // Total sectors
336 512, // Sector size
337 8, // Sectors per cluster
338 1, // Heads
339 1); // Sectors per track
340
341 /* Open the RAM disk. */
342 status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
343 status += fx_file_create(&ram_disk, "TEST.TXT");
344 status += fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
345 status += fx_file_write(&my_file, "https server", 12);
346 status += fx_file_close(&my_file);
347 if(status)
348 error_counter++;
349
350 /* Give NetX a chance to initialize the system. */
351 tx_thread_sleep(NX_IP_PERIODIC_RATE);
352
353 /* First loop test HTTP, second loop test HTTPS. */
354 for (i = 0; i < loop; i++)
355 {
356
357 if (i == 1)
358 {
359 server_port = NX_WEB_HTTPS_SERVER_PORT;
360 }
361
362 /* Create the HTTP Server. */
363 status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
364 &server_stack, sizeof(server_stack), &server_pool,
365 NX_NULL, server_request_callback);
366 if (status)
367 error_counter++;
368
369 #ifdef NX_WEB_HTTPS_ENABLE
370 /* Set TLS for HTTPS. */
371 if (i == 1)
372 {
373 /* Initialize device certificate (used for all sessions in HTTPS server). */
374 memset(&certificate, 0, sizeof(certificate));
375 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);
376
377 /* Setup TLS session data for the TCP server. */
378 status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
379 crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
380 &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
381 if (status)
382 error_counter++;
383 }
384 #endif /* NX_WEB_HTTPS_ENABLE */
385
386 /* OK to start the HTTP Server. */
387 status = nx_web_http_server_start(&my_server);
388 if (status)
389 error_counter++;
390
391 /* Set the flag. */
392 if (i == 0)
393 {
394 http_server_start = 1;
395
396 /* Wait HTTP test finished. */
397 while(!http_client_stop)
398 {
399 tx_thread_sleep(NX_IP_PERIODIC_RATE);
400 }
401 }
402 #ifdef NX_WEB_HTTPS_ENABLE
403 else
404 {
405 https_server_start = 1;
406
407 /* Wait HTTPS test finished. */
408 while(!https_client_stop)
409 {
410 tx_thread_sleep(NX_IP_PERIODIC_RATE);
411 }
412 }
413 #endif /* NX_WEB_HTTPS_ENABLE */
414
415 status = nx_web_http_server_delete(&my_server);
416 if (status)
417 error_counter++;
418 }
419
420 /* Check packet pool. */
421 if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
422 {
423 error_counter++;
424 }
425
426 if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total)
427 {
428 error_counter++;
429 }
430
431 if(error_counter)
432 {
433 printf("ERROR!\n");
434 test_control_return(1);
435 }
436 else
437 {
438 printf("SUCCESS!\n");
439 test_control_return(0);
440 }
441 }
442
443 /* Define the server request callback function. */
server_request_callback(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,NX_PACKET * packet_ptr)444 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr)
445 {
446 NX_PACKET *response_pkt;
447 UINT status;
448 CHAR temp_string[20];
449
450
451 /* Check the Host field. */
452 if(request_type == NX_WEB_HTTP_SERVER_GET_REQUEST)
453 {
454
455 /* Get the Host field. */
456 if (_nx_web_http_server_field_value_get(packet_ptr, (UCHAR *)"Host", 4, (UCHAR *)temp_string, sizeof(temp_string)) == NX_SUCCESS)
457 {
458 if (memcmp(temp_string, host_test, strlen(host_test)) != 0)
459 {
460 error_counter++;
461 }
462 }
463 else
464 {
465 error_counter++;
466 }
467
468 /* Generate HTTP header. */
469 status = nx_web_http_server_callback_generate_response_header(server_ptr,
470 &response_pkt, NX_WEB_HTTP_STATUS_OK, 0, NX_NULL,
471 NX_NULL);
472
473 if(status)
474 {
475 return(status);
476 }
477
478 if(status == NX_SUCCESS)
479 {
480 if(nx_web_http_server_callback_packet_send(server_ptr, response_pkt) != NX_SUCCESS)
481 {
482 nx_packet_release(response_pkt);
483 }
484 }
485 }
486 else
487 {
488 /* Indicate we have not processed the response to client yet. */
489 return(NX_SUCCESS);
490 }
491
492 /* Indicate the response to client is transmitted. */
493 return(NX_WEB_HTTP_CALLBACK_COMPLETED);
494 }
495 #else
496
497 #ifdef CTEST
test_application_define(void * first_unused_memory)498 VOID test_application_define(void *first_unused_memory)
499 #else
500 void netx_web_host_field_test_application_define(void *first_unused_memory)
501 #endif
502 {
503
504 /* Print out test information banner. */
505 printf("NetX Test: Web Host Field Test.......................................N/A\n");
506
507 test_control_return(3);
508 }
509 #endif
510
511