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