1 /* This case tests the basic authentication,
2  * name:password  is the correct account
3  * name2:password is the wrong account
4  */
5 
6 #include    "tx_api.h"
7 #include    "nx_api.h"
8 #include    "fx_api.h"
9 #include    "nxd_http_client.h"
10 #include    "nxd_http_server.h"
11 
12 extern void test_control_return(UINT);
13 
14 #if !defined(NX_DISABLE_IPV4)
15 
16 #define     DEMO_STACK_SIZE         4096
17 
18 /* Set up FileX and file memory resources. */
19 static CHAR             *ram_disk_memory;
20 static FX_MEDIA         ram_disk;
21 static unsigned char    media_memory[512];
22 
23 /* Define device drivers.  */
24 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
25 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
26 
27 /* Set up the HTTP client global variables. */
28 
29 #define         CLIENT_PACKET_SIZE  (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2)
30 
31 static TX_THREAD       client_thread;
32 static NX_PACKET_POOL  client_pool;
33 static NX_HTTP_CLIENT  my_client;
34 static NX_IP           client_ip;
35 static UINT            error_counter;
36 
37 /* Set up the HTTP server global variables */
38 
39 #define         SERVER_PACKET_SIZE  (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2)
40 
41 static NX_HTTP_SERVER  my_server;
42 static NX_PACKET_POOL  server_pool;
43 static TX_THREAD       server_thread;
44 static NX_IP           server_ip;
45 #ifdef __PRODUCT_NETXDUO__
46 static NXD_ADDRESS     server_ip_address;
47 #else
48 static ULONG           server_ip_address;
49 #endif
50 
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(1,2,3,4)
56 #define HTTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
57 
58 
59 static TX_SEMAPHORE server_start;
60 static TX_SEMAPHORE client_stop;
61 
62 
63 /* Define the application's authentication check.  This is called by
64    the HTTP server whenever a new request is received.  */
authentication_check(NX_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,CHAR ** password,CHAR ** realm)65 static UINT  authentication_check(NX_HTTP_SERVER *server_ptr, UINT request_type,
66             CHAR *resource, CHAR **name, CHAR **password, CHAR **realm)
67 {
68 
69     /* Just use a simple name, password, and realm for all
70        requests and resources.  */
71     *name =     "name";
72     *password = "password";
73     *realm =    "NetX Duo HTTP demo";
74 
75     /* Request basic authentication.  */
76     return(NX_HTTP_BASIC_AUTHENTICATE);
77 }
78 
authentication_check_extended(NX_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,UINT * name_length,CHAR ** password,UINT * password_length,CHAR ** realm,UINT * realm_length)79 static UINT  authentication_check_extended(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, UINT *name_length,
80                                            CHAR **password, UINT *password_length, CHAR **realm, UINT *realm_length)
81 {
82 
83     /* Just use a simple name, password, and realm for all
84        requests and resources.  */
85     *name =     "name";
86     *password = "password";
87     *realm =    "NetX Duo HTTP demo";
88     *name_length = 4;
89     *password_length = 8;
90     *realm_length = 18;
91 
92     /* Request basic authentication.  */
93     return(NX_HTTP_BASIC_AUTHENTICATE);
94 }
95 
96 #ifdef CTEST
test_application_define(void * first_unused_memory)97 VOID test_application_define(void *first_unused_memory)
98 #else
99 void    netx_http_basic_authenticate_test_application_define(void *first_unused_memory)
100 #endif
101 {
102 
103 CHAR    *pointer;
104 UINT    status;
105 
106     error_counter = 0;
107 
108     /* Setup the working pointer.  */
109     pointer =  (CHAR *) first_unused_memory;
110 
111     /* Create a helper thread for the server. */
112     tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
113                      pointer, DEMO_STACK_SIZE,
114                      4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
115 
116     pointer =  pointer + DEMO_STACK_SIZE;
117 
118     /* Initialize the NetX system.  */
119     nx_system_initialize();
120 
121     /* Create the server packet pool.  */
122     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
123                                     pointer, SERVER_PACKET_SIZE*8);
124     pointer = pointer + SERVER_PACKET_SIZE * 8;
125     if (status)
126         error_counter++;
127 
128     /* Create an IP instance.  */
129     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
130                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
131                           pointer, 4096, 1);
132     pointer =  pointer + 4096;
133     if (status)
134         error_counter++;
135 
136     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
137     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
138     pointer = pointer + 1024;
139     if (status)
140         error_counter++;
141 
142 
143      /* Enable TCP traffic.  */
144     status = nx_tcp_enable(&server_ip);
145     if (status)
146         error_counter++;
147 
148     /* Set up the server's IPv4 address here. */
149 #ifdef __PRODUCT_NETXDUO__
150     server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
151     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
152 #else
153     server_ip_address = HTTP_SERVER_ADDRESS;
154 #endif
155 
156     /* Create the HTTP Server.  */
157     status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk,
158                           pointer, 2048, &server_pool, authentication_check, NX_NULL);
159     pointer =  pointer + 2048;
160     if (status)
161         error_counter++;
162 
163     /* Save the memory pointer for the RAM disk.  */
164     ram_disk_memory =  pointer;
165 
166     /* Create the HTTP Client thread. */
167     status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0,
168                      pointer, DEMO_STACK_SIZE,
169                      6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
170     pointer =  pointer + DEMO_STACK_SIZE;
171     if (status)
172         error_counter++;
173 
174     /* Create the Client packet pool.  */
175     status =  nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
176                                     pointer, CLIENT_PACKET_SIZE*8);
177     pointer = pointer + CLIENT_PACKET_SIZE * 8;
178     if (status)
179         error_counter++;
180 
181     /* Create an IP instance.  */
182     status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
183                           0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
184                           pointer, 2048, 1);
185     pointer =  pointer + 2048;
186     if (status)
187         error_counter++;
188 
189     status  = nx_arp_enable(&client_ip, (void *) pointer, 1024);
190     pointer =  pointer + 2048;
191     if (status)
192         error_counter++;
193 
194      /* Enable TCP traffic.  */
195     status = nx_tcp_enable(&client_ip);
196     if (status)
197         error_counter++;
198 
199     tx_semaphore_create(&server_start, "server start", 0);
200     tx_semaphore_create(&client_stop, "client stop", 0);
201 }
202 
203 
thread_client_entry(ULONG thread_input)204 void thread_client_entry(ULONG thread_input)
205 {
206 
207 UINT            status;
208 NX_PACKET       *send_packet;
209 
210     /* Format the RAM disk - the memory for the RAM disk was setup in
211       tx_application_define above.  This must be set up before the client(s) start
212       sending requests. */
213     status = fx_media_format(&ram_disk,
214                             _fx_ram_driver,         /* Driver entry               */
215                             ram_disk_memory,        /* RAM disk memory pointer    */
216                             media_memory,           /* Media buffer pointer       */
217                             sizeof(media_memory),   /* Media buffer size          */
218                             "MY_RAM_DISK",          /* Volume Name                */
219                             1,                      /* Number of FATs             */
220                             32,                     /* Directory Entries          */
221                             0,                      /* Hidden sectors             */
222                             256,                    /* Total sectors              */
223                             128,                    /* Sector size                */
224                             1,                      /* Sectors per cluster        */
225                             1,                      /* Heads                      */
226                             1);                     /* Sectors per track          */
227 
228     /* Check the media format status.  */
229     if (status != FX_SUCCESS)
230         error_counter++;
231 
232     /* Open the RAM disk.  */
233     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory));
234     if (status != FX_SUCCESS)
235         error_counter++;
236 
237     /* Create an HTTP client instance.  */
238     status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600);
239     if (status)
240         error_counter++;
241 
242 #ifdef __PRODUCT_NETXDUO__
243 
244     /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */
245     status =  nxd_http_client_put_start(&my_client, &server_ip_address, "/client_test.htm",
246                                             "name", "password", 103, 5 * NX_IP_PERIODIC_RATE);
247 #else
248 
249     /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */
250     status =  nx_http_client_put_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm",
251                                    "name", "password", 103, 5 * NX_IP_PERIODIC_RATE);
252 #endif
253 
254     /* Check status.  */
255     if (status)
256         error_counter++;
257 
258     /* Allocate a packet.  */
259     status =  nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER);
260     if(status)
261         error_counter++;
262 
263     /* Build a simple 103-byte HTML page.  */
264     nx_packet_data_append(send_packet, "<HTML>\r\n", 8,
265                         &client_pool, NX_WAIT_FOREVER);
266     nx_packet_data_append(send_packet,
267                  "<HEAD><TITLE>NetX HTTP Test</TITLE></HEAD>\r\n", 44,
268                         &client_pool, NX_WAIT_FOREVER);
269     nx_packet_data_append(send_packet, "<BODY>\r\n", 8,
270                         &client_pool, NX_WAIT_FOREVER);
271     nx_packet_data_append(send_packet, "<H1>Another NetX Test Page!</H1>\r\n", 25,
272                         &client_pool, NX_WAIT_FOREVER);
273     nx_packet_data_append(send_packet, "</BODY>\r\n", 9,
274                         &client_pool, NX_WAIT_FOREVER);
275     nx_packet_data_append(send_packet, "</HTML>\r\n", 9,
276                         &client_pool, NX_WAIT_FOREVER);
277 
278     /* Complete the PUT by writing the total length.  */
279     status =  nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE);
280     if(status)
281         error_counter++;
282 
283     /* Basic authentication, name = "name", passwd = "password". */
284 #ifdef __PRODUCT_NETXDUO__
285 
286     /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */
287     status =  nxd_http_client_get_start(&my_client, &server_ip_address,
288                                             "/client_test.htm", NX_NULL, 0, "name", "password", 50);
289 #else
290 
291     /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */
292     status =  nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm",
293                                        NX_NULL, 0, "name", "password", 50);
294 #endif
295 
296     /* Should  pass the authentication. */
297     if(status)
298         error_counter++;
299 
300     status = nx_http_client_delete(&my_client);
301     if(status)
302         error_counter++;
303 
304     /* Create an HTTP client instance.  */
305     status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600);
306     if (status)
307         error_counter++;
308 
309     /* Basic Authentication, name = "name2", passwd = "password". */
310 #ifdef __PRODUCT_NETXDUO__
311 
312     /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */
313     status =  nxd_http_client_get_start(&my_client, &server_ip_address,
314                                             "/client_test.htm", NX_NULL, 0, "name2", "password", 50);
315 #else
316 
317     /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */
318     status =  nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm",
319                                        NX_NULL, 0, "name2", "password", 50);
320 #endif
321 
322     /* Shouldn't pass the authentication. */
323     if(status != NX_HTTP_AUTHENTICATION_ERROR)
324         error_counter++;
325 
326     status = nx_http_client_delete(&my_client);
327     if(status)
328         error_counter++;
329 
330     /* Create an HTTP client instance.  */
331     status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600);
332     if (status)
333         error_counter++;
334 
335     /* Basic Authentication, name = "name", passwd = "". */
336 #ifdef __PRODUCT_NETXDUO__
337 
338     /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */
339     status =  nxd_http_client_get_start(&my_client, &server_ip_address,
340                                             "/client_test.htm", NX_NULL, 0, "name", "", 50);
341 #else
342 
343     /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */
344     status =  nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm",
345                                        NX_NULL, 0, "name", "", 50);
346 #endif
347 
348     /* Shouldn't pass the authentication. */
349     if(status != NX_HTTP_AUTHENTICATION_ERROR)
350         error_counter++;
351 
352     status = nx_http_client_delete(&my_client);
353     if(status)
354         error_counter++;
355 
356     tx_semaphore_put(&client_stop);
357     tx_semaphore_get(&server_start, NX_WAIT_FOREVER);
358 
359     /* Create an HTTP client instance.  */
360     status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600);
361     if (status)
362         error_counter++;
363 
364     /* Basic Authentication, name = "name2", passwd = "password". */
365 #ifdef __PRODUCT_NETXDUO__
366 
367     /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */
368     status =  nxd_http_client_get_start(&my_client, &server_ip_address,
369                                         "/client_test.htm", NX_NULL, 0, "name", "password", 50);
370 #else
371 
372     /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */
373     status =  nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm",
374                                        NX_NULL, 0, "name", "password", 50);
375 #endif
376 
377     /* Should  pass the authentication. */
378     if(status)
379         error_counter++;
380 
381     if(error_counter)
382     {
383         printf("ERROR!\n");
384         test_control_return(1);
385     }
386     else
387     {
388         printf("SUCCESS!\n");
389         test_control_return(0);
390     }
391 
392 }
393 
394 
395 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)396 void    thread_server_entry(ULONG thread_input)
397 {
398 
399 UINT            status;
400 
401     /* Print out test information banner.  */
402     printf("NetX Test:   HTTP Basic Athentication Test.............................");
403 
404     /* Check for earlier error. */
405     if(error_counter)
406     {
407         printf("ERROR!\n");
408         test_control_return(1);
409     }
410 
411     /* OK to start the HTTP Server.   */
412     status = nx_http_server_start(&my_server);
413     if(status)
414         error_counter++;
415 
416     tx_semaphore_get(&client_stop, NX_WAIT_FOREVER);
417 
418     status = nx_http_server_authentication_check_set(&my_server, authentication_check_extended);
419     if (status)
420         error_counter++;
421 
422     tx_semaphore_put(&server_start);
423 }
424 #else
425 
426 #ifdef CTEST
test_application_define(void * first_unused_memory)427 VOID test_application_define(void *first_unused_memory)
428 #else
429 void    netx_http_basic_authenticate_test_application_define(void *first_unused_memory)
430 #endif
431 {
432 
433     /* Print out test information banner.  */
434     printf("NetX Test:   HTTP Basic Athentication Test.............................N/A\n");
435 
436     test_control_return(3);
437 }
438 #endif