1 /* This case tests whether HTTP server can work well with multipart/form-data.
2  * server packet size 800
3  * client packet size 1400
4  * pkt size is bigger than 1500 to cause client/server fragmentation.
5  */
6 
7 /* Here is the packet content. */
8 /*
9 ------------------------------4ebf00fbcf09
10 Content-Disposition: form-data; name="example"
11 
12 test(repeat 49 times)
13 ------------------------------4ebf00fbcf09
14 Content-Disposition: form-data; name="example2"
15 
16 test2(repeat 35 times)
17 ------------------------------4ebf00fbcf09
18 Content-Disposition: form-data; name="example3"
19 
20 test3(repeat 39 times)
21 ------------------------------4ebf00fbcf09
22 Content-Disposition: form-data; name="example4"
23 
24 test4(repeat 51times)
25 ------------------------------4ebf00fbcf09
26 Content-Disposition: form-data; name="example5"
27 
28 test5(repeat 54times)
29 ------------------------------4ebf00fbcf09--
30 */
31 
32 /* length1 = 196,
33  * length2 = 175,
34  * length3 = 195,
35  * length4 = 205
36  * length5 = 220.
37  * */
38 #include    "tx_api.h"
39 #include    "nx_api.h"
40 #include    "fx_api.h"
41 #include    "nx_web_http_client.h"
42 #include    "nx_web_http_server.h"
43 
44 extern void test_control_return(UINT);
45 
46 #if defined(NX_WEB_HTTP_MULTIPART_ENABLE) && !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_PACKET_CHAIN)
47 
48 #include "test_device_cert.c"
49 #include "test_ca_cert.c"
50 #define ca_cert_der test_ca_cert_der
51 #define ca_cert_der_len test_ca_cert_der_len
52 
53 #define     DEMO_STACK_SIZE         4096
54 
55 /* Set up FileX and file memory resources. */
56 static CHAR             ram_disk_memory[4096];
57 static FX_MEDIA         ram_disk;
58 static UCHAR            media_memory[4096];
59 
60 static UCHAR            server_stack[16000];
61 
62 /* Define device drivers.  */
63 extern void _fx_ram_driver(FX_MEDIA *media_ptr);
64 extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr);
65 
66 /* Set up the HTTP client global variables. */
67 
68 #define         CLIENT_PACKET_SIZE  (NX_WEB_HTTP_CLIENT_MIN_PACKET_SIZE * 2)
69 
70 static TX_THREAD           client_thread;
71 static NX_PACKET_POOL      client_pool;
72 static NX_WEB_HTTP_CLIENT  my_client;
73 static NX_IP               client_ip;
74 static UINT                error_counter;
75 
76 /* Set up the HTTP server global variables */
77 
78 #define         SERVER_PACKET_SIZE  (NX_WEB_HTTP_SERVER_MIN_PACKET_SIZE * 2)
79 
80 static NX_WEB_HTTP_SERVER  my_server;
81 static NX_PACKET_POOL      server_pool;
82 static TX_THREAD           server_thread;
83 static NX_IP               server_ip;
84 static NXD_ADDRESS         server_ip_address;
85 static UINT                http_server_start = 0;
86 static UINT                http_client_stop = 0;
87 
88 static void thread_client_entry(ULONG thread_input);
89 static void thread_server_entry(ULONG thread_input);
90 
91 #define HTTP_SERVER_ADDRESS  IP_ADDRESS(1,2,3,4)
92 #define HTTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
93 
94 #ifdef NX_WEB_HTTPS_ENABLE
95 static UINT                https_server_start = 0;
96 static UINT                https_client_stop = 0;
97 static UINT loop = 2;
98 extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;
99 static CHAR crypto_metadata_server[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
100 static CHAR crypto_metadata_client[20000 * NX_WEB_HTTP_SERVER_SESSION_MAX];
101 static UCHAR tls_packet_buffer[18500];
102 static NX_SECURE_X509_CERT certificate;
103 static NX_SECURE_X509_CERT trusted_certificate;
104 static NX_SECURE_X509_CERT remote_certificate, remote_issuer;
105 static UCHAR remote_cert_buffer[2000];
106 static UCHAR remote_issuer_buffer[2000];
107 #else
108 static UINT loop = 1;
109 #endif /* NX_WEB_HTTPS_ENABLE  */
110 static UINT multipart_flag;
111 
112 extern UINT _nx_web_http_client_receive(NX_WEB_HTTP_CLIENT *client_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
113 extern UINT _nx_web_http_client_send(NX_WEB_HTTP_CLIENT *client_ptr, NX_PACKET *packet_ptr, ULONG wait_option);
114 
115 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr);
116 
117 //#define TEST_CHUNKED
118 
119 /* This is a HTTP get packet captured by wireshark. HEAD index.html*/
120 static char pkt[] = {
121     0x50, 0x4f, 0x53, 0x54, 0x20, 0x2f, 0x20, 0x48, /* POST / H */
122     0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, /* TTP/1.1. */
123     0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, /* .User-Ag */
124     0x65, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x75, 0x72, /* ent: cur */
125     0x6c, 0x2f, 0x37, 0x2e, 0x33, 0x32, 0x2e, 0x30, /* l/7.32.0 */
126 #ifdef TEST_CHUNKED
127     0x0d, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66,
128     0x65, 0x72, 0x2d, 0x45, 0x6e, 0x63, 0x6f, 0x64,
129     0x69, 0x6e, 0x67, 0x3a, 0x20, 0x63, 0x68, 0x75,
130     0x6e, 0x6b, 0x65, 0x64,
131 #endif
132     0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, /* ..Host:  */
133     0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, /* 192.168. */
134     0x30, 0x2e, 0x31, 0x32, 0x33, 0x0d, 0x0a, 0x41, /* 0.123..A */
135     0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, /* ccept: * */
136     0x2f, 0x2a, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, /*  *..Cont */
137     0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, /* ent-Type */
138     0x3a, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* : multip */
139     0x61, 0x72, 0x74, 0x2f, 0x66, 0x6f, 0x72, 0x6d, /* art/form */
140     0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, 0x62, /* -data; b */
141     0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x3d, /* oundary= */
142     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
143     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
144     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
145     0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, /* ----4ebf */
146     0x30, 0x30, 0x66, 0x62, 0x63, 0x66, 0x30, 0x39, /* 00fbcf09 */
147     0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* ..Conten */
148     0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, /* t-Length */
149     0x3a, 0x20, 0x31, 0x35, 0x32, 0x31, 0x0d, 0x0a, /* : 1521.. */
150     0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x3a, 0x20, /* Expect:  */
151     0x31, 0x30, 0x30, 0x2d, 0x63, 0x6f, 0x6e, 0x74, /* 100-cont */
152     0x69, 0x6e, 0x75, 0x65, 0x0d, 0x0a, 0x0d, 0x0a, /* inue.... */
153 #ifdef TEST_CHUNKED
154     0x38, 0x30, 0x0d, 0x0a,
155 #endif
156     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
157     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
158     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
159     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, /* ------4e */
160     0x62, 0x66, 0x30, 0x30, 0x66, 0x62, 0x63, 0x66, /* bf00fbcf */
161     0x30, 0x39, 0x0d, 0x0a, 0x0d, 0x0a, 0x6e, 0x74, /* 09..Cont */
162     0x65, 0x6e, 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, /* ent-Disp */
163     0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, /* osition: */
164     0x20, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, /*  form-da */
165     0x74, 0x61, 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, /* ta; name */
166     0x3d, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, /* ="exampl */
167     0x65, 0x22, 0x0d, 0x0a, 0x0d, 0x0a, 0x74, 0x65, /* e"....te */
168     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
169     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
170     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
171     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
172 #ifdef TEST_CHUNKED
173     0x0d, 0x0a,
174     0x35, 0x37, 0x31, 0x0d, 0x0a,
175 #endif
176     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
177     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
178     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
179     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
180     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
181     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
182     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
183     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
184     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
185     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
186     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
187     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
188     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
189     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
190     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
191     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
192     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
193     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
194     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
195     0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */
196     0x73, 0x74, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, /* st..---- */
197     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
198     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
199     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
200     0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, 0x30, 0x30, /* --4ebf00 */
201     0x66, 0x62, 0x63, 0x66, 0x30, 0x39, 0x0d, 0x0a, /* fbcf09.. */
202     0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* Content- */
203     0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69, 0x74, /* Disposit */
204     0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x6f, 0x72, /* ion: for */
205     0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, /* m-data;  */
206     0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x65, 0x78, /* name="ex */
207     0x61, 0x6d, 0x70, 0x6c, 0x65, 0x32, 0x22, 0x0d, /* ample2". */
208     0x0a, 0x0d, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x32, /* ...test2 */
209     0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */
210     0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */
211     0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */
212     0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */
213     0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */
214     0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */
215     0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */
216     0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */
217     0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */
218     0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */
219     0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */
220     0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */
221     0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */
222     0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */
223     0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */
224     0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */
225     0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */
226     0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */
227     0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */
228     0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */
229     0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */
230     0x74, 0x32, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, /* t2..---- */
231     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
232     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
233     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
234     0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, 0x30, 0x30, /* --4ebf00 */
235     0x66, 0x62, 0x63, 0x66, 0x30, 0x39, 0x0d, 0x0a, /* fbcf09.. */
236     0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* Content- */
237     0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69, 0x74, /* Disposit */
238     0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x6f, 0x72, /* ion: for */
239     0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, /* m-data;  */
240     0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x65, 0x78, /* name="ex */
241     0x61, 0x6d, 0x70, 0x6c, 0x65, 0x33, 0x22, 0x0d, /* ample3". */
242     0x0a, 0x0d, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x33, /* ...test3 */
243     0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */
244     0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */
245     0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */
246     0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */
247     0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */
248     0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */
249     0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */
250     0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */
251     0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */
252     0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */
253     0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */
254     0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */
255     0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */
256     0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */
257     0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */
258     0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */
259     0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */
260     0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */
261     0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */
262     0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */
263     0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */
264     0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */
265     0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */
266     0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x0d, 0x0a, /* 3test3.. */
267     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
268     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
269     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
270     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, /* ------4e */
271     0x62, 0x66, 0x30, 0x30, 0x66, 0x62, 0x63, 0x66, /* bf00fbcf */
272     0x30, 0x39, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, /* 09..Cont */
273     0x65, 0x6e, 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, /* ent-Disp */
274     0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, /* osition: */
275     0x20, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, /*  form-da */
276     0x74, 0x61, 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, /* ta; name */
277     0x3d, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, /* ="exampl */
278     0x65, 0x34, 0x22, 0x0d, 0x0a, 0x0d, 0x0a, 0x74, /* e4"....t */
279     0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */
280     0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */
281     0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */
282     0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */
283     0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */
284     0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */
285     0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */
286     0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */
287     0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */
288     0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */
289     0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */
290     0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */
291     0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */
292     0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */
293     0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */
294     0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */
295     0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */
296     0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */
297     0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */
298     0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */
299     0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */
300     0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */
301     0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */
302     0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */
303     0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */
304     0x65, 0x73, 0x74, 0x34, 0x0d, 0x0a, 0x2d, 0x2d, /* est4..-- */
305     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
306     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
307     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
308     0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, /* ----4ebf */
309     0x30, 0x30, 0x66, 0x62, 0x63, 0x66, 0x30, 0x39, /* 00fbcf09 */
310     0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* ..Conten */
311     0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, /* t-Dispos */
312     0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, /* ition: f */
313     0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, /* orm-data */
314     0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, /* ; name=" */
315     0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x35, /* example5 */
316     0x22, 0x0d, 0x0a, 0x0d, 0x0a, 0x74, 0x65, 0x73, /* "....tes */
317     0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */
318     0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */
319     0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */
320     0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */
321     0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */
322     0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */
323     0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */
324     0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */
325     0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */
326     0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */
327     0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */
328     0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */
329     0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */
330     0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */
331     0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */
332     0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */
333     0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */
334     0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */
335     0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */
336     0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */
337     0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */
338     0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */
339     0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */
340     0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */
341     0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */
342     0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */
343     0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */
344     0x35, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* 5..----- */
345     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
346     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
347     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */
348     0x2d, 0x34, 0x65, 0x62, 0x66, 0x30, 0x30, 0x66, /* -4ebf00f */
349     0x62, 0x63, 0x66, 0x30, 0x39, 0x2d, 0x2d, 0x0d, /* bcf09--. */
350     0x0a,                                           /* . */
351 #ifdef TEST_CHUNKED
352     0x0d, 0x0a,
353     0x30, 0x0d, 0x0a, 0x0d, 0x0a,
354 #endif
355 };
356 
357 #ifdef CTEST
test_application_define(void * first_unused_memory)358 VOID test_application_define(void *first_unused_memory)
359 #else
360 void    netx_web_multipart_underflow_test_application_define(void *first_unused_memory)
361 #endif
362 {
363 CHAR    *pointer;
364 UINT    status;
365 
366 
367     error_counter = 0;
368 
369     /* Setup the working pointer.  */
370     pointer =  (CHAR *) first_unused_memory;
371 
372     /* Create a helper thread for the server. */
373     tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0,
374                      pointer, DEMO_STACK_SIZE,
375                      NX_WEB_HTTP_SERVER_PRIORITY, NX_WEB_HTTP_SERVER_PRIORITY, TX_NO_TIME_SLICE, TX_AUTO_START);
376 
377     pointer =  pointer + DEMO_STACK_SIZE;
378 
379     /* Initialize the NetX system.  */
380     nx_system_initialize();
381 
382     /* Create the server packet pool.  */
383     status =  nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE,
384                                     pointer, SERVER_PACKET_SIZE*16);
385     pointer = pointer + SERVER_PACKET_SIZE * 16;
386     if (status)
387         error_counter++;
388 
389     /* Create an IP instance.  */
390     status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS,
391                           0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024,
392                           pointer, 4096, 1);
393     pointer =  pointer + 4096;
394     if (status)
395         error_counter++;
396 
397     /* Enable ARP and supply ARP cache memory for the server IP instance.  */
398     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
399     pointer = pointer + 1024;
400     if (status)
401         error_counter++;
402 
403      /* Enable TCP traffic.  */
404     status = nx_tcp_enable(&server_ip);
405     if (status)
406         error_counter++;
407 
408     /* Create the HTTP Client thread. */
409     status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0,
410                               pointer, DEMO_STACK_SIZE,
411                               NX_WEB_HTTP_SERVER_PRIORITY + 2, NX_WEB_HTTP_SERVER_PRIORITY + 2, TX_NO_TIME_SLICE, TX_AUTO_START);
412     pointer =  pointer + DEMO_STACK_SIZE;
413     if (status)
414         error_counter++;
415 
416     /* Create the Client packet pool.  */
417     status =  nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE,
418                                     pointer, CLIENT_PACKET_SIZE*16);
419     pointer = pointer + CLIENT_PACKET_SIZE * 16;
420     if (status)
421         error_counter++;
422 
423     /* Create an IP instance.  */
424     status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS,
425                           0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024,
426                           pointer, 2048, 1);
427     pointer =  pointer + 2048;
428     if (status)
429         error_counter++;
430 
431     status  = nx_arp_enable(&client_ip, (void *) pointer, 1024);
432     pointer =  pointer + 2048;
433     if (status)
434         error_counter++;
435 
436      /* Enable TCP traffic.  */
437     status = nx_tcp_enable(&client_ip);
438     if (status)
439         error_counter++;
440 }
441 
442 #ifdef NX_WEB_HTTPS_ENABLE
443 /* Define the TLS setup callback function.  */
tls_setup_callback(NX_WEB_HTTP_CLIENT * client_ptr,NX_SECURE_TLS_SESSION * tls_session)444 static UINT tls_setup_callback(NX_WEB_HTTP_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *tls_session)
445 {
446 UINT status;
447 
448 
449     /* Initialize and create TLS session.  */
450     status = nx_secure_tls_session_create(tls_session, &nx_crypto_tls_ciphers, crypto_metadata_client, sizeof(crypto_metadata_client));
451 
452     /* Check status.  */
453     if (status)
454     {
455         return(status);
456     }
457 
458     /* Allocate space for packet reassembly.  */
459     status = nx_secure_tls_session_packet_buffer_set(&(client_ptr -> nx_web_http_client_tls_session), tls_packet_buffer, sizeof(tls_packet_buffer));
460 
461     /* Check status.  */
462     if (status)
463     {
464         return(status);
465     }
466 
467     /* Add a CA Certificate to our trusted store for verifying incoming server certificates.  */
468     nx_secure_x509_certificate_initialize(&trusted_certificate, ca_cert_der, ca_cert_der_len, NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
469     nx_secure_tls_trusted_certificate_add(&(client_ptr -> nx_web_http_client_tls_session), &trusted_certificate);
470 
471     /* Need to allocate space for the certificate coming in from the remote host.  */
472     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
473     nx_secure_tls_remote_certificate_allocate(&(client_ptr -> nx_web_http_client_tls_session), &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));
474 
475     return(NX_SUCCESS);
476 }
477 #endif /* NX_WEB_HTTPS_ENABLE  */
478 
thread_client_entry(ULONG thread_input)479 void thread_client_entry(ULONG thread_input)
480 {
481 UINT            i;
482 UINT            status;
483 NX_PACKET       *recv_packet;
484 NX_PACKET       *my_packet;
485 CHAR            *buffer_ptr;
486 
487 
488     /* Give IP task and driver a chance to initialize the system. */
489     tx_thread_sleep(NX_IP_PERIODIC_RATE);
490 
491     /* Set server IP address.  */
492     server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS;
493     server_ip_address.nxd_ip_version = NX_IP_VERSION_V4;
494 
495     /* First loop test HTTP, second loop test HTTPS.  */
496     for (i = 0; i < loop ; i++)
497     {
498         if (i == 0)
499         {
500 
501             /* Wait HTTP server started.  */
502             while(!http_server_start)
503             {
504                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
505             }
506         }
507 #ifdef NX_WEB_HTTPS_ENABLE
508         else
509         {
510 
511             /* Wait HTTPS server started.  */
512             while(!https_server_start)
513             {
514                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
515             }
516         }
517 #endif /* NX_WEB_HTTPS_ENABLE  */
518 
519         multipart_flag = 0;
520 
521         /* Create an HTTP client instance.  */
522         status = nx_web_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1536);
523 
524         /* Check status.  */
525         if (status)
526             error_counter++;
527 
528         /* Connect to server.  */
529         if (i == 0)
530         {
531             status = nx_web_http_client_connect(&my_client, &server_ip_address, NX_WEB_HTTP_SERVER_PORT, NX_WAIT_FOREVER);
532 
533             /* Check status.  */
534             if (status)
535                 error_counter++;
536         }
537 #ifdef NX_WEB_HTTPS_ENABLE
538         else
539         {
540             status = nx_web_http_client_secure_connect(&my_client, &server_ip_address, NX_WEB_HTTPS_SERVER_PORT,
541                                                         tls_setup_callback, NX_WAIT_FOREVER);
542 
543             /* Check status.  */
544             if (status)
545                 error_counter++;
546         }
547 #endif /* NX_WEB_HTTPS_ENABLE  */
548 
549         /* Allocate a packet.  */
550         status = nx_web_http_client_request_packet_allocate(&my_client, &my_packet, 1 * NX_IP_PERIODIC_RATE);
551         if(status)
552             error_counter++;
553 
554         /* Write packet into the packet payload.  */
555         status = nx_packet_data_append(my_packet, pkt , sizeof(pkt), &client_pool, 1 * NX_IP_PERIODIC_RATE);
556         if(status)
557             error_counter++;
558 
559         /* Send the request.  */
560         status = _nx_web_http_client_send(&my_client, my_packet, NX_WAIT_FOREVER);
561         if((status) || (multipart_flag != 1))
562         {
563 
564             if (status)
565                 nx_packet_release(my_packet);
566 
567             error_counter++;
568         }
569 
570        /* Receive the response from http server.  */
571         status = _nx_web_http_client_receive(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE);
572         if(status)
573             error_counter++;
574         else
575         {
576             buffer_ptr = (CHAR *)recv_packet ->nx_packet_prepend_ptr;
577 
578             /* Check the status, If success , it should be 200. */
579             if((buffer_ptr[9] != '2') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '0'))
580                 error_counter++;
581 
582             nx_packet_release(recv_packet);
583         }
584 
585         status = nx_web_http_client_delete(&my_client);
586         if (status)
587             error_counter++;
588 
589         /* Set the flag.  */
590         if (i == 0)
591         {
592             http_client_stop = 1;
593         }
594 #ifdef NX_WEB_HTTPS_ENABLE
595         else
596         {
597             https_client_stop = 1;
598         }
599 #endif /* NX_WEB_HTTPS_ENABLE  */
600     }
601 
602     if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
603     {
604         error_counter++;
605     }
606 }
607 
608 
609 /* Define the helper HTTP server thread.  */
thread_server_entry(ULONG thread_input)610 void    thread_server_entry(ULONG thread_input)
611 {
612 UINT            i;
613 UINT            status;
614 FX_FILE         my_file;
615 UINT            server_port = NX_WEB_HTTP_SERVER_PORT;
616 
617 
618     /* Print out test information banner.  */
619     printf("NetX Test:   Web Multipart Fragment Test...............................");
620 
621     /* Check for earlier error. */
622     if(error_counter)
623     {
624         printf("ERROR!\n");
625         test_control_return(1);
626     }
627 
628     fx_media_format(&ram_disk,
629                     _fx_ram_driver,               // Driver entry
630                     ram_disk_memory,              // RAM disk memory pointer
631                     media_memory,                 // Media buffer pointer
632                     sizeof(media_memory),         // Media buffer size
633                     "MY_RAM_DISK",                // Volume Name
634                     1,                            // Number of FATs
635                     32,                           // Directory Entries
636                     0,                            // Hidden sectors
637                     256,                          // Total sectors
638                     512,                          // Sector size
639                     8,                            // Sectors per cluster
640                     1,                            // Heads
641                     1);                           // Sectors per track
642 
643     /* Open the RAM disk.  */
644     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ;
645     status += fx_file_create(&ram_disk, "TEST.TXT");
646     status += fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
647     status += fx_file_write(&my_file, "https server", 12);
648     status += fx_file_close(&my_file);
649     if(status)
650         error_counter++;
651 
652     /* Give NetX a chance to initialize the system. */
653     tx_thread_sleep(NX_IP_PERIODIC_RATE);
654 
655     /* First loop test HTTP, second loop test HTTPS.  */
656     for (i = 0; i < loop; i++)
657     {
658 
659         if (i == 1)
660         {
661             server_port = NX_WEB_HTTPS_SERVER_PORT;
662         }
663 
664         /* Create the HTTP Server. */
665         status = nx_web_http_server_create(&my_server, "My HTTP Server", &server_ip, server_port, &ram_disk,
666                                            &server_stack, sizeof(server_stack), &server_pool,
667                                            NX_NULL, server_request_callback);
668         if (status)
669             error_counter++;
670 
671 #ifdef NX_WEB_HTTPS_ENABLE
672         /* Set TLS for HTTPS.  */
673         if (i == 1)
674         {
675             /* Initialize device certificate (used for all sessions in HTTPS server). */
676             memset(&certificate, 0, sizeof(certificate));
677             nx_secure_x509_certificate_initialize(&certificate, test_device_cert_der, test_device_cert_der_len, NX_NULL, 0, test_device_cert_key_der, test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER);
678 
679             /* Setup TLS session data for the TCP server. */
680             status = nx_web_http_server_secure_configure(&my_server, &nx_crypto_tls_ciphers,
681                                                          crypto_metadata_server, sizeof(crypto_metadata_server), tls_packet_buffer, sizeof(tls_packet_buffer),
682                                                          &certificate, NX_NULL, 0, NX_NULL, 0, NX_NULL, 0);
683             if (status)
684                 error_counter++;
685         }
686 #endif /* NX_WEB_HTTPS_ENABLE  */
687 
688         /* OK to start the HTTP Server.   */
689         status = nx_web_http_server_start(&my_server);
690         if (status)
691             error_counter++;
692 
693         /* Set the flag.  */
694         if (i == 0)
695         {
696             http_server_start = 1;
697 
698             /* Wait HTTP test finished.  */
699             while(!http_client_stop)
700             {
701                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
702             }
703         }
704 #ifdef NX_WEB_HTTPS_ENABLE
705         else
706         {
707             https_server_start = 1;
708 
709             /* Wait HTTPS test finished.  */
710             while(!https_client_stop)
711             {
712                 tx_thread_sleep(NX_IP_PERIODIC_RATE);
713             }
714         }
715 #endif /* NX_WEB_HTTPS_ENABLE  */
716 
717         status = nx_web_http_server_delete(&my_server);
718         if (status)
719             error_counter++;
720     }
721 
722     /* Check packet pool.  */
723     if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total)
724     {
725         error_counter++;
726     }
727 
728     if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total)
729     {
730         error_counter++;
731     }
732 
733     if(error_counter)
734     {
735         printf("ERROR!\n");
736         test_control_return(1);
737     }
738     else
739     {
740         printf("SUCCESS!\n");
741         test_control_return(0);
742     }
743 }
744 
745 /* Define the server request callback function.  */
server_request_callback(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,NX_PACKET * packet_ptr)746 static UINT server_request_callback(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr)
747 {
748 ULONG      offset, total_length;
749 ULONG      length;
750 UCHAR       buffer[1440];
751 UINT       count = 0;
752 UINT       status;
753 NX_PACKET *response_pkt;
754 
755     /* Set first 5 bytes to 0. */
756     buffer[0] = 0xFF;
757     buffer[1] = 0xFF;
758     buffer[2] = 0xFF;
759     buffer[3] = 0xFF;
760     buffer[4] = 0xFF;
761 
762     /* Process multipart data.  */
763     if(request_type == NX_WEB_HTTP_SERVER_POST_REQUEST)
764     {
765         while(nx_web_http_server_get_entity_header(server_ptr, &packet_ptr, buffer + 5, sizeof(buffer) - 5) == NX_SUCCESS)
766         {
767             if ((buffer[0] & buffer[1] & buffer[2] & buffer[3] & buffer[4]) != 0xFF)
768             {
769 
770                 /* Detected underflow. */
771                 error_counter++;
772             }
773 
774             multipart_flag = 1;
775 
776             /* Send the result.  */
777             total_length = 0;
778             count++;
779 
780             while(nx_web_http_server_get_entity_content(server_ptr, &packet_ptr, &offset, &length) == NX_SUCCESS)
781             {
782                 /* Print content data.  */
783                 nx_packet_data_extract_offset(packet_ptr, offset, buffer + 5, length, &length);
784                 buffer[length + 5] = 0;
785                 total_length += length;
786             }
787 
788             /* Check the data length.  */
789             /* if((count == 1) && (total_length != 196))
790                 error_counter++; */
791             if((count == 2) && (total_length != 175))
792                 error_counter++;
793             else if((count == 3) && (total_length != 195))
794                 error_counter++;
795             else if((count == 4) && (total_length != 205))
796                 error_counter++;
797             else if((count == 5) && (total_length != 220))
798                 error_counter++;
799         }
800 
801         /* Generate HTTP header.  */
802         status = nx_web_http_server_callback_generate_response_header(server_ptr, &response_pkt, NX_WEB_HTTP_STATUS_OK, 800, "text/html", "Server: NetXDuo HTTP 5.3\r\n");
803         if(status == NX_SUCCESS)
804         {
805             if(nx_web_http_server_callback_packet_send(server_ptr, response_pkt))
806                 nx_packet_release(response_pkt);
807         }
808         else
809             error_counter++;
810     }
811     else
812     {
813         return(NX_SUCCESS);
814     }
815 
816     return(NX_WEB_HTTP_CALLBACK_COMPLETED);
817 }
818 #else
819 
820 #ifdef CTEST
test_application_define(void * first_unused_memory)821 VOID test_application_define(void *first_unused_memory)
822 #else
823 void    netx_web_multipart_underflow_test_application_define(void *first_unused_memory)
824 #endif
825 {
826 
827     /* Print out test information banner.  */
828     printf("NetX Test:   Web Multipart Underflow Test..............................N/A\n");
829 
830     test_control_return(3);
831 }
832 #endif
833