1 /* This case tests basic HTTP Proxy connection. */
2 #include "tx_api.h"
3 #include "nx_api.h"
4
5 extern void test_control_return(UINT);
6
7 #if !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_HTTP_PROXY) && defined(__PRODUCT_NETXDUO__)
8 #include "nx_http_proxy_client.h"
9
10 #define DEMO_STACK_SIZE 4096
11 #define PACKET_SIZE 1536
12 #define TOTAL_SIZE DEMO_STACK_SIZE + (PACKET_SIZE * 8) + 2048 + 1024
13
14 /* Define device drivers. */
15 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
16
17 static TX_THREAD client_thread;
18 static NX_PACKET_POOL client_pool;
19 static NX_TCP_SOCKET test_client;
20 static NX_IP client_ip;
21 static UINT error_counter;
22
23 static NX_TCP_SOCKET test_server;
24 static NX_PACKET_POOL server_pool;
25 static TX_THREAD server_thread;
26 static NX_IP server_ip;
27 static UINT test_server_start = 0;
28 static UINT test_client_stop = 0;
29
30 /* Set up the HTTP proxy server global variables */
31 static TX_THREAD proxy_thread;
32 static NX_PACKET_POOL proxy_pool;
33 static NX_IP proxy_ip;
34 static NX_TCP_SOCKET agent_server, agent_client;
35
36 static void thread_client_entry(ULONG thread_input);
37 static void thread_server_entry(ULONG thread_input);
38 static void thread_proxy_entry(ULONG thread_input);
39
40 #define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4)
41 #define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5)
42 #define HTTP_PROXY_ADDRESS IP_ADDRESS(1,2,3,6)
43 #define HTTP_PROXY_PORT 8888
44 #define TEST_SERVER_PORT 8080
45
46 static UCHAR connect_200[] =
47 {
48 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x43, 0x6f, 0x6e,
49 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73,
50 0x68, 0x65, 0x64, 0x0d, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,
51 0x3a, 0x20, 0x74, 0x69, 0x6e, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x31, 0x2e, 0x38, 0x2e,
52 0x34, 0x0d, 0x0a, 0x0d, 0x0a,
53 };
54
55 static UCHAR connect_req[] =
56 {
57 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x3a, /* CONNECT 1.2.3.4: */
58 0x38, 0x30, 0x38, 0x30, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, /* 8080 HTTP/1.1..H */
59 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x0d, 0x0a, 0x50, 0x72, /* ost: 1.2.3.4..Pr */
60 0x6f, 0x78, 0x79, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, /* oxy-authorizatio */
61 0x6e, 0x3a, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x64, 0x58, 0x4e, 0x6c, 0x63, 0x6a, 0x70, /* n: Basic dXNlcjp */
62 0x77, 0x59, 0x58, 0x4e, 0x7a, 0x64, 0x32, 0x39, 0x79, 0x5a, 0x41, 0x3d, 0x3d, 0x0d, 0x0a, 0x0d, /* wYXNzd29yZA==... */
63 0x0a
64 };
65
66 static UCHAR test_data[] = "HTTP Proxy Basic Test!";
67
68 #define TEST_LOOP 3
69
70 #ifdef CTEST
test_application_define(void * first_unused_memory)71 VOID test_application_define(void *first_unused_memory)
72 #else
73 void netx_http_proxy_basic_test_application_define(void *first_unused_memory)
74 #endif
75 {
76 CHAR *pointer;
77 UINT status;
78
79
80 error_counter = 0;
81
82 /* Setup the working pointer. */
83 pointer = (CHAR *) first_unused_memory;
84
85 /* Create a helper thread for the server. */
86 tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0,
87 pointer, DEMO_STACK_SIZE,
88 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
89
90 pointer = pointer + DEMO_STACK_SIZE;
91
92 /* Initialize the NetX system. */
93 nx_system_initialize();
94
95 /* Create the server packet pool. */
96 status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE,
97 pointer, PACKET_SIZE * 8);
98 pointer = pointer + PACKET_SIZE * 8;
99 if (status)
100 error_counter++;
101
102 /* Create an IP instance. */
103 status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS,
104 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
105 pointer, 2048, 1);
106 pointer = pointer + 2048;
107 if (status)
108 error_counter++;
109
110 /* Enable ARP and supply ARP cache memory for the server IP instance. */
111 status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
112 pointer = pointer + 1024;
113 if (status)
114 error_counter++;
115
116
117 /* Enable TCP traffic. */
118 status = nx_tcp_enable(&server_ip);
119 if (status)
120 error_counter++;
121
122 /* Create the Test Client thread. */
123 status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0,
124 pointer, DEMO_STACK_SIZE,
125 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
126 pointer = pointer + DEMO_STACK_SIZE;
127 if (status)
128 error_counter++;
129
130 /* Create the Client packet pool. */
131 status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE,
132 pointer, PACKET_SIZE * 8);
133 pointer = pointer + PACKET_SIZE * 8;
134 if (status)
135 error_counter++;
136
137 /* Create an IP instance. */
138 status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS,
139 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
140 pointer, 2048, 1);
141 pointer = pointer + 2048;
142 if (status)
143 error_counter++;
144
145 status = nx_arp_enable(&client_ip, (void *) pointer, 1024);
146 pointer = pointer + 1024;
147 if (status)
148 error_counter++;
149
150 /* Enable TCP traffic. */
151 status = nx_tcp_enable(&client_ip);
152 if (status)
153 error_counter++;
154
155 /* Create the HTTP Proxy thread. */
156 status = tx_thread_create(&proxy_thread, "HTTP Proxy", thread_proxy_entry, 0,
157 pointer, DEMO_STACK_SIZE,
158 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START);
159 pointer = pointer + DEMO_STACK_SIZE;
160 if (status)
161 error_counter++;
162
163 /* Create the Client packet pool. */
164 status = nx_packet_pool_create(&proxy_pool, "HTTP Proxy Packet Pool", PACKET_SIZE,
165 pointer, PACKET_SIZE * 8);
166 pointer = pointer + PACKET_SIZE * 8;
167 if (status)
168 error_counter++;
169
170 /* Create an IP instance. */
171 status = nx_ip_create(&proxy_ip, "HTTP Proxy IP", HTTP_PROXY_ADDRESS,
172 0xFFFFFF00UL, &proxy_pool, _nx_ram_network_driver_1024,
173 pointer, 2048, 1);
174 pointer = pointer + 2048;
175 if (status)
176 error_counter++;
177
178 status = nx_arp_enable(&proxy_ip, (void *) pointer, 1024);
179 pointer = pointer + 1024;
180 if (status)
181 error_counter++;
182
183 /* Enable TCP traffic. */
184 status = nx_tcp_enable(&proxy_ip);
185 if (status)
186 error_counter++;
187 }
188
thread_client_entry(ULONG thread_input)189 void thread_client_entry(ULONG thread_input)
190 {
191 UINT i, status;
192 NX_PACKET *packet_ptr;
193 NXD_ADDRESS proxy_server_address;
194 NXD_ADDRESS server_ip_address;
195
196
197 /* Give IP task and driver a chance to initialize the system. */
198 tx_thread_sleep(NX_IP_PERIODIC_RATE);
199
200 /* Set server IP address. */
201 server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS;
202 server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
203
204 proxy_server_address.nxd_ip_version = NX_IP_VERSION_V4;
205 proxy_server_address.nxd_ip_address.v4 = HTTP_PROXY_ADDRESS;
206
207 status = nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, NX_NULL, 1, "password", sizeof("password") - 1);
208 if (status != NX_PTR_ERROR)
209 error_counter++;
210
211 status = nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, NX_NULL, 1);
212 if (status != NX_PTR_ERROR)
213 error_counter++;
214
215 status = nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", NX_HTTP_PROXY_MAX_USERNAME + 1, "password", sizeof("password") - 1);
216 if (status != NX_SIZE_ERROR)
217 error_counter++;
218
219 status = nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, "password", NX_HTTP_PROXY_MAX_PASSWORD + 1);
220 if (status != NX_SIZE_ERROR)
221 error_counter++;
222
223 status = nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, "password", sizeof("password") - 1);
224 if(status)
225 error_counter++;
226
227 status = nx_tcp_socket_create(&client_ip, &test_client, "Test Client Socket",
228 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000,
229 NX_NULL, NX_NULL);
230 if(status)
231 error_counter++;
232
233 /* Bind and connect to server. */
234 status = nx_tcp_client_socket_bind(&test_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE);
235 if(status)
236 error_counter++;
237
238 for ( i = 0 ; i < TEST_LOOP; i++)
239 {
240
241 /* Wait test server started. */
242 while(!test_server_start)
243 {
244 tx_thread_sleep(NX_IP_PERIODIC_RATE);
245 }
246
247 status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE);
248 if(status)
249 error_counter++;
250
251 /* Send data. */
252 status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE);
253 if(status)
254 error_counter++;
255
256 status = nx_packet_data_append(packet_ptr, test_data, sizeof(test_data) - 1, &client_pool, NX_IP_PERIODIC_RATE);
257 if(status)
258 error_counter++;
259
260 status = nx_tcp_socket_send(&test_client, packet_ptr, NX_IP_PERIODIC_RATE);
261 if(status)
262 error_counter++;
263
264 /* Receive the echo data from server. */
265 status = nx_tcp_socket_receive(&test_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
266 if(status)
267 error_counter++;
268 else
269 {
270
271 /* Check the received data. */
272 if ((packet_ptr -> nx_packet_length != (sizeof(test_data) - 1)) ||
273 (memcmp(packet_ptr -> nx_packet_prepend_ptr, test_data, packet_ptr -> nx_packet_length) != 0))
274 error_counter++;
275
276 nx_packet_release(packet_ptr);
277 }
278
279 /* Set the flag. */
280 test_client_stop = 1;
281 nx_tcp_socket_disconnect(&test_client, NX_IP_PERIODIC_RATE);
282 }
283
284 nx_tcp_client_socket_unbind(&test_client);
285 nx_tcp_socket_delete(&test_client);
286 }
287
thread_proxy_entry(ULONG thread_input)288 void thread_proxy_entry(ULONG thread_input)
289 {
290 UINT i, status;
291 ULONG actual_status;
292 NX_PACKET *packet_ptr;
293 NXD_ADDRESS server_ip_address;
294
295 /* Set server IP address. */
296 server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS;
297 server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
298
299 /* Ensure the IP instance has been initialized. */
300 status = nx_ip_status_check(&proxy_ip, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE);
301 if(status)
302 error_counter++;
303
304 /* Create a socket. */
305 status = nx_tcp_socket_create(&proxy_ip, &agent_server, "Agent Server Socket",
306 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000,
307 NX_NULL, NX_NULL);
308 status += nx_tcp_socket_create(&proxy_ip, &agent_client, "Agent Client Socket",
309 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000,
310 NX_NULL, NX_NULL);
311 if(status)
312 error_counter++;
313
314 /* Setup this thread to listen. */
315 status = nx_tcp_server_socket_listen(&proxy_ip, HTTP_PROXY_PORT, &agent_server, 5, NX_NULL);
316 if(status)
317 error_counter++;
318
319 for (i = 0; i < TEST_LOOP; i++)
320 {
321
322 /* Accept a connection from test client. */
323 status = nx_tcp_server_socket_accept(&agent_server, 5 * NX_IP_PERIODIC_RATE);
324 if(status)
325 error_counter++;
326
327 /* Receive CONNECT request. */
328 status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
329 if(status)
330 error_counter++;
331
332 /* Check the received CONNECT request. */
333 if (memcmp(packet_ptr -> nx_packet_prepend_ptr, connect_req, sizeof(connect_req)) != 0)
334 error_counter++;
335
336 /* Connect to the test server. */
337 status = nx_tcp_client_socket_bind(&agent_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE);
338 status += nxd_tcp_client_socket_connect(&agent_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE);
339 if(status)
340 error_counter++;
341
342 /* Send response to test client. */
343 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr;
344 packet_ptr -> nx_packet_length = 0;
345 nx_packet_data_append(packet_ptr, connect_200, sizeof(connect_200), &proxy_pool, NX_IP_PERIODIC_RATE);
346 status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE);
347 if(status)
348 error_counter++;
349
350 /* Tunneling... */
351 status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
352 if(status)
353 error_counter++;
354 status = nx_tcp_socket_send(&agent_client, packet_ptr, NX_IP_PERIODIC_RATE);
355 if(status)
356 error_counter++;
357 status = nx_tcp_socket_receive(&agent_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
358 if(status)
359 error_counter++;
360 status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE);
361 if(status)
362 error_counter++;
363
364 /* Wait client test finished. */
365 tx_thread_sleep(NX_IP_PERIODIC_RATE);
366
367 /* Disconnet. */
368 nx_tcp_socket_disconnect(&agent_server, NX_IP_PERIODIC_RATE);
369 nx_tcp_server_socket_unaccept(&agent_server);
370 nx_tcp_server_socket_relisten(&proxy_ip, HTTP_PROXY_PORT, &agent_server);
371 nx_tcp_socket_disconnect(&agent_client, NX_IP_PERIODIC_RATE);
372 nx_tcp_client_socket_unbind(&agent_client);
373 }
374
375 nx_tcp_socket_delete(&agent_server);
376 nx_tcp_socket_delete(&agent_client);
377 }
378
379 /* Define the helper Test server thread. */
thread_server_entry(ULONG thread_input)380 void thread_server_entry(ULONG thread_input)
381 {
382 UINT i, status;
383 NX_PACKET *packet_ptr;
384
385
386 /* Print out test information banner. */
387 printf("NetX Test: HTTP Proxy Basic Test.....................................");
388
389 /* Check for earlier error. */
390 if(error_counter)
391 {
392 printf("ERROR!\n");
393 test_control_return(1);
394 }
395
396 /* Give NetX a chance to initialize the system. */
397 tx_thread_sleep(NX_IP_PERIODIC_RATE);
398
399 status = nx_tcp_socket_create(&server_ip, &test_server, "Test Server Socket",
400 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000,
401 NX_NULL, NX_NULL);
402
403 status = nx_tcp_server_socket_listen(&server_ip, TEST_SERVER_PORT, &test_server, 5, NX_NULL);
404 if(status)
405 error_counter++;
406
407 for (i = 0; i < TEST_LOOP; i++)
408 {
409
410 /* Set the flag. */
411 test_server_start = 1;
412
413 /* Accept a connection from test client. */
414 status = nx_tcp_server_socket_accept(&test_server, 5 * NX_IP_PERIODIC_RATE);
415 if(status)
416 error_counter++;
417
418 /* Receive client data. */
419 status = nx_tcp_socket_receive(&test_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE);
420 if(status)
421 error_counter++;
422
423 /* Echo data. */
424 status = nx_tcp_socket_send(&test_server, packet_ptr, NX_IP_PERIODIC_RATE);
425 if(status)
426 error_counter++;
427
428 /* Wait client test finished. */
429 while(!test_client_stop)
430 {
431 tx_thread_sleep(NX_IP_PERIODIC_RATE);
432 }
433 test_server_start = 0;
434 test_client_stop = 0;
435
436 nx_tcp_socket_disconnect(&test_server, NX_IP_PERIODIC_RATE);
437 nx_tcp_server_socket_unaccept(&test_server);
438 nx_tcp_server_socket_relisten(&server_ip, TEST_SERVER_PORT, &test_server);
439 }
440 nx_tcp_server_socket_unlisten(&server_ip, TEST_SERVER_PORT);
441 nx_tcp_socket_delete(&test_server);
442
443 /* Check packet pool. */
444 if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
445 {
446 error_counter++;
447 }
448
449 if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total)
450 {
451 error_counter++;
452 }
453
454 if(error_counter)
455 {
456 printf("ERROR!\n");
457 test_control_return(1);
458 }
459 else
460 {
461 printf("SUCCESS!\n");
462 test_control_return(0);
463 }
464 }
465
466 #else
467
468 #ifdef CTEST
test_application_define(void * first_unused_memory)469 VOID test_application_define(void *first_unused_memory)
470 #else
471 void netx_http_proxy_basic_test_application_define(void *first_unused_memory)
472 #endif
473 {
474
475 /* Print out test information banner. */
476 printf("NetX Test: HTTP Proxy Basic Test.....................................N/A\n");
477
478 test_control_return(3);
479 }
480 #endif
481
482