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