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