1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** NetX Component                                                        */
17 /**                                                                       */
18 /**   Hypertext Transfer Protocol (HTTP)                                  */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_HTTP_SOURCE_CODE
24 
25 
26 /* Force error checking to be disabled in this module */
27 
28 #ifndef NX_DISABLE_ERROR_CHECKING
29 #define NX_DISABLE_ERROR_CHECKING
30 #endif
31 
32 /* Include necessary system files.  */
33 
34 
35 #include    "nx_api.h"
36 #include    "nx_ip.h"
37 #include    "nx_tcp.h"
38 #include    "nxd_http_client.h"
39 #include    "stdio.h"
40 #include    "string.h"
41 
42 
43 /* Define global HTTP variables and strings.  */
44 
45 /* Bring in externs for caller checking code.  */
46 
47 NX_CALLER_CHECKING_EXTERNS
48 
49 
50 /**************************************************************************/
51 /*                                                                        */
52 /*  FUNCTION                                               RELEASE        */
53 /*                                                                        */
54 /*    _nxe_http_client_create                             PORTABLE C      */
55 /*                                                           6.1          */
56 /*  AUTHOR                                                                */
57 /*                                                                        */
58 /*    Yuxin Zhou, Microsoft Corporation                                   */
59 /*                                                                        */
60 /*  DESCRIPTION                                                           */
61 /*                                                                        */
62 /*    This function checks for errors in the HTTP client create call.     */
63 /*                                                                        */
64 /*                                                                        */
65 /*  INPUT                                                                 */
66 /*                                                                        */
67 /*    client_ptr                            Pointer to HTTP client        */
68 /*    client_name                           Name of HTTP client           */
69 /*    ip_ptr                                Pointer to IP instance        */
70 /*    pool_ptr                              Pointer to packet pool        */
71 /*    window_size                           Size of HTTP client rx window */
72 /*    http_client_size                      Size of HTTP client           */
73 /*                                                                        */
74 /*  OUTPUT                                                                */
75 /*                                                                        */
76 /*    status                                Completion status             */
77 /*                                                                        */
78 /*  CALLS                                                                 */
79 /*                                                                        */
80 /*    _nx_http_client_create                Actual client create call     */
81 /*                                                                        */
82 /*  CALLED BY                                                             */
83 /*                                                                        */
84 /*    Application Code                                                    */
85 /*                                                                        */
86 /*  RELEASE HISTORY                                                       */
87 /*                                                                        */
88 /*    DATE              NAME                      DESCRIPTION             */
89 /*                                                                        */
90 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
91 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
92 /*                                            resulting in version 6.1    */
93 /*                                                                        */
94 /**************************************************************************/
_nxe_http_client_create(NX_HTTP_CLIENT * client_ptr,CHAR * client_name,NX_IP * ip_ptr,NX_PACKET_POOL * pool_ptr,ULONG window_size,UINT http_client_size)95 UINT  _nxe_http_client_create(NX_HTTP_CLIENT *client_ptr, CHAR *client_name, NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr, ULONG window_size, UINT http_client_size)
96 {
97 
98 NX_PACKET   *packet_ptr;
99 UINT        status;
100 
101 
102     /* Check for invalid input pointers.  */
103     if ((ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
104         (client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id == NXD_HTTP_CLIENT_ID) ||
105         (pool_ptr == NX_NULL) || (http_client_size != sizeof(NX_HTTP_CLIENT)))
106         return(NX_PTR_ERROR);
107 
108     /* Pickup a packet from the supplied packet pool.  */
109     packet_ptr =  pool_ptr -> nx_packet_pool_available_list;
110 
111     /* Determine if the packet payload is equal to or greater than the maximum HTTP header supported.  */
112     if ((packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_data_start) < NX_HTTP_CLIENT_MIN_PACKET_SIZE)
113         return(NX_HTTP_POOL_ERROR);
114 
115     /* Call actual client create function.  */
116     status =  _nx_http_client_create(client_ptr, client_name, ip_ptr, pool_ptr, window_size);
117 
118     /* Return completion status.  */
119     return(status);
120 }
121 
122 
123 /**************************************************************************/
124 /*                                                                        */
125 /*  FUNCTION                                               RELEASE        */
126 /*                                                                        */
127 /*    _nx_http_client_create                              PORTABLE C      */
128 /*                                                           6.1          */
129 /*  AUTHOR                                                                */
130 /*                                                                        */
131 /*    Yuxin Zhou, Microsoft Corporation                                   */
132 /*                                                                        */
133 /*  DESCRIPTION                                                           */
134 /*                                                                        */
135 /*    This function creates a HTTP client on the specified IP. In doing   */
136 /*    so this function creates an TCP socket for subsequent HTTP          */
137 /*    transfers.                                                          */
138 /*                                                                        */
139 /*                                                                        */
140 /*  INPUT                                                                 */
141 /*                                                                        */
142 /*    client_ptr                            Pointer to HTTP client        */
143 /*    client_name                           Name of HTTP client           */
144 /*    ip_ptr                                Pointer to IP instance        */
145 /*    pool_ptr                              Pointer to packet pool        */
146 /*    window_size                           Size of HTTP client rx window */
147 /*                                                                        */
148 /*  OUTPUT                                                                */
149 /*                                                                        */
150 /*    status                                Completion status             */
151 /*                                                                        */
152 /*  CALLS                                                                 */
153 /*                                                                        */
154 /*    nx_tcp_socket_create                  Create HTTP client socket     */
155 /*                                                                        */
156 /*  CALLED BY                                                             */
157 /*                                                                        */
158 /*    Application Code                                                    */
159 /*                                                                        */
160 /*  RELEASE HISTORY                                                       */
161 /*                                                                        */
162 /*    DATE              NAME                      DESCRIPTION             */
163 /*                                                                        */
164 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
165 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
166 /*                                            resulting in version 6.1    */
167 /*                                                                        */
168 /**************************************************************************/
_nx_http_client_create(NX_HTTP_CLIENT * client_ptr,CHAR * client_name,NX_IP * ip_ptr,NX_PACKET_POOL * pool_ptr,ULONG window_size)169 UINT  _nx_http_client_create(NX_HTTP_CLIENT *client_ptr, CHAR *client_name, NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr, ULONG window_size)
170 {
171 
172 UINT        status;
173 
174 
175     /* Clear the HTTP Client structure.  */
176     memset((void *) client_ptr, 0, sizeof(NX_HTTP_CLIENT));
177 
178     /* Create the Client's TCP socket.  */
179     status =  nx_tcp_socket_create(ip_ptr, &(client_ptr -> nx_http_client_socket), client_name,
180                           NX_HTTP_TYPE_OF_SERVICE,  NX_HTTP_FRAGMENT_OPTION, NX_HTTP_TIME_TO_LIVE,
181                           window_size, NX_NULL, NX_NULL);
182 
183     /* Determine if an error occurred.   */
184     if (status != NX_SUCCESS)
185     {
186 
187         /* Yes, return error code.  */
188         return(status);
189     }
190 
191     /* Save the Client name.  */
192     client_ptr -> nx_http_client_name =  client_name;
193 
194     /* Save the IP pointer address.  */
195     client_ptr -> nx_http_client_ip_ptr =  ip_ptr;
196 
197     /* Save the packet pool pointer.  */
198     client_ptr -> nx_http_client_packet_pool_ptr =  pool_ptr;
199 
200     /* Set the client state to ready to indicate a get or put operation can be done.  */
201     client_ptr -> nx_http_client_state =  NX_HTTP_CLIENT_STATE_READY;
202 
203     /* Set the Client ID to indicate the HTTP client thread is ready.  */
204     client_ptr -> nx_http_client_id =  NXD_HTTP_CLIENT_ID;
205 
206     /* Set the default port the client connects to the HTTP server on (80). */
207     client_ptr -> nx_http_client_connect_port = NX_HTTP_SERVER_PORT;
208 
209 
210     /* Return successful completion.  */
211     return(NX_SUCCESS);
212 }
213 
214 
215 /**************************************************************************/
216 /*                                                                        */
217 /*  FUNCTION                                               RELEASE        */
218 /*                                                                        */
219 /*    _nxe_http_client_delete                             PORTABLE C      */
220 /*                                                           6.1          */
221 /*  AUTHOR                                                                */
222 /*                                                                        */
223 /*    Yuxin Zhou, Microsoft Corporation                                   */
224 /*                                                                        */
225 /*  DESCRIPTION                                                           */
226 /*                                                                        */
227 /*    This function checks for errors in the HTTP client delete call.     */
228 /*                                                                        */
229 /*                                                                        */
230 /*  INPUT                                                                 */
231 /*                                                                        */
232 /*    client_ptr                            Pointer to HTTP client        */
233 /*                                                                        */
234 /*  OUTPUT                                                                */
235 /*                                                                        */
236 /*    status                                Completion status             */
237 /*                                                                        */
238 /*  CALLS                                                                 */
239 /*                                                                        */
240 /*    _nx_http_client_delete                Actual client delete call     */
241 /*                                                                        */
242 /*  CALLED BY                                                             */
243 /*                                                                        */
244 /*    Application Code                                                    */
245 /*                                                                        */
246 /*  RELEASE HISTORY                                                       */
247 /*                                                                        */
248 /*    DATE              NAME                      DESCRIPTION             */
249 /*                                                                        */
250 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
251 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
252 /*                                            resulting in version 6.1    */
253 /*                                                                        */
254 /**************************************************************************/
_nxe_http_client_delete(NX_HTTP_CLIENT * client_ptr)255 UINT  _nxe_http_client_delete(NX_HTTP_CLIENT *client_ptr)
256 {
257 
258 UINT    status;
259 
260 
261     /* Check for invalid input pointers.  */
262     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID))
263         return(NX_PTR_ERROR);
264 
265     /* Check for appropriate caller.  */
266     NX_THREADS_ONLY_CALLER_CHECKING
267 
268     /* Call actual client delete function.  */
269     status =  _nx_http_client_delete(client_ptr);
270 
271     /* Return completion status.  */
272     return(status);
273 }
274 
275 
276 /**************************************************************************/
277 /*                                                                        */
278 /*  FUNCTION                                               RELEASE        */
279 /*                                                                        */
280 /*    _nx_http_client_delete                              PORTABLE C      */
281 /*                                                           6.1          */
282 /*  AUTHOR                                                                */
283 /*                                                                        */
284 /*    Yuxin Zhou, Microsoft Corporation                                   */
285 /*                                                                        */
286 /*  DESCRIPTION                                                           */
287 /*                                                                        */
288 /*    This function deletes a previously created HTTP client on the       */
289 /*    specified IP.                                                       */
290 /*                                                                        */
291 /*                                                                        */
292 /*  INPUT                                                                 */
293 /*                                                                        */
294 /*    client_ptr                            Pointer to HTTP client        */
295 /*                                                                        */
296 /*  OUTPUT                                                                */
297 /*                                                                        */
298 /*    status                                Completion status             */
299 /*                                                                        */
300 /*  CALLS                                                                 */
301 /*                                                                        */
302 /*    nx_tcp_socket_delete                  Delete the HTTP client socket */
303 /*                                                                        */
304 /*  CALLED BY                                                             */
305 /*                                                                        */
306 /*    Application Code                                                    */
307 /*                                                                        */
308 /*  RELEASE HISTORY                                                       */
309 /*                                                                        */
310 /*    DATE              NAME                      DESCRIPTION             */
311 /*                                                                        */
312 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
313 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
314 /*                                            resulting in version 6.1    */
315 /*                                                                        */
316 /**************************************************************************/
_nx_http_client_delete(NX_HTTP_CLIENT * client_ptr)317 UINT  _nx_http_client_delete(NX_HTTP_CLIENT *client_ptr)
318 {
319 
320     /* Clear the client ID to indicate the HTTP client is no longer ready.  */
321     client_ptr -> nx_http_client_id =  0;
322 
323     /* Determine if a GET or PUT state is present.  */
324     if ((client_ptr -> nx_http_client_state == NX_HTTP_CLIENT_STATE_PUT) ||
325         (client_ptr -> nx_http_client_state == NX_HTTP_CLIENT_STATE_GET))
326     {
327 
328         /* Check for a saved packet.  */
329         if (client_ptr -> nx_http_client_first_packet)
330         {
331 
332             /* Release the packet.  */
333             nx_packet_release(client_ptr -> nx_http_client_first_packet);
334         }
335 
336         /* Disconnect and unbind the socket.  */
337         nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), NX_HTTP_CLIENT_TIMEOUT);
338         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
339     }
340 
341     /* Delete the TCP socket.  */
342     nx_tcp_socket_delete(&(client_ptr -> nx_http_client_socket));
343 
344     /* Return successful completion.  */
345     return(NX_SUCCESS);
346 }
347 
348 /**************************************************************************/
349 /*                                                                        */
350 /*  FUNCTION                                               RELEASE        */
351 /*                                                                        */
352 /*    _nxe_http_client_set_connect_port                   PORTABLE C      */
353 /*                                                           6.1          */
354 /*  AUTHOR                                                                */
355 /*                                                                        */
356 /*    Yuxin Zhou, Microsoft Corporation                                   */
357 /*                                                                        */
358 /*  DESCRIPTION                                                           */
359 /*                                                                        */
360 /*    This function checks for errors in the HTTP client set connect port */
361 /*    call.                                                               */
362 /*                                                                        */
363 /*                                                                        */
364 /*  INPUT                                                                 */
365 /*                                                                        */
366 /*    client_ptr                            Pointer to HTTP client        */
367 /*    port                                  Port to connect to server on  */
368 /*                                                                        */
369 /*  OUTPUT                                                                */
370 /*                                                                        */
371 /*    status                                Completion status             */
372 /*                                                                        */
373 /*  CALLS                                                                 */
374 /*                                                                        */
375 /*    _nx_http_client_set_connect_port      Actual set port call          */
376 /*                                                                        */
377 /*  CALLED BY                                                             */
378 /*                                                                        */
379 /*    Application Code                                                    */
380 /*                                                                        */
381 /*  RELEASE HISTORY                                                       */
382 /*                                                                        */
383 /*    DATE              NAME                      DESCRIPTION             */
384 /*                                                                        */
385 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
386 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
387 /*                                            resulting in version 6.1    */
388 /*                                                                        */
389 /**************************************************************************/
_nxe_http_client_set_connect_port(NX_HTTP_CLIENT * client_ptr,UINT port)390 UINT  _nxe_http_client_set_connect_port(NX_HTTP_CLIENT *client_ptr, UINT port)
391 {
392 UINT status;
393 
394 
395     /* Check for invalid input pointers.  */
396     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID))
397         return(NX_PTR_ERROR);
398 
399     /* Check for an invalid port.  */
400     if (((ULONG)port) > (ULONG)NX_MAX_PORT)
401     {
402         return(NX_INVALID_PORT);
403     }
404     else if (port == 0)
405     {
406         return(NX_INVALID_PORT);
407     }
408 
409     status = _nx_http_client_set_connect_port(client_ptr, port);
410 
411     return(status);
412 }
413 
414 /**************************************************************************/
415 /*                                                                        */
416 /*  FUNCTION                                               RELEASE        */
417 /*                                                                        */
418 /*    _nx_http_client_set_connect_port                    PORTABLE C      */
419 /*                                                           6.1          */
420 /*  AUTHOR                                                                */
421 /*                                                                        */
422 /*    Yuxin Zhou, Microsoft Corporation                                   */
423 /*                                                                        */
424 /*  DESCRIPTION                                                           */
425 /*                                                                        */
426 /*    This function sets the HTTP Client port to connect to the server on.*/
427 /*    This is useful if the HTTP Client needs to connect to a server on   */
428 /*    another port than the default 80 port.                              */
429 /*                                                                        */
430 /*  INPUT                                                                 */
431 /*                                                                        */
432 /*    client_ptr                            Pointer to HTTP client        */
433 /*    port                                  Port to connect to server on  */
434 /*                                                                        */
435 /*  OUTPUT                                                                */
436 /*                                                                        */
437 /*    NX_SUCCESS                            Completion status             */
438 /*                                                                        */
439 /*  CALLS                                                                 */
440 /*                                                                        */
441 /*    None                                                                */
442 /*                                                                        */
443 /*  CALLED BY                                                             */
444 /*                                                                        */
445 /*    Application Code                                                    */
446 /*                                                                        */
447 /*  RELEASE HISTORY                                                       */
448 /*                                                                        */
449 /*    DATE              NAME                      DESCRIPTION             */
450 /*                                                                        */
451 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
452 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
453 /*                                            resulting in version 6.1    */
454 /*                                                                        */
455 /**************************************************************************/
_nx_http_client_set_connect_port(NX_HTTP_CLIENT * client_ptr,UINT port)456 UINT  _nx_http_client_set_connect_port(NX_HTTP_CLIENT *client_ptr, UINT port)
457 {
458 
459     client_ptr-> nx_http_client_connect_port = port;
460 
461     return(NX_SUCCESS);
462 }
463 
464 
465 /**************************************************************************/
466 /*                                                                        */
467 /*  FUNCTION                                               RELEASE        */
468 /*                                                                        */
469 /*    _nxe_http_client_get_start                          PORTABLE C      */
470 /*                                                           6.1          */
471 /*  AUTHOR                                                                */
472 /*                                                                        */
473 /*    Yuxin Zhou, Microsoft Corporation                                   */
474 /*                                                                        */
475 /*  DESCRIPTION                                                           */
476 /*                                                                        */
477 /*    This function checks for errors in the HTTP client get start call.  */
478 /*                                                                        */
479 /*                                                                        */
480 /*  INPUT                                                                 */
481 /*                                                                        */
482 /*    client_ptr                            Pointer to HTTP client        */
483 /*    ip_address                            IP address of HTTP Server     */
484 /*    resource                              Pointer to resource (URL)     */
485 /*    input_ptr                             Additional input pointer      */
486 /*    input_size                            Additional input size         */
487 /*    username                              Pointer to username           */
488 /*    password                              Pointer to password           */
489 /*    wait_option                           Suspension option             */
490 /*                                                                        */
491 /*  OUTPUT                                                                */
492 /*                                                                        */
493 /*    status                                Completion status             */
494 /*                                                                        */
495 /*  CALLS                                                                 */
496 /*                                                                        */
497 /*    _nx_http_client_get_start             Actual client get start call  */
498 /*                                                                        */
499 /*  CALLED BY                                                             */
500 /*                                                                        */
501 /*    Application Code                                                    */
502 /*                                                                        */
503 /*  RELEASE HISTORY                                                       */
504 /*                                                                        */
505 /*    DATE              NAME                      DESCRIPTION             */
506 /*                                                                        */
507 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
508 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
509 /*                                            resulting in version 6.1    */
510 /*                                                                        */
511 /**************************************************************************/
_nxe_http_client_get_start(NX_HTTP_CLIENT * client_ptr,ULONG ip_address,CHAR * resource,CHAR * input_ptr,UINT input_size,CHAR * username,CHAR * password,ULONG wait_option)512 UINT  _nxe_http_client_get_start(NX_HTTP_CLIENT *client_ptr, ULONG ip_address, CHAR *resource, CHAR *input_ptr,
513                                  UINT input_size, CHAR *username, CHAR *password, ULONG wait_option)
514 {
515 
516 #ifndef NX_DISABLE_IPV4
517 UINT    status;
518 
519 
520     /* Check for invalid input pointers.  */
521     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID) || (resource == NX_NULL))
522         return(NX_PTR_ERROR);
523 
524     /* Check for appropriate caller.  */
525     NX_THREADS_ONLY_CALLER_CHECKING
526 
527     /* Call actual GET start routine.  */
528     status =  _nx_http_client_get_start(client_ptr, ip_address, resource, input_ptr, input_size,
529                                         username, password, wait_option);
530 
531     /* Return completion status.  */
532     return(status);
533 #else
534     NX_PARAMETER_NOT_USED(client_ptr);
535     NX_PARAMETER_NOT_USED(ip_address);
536     NX_PARAMETER_NOT_USED(resource);
537     NX_PARAMETER_NOT_USED(input_ptr);
538     NX_PARAMETER_NOT_USED(input_size);
539     NX_PARAMETER_NOT_USED(username);
540     NX_PARAMETER_NOT_USED(password);
541     NX_PARAMETER_NOT_USED(wait_option);
542 
543     return(NX_NOT_SUPPORTED);
544 #endif /* NX_DISABLE_IPV4 */
545 }
546 
547 /**************************************************************************/
548 /*                                                                        */
549 /*  FUNCTION                                               RELEASE        */
550 /*                                                                        */
551 /*    _nxe_http_client_get_start_extended                 PORTABLE C      */
552 /*                                                           6.1          */
553 /*  AUTHOR                                                                */
554 /*                                                                        */
555 /*    Yuxin Zhou, Microsoft Corporation                                   */
556 /*                                                                        */
557 /*  DESCRIPTION                                                           */
558 /*                                                                        */
559 /*    This function checks for errors in the HTTP client get start call.  */
560 /*                                                                        */
561 /*                                                                        */
562 /*  INPUT                                                                 */
563 /*                                                                        */
564 /*    client_ptr                            Pointer to HTTP client        */
565 /*    ip_address                            IP address of HTTP Server     */
566 /*    resource                              Pointer to resource (URL)     */
567 /*    resource_length                       Length of resource (URL)      */
568 /*    input_ptr                             Additional input pointer      */
569 /*    input_size                            Additional input size         */
570 /*    username                              Pointer to username           */
571 /*    username_length                       Length of username            */
572 /*    password                              Pointer to password           */
573 /*    password_length                       Length of password            */
574 /*    wait_option                           Suspension option             */
575 /*                                                                        */
576 /*  OUTPUT                                                                */
577 /*                                                                        */
578 /*    status                                Completion status             */
579 /*                                                                        */
580 /*  CALLS                                                                 */
581 /*                                                                        */
582 /*    _nx_http_client_get_start_extended    Actual client get start call  */
583 /*                                                                        */
584 /*  CALLED BY                                                             */
585 /*                                                                        */
586 /*    Application Code                                                    */
587 /*                                                                        */
588 /*  RELEASE HISTORY                                                       */
589 /*                                                                        */
590 /*    DATE              NAME                      DESCRIPTION             */
591 /*                                                                        */
592 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
593 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
594 /*                                            resulting in version 6.1    */
595 /*                                                                        */
596 /**************************************************************************/
_nxe_http_client_get_start_extended(NX_HTTP_CLIENT * client_ptr,ULONG ip_address,CHAR * resource,UINT resource_length,CHAR * input_ptr,UINT input_size,CHAR * username,UINT username_length,CHAR * password,UINT password_length,ULONG wait_option)597 UINT  _nxe_http_client_get_start_extended(NX_HTTP_CLIENT *client_ptr, ULONG ip_address, CHAR *resource, UINT resource_length,
598                                           CHAR *input_ptr, UINT input_size, CHAR *username, UINT username_length,
599                                           CHAR *password, UINT password_length, ULONG wait_option)
600 {
601 
602 #ifndef NX_DISABLE_IPV4
603 UINT    status;
604 
605 
606     /* Check for invalid input pointers.  */
607     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID) || (resource == NX_NULL))
608         return(NX_PTR_ERROR);
609 
610     /* Check for appropriate caller.  */
611     NX_THREADS_ONLY_CALLER_CHECKING
612 
613     /* Call actual GET start routine.  */
614     status =  _nx_http_client_get_start_extended(client_ptr, ip_address, resource, resource_length,
615                                                  input_ptr, input_size, username, username_length,
616                                                  password, password_length, wait_option);
617 
618     /* Return completion status.  */
619     return(status);
620 #else
621     NX_PARAMETER_NOT_USED(client_ptr);
622     NX_PARAMETER_NOT_USED(ip_address);
623     NX_PARAMETER_NOT_USED(resource);
624     NX_PARAMETER_NOT_USED(resource_length);
625     NX_PARAMETER_NOT_USED(input_ptr);
626     NX_PARAMETER_NOT_USED(input_size);
627     NX_PARAMETER_NOT_USED(username);
628     NX_PARAMETER_NOT_USED(username_length);
629     NX_PARAMETER_NOT_USED(password);
630     NX_PARAMETER_NOT_USED(password_length);
631     NX_PARAMETER_NOT_USED(wait_option);
632 
633     return(NX_NOT_SUPPORTED);
634 #endif /* NX_DISABLE_IPV4 */
635 }
636 
637 
638 /**************************************************************************/
639 /*                                                                        */
640 /*  FUNCTION                                               RELEASE        */
641 /*                                                                        */
642 /*    _nx_http_client_get_start                           PORTABLE C      */
643 /*                                                           6.1          */
644 /*  AUTHOR                                                                */
645 /*                                                                        */
646 /*    Yuxin Zhou, Microsoft Corporation                                   */
647 /*                                                                        */
648 /*  DESCRIPTION                                                           */
649 /*                                                                        */
650 /*    This function is a wrapper for the actual _nxd_http_client_get_start*/
651 /*    service that enables HTTP applications running on IPv4 to access    */
652 /*    HTTP duo API without enabling IPv6.                                 */
653 /*                                                                        */
654 /*                                                                        */
655 /*  INPUT                                                                 */
656 /*                                                                        */
657 /*    client_ptr                            Pointer to HTTP client        */
658 /*    ip_address                            IPv4 address of HTTP Server   */
659 /*    resource                              Pointer to resource (URL)     */
660 /*    input_ptr                             Additional input pointer      */
661 /*    input_size                            Additional input size         */
662 /*    username                              Pointer to username           */
663 /*    password                              Pointer to password           */
664 /*    wait_option                           Suspension option             */
665 /*                                                                        */
666 /*  OUTPUT                                                                */
667 /*                                                                        */
668 /*    status                                Completion status             */
669 /*                                                                        */
670 /*  CALLS                                                                 */
671 /*                                                                        */
672 /*    _nxd_http_client_get_start            Actual HTTP Client duo get    */
673 /*                                               start service            */
674 /*  CALLED BY                                                             */
675 /*                                                                        */
676 /*    Application Code                                                    */
677 /*                                                                        */
678 /*  RELEASE HISTORY                                                       */
679 /*                                                                        */
680 /*    DATE              NAME                      DESCRIPTION             */
681 /*                                                                        */
682 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
683 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
684 /*                                            resulting in version 6.1    */
685 /*                                                                        */
686 /**************************************************************************/
_nx_http_client_get_start(NX_HTTP_CLIENT * client_ptr,ULONG ip_address,CHAR * resource,CHAR * input_ptr,UINT input_size,CHAR * username,CHAR * password,ULONG wait_option)687 UINT  _nx_http_client_get_start(NX_HTTP_CLIENT *client_ptr, ULONG ip_address, CHAR *resource, CHAR *input_ptr,
688                                 UINT input_size, CHAR *username, CHAR *password, ULONG wait_option)
689 {
690 
691 #ifndef NX_DISABLE_IPV4
692 UINT            status;
693 NXD_ADDRESS     server_ip_addr;
694 
695     /* Construct an IP address structure, and fill in IPv4 address information. */
696     server_ip_addr.nxd_ip_version = NX_IP_VERSION_V4;
697     server_ip_addr.nxd_ip_address.v4 = ip_address;
698 
699     /* Call the NetX HTTP 'duo' get start service. */
700     status = _nxd_http_client_get_start(client_ptr, &server_ip_addr, resource, input_ptr, input_size,
701                                         username, password, wait_option);
702 
703     return status;
704 #else
705     NX_PARAMETER_NOT_USED(client_ptr);
706     NX_PARAMETER_NOT_USED(ip_address);
707     NX_PARAMETER_NOT_USED(resource);
708     NX_PARAMETER_NOT_USED(input_ptr);
709     NX_PARAMETER_NOT_USED(input_size);
710     NX_PARAMETER_NOT_USED(username);
711     NX_PARAMETER_NOT_USED(password);
712     NX_PARAMETER_NOT_USED(wait_option);
713 
714     return(NX_NOT_SUPPORTED);
715 #endif /* NX_DISABLE_IPV4 */
716 }
717 
718 /**************************************************************************/
719 /*                                                                        */
720 /*  FUNCTION                                               RELEASE        */
721 /*                                                                        */
722 /*    _nx_http_client_get_start_extended                  PORTABLE C      */
723 /*                                                           6.1          */
724 /*  AUTHOR                                                                */
725 /*                                                                        */
726 /*    Yuxin Zhou, Microsoft Corporation                                   */
727 /*                                                                        */
728 /*  DESCRIPTION                                                           */
729 /*                                                                        */
730 /*    This function is a wrapper for the actual _nxd_http_client_get_start*/
731 /*    service that enables HTTP applications running on IPv4 to access    */
732 /*    HTTP duo API without enabling IPv6.                                 */
733 /*                                                                        */
734 /*    Note: The strings of resource, username and password must be        */
735 /*    NULL-terminated and length of each string matches the length        */
736 /*    specified in the argument list.                                     */
737 /*                                                                        */
738 /*                                                                        */
739 /*  INPUT                                                                 */
740 /*                                                                        */
741 /*    client_ptr                            Pointer to HTTP client        */
742 /*    ip_address                            IPv4 address of HTTP Server   */
743 /*    resource                              Pointer to resource (URL)     */
744 /*    resource_length                       Length to resource (URL)      */
745 /*    input_ptr                             Additional input pointer      */
746 /*    input_size                            Additional input size         */
747 /*    username                              Pointer to username           */
748 /*    username_length                       Length of username            */
749 /*    password                              Pointer to password           */
750 /*    password_length                       Length of password            */
751 /*    wait_option                           Suspension option             */
752 /*                                                                        */
753 /*  OUTPUT                                                                */
754 /*                                                                        */
755 /*    status                                Completion status             */
756 /*                                                                        */
757 /*  CALLS                                                                 */
758 /*                                                                        */
759 /*    _nxd_http_client_get_start_extended   Actual HTTP Client duo get    */
760 /*                                               start service            */
761 /*  CALLED BY                                                             */
762 /*                                                                        */
763 /*    Application Code                                                    */
764 /*                                                                        */
765 /*  RELEASE HISTORY                                                       */
766 /*                                                                        */
767 /*    DATE              NAME                      DESCRIPTION             */
768 /*                                                                        */
769 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
770 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
771 /*                                            resulting in version 6.1    */
772 /*                                                                        */
773 /**************************************************************************/
_nx_http_client_get_start_extended(NX_HTTP_CLIENT * client_ptr,ULONG ip_address,CHAR * resource,UINT resource_length,CHAR * input_ptr,UINT input_size,CHAR * username,UINT username_length,CHAR * password,UINT password_length,ULONG wait_option)774 UINT  _nx_http_client_get_start_extended(NX_HTTP_CLIENT *client_ptr, ULONG ip_address, CHAR *resource, UINT resource_length,
775                                          CHAR *input_ptr, UINT input_size, CHAR *username, UINT username_length,
776                                          CHAR *password, UINT password_length, ULONG wait_option)
777 {
778 
779 #ifndef NX_DISABLE_IPV4
780 UINT            status;
781 NXD_ADDRESS     server_ip_addr;
782 
783     /* Construct an IP address structure, and fill in IPv4 address information. */
784     server_ip_addr.nxd_ip_version = NX_IP_VERSION_V4;
785     server_ip_addr.nxd_ip_address.v4 = ip_address;
786 
787     /* Call the NetX HTTP 'duo' get start service. */
788     status = _nxd_http_client_get_start_extended(client_ptr, &server_ip_addr, resource, resource_length,
789                                                  input_ptr, input_size, username, username_length,
790                                                  password, password_length, wait_option);
791 
792     return status;
793 #else
794     NX_PARAMETER_NOT_USED(client_ptr);
795     NX_PARAMETER_NOT_USED(ip_address);
796     NX_PARAMETER_NOT_USED(resource);
797     NX_PARAMETER_NOT_USED(resource_length);
798     NX_PARAMETER_NOT_USED(input_ptr);
799     NX_PARAMETER_NOT_USED(input_size);
800     NX_PARAMETER_NOT_USED(username);
801     NX_PARAMETER_NOT_USED(username_length);
802     NX_PARAMETER_NOT_USED(password);
803     NX_PARAMETER_NOT_USED(password_length);
804     NX_PARAMETER_NOT_USED(wait_option);
805 
806     return(NX_NOT_SUPPORTED);
807 #endif /* NX_DISABLE_IPV4 */
808 }
809 
810 
811 /**************************************************************************/
812 /*                                                                        */
813 /*  FUNCTION                                               RELEASE        */
814 /*                                                                        */
815 /*    _nxde_http_client_get_start                          PORTABLE C     */
816 /*                                                           6.1          */
817 /*  AUTHOR                                                                */
818 /*                                                                        */
819 /*    Yuxin Zhou, Microsoft Corporation                                   */
820 /*                                                                        */
821 /*  DESCRIPTION                                                           */
822 /*                                                                        */
823 /*    This function checks for errors in the HTTP Duo client get start    */
824 /*    call.                                                               */
825 /*                                                                        */
826 /*                                                                        */
827 /*  INPUT                                                                 */
828 /*                                                                        */
829 /*    client_ptr                            Pointer to HTTP client        */
830 /*    ip_address                            IP duo address of HTTP Server */
831 /*    resource                              Pointer to resource (URL)     */
832 /*    input_ptr                             Additional input pointer      */
833 /*    input_size                            Additional input size         */
834 /*    username                              Pointer to username           */
835 /*    password                              Pointer to password           */
836 /*    wait_option                           Suspension option             */
837 /*                                                                        */
838 /*  OUTPUT                                                                */
839 /*                                                                        */
840 /*    status                                Completion status             */
841 /*                                                                        */
842 /*  CALLS                                                                 */
843 /*                                                                        */
844 /*    _nx_http_client_get_start             Actual client get start call  */
845 /*                                                                        */
846 /*  CALLED BY                                                             */
847 /*                                                                        */
848 /*    Application Code                                                    */
849 /*                                                                        */
850 /*  RELEASE HISTORY                                                       */
851 /*                                                                        */
852 /*    DATE              NAME                      DESCRIPTION             */
853 /*                                                                        */
854 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
855 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
856 /*                                            resulting in version 6.1    */
857 /*                                                                        */
858 /**************************************************************************/
_nxde_http_client_get_start(NX_HTTP_CLIENT * client_ptr,NXD_ADDRESS * ip_address,CHAR * resource,CHAR * input_ptr,UINT input_size,CHAR * username,CHAR * password,ULONG wait_option)859 UINT  _nxde_http_client_get_start(NX_HTTP_CLIENT *client_ptr, NXD_ADDRESS *ip_address, CHAR *resource,
860                                   CHAR *input_ptr, UINT input_size, CHAR *username, CHAR *password,
861                                   ULONG wait_option)
862 {
863 
864 UINT    status;
865 
866 
867     /* Check for invalid input pointers.  */
868     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID) ||
869         (resource == NX_NULL) || !ip_address)
870         return(NX_PTR_ERROR);
871 
872     /* Check for appropriate caller.  */
873     NX_THREADS_ONLY_CALLER_CHECKING
874 
875     /* Call actual GET start routine.  */
876     status =  _nxd_http_client_get_start(client_ptr, ip_address, resource, input_ptr, input_size,
877                                          username, password, wait_option);
878 
879     /* Return completion status.  */
880     return(status);
881 }
882 
883 /**************************************************************************/
884 /*                                                                        */
885 /*  FUNCTION                                               RELEASE        */
886 /*                                                                        */
887 /*    _nxde_http_client_get_start_extended                 PORTABLE C     */
888 /*                                                           6.1          */
889 /*  AUTHOR                                                                */
890 /*                                                                        */
891 /*    Yuxin Zhou, Microsoft Corporation                                   */
892 /*                                                                        */
893 /*  DESCRIPTION                                                           */
894 /*                                                                        */
895 /*    This function checks for errors in the HTTP Duo client get start    */
896 /*    call.                                                               */
897 /*                                                                        */
898 /*                                                                        */
899 /*  INPUT                                                                 */
900 /*                                                                        */
901 /*    client_ptr                            Pointer to HTTP client        */
902 /*    ip_address                            IP duo address of HTTP Server */
903 /*    resource                              Pointer to resource (URL)     */
904 /*    resource_length                       Length of resource (URL)      */
905 /*    input_ptr                             Additional input pointer      */
906 /*    input_size                            Additional input size         */
907 /*    username                              Pointer to username           */
908 /*    username_length                       Length of username            */
909 /*    password                              Pointer to password           */
910 /*    password_length                       Length of password            */
911 /*    wait_option                           Suspension option             */
912 /*                                                                        */
913 /*  OUTPUT                                                                */
914 /*                                                                        */
915 /*    status                                Completion status             */
916 /*                                                                        */
917 /*  CALLS                                                                 */
918 /*                                                                        */
919 /*    _nxd_http_client_get_start_extended   Actual client get start call  */
920 /*                                                                        */
921 /*  CALLED BY                                                             */
922 /*                                                                        */
923 /*    Application Code                                                    */
924 /*                                                                        */
925 /*  RELEASE HISTORY                                                       */
926 /*                                                                        */
927 /*    DATE              NAME                      DESCRIPTION             */
928 /*                                                                        */
929 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
930 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
931 /*                                            resulting in version 6.1    */
932 /*                                                                        */
933 /**************************************************************************/
_nxde_http_client_get_start_extended(NX_HTTP_CLIENT * client_ptr,NXD_ADDRESS * ip_address,CHAR * resource,UINT resource_length,CHAR * input_ptr,UINT input_size,CHAR * username,UINT username_length,CHAR * password,UINT password_length,ULONG wait_option)934 UINT  _nxde_http_client_get_start_extended(NX_HTTP_CLIENT *client_ptr, NXD_ADDRESS *ip_address, CHAR *resource, UINT resource_length,
935                                            CHAR *input_ptr, UINT input_size, CHAR *username, UINT username_length,
936                                            CHAR *password, UINT password_length, ULONG wait_option)
937 {
938 
939 UINT    status;
940 
941 
942     /* Check for invalid input pointers.  */
943     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID) ||
944         (resource == NX_NULL) || !ip_address)
945         return(NX_PTR_ERROR);
946 
947     /* Check for appropriate caller.  */
948     NX_THREADS_ONLY_CALLER_CHECKING
949 
950     /* Call actual GET start routine.  */
951     status =  _nxd_http_client_get_start_extended(client_ptr, ip_address, resource, resource_length,
952                                                   input_ptr, input_size, username, username_length,
953                                                   password, password_length, wait_option);
954 
955     /* Return completion status.  */
956     return(status);
957 }
958 
959 /**************************************************************************/
960 /*                                                                        */
961 /*  FUNCTION                                               RELEASE        */
962 /*                                                                        */
963 /*    _nxd_http_client_get_start                          PORTABLE C      */
964 /*                                                           6.1          */
965 /*  AUTHOR                                                                */
966 /*                                                                        */
967 /*    Yuxin Zhou, Microsoft Corporation                                   */
968 /*                                                                        */
969 /*  DESCRIPTION                                                           */
970 /*                                                                        */
971 /*    This function processes the application GET request.  The specified */
972 /*    resource (URL) is requested from the HTTP Server at the specified   */
973 /*    IP address. If input was specified, the request will actually be    */
974 /*    sent as a POST instead of a GET.                                    */
975 /*                                                                        */
976 /*                                                                        */
977 /*  INPUT                                                                 */
978 /*                                                                        */
979 /*    client_ptr                            Pointer to HTTP client        */
980 /*    server_ip                             HTTP Server IP address        */
981 /*    resource                              Pointer to resource (URL)     */
982 /*    input_ptr                             Additional input pointer      */
983 /*    input_size                            Additional input size         */
984 /*    username                              Pointer to username           */
985 /*    password                              Pointer to password           */
986 /*    wait_option                           Suspension option             */
987 /*                                                                        */
988 /*  OUTPUT                                                                */
989 /*                                                                        */
990 /*    status                                Completion status             */
991 /*                                                                        */
992 /*  CALLS                                                                 */
993 /*                                                                        */
994 /*    _nxd_http_client_get_start_extended   Actual client get start call  */
995 /*    _nx_utility_string_length_check       Check string length           */
996 /*                                                                        */
997 /*  CALLED BY                                                             */
998 /*                                                                        */
999 /*    Application Code                                                    */
1000 /*                                                                        */
1001 /*  RELEASE HISTORY                                                       */
1002 /*                                                                        */
1003 /*    DATE              NAME                      DESCRIPTION             */
1004 /*                                                                        */
1005 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1006 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1007 /*                                            resulting in version 6.1    */
1008 /*                                                                        */
1009 /**************************************************************************/
_nxd_http_client_get_start(NX_HTTP_CLIENT * client_ptr,NXD_ADDRESS * server_ip,CHAR * resource,CHAR * input_ptr,UINT input_size,CHAR * username,CHAR * password,ULONG wait_option)1010 UINT  _nxd_http_client_get_start(NX_HTTP_CLIENT *client_ptr, NXD_ADDRESS *server_ip, CHAR *resource, CHAR *input_ptr,
1011                                  UINT input_size, CHAR *username, CHAR *password, ULONG wait_option)
1012 {
1013 
1014 UINT resource_length = 0;
1015 UINT username_length = 0;
1016 UINT password_length = 0;
1017 UINT status;
1018 
1019     /* Make sure there is enough room in the destination string.  */
1020     if((username) && (password))
1021     {
1022         if (_nx_utility_string_length_check(username, &username_length, NX_HTTP_MAX_NAME) ||
1023             _nx_utility_string_length_check(password, &password_length, NX_HTTP_MAX_PASSWORD))
1024         {
1025 
1026             /* Error, return to caller.  */
1027             return(NX_HTTP_PASSWORD_TOO_LONG);
1028         }
1029     }
1030 
1031     /* Check resource length.  */
1032     if (_nx_utility_string_length_check(resource, &resource_length, NX_MAX_STRING_LENGTH))
1033     {
1034         return(NX_HTTP_ERROR);
1035     }
1036 
1037     status = _nxd_http_client_get_start_extended(client_ptr, server_ip, resource, resource_length,
1038                                                  input_ptr, input_size, username, username_length,
1039                                                  password, password_length, wait_option);
1040 
1041     return(status);
1042 }
1043 
1044 
1045 /**************************************************************************/
1046 /*                                                                        */
1047 /*  FUNCTION                                               RELEASE        */
1048 /*                                                                        */
1049 /*    _nxd_http_client_get_start_extended                 PORTABLE C      */
1050 /*                                                           6.1.11       */
1051 /*  AUTHOR                                                                */
1052 /*                                                                        */
1053 /*    Yuxin Zhou, Microsoft Corporation                                   */
1054 /*                                                                        */
1055 /*  DESCRIPTION                                                           */
1056 /*                                                                        */
1057 /*    This function processes the application GET request.  The specified */
1058 /*    resource (URL) is requested from the HTTP Server at the specified   */
1059 /*    IP address. If input was specified, the request will actually be    */
1060 /*    sent as a POST instead of a GET.                                    */
1061 /*                                                                        */
1062 /*    Note: The strings of resource, username and password must be        */
1063 /*    NULL-terminated and length of each string matches the length        */
1064 /*    specified in the argument list.                                     */
1065 /*                                                                        */
1066 /*                                                                        */
1067 /*  INPUT                                                                 */
1068 /*                                                                        */
1069 /*    client_ptr                            Pointer to HTTP client        */
1070 /*    server_ip                             HTTP Server IP address        */
1071 /*    resource                              Pointer to resource (URL)     */
1072 /*    resource_length                       Length of resource (URL)      */
1073 /*    input_ptr                             Additional input pointer      */
1074 /*    input_size                            Additional input size         */
1075 /*    username                              Pointer to username           */
1076 /*    username_length                       Length of username            */
1077 /*    password                              Pointer to password           */
1078 /*    password_length                       Length of password            */
1079 /*    wait_option                           Suspension option             */
1080 /*                                                                        */
1081 /*  OUTPUT                                                                */
1082 /*                                                                        */
1083 /*    status                                Completion status             */
1084 /*                                                                        */
1085 /*  CALLS                                                                 */
1086 /*                                                                        */
1087 /*    _nx_http_client_base64_encode         Encode username/password      */
1088 /*    _nx_http_client_calculate_content_offset Calculate content offset   */
1089 /*    _nx_http_client_content_length_get    Get content length            */
1090 /*    _nx_http_client_number_convert        Convert number to ASCII       */
1091 /*    nx_packet_allocate                    Allocate a packet             */
1092 /*    nx_packet_data_append                 Append data to packet         */
1093 /*    nx_packet_release                     Release packet                */
1094 /*    nx_tcp_client_socket_bind             Bind client socket to port    */
1095 /*    nxd_tcp_client_socket_connect         Connect to HTTP Server        */
1096 /*    nx_tcp_socket_disconnect              Disconnect client socket      */
1097 /*    nx_tcp_client_socket_unbind           Unbind client socket          */
1098 /*    nx_tcp_socket_receive                 Get response packet           */
1099 /*    nx_tcp_socket_send                    Send request to Server        */
1100 /*    _nx_utility_string_length_check       Check string length           */
1101 /*                                                                        */
1102 /*  CALLED BY                                                             */
1103 /*                                                                        */
1104 /*    Application Code                                                    */
1105 /*                                                                        */
1106 /*  RELEASE HISTORY                                                       */
1107 /*                                                                        */
1108 /*    DATE              NAME                      DESCRIPTION             */
1109 /*                                                                        */
1110 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1111 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
1112 /*                                            verified memcpy use cases,  */
1113 /*                                            resulting in version 6.1    */
1114 /*  04-02-2021     Yuxin Zhou               Modified comment(s), and      */
1115 /*                                            improved the logic of       */
1116 /*                                            parsing base64,             */
1117 /*                                            resulting in version 6.1.6  */
1118 /*  04-25-2022     Yuxin Zhou               Modified comment(s), and      */
1119 /*                                            correted the status when    */
1120 /*                                            received error code,        */
1121 /*                                            resulting in version 6.1.11 */
1122 /*                                                                        */
1123 /**************************************************************************/
_nxd_http_client_get_start_extended(NX_HTTP_CLIENT * client_ptr,NXD_ADDRESS * server_ip,CHAR * resource,UINT resource_length,CHAR * input_ptr,UINT input_size,CHAR * username,UINT username_length,CHAR * password,UINT password_length,ULONG wait_option)1124 UINT  _nxd_http_client_get_start_extended(NX_HTTP_CLIENT *client_ptr, NXD_ADDRESS *server_ip, CHAR *resource, UINT resource_length,
1125                                           CHAR *input_ptr, UINT input_size, CHAR *username, UINT username_length,
1126                                           CHAR *password, UINT password_length, ULONG wait_option)
1127 {
1128 
1129 UINT        status;
1130 NX_PACKET   *packet_ptr;
1131 UINT        length = 0, offset = 0;
1132 NX_PACKET   *response_packet_ptr;
1133 CHAR        string1[NX_HTTP_MAX_NAME + NX_HTTP_MAX_PASSWORD + 2];
1134 CHAR        string2[NX_HTTP_MAX_STRING + 1];
1135 CHAR        *buffer_ptr;
1136 CHAR        crlf[2] = {13,10};
1137 UINT        string1_length;
1138 UINT        string2_length;
1139 UINT        temp_resource_length = 0;
1140 UINT        temp_username_length = 0;
1141 UINT        temp_password_length = 0;
1142 
1143 
1144     /* Determine if the client is in a ready state.  */
1145     if (client_ptr -> nx_http_client_state != NX_HTTP_CLIENT_STATE_READY)
1146     {
1147 
1148         /* Client not ready, return error.  */
1149         return(NX_HTTP_NOT_READY);
1150     }
1151 
1152     /* Make sure there is enough room in the destination string.  */
1153     if((username) && (password))
1154     {
1155         if (_nx_utility_string_length_check(username, &temp_username_length, username_length) ||
1156             _nx_utility_string_length_check(password, &temp_password_length, password_length))
1157         {
1158 
1159             /* Error, return to caller.  */
1160             return(NX_HTTP_PASSWORD_TOO_LONG);
1161         }
1162 
1163         /* Validate string length. */
1164         if ((username_length != temp_username_length) ||
1165             (password_length != temp_password_length))
1166         {
1167             return(NX_HTTP_ERROR);
1168         }
1169     }
1170 
1171     /* Check resource length.  */
1172     if (_nx_utility_string_length_check(resource, &temp_resource_length, resource_length))
1173     {
1174         return(NX_HTTP_ERROR);
1175     }
1176 
1177     /* Validate string length. */
1178     if (resource_length != temp_resource_length)
1179     {
1180         return(NX_HTTP_ERROR);
1181     }
1182 
1183     /* Otherwise, attempt to bind the client socket.  */
1184     status =  nx_tcp_client_socket_bind(&(client_ptr -> nx_http_client_socket), NX_ANY_PORT, wait_option);
1185 
1186     /* Check status of the bind.  */
1187     if (status != NX_SUCCESS)
1188     {
1189 
1190         /* Error binding to a port, return to caller.  */
1191         return(status);
1192     }
1193 
1194     /* Invoke the connection call. */
1195     status = nxd_tcp_client_socket_connect(&(client_ptr -> nx_http_client_socket), server_ip,
1196                                              client_ptr -> nx_http_client_connect_port, wait_option);
1197 
1198     /* Check for connection status.  */
1199     if (status != NX_SUCCESS)
1200     {
1201 
1202         /* Error, unbind the port and return an error.  */
1203         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
1204         return(status);
1205     }
1206 
1207     /* At this point we have a connection setup with an HTTP server!  */
1208 
1209     /* Allocate a packet for the GET (or POST) message.  */
1210     if (server_ip -> nxd_ip_version == NX_IP_VERSION_V4)
1211     {
1212         status =  nx_packet_allocate(client_ptr -> nx_http_client_packet_pool_ptr, &packet_ptr,
1213                                      NX_IPv4_TCP_PACKET, wait_option);
1214     }
1215     else
1216     {
1217 
1218         status =  nx_packet_allocate(client_ptr -> nx_http_client_packet_pool_ptr, &packet_ptr,
1219                                     NX_IPv6_TCP_PACKET, wait_option);
1220     }
1221 
1222     /* Check allocation status.  */
1223     if (status != NX_SUCCESS)
1224     {
1225 
1226         /* Error, unbind the port and return an error.  */
1227         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
1228         return(status);
1229     }
1230 
1231     /* Determine if a GET or POST is requested.  */
1232     if ((input_ptr) && (input_size))
1233     {
1234 
1235         /* Additional information requested, build the POST request.  */
1236         nx_packet_data_append(packet_ptr, "POST ", 5, client_ptr -> nx_http_client_packet_pool_ptr,
1237                               NX_WAIT_FOREVER);
1238     }
1239     else
1240     {
1241 
1242         /* No additional information, build the GET request.  */
1243         nx_packet_data_append(packet_ptr, "GET ", 4, client_ptr -> nx_http_client_packet_pool_ptr,
1244                               NX_WAIT_FOREVER);
1245     }
1246 
1247     /* Determine if the resource needs a leading "/".  */
1248     if (resource[0] != '/')
1249     {
1250 
1251         /* Is this another website e.g. begins with http and has a colon? */
1252         if  (
1253              ((resource[0] == 'h') || (resource[0] == 'H')) &&
1254              ((resource[1] == 't') || (resource[1] == 'T')) &&
1255              ((resource[2] == 't') || (resource[2] == 'T')) &&
1256              ((resource[3] == 'p') || (resource[3] == 'P'))  &&
1257              (resource[4] == ':')
1258             )
1259         {
1260 
1261             /* Yes, to send this string as is. */
1262         }
1263         else
1264         {
1265 
1266             /* Local file URI which needs a leading '/' character.  */
1267             nx_packet_data_append(packet_ptr, "/", 1, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
1268         }
1269     }
1270     /* Else URI string refers to root directory file, and has a leading '/' character already. */
1271 
1272     /* Place the resource in the header.  */
1273     nx_packet_data_append(packet_ptr, resource, resource_length, client_ptr -> nx_http_client_packet_pool_ptr,
1274                           NX_WAIT_FOREVER);
1275 
1276     /* Place the HTTP version in the header.  */
1277     nx_packet_data_append(packet_ptr, " HTTP/1.0", 9, client_ptr -> nx_http_client_packet_pool_ptr,
1278                           NX_WAIT_FOREVER);
1279 
1280     /* Place the end of line character in the header.  */
1281     nx_packet_data_append(packet_ptr, crlf, 2, client_ptr -> nx_http_client_packet_pool_ptr,
1282                           NX_WAIT_FOREVER);
1283 
1284     /* Determine if basic authentication is required.  */
1285     if ((username) && (password))
1286     {
1287 
1288         /* Yes, attempt to build basic authentication.  */
1289         nx_packet_data_append(packet_ptr, "Authorization: Basic ", 21, client_ptr -> nx_http_client_packet_pool_ptr,
1290                               NX_WAIT_FOREVER);
1291 
1292         /* Encode and append the "name:password" into next.  */
1293 
1294         /* Place the name and password in a single string.  */
1295 
1296         /* Copy the name into the merged string.  */
1297         memcpy(string1, username, username_length); /* Use case of memcpy is verified. */
1298 
1299         /* Insert the colon.  */
1300         string1[username_length] =  ':';
1301 
1302         /* Copy the password into the merged string.  */
1303         memcpy(&string1[username_length + 1], password, password_length); /* Use case of memcpy is verified. */
1304 
1305         /* Make combined string NULL terminated.  */
1306         string1[username_length + password_length + 1] =  NX_NULL;
1307 
1308         /* Now encode the username:password string.  */
1309         _nx_utility_base64_encode((UCHAR *)string1, username_length + password_length + 1, (UCHAR *)string2, sizeof(string2), &string2_length);
1310         nx_packet_data_append(packet_ptr, string2, string2_length, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
1311         nx_packet_data_append(packet_ptr, crlf, 2, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
1312     }
1313 
1314     /* Check to see if a Content-Length field is needed.  */
1315     if ((input_ptr) && (input_size))
1316     {
1317 
1318         /* Now build the content-length entry.  */
1319         nx_packet_data_append(packet_ptr, "Content-Length: ", 16, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
1320         string1_length =  _nx_http_client_number_convert(input_size, string1);
1321         nx_packet_data_append(packet_ptr, string1, string1_length, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
1322         nx_packet_data_append(packet_ptr, crlf, 2, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
1323     }
1324 
1325     /* Place an extra cr/lf to signal the end of the HTTP header.  */
1326     nx_packet_data_append(packet_ptr, crlf, 2, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
1327 
1328     /* Check to see if we need to append the additional user data.  */
1329     if ((input_ptr) && (input_size))
1330     {
1331 
1332         /* Now build the content-length entry.  */
1333         nx_packet_data_append(packet_ptr, input_ptr, input_size, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
1334     }
1335 
1336     /* Now send the packet to the HTTP server.  */
1337     status =  nx_tcp_socket_send(&(client_ptr -> nx_http_client_socket), packet_ptr, wait_option);
1338 
1339     /* Determine if the send was successful.  */
1340     if (status != NX_SUCCESS)
1341     {
1342 
1343         /* No, send was not successful.  */
1344 
1345         /* Release the packet.  */
1346         nx_packet_release(packet_ptr);
1347 
1348         /* Disconnect and unbind the socket.  */
1349         nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
1350         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
1351 
1352         /* Return an error.  */
1353         return(status);
1354     }
1355 
1356     /* Pickup the response from the Server.  */
1357     status =  nx_tcp_socket_receive(&(client_ptr -> nx_http_client_socket), &response_packet_ptr, wait_option);
1358 
1359     /* Check for a response from the Server.  */
1360     if (status == NX_SUCCESS)
1361     {
1362 
1363         /* Setup pointer to server response.  */
1364         buffer_ptr =  (CHAR *) response_packet_ptr -> nx_packet_prepend_ptr;
1365 
1366         /* Check if packet contains the HTTP status. */
1367         if ((buffer_ptr + 11) >= (CHAR *)response_packet_ptr -> nx_packet_append_ptr)
1368         {
1369 
1370             /* Release the packet.  */
1371             nx_packet_release(response_packet_ptr);
1372 
1373             /* Disconnect and unbind the socket.  */
1374             nx_tcp_socket_disconnect(&(client_ptr->nx_http_client_socket), wait_option);
1375             nx_tcp_client_socket_unbind(&(client_ptr->nx_http_client_socket));
1376 
1377             /* Return an error.  */
1378             return(NX_HTTP_FAILED);
1379         }
1380 
1381         /* Determine if the request was successful.  */
1382         if (buffer_ptr[9] == '2')
1383         {
1384 
1385             /* Determine if we need to copy the packet.  */
1386             if ((response_packet_ptr -> nx_packet_data_end - response_packet_ptr -> nx_packet_data_start) < NX_HTTP_CLIENT_MIN_PACKET_SIZE)
1387             {
1388 
1389                 /* Copy the packet to a packet in the packet pool.  */
1390                 nx_packet_copy(response_packet_ptr, &packet_ptr, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
1391 
1392                 /* Release the original packet.  */
1393                 nx_packet_release(response_packet_ptr);
1394 
1395                 /* Copy the packet pointer.  */
1396                 response_packet_ptr =  packet_ptr;
1397             }
1398 
1399             /* Pickup the content length.  */
1400             length =  _nx_http_client_content_length_get(response_packet_ptr);
1401 
1402             /* Pickup the content offset.  */
1403             offset =  _nx_http_client_calculate_content_offset(response_packet_ptr);
1404 
1405             /* Indicate a successful completion.  */
1406             status =  NX_SUCCESS;
1407         }
1408         /* Determine if it is an authentication error.  */
1409         else if ((buffer_ptr[9] == '4') && (buffer_ptr[10] == '0') && (buffer_ptr[11] == '1'))
1410         {
1411 
1412             /* Release the packet.  */
1413             nx_packet_release(response_packet_ptr);
1414 
1415             /* Inform caller of an authentication error.  */
1416             status =  NX_HTTP_AUTHENTICATION_ERROR;
1417         }
1418         else
1419         {
1420 
1421             /* Release the packet.  */
1422             nx_packet_release(response_packet_ptr);
1423 
1424             /* Received error code.  */
1425             status = NX_HTTP_REQUEST_UNSUCCESSFUL_CODE;
1426         }
1427     }
1428 
1429     /* Check for error processing received packet. */
1430     if (status != NX_SUCCESS)
1431     {
1432 
1433         /* Disconnect and unbind the socket.  */
1434         nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
1435         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
1436 
1437         return status;
1438     }
1439 
1440     /* Check for invalid packet parameters.  */
1441     if ((length == 0) || (offset == 0))
1442     {
1443 
1444         /* Release the packet.  */
1445         nx_packet_release(response_packet_ptr);
1446 
1447         /* Disconnect and unbind the socket.  */
1448         nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
1449         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
1450 
1451         /* Return an error.  */
1452         return(NX_HTTP_FAILED);
1453     }
1454 
1455 
1456     /* Determine if the offset is in this request.  */
1457     if (response_packet_ptr -> nx_packet_length > (offset + 3))
1458     {
1459 
1460         /* Adjust the pointers to skip over the response header.  */
1461         response_packet_ptr -> nx_packet_prepend_ptr =  response_packet_ptr -> nx_packet_prepend_ptr + offset;
1462 
1463         /* Reduce the length.  */
1464         response_packet_ptr -> nx_packet_length =  response_packet_ptr -> nx_packet_length - offset;
1465 
1466         /* Save the packet pointer for the get packet call.  */
1467         client_ptr -> nx_http_client_first_packet =  response_packet_ptr;
1468     }
1469     else
1470     {
1471 
1472         /* Clear the saved packet pointer.  */
1473         client_ptr -> nx_http_client_first_packet =  NX_NULL;
1474 
1475         /* This packet only contains the header, just release it!  */
1476         nx_packet_release(response_packet_ptr);
1477     }
1478 
1479     /* Store the total number of bytes to receive.  */
1480     client_ptr -> nx_http_client_total_transfer_bytes =     length;
1481     client_ptr -> nx_http_client_actual_bytes_transferred =  0;
1482 
1483     /* Enter the GET state.  */
1484     client_ptr -> nx_http_client_state =  NX_HTTP_CLIENT_STATE_GET;
1485 
1486     /* Return success to the caller.  */
1487     return  NX_SUCCESS;
1488 }
1489 
1490 
1491 /**************************************************************************/
1492 /*                                                                        */
1493 /*  FUNCTION                                               RELEASE        */
1494 /*                                                                        */
1495 /*    _nxe_http_client_get_packet                         PORTABLE C      */
1496 /*                                                           6.1          */
1497 /*  AUTHOR                                                                */
1498 /*                                                                        */
1499 /*    Yuxin Zhou, Microsoft Corporation                                   */
1500 /*                                                                        */
1501 /*  DESCRIPTION                                                           */
1502 /*                                                                        */
1503 /*    This function checks for errors in the HTTP client get packet call. */
1504 /*                                                                        */
1505 /*                                                                        */
1506 /*  INPUT                                                                 */
1507 /*                                                                        */
1508 /*    client_ptr                            Pointer to HTTP client        */
1509 /*    packet_ptr                            Destination for packet pointer*/
1510 /*    wait_option                           Suspension option             */
1511 /*                                                                        */
1512 /*  OUTPUT                                                                */
1513 /*                                                                        */
1514 /*    status                                Completion status             */
1515 /*                                                                        */
1516 /*  CALLS                                                                 */
1517 /*                                                                        */
1518 /*    _nx_http_client_get_packet            Actual client get packet call */
1519 /*                                                                        */
1520 /*  CALLED BY                                                             */
1521 /*                                                                        */
1522 /*    Application Code                                                    */
1523 /*                                                                        */
1524 /*  RELEASE HISTORY                                                       */
1525 /*                                                                        */
1526 /*    DATE              NAME                      DESCRIPTION             */
1527 /*                                                                        */
1528 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1529 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1530 /*                                            resulting in version 6.1    */
1531 /*                                                                        */
1532 /**************************************************************************/
_nxe_http_client_get_packet(NX_HTTP_CLIENT * client_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)1533 UINT  _nxe_http_client_get_packet(NX_HTTP_CLIENT *client_ptr, NX_PACKET **packet_ptr, ULONG wait_option)
1534 {
1535 
1536 UINT    status;
1537 
1538 
1539     /* Check for invalid input pointers.  */
1540     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID) ||
1541         (packet_ptr == NX_NULL))
1542         return(NX_PTR_ERROR);
1543 
1544     /* Check for appropriate caller.  */
1545     NX_THREADS_ONLY_CALLER_CHECKING
1546 
1547     /* Call actual GET packet routine.  */
1548     status =  _nx_http_client_get_packet(client_ptr, packet_ptr, wait_option);
1549 
1550     /* Return completion status.  */
1551     return(status);
1552 }
1553 
1554 
1555 /**************************************************************************/
1556 /*                                                                        */
1557 /*  FUNCTION                                               RELEASE        */
1558 /*                                                                        */
1559 /*    _nx_http_client_get_packet                          PORTABLE C      */
1560 /*                                                           6.1          */
1561 /*  AUTHOR                                                                */
1562 /*                                                                        */
1563 /*    Yuxin Zhou, Microsoft Corporation                                   */
1564 /*                                                                        */
1565 /*  DESCRIPTION                                                           */
1566 /*                                                                        */
1567 /*    This function gets a data packet associated with the resource       */
1568 /*    specified by the previous GET start request.                        */
1569 /*                                                                        */
1570 /*                                                                        */
1571 /*  INPUT                                                                 */
1572 /*                                                                        */
1573 /*    client_ptr                            Pointer to HTTP client        */
1574 /*    packet_ptr                            Destination for packet pointer*/
1575 /*    wait_option                           Suspension option             */
1576 /*                                                                        */
1577 /*  OUTPUT                                                                */
1578 /*                                                                        */
1579 /*    status                                Completion status             */
1580 /*                                                                        */
1581 /*  CALLS                                                                 */
1582 /*                                                                        */
1583 /*    nx_tcp_client_socket_unbind           Unbind client socket          */
1584 /*    nx_tcp_socket_disconnect              Disconnect client socket      */
1585 /*    nx_tcp_socket_receive                 Receive a resource data packet*/
1586 /*                                                                        */
1587 /*  CALLED BY                                                             */
1588 /*                                                                        */
1589 /*    Application Code                                                    */
1590 /*                                                                        */
1591 /*  RELEASE HISTORY                                                       */
1592 /*                                                                        */
1593 /*    DATE              NAME                      DESCRIPTION             */
1594 /*                                                                        */
1595 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1596 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1597 /*                                            resulting in version 6.1    */
1598 /*                                                                        */
1599 /**************************************************************************/
_nx_http_client_get_packet(NX_HTTP_CLIENT * client_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)1600 UINT  _nx_http_client_get_packet(NX_HTTP_CLIENT *client_ptr, NX_PACKET **packet_ptr, ULONG wait_option)
1601 {
1602 
1603 NX_PACKET   *data_packet_ptr;
1604 UINT        status;
1605 
1606 
1607     /* Default the return packet to NULL.  */
1608     *packet_ptr =  NX_NULL;
1609 
1610     /* Determine if the client is in a get state.  */
1611     if (client_ptr -> nx_http_client_state != NX_HTTP_CLIENT_STATE_GET)
1612     {
1613 
1614         /* Client not ready, return error.  */
1615         return(NX_HTTP_NOT_READY);
1616     }
1617 
1618     /* Determine if the GET packet operation is complete.  */
1619     if (client_ptr -> nx_http_client_total_transfer_bytes == client_ptr -> nx_http_client_actual_bytes_transferred)
1620     {
1621 
1622         /* Yes, we are finished.  */
1623 
1624         /* Disconnect and unbind the socket.  */
1625         nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
1626         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
1627 
1628         /* Reenter the READY state.  */
1629         client_ptr -> nx_http_client_state =  NX_HTTP_CLIENT_STATE_READY;
1630 
1631         /* Return the GET done code.  */
1632         return(NX_HTTP_GET_DONE);
1633     }
1634 
1635     /* Determine if there is a queued packet.  */
1636     if (client_ptr -> nx_http_client_first_packet)
1637     {
1638 
1639         /* Yes, just use the saved packet.  */
1640         data_packet_ptr =  client_ptr -> nx_http_client_first_packet;
1641 
1642         /* Clear the saved packet pointer.  */
1643         client_ptr -> nx_http_client_first_packet =  NX_NULL;
1644     }
1645     else
1646     {
1647 
1648         /* Receive a data packet from the TCP connection.  */
1649         status =  nx_tcp_socket_receive(&(client_ptr -> nx_http_client_socket), &data_packet_ptr, wait_option);
1650 
1651         /* Determine if a packet is available.  */
1652         if (status != NX_SUCCESS)
1653         {
1654 
1655             /* Ensure the packet pointer is NULL.  */
1656             data_packet_ptr =  NX_NULL;
1657             /* Disconnect and unbind the socket.  */
1658             nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
1659             nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
1660             return status;
1661         }
1662     }
1663 
1664     /* Check for an error condition.  */
1665     if (data_packet_ptr -> nx_packet_length > (client_ptr -> nx_http_client_total_transfer_bytes - client_ptr -> nx_http_client_actual_bytes_transferred))
1666     {
1667 
1668         /* Release the invalid HTTP packet. */
1669         nx_packet_release(data_packet_ptr);
1670 
1671         /* Error, break down the connection and return to the caller.  */
1672 
1673         /* Disconnect and unbind the socket.  */
1674         nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
1675         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
1676 
1677         /* Reenter the READY state.  */
1678         client_ptr -> nx_http_client_state =  NX_HTTP_CLIENT_STATE_READY;
1679 
1680         /* Return an error.  */
1681         return(NX_HTTP_BAD_PACKET_LENGTH);
1682     }
1683 
1684     /* Adjust the actual transfer bytes.  */
1685     client_ptr -> nx_http_client_actual_bytes_transferred =  client_ptr -> nx_http_client_actual_bytes_transferred +
1686                                                             data_packet_ptr -> nx_packet_length;
1687 
1688     /* Move the packet pointer into the return pointer.  */
1689     *packet_ptr =  data_packet_ptr;
1690 
1691     /* Return a successful completion.  */
1692     return(NX_SUCCESS);
1693 }
1694 
1695 /**************************************************************************/
1696 /*                                                                        */
1697 /*  FUNCTION                                               RELEASE        */
1698 /*                                                                        */
1699 /*    _nxe_http_client_put_start                          PORTABLE C      */
1700 /*                                                           6.1          */
1701 /*  AUTHOR                                                                */
1702 /*                                                                        */
1703 /*    Yuxin Zhou, Microsoft Corporation                                   */
1704 /*                                                                        */
1705 /*  DESCRIPTION                                                           */
1706 /*                                                                        */
1707 /*    This function checks for errors in the HTTP (IPv4) Client put start */
1708 /*    call.                                                               */
1709 /*                                                                        */
1710 /*                                                                        */
1711 /*  INPUT                                                                 */
1712 /*                                                                        */
1713 /*    client_ptr                            Pointer to HTTP client        */
1714 /*    ip_address                            IPv4 address of HTTP Server   */
1715 /*    resource                              Pointer to resource (URL)     */
1716 /*    username                              Pointer to username           */
1717 /*    password                              Pointer to password           */
1718 /*    total_bytes                           Total bytes to send           */
1719 /*    wait_option                           Suspension option             */
1720 /*                                                                        */
1721 /*  OUTPUT                                                                */
1722 /*                                                                        */
1723 /*    status                                Completion status             */
1724 /*                                                                        */
1725 /*  CALLS                                                                 */
1726 /*                                                                        */
1727 /*    _nx_http_client_put_start             Actual IPv4 HTTP Client put   */
1728 /*                                                 start call             */
1729 /*                                                                        */
1730 /*  CALLED BY                                                             */
1731 /*                                                                        */
1732 /*    Application Code                                                    */
1733 /*                                                                        */
1734 /*  RELEASE HISTORY                                                       */
1735 /*                                                                        */
1736 /*    DATE              NAME                      DESCRIPTION             */
1737 /*                                                                        */
1738 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1739 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1740 /*                                            resulting in version 6.1    */
1741 /*                                                                        */
1742 /**************************************************************************/
1743 
_nxe_http_client_put_start(NX_HTTP_CLIENT * client_ptr,ULONG ip_address,CHAR * resource,CHAR * username,CHAR * password,ULONG total_bytes,ULONG wait_option)1744 UINT  _nxe_http_client_put_start(NX_HTTP_CLIENT *client_ptr, ULONG ip_address, CHAR *resource,
1745                                    CHAR *username, CHAR *password, ULONG total_bytes, ULONG wait_option)
1746 {
1747 
1748 #ifndef NX_DISABLE_IPV4
1749 UINT    status;
1750 
1751 
1752     /* Check for invalid input pointers.  */
1753     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID) ||
1754         resource == NX_NULL || !ip_address)
1755         return(NX_PTR_ERROR);
1756 
1757     /* Check for invalid total bytes.  */
1758     if (total_bytes == 0)
1759         return(NX_SIZE_ERROR);
1760 
1761     /* Check for appropriate caller.  */
1762     NX_THREADS_ONLY_CALLER_CHECKING
1763 
1764     /* Call actual PUT start routine.  */
1765     status =  _nx_http_client_put_start(client_ptr, ip_address, resource, username, password,
1766                                         total_bytes, wait_option);
1767 
1768     /* Return completion status.  */
1769     return(status);
1770 #else
1771     NX_PARAMETER_NOT_USED(client_ptr);
1772     NX_PARAMETER_NOT_USED(ip_address);
1773     NX_PARAMETER_NOT_USED(resource);
1774     NX_PARAMETER_NOT_USED(username);
1775     NX_PARAMETER_NOT_USED(password);
1776     NX_PARAMETER_NOT_USED(total_bytes);
1777     NX_PARAMETER_NOT_USED(wait_option);
1778 
1779     return(NX_NOT_SUPPORTED);
1780 #endif /* NX_DISABLE_IPV4 */
1781 }
1782 
1783 
1784 /**************************************************************************/
1785 /*                                                                        */
1786 /*  FUNCTION                                               RELEASE        */
1787 /*                                                                        */
1788 /*    _nxe_http_client_put_start_extended                 PORTABLE C      */
1789 /*                                                           6.1          */
1790 /*  AUTHOR                                                                */
1791 /*                                                                        */
1792 /*    Yuxin Zhou, Microsoft Corporation                                   */
1793 /*                                                                        */
1794 /*  DESCRIPTION                                                           */
1795 /*                                                                        */
1796 /*    This function checks for errors in the HTTP (IPv4) Client put start */
1797 /*    call.                                                               */
1798 /*                                                                        */
1799 /*                                                                        */
1800 /*  INPUT                                                                 */
1801 /*                                                                        */
1802 /*    client_ptr                            Pointer to HTTP client        */
1803 /*    ip_address                            IPv4 address of HTTP Server   */
1804 /*    resource                              Pointer to resource (URL)     */
1805 /*    resource_length                       Length of resource (URL)      */
1806 /*    username                              Pointer to username           */
1807 /*    username_length                       Length of username            */
1808 /*    password                              Pointer to password           */
1809 /*    password_length                       Length of password            */
1810 /*    total_bytes                           Total bytes to send           */
1811 /*    wait_option                           Suspension option             */
1812 /*                                                                        */
1813 /*  OUTPUT                                                                */
1814 /*                                                                        */
1815 /*    status                                Completion status             */
1816 /*                                                                        */
1817 /*  CALLS                                                                 */
1818 /*                                                                        */
1819 /*    _nx_http_client_put_start_extended    Actual IPv4 HTTP Client put   */
1820 /*                                                 start call             */
1821 /*                                                                        */
1822 /*  CALLED BY                                                             */
1823 /*                                                                        */
1824 /*    Application Code                                                    */
1825 /*                                                                        */
1826 /*  RELEASE HISTORY                                                       */
1827 /*                                                                        */
1828 /*    DATE              NAME                      DESCRIPTION             */
1829 /*                                                                        */
1830 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1831 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1832 /*                                            resulting in version 6.1    */
1833 /*                                                                        */
1834 /**************************************************************************/
1835 
_nxe_http_client_put_start_extended(NX_HTTP_CLIENT * client_ptr,ULONG ip_address,CHAR * resource,UINT resource_length,CHAR * username,UINT username_length,CHAR * password,UINT password_length,ULONG total_bytes,ULONG wait_option)1836 UINT  _nxe_http_client_put_start_extended(NX_HTTP_CLIENT *client_ptr, ULONG ip_address, CHAR *resource,
1837                                           UINT resource_length, CHAR *username, UINT username_length,
1838                                           CHAR *password, UINT password_length, ULONG total_bytes, ULONG wait_option)
1839 {
1840 
1841 #ifndef NX_DISABLE_IPV4
1842 UINT    status;
1843 
1844 
1845     /* Check for invalid input pointers.  */
1846     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID) ||
1847         resource == NX_NULL || !ip_address)
1848         return(NX_PTR_ERROR);
1849 
1850     /* Check for invalid total bytes.  */
1851     if (total_bytes == 0)
1852         return(NX_SIZE_ERROR);
1853 
1854     /* Check for appropriate caller.  */
1855     NX_THREADS_ONLY_CALLER_CHECKING
1856 
1857     /* Call actual PUT start routine.  */
1858     status =  _nx_http_client_put_start_extended(client_ptr, ip_address, resource, resource_length,
1859                                                  username, username_length, password, password_length,
1860                                                  total_bytes, wait_option);
1861 
1862     /* Return completion status.  */
1863     return(status);
1864 #else
1865     NX_PARAMETER_NOT_USED(client_ptr);
1866     NX_PARAMETER_NOT_USED(ip_address);
1867     NX_PARAMETER_NOT_USED(resource);
1868     NX_PARAMETER_NOT_USED(resource_length);
1869     NX_PARAMETER_NOT_USED(username);
1870     NX_PARAMETER_NOT_USED(username_length);
1871     NX_PARAMETER_NOT_USED(password);
1872     NX_PARAMETER_NOT_USED(password_length);
1873     NX_PARAMETER_NOT_USED(total_bytes);
1874     NX_PARAMETER_NOT_USED(wait_option);
1875 
1876     return(NX_NOT_SUPPORTED);
1877 #endif /* NX_DISABLE_IPV4 */
1878 }
1879 
1880 
1881 /**************************************************************************/
1882 /*                                                                        */
1883 /*  FUNCTION                                               RELEASE        */
1884 /*                                                                        */
1885 /*    _nx_http_client_put_start                           PORTABLE C      */
1886 /*                                                           6.1          */
1887 /*  AUTHOR                                                                */
1888 /*                                                                        */
1889 /*    Yuxin Zhou, Microsoft Corporation                                   */
1890 /*                                                                        */
1891 /*  DESCRIPTION                                                           */
1892 /*                                                                        */
1893 /*    This function is a wrapper for the actual _nxd_http_client_put_start*/
1894 /*    service that enables HTTP applications running on IPv4 to access    */
1895 /*    HTTP duo API without enabling IPv6.                                 */
1896 /*                                                                        */
1897 /*                                                                        */
1898 /*  INPUT                                                                 */
1899 /*                                                                        */
1900 /*    client_ptr                            Pointer to HTTP client        */
1901 /*    ip_address                            IPv4 address of HTTP Server   */
1902 /*    resource                              Pointer to resource (URL)     */
1903 /*    username                              Pointer to username           */
1904 /*    password                              Pointer to password           */
1905 /*    total_bytes                           Total bytes to send           */
1906 /*    wait_option                           Suspension option             */
1907 /*                                                                        */
1908 /*  OUTPUT                                                                */
1909 /*                                                                        */
1910 /*    status                                Completion status             */
1911 /*                                                                        */
1912 /*  CALLS                                                                 */
1913 /*                                                                        */
1914 /*    _nxd_http_client_put_start            Actual put start service for  */
1915 /*                                               HTTP Duo Client          */
1916 /*                                                                        */
1917 /*  CALLED BY                                                             */
1918 /*                                                                        */
1919 /*    Application Code                                                    */
1920 /*                                                                        */
1921 /*  RELEASE HISTORY                                                       */
1922 /*                                                                        */
1923 /*    DATE              NAME                      DESCRIPTION             */
1924 /*                                                                        */
1925 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1926 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1927 /*                                            resulting in version 6.1    */
1928 /*                                                                        */
1929 /**************************************************************************/
_nx_http_client_put_start(NX_HTTP_CLIENT * client_ptr,ULONG ip_address,CHAR * resource,CHAR * username,CHAR * password,ULONG total_bytes,ULONG wait_option)1930 UINT  _nx_http_client_put_start(NX_HTTP_CLIENT *client_ptr, ULONG ip_address, CHAR *resource, CHAR *username,
1931                                 CHAR *password, ULONG total_bytes, ULONG wait_option)
1932 {
1933 
1934 #ifndef NX_DISABLE_IPV4
1935 UINT            status;
1936 NXD_ADDRESS     server_ip_addr;
1937 
1938 
1939     /* Construct an IP address structure, and fill in IPv4 address information. */
1940     server_ip_addr.nxd_ip_version = NX_IP_VERSION_V4;
1941     server_ip_addr.nxd_ip_address.v4 = ip_address;
1942 
1943     status = _nxd_http_client_put_start(client_ptr, &server_ip_addr, resource, username,
1944                                        password, total_bytes, wait_option);
1945 
1946     return status;
1947 #else
1948     NX_PARAMETER_NOT_USED(client_ptr);
1949     NX_PARAMETER_NOT_USED(ip_address);
1950     NX_PARAMETER_NOT_USED(resource);
1951     NX_PARAMETER_NOT_USED(username);
1952     NX_PARAMETER_NOT_USED(password);
1953     NX_PARAMETER_NOT_USED(total_bytes);
1954     NX_PARAMETER_NOT_USED(wait_option);
1955 
1956     return(NX_NOT_SUPPORTED);
1957 #endif /* NX_DISABLE_IPV4 */
1958 }
1959 
1960 /**************************************************************************/
1961 /*                                                                        */
1962 /*  FUNCTION                                               RELEASE        */
1963 /*                                                                        */
1964 /*    _nx_http_client_put_start_extended                  PORTABLE C      */
1965 /*                                                           6.1          */
1966 /*  AUTHOR                                                                */
1967 /*                                                                        */
1968 /*    Yuxin Zhou, Microsoft Corporation                                   */
1969 /*                                                                        */
1970 /*  DESCRIPTION                                                           */
1971 /*                                                                        */
1972 /*    This function is a wrapper for the actual _nxd_http_client_put_start*/
1973 /*    service that enables HTTP applications running on IPv4 to access    */
1974 /*    HTTP duo API without enabling IPv6.                                 */
1975 /*                                                                        */
1976 /*    Note: The strings of resource, username and password must be        */
1977 /*    NULL-terminated and length of each string matches the length        */
1978 /*    specified in the argument list.                                     */
1979 /*                                                                        */
1980 /*                                                                        */
1981 /*  INPUT                                                                 */
1982 /*                                                                        */
1983 /*    client_ptr                            Pointer to HTTP client        */
1984 /*    ip_address                            IPv4 address of HTTP Server   */
1985 /*    resource                              Pointer to resource (URL)     */
1986 /*    resource_length                       Length of resource (URL)      */
1987 /*    username                              Pointer to username           */
1988 /*    username_length                       Length of username            */
1989 /*    password                              Pointer to password           */
1990 /*    password_length                       Length of password            */
1991 /*    total_bytes                           Total bytes to send           */
1992 /*    wait_option                           Suspension option             */
1993 /*                                                                        */
1994 /*  OUTPUT                                                                */
1995 /*                                                                        */
1996 /*    status                                Completion status             */
1997 /*                                                                        */
1998 /*  CALLS                                                                 */
1999 /*                                                                        */
2000 /*    _nxd_http_client_put_start_extended   Actual put start service for  */
2001 /*                                               HTTP Duo Client          */
2002 /*                                                                        */
2003 /*  CALLED BY                                                             */
2004 /*                                                                        */
2005 /*    Application Code                                                    */
2006 /*                                                                        */
2007 /*  RELEASE HISTORY                                                       */
2008 /*                                                                        */
2009 /*    DATE              NAME                      DESCRIPTION             */
2010 /*                                                                        */
2011 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2012 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2013 /*                                            resulting in version 6.1    */
2014 /*                                                                        */
2015 /**************************************************************************/
_nx_http_client_put_start_extended(NX_HTTP_CLIENT * client_ptr,ULONG ip_address,CHAR * resource,UINT resource_length,CHAR * username,UINT username_length,CHAR * password,UINT password_length,ULONG total_bytes,ULONG wait_option)2016 UINT  _nx_http_client_put_start_extended(NX_HTTP_CLIENT *client_ptr, ULONG ip_address, CHAR *resource,
2017                                          UINT resource_length, CHAR *username, UINT username_length,
2018                                          CHAR *password, UINT password_length, ULONG total_bytes, ULONG wait_option)
2019 {
2020 
2021 #ifndef NX_DISABLE_IPV4
2022 UINT            status;
2023 NXD_ADDRESS     server_ip_addr;
2024 
2025 
2026     /* Construct an IP address structure, and fill in IPv4 address information. */
2027     server_ip_addr.nxd_ip_version = NX_IP_VERSION_V4;
2028     server_ip_addr.nxd_ip_address.v4 = ip_address;
2029 
2030     status = _nxd_http_client_put_start_extended(client_ptr, &server_ip_addr, resource, resource_length,
2031                                                  username, username_length, password, password_length,
2032                                                  total_bytes, wait_option);
2033 
2034     return status;
2035 #else
2036     NX_PARAMETER_NOT_USED(client_ptr);
2037     NX_PARAMETER_NOT_USED(ip_address);
2038     NX_PARAMETER_NOT_USED(resource);
2039     NX_PARAMETER_NOT_USED(resource_length);
2040     NX_PARAMETER_NOT_USED(username);
2041     NX_PARAMETER_NOT_USED(username_length);
2042     NX_PARAMETER_NOT_USED(password);
2043     NX_PARAMETER_NOT_USED(password_length);
2044     NX_PARAMETER_NOT_USED(total_bytes);
2045     NX_PARAMETER_NOT_USED(wait_option);
2046 
2047     return(NX_NOT_SUPPORTED);
2048 #endif /* NX_DISABLE_IPV4 */
2049 }
2050 
2051 /**************************************************************************/
2052 /*                                                                        */
2053 /*  FUNCTION                                               RELEASE        */
2054 /*                                                                        */
2055 /*    _nxde_http_client_put_start                         PORTABLE C      */
2056 /*                                                           6.1          */
2057 /*  AUTHOR                                                                */
2058 /*                                                                        */
2059 /*    Yuxin Zhou, Microsoft Corporation                                   */
2060 /*                                                                        */
2061 /*  DESCRIPTION                                                           */
2062 /*                                                                        */
2063 /*    This function checks for errors in the HTTP Duo Client put start    */
2064 /*        call.                                                           */
2065 /*                                                                        */
2066 /*                                                                        */
2067 /*  INPUT                                                                 */
2068 /*                                                                        */
2069 /*    client_ptr                            Pointer to HTTP client        */
2070 /*    server_ip                             IP duo address of HTTP Server */
2071 /*    resource                              Pointer to resource (URL)     */
2072 /*    username                              Pointer to username           */
2073 /*    password                              Pointer to password           */
2074 /*    total_bytes                           Total bytes to send           */
2075 /*    wait_option                           Suspension option             */
2076 /*                                                                        */
2077 /*  OUTPUT                                                                */
2078 /*                                                                        */
2079 /*    status                                Completion status             */
2080 /*                                                                        */
2081 /*  CALLS                                                                 */
2082 /*                                                                        */
2083 /*    _nx_http_client_put_start             Actual client put start call  */
2084 /*                                                                        */
2085 /*  CALLED BY                                                             */
2086 /*                                                                        */
2087 /*    Application Code                                                    */
2088 /*                                                                        */
2089 /*  RELEASE HISTORY                                                       */
2090 /*                                                                        */
2091 /*    DATE              NAME                      DESCRIPTION             */
2092 /*                                                                        */
2093 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2094 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2095 /*                                            resulting in version 6.1    */
2096 /*                                                                        */
2097 /**************************************************************************/
_nxde_http_client_put_start(NX_HTTP_CLIENT * client_ptr,NXD_ADDRESS * server_ip,CHAR * resource,CHAR * username,CHAR * password,ULONG total_bytes,ULONG wait_option)2098 UINT  _nxde_http_client_put_start(NX_HTTP_CLIENT *client_ptr, NXD_ADDRESS *server_ip, CHAR *resource,
2099                                    CHAR *username, CHAR *password, ULONG total_bytes, ULONG wait_option)
2100 {
2101 
2102 UINT    status;
2103 
2104 
2105     /* Check for invalid input pointers.  */
2106     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID) ||
2107         resource == NX_NULL || !server_ip)
2108         return(NX_PTR_ERROR);
2109 
2110     /* Check for invalid total bytes.  */
2111     if (total_bytes == 0)
2112         return(NX_SIZE_ERROR);
2113 
2114     /* Check for appropriate caller.  */
2115     NX_THREADS_ONLY_CALLER_CHECKING
2116 
2117     /* Call actual PUT start routine.  */
2118     status =  _nxd_http_client_put_start(client_ptr, server_ip, resource, username, password,
2119                                          total_bytes, wait_option);
2120 
2121     /* Return completion status.  */
2122     return(status);
2123 }
2124 
2125 
2126 /**************************************************************************/
2127 /*                                                                        */
2128 /*  FUNCTION                                               RELEASE        */
2129 /*                                                                        */
2130 /*    _nxde_http_client_put_start_extended                PORTABLE C      */
2131 /*                                                           6.1          */
2132 /*  AUTHOR                                                                */
2133 /*                                                                        */
2134 /*    Yuxin Zhou, Microsoft Corporation                                   */
2135 /*                                                                        */
2136 /*  DESCRIPTION                                                           */
2137 /*                                                                        */
2138 /*    This function checks for errors in the HTTP Duo Client put start    */
2139 /*        call.                                                           */
2140 /*                                                                        */
2141 /*                                                                        */
2142 /*  INPUT                                                                 */
2143 /*                                                                        */
2144 /*    client_ptr                            Pointer to HTTP client        */
2145 /*    server_ip                             IP duo address of HTTP Server */
2146 /*    resource                              Pointer to resource (URL)     */
2147 /*    resource_length                       Length of resource (URL)      */
2148 /*    username                              Pointer to username           */
2149 /*    username_length                       Length of username            */
2150 /*    password                              Pointer to password           */
2151 /*    password_length                       Length of password            */
2152 /*    total_bytes                           Total bytes to send           */
2153 /*    wait_option                           Suspension option             */
2154 /*                                                                        */
2155 /*  OUTPUT                                                                */
2156 /*                                                                        */
2157 /*    status                                Completion status             */
2158 /*                                                                        */
2159 /*  CALLS                                                                 */
2160 /*                                                                        */
2161 /*    _nxd_http_client_put_start_extended   Actual client put start call  */
2162 /*                                                                        */
2163 /*  CALLED BY                                                             */
2164 /*                                                                        */
2165 /*    Application Code                                                    */
2166 /*                                                                        */
2167 /*  RELEASE HISTORY                                                       */
2168 /*                                                                        */
2169 /*    DATE              NAME                      DESCRIPTION             */
2170 /*                                                                        */
2171 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2172 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2173 /*                                            resulting in version 6.1    */
2174 /*                                                                        */
2175 /**************************************************************************/
_nxde_http_client_put_start_extended(NX_HTTP_CLIENT * client_ptr,NXD_ADDRESS * server_ip,CHAR * resource,UINT resource_length,CHAR * username,UINT username_length,CHAR * password,UINT password_length,ULONG total_bytes,ULONG wait_option)2176 UINT  _nxde_http_client_put_start_extended(NX_HTTP_CLIENT *client_ptr, NXD_ADDRESS *server_ip, CHAR *resource,
2177                                            UINT resource_length, CHAR *username, UINT username_length,
2178                                            CHAR *password, UINT password_length, ULONG total_bytes, ULONG wait_option)
2179 {
2180 
2181 UINT    status;
2182 
2183 
2184     /* Check for invalid input pointers.  */
2185     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID) ||
2186         resource == NX_NULL || !server_ip)
2187         return(NX_PTR_ERROR);
2188 
2189     /* Check for invalid total bytes.  */
2190     if (total_bytes == 0)
2191         return(NX_SIZE_ERROR);
2192 
2193     /* Check for appropriate caller.  */
2194     NX_THREADS_ONLY_CALLER_CHECKING
2195 
2196     /* Call actual PUT start routine.  */
2197     status =  _nxd_http_client_put_start_extended(client_ptr, server_ip, resource, resource_length,
2198                                                   username, username_length, password, password_length,
2199                                                   total_bytes, wait_option);
2200 
2201     /* Return completion status.  */
2202     return(status);
2203 }
2204 
2205 
2206 /**************************************************************************/
2207 /*                                                                        */
2208 /*  FUNCTION                                               RELEASE        */
2209 /*                                                                        */
2210 /*    _nxd_http_client_put_start                          PORTABLE C      */
2211 /*                                                           6.1          */
2212 /*  AUTHOR                                                                */
2213 /*                                                                        */
2214 /*    Yuxin Zhou, Microsoft Corporation                                   */
2215 /*                                                                        */
2216 /*  DESCRIPTION                                                           */
2217 /*                                                                        */
2218 /*    This function processesthe application PUT request. Transferring the*/
2219 /*    specified resource (URL) is started by this routine. The            */
2220 /*    application must call put packet one or more times to transfer      */
2221 /*    the resource contents.                                              */
2222 /*                                                                        */
2223 /*                                                                        */
2224 /*  INPUT                                                                 */
2225 /*                                                                        */
2226 /*    client_ptr                            Pointer to HTTP client        */
2227 /*    server_ip                             IP address of HTTP Server     */
2228 /*    resource                              Pointer to resource (URL)     */
2229 /*    username                              Pointer to username           */
2230 /*    password                              Pointer to password           */
2231 /*    total_bytes                           Total bytes to send           */
2232 /*    wait_option                           Suspension option             */
2233 /*                                                                        */
2234 /*  OUTPUT                                                                */
2235 /*                                                                        */
2236 /*    status                                Completion status             */
2237 /*                                                                        */
2238 /*  CALLS                                                                 */
2239 /*                                                                        */
2240 /*    _nxd_http_client_put_start_extended   Actual client put start call  */
2241 /*    _nx_utility_string_length_check       Check string length           */
2242 /*                                                                        */
2243 /*  CALLED BY                                                             */
2244 /*                                                                        */
2245 /*    Application Code                                                    */
2246 /*                                                                        */
2247 /*  RELEASE HISTORY                                                       */
2248 /*                                                                        */
2249 /*    DATE              NAME                      DESCRIPTION             */
2250 /*                                                                        */
2251 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2252 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2253 /*                                            resulting in version 6.1    */
2254 /*                                                                        */
2255 /**************************************************************************/
_nxd_http_client_put_start(NX_HTTP_CLIENT * client_ptr,NXD_ADDRESS * server_ip,CHAR * resource,CHAR * username,CHAR * password,ULONG total_bytes,ULONG wait_option)2256 UINT  _nxd_http_client_put_start(NX_HTTP_CLIENT *client_ptr, NXD_ADDRESS *server_ip, CHAR *resource,
2257                                  CHAR *username, CHAR *password, ULONG total_bytes, ULONG wait_option)
2258 
2259 {
2260 
2261 UINT resource_length = 0;
2262 UINT username_length = 0;
2263 UINT password_length = 0;
2264 UINT status;
2265 
2266     /* Make sure there is enough room in the destination string.  */
2267     if((username) && (password))
2268     {
2269         if (_nx_utility_string_length_check(username, &username_length, NX_HTTP_MAX_NAME) ||
2270             _nx_utility_string_length_check(password, &password_length, NX_HTTP_MAX_PASSWORD))
2271         {
2272 
2273             /* Error, return to caller.  */
2274             return(NX_HTTP_PASSWORD_TOO_LONG);
2275         }
2276     }
2277 
2278     /* Check resource length.  */
2279     if (_nx_utility_string_length_check(resource, &resource_length, NX_MAX_STRING_LENGTH))
2280     {
2281         return(NX_HTTP_ERROR);
2282     }
2283 
2284     status = _nxd_http_client_put_start_extended(client_ptr, server_ip, resource, resource_length,
2285                                                  username, username_length, password, password_length,
2286                                                  total_bytes, wait_option);
2287 
2288     /* Return status to the caller.  */
2289     return(status);
2290 }
2291 
2292 
2293 /**************************************************************************/
2294 /*                                                                        */
2295 /*  FUNCTION                                               RELEASE        */
2296 /*                                                                        */
2297 /*    _nxd_http_client_put_start_extended                 PORTABLE C      */
2298 /*                                                           6.1.6        */
2299 /*  AUTHOR                                                                */
2300 /*                                                                        */
2301 /*    Yuxin Zhou, Microsoft Corporation                                   */
2302 /*                                                                        */
2303 /*  DESCRIPTION                                                           */
2304 /*                                                                        */
2305 /*    This function processesthe application PUT request. Transferring the*/
2306 /*    specified resource (URL) is started by this routine. The            */
2307 /*    application must call put packet one or more times to transfer      */
2308 /*    the resource contents.                                              */
2309 /*                                                                        */
2310 /*    Note: The strings of resource, username and password must be        */
2311 /*    NULL-terminated and length of each string matches the length        */
2312 /*    specified in the argument list.                                     */
2313 /*                                                                        */
2314 /*                                                                        */
2315 /*  INPUT                                                                 */
2316 /*                                                                        */
2317 /*    client_ptr                            Pointer to HTTP client        */
2318 /*    server_ip                             IP address of HTTP Server     */
2319 /*    resource                              Pointer to resource (URL)     */
2320 /*    resource_length                       Length of resource (URL)      */
2321 /*    username                              Pointer to username           */
2322 /*    username_length                       Length of username            */
2323 /*    password                              Pointer to password           */
2324 /*    password_length                       Length of password            */
2325 /*    total_bytes                           Total bytes to send           */
2326 /*    wait_option                           Suspension option             */
2327 /*                                                                        */
2328 /*  OUTPUT                                                                */
2329 /*                                                                        */
2330 /*    status                                Completion status             */
2331 /*                                                                        */
2332 /*  CALLS                                                                 */
2333 /*                                                                        */
2334 /*    _nx_http_client_base64_encode         Encode username/password      */
2335 /*    _nx_http_client_number_convert        Convert number to ASCII       */
2336 /*    nx_http_client_type_get               Get the HTTP file type        */
2337 /*    nx_packet_allocate                    Allocate a packet             */
2338 /*    nx_packet_data_append                 Append data to packet         */
2339 /*    nx_packet_release                     Release packet                */
2340 /*    nx_tcp_client_socket_bind             Bind client socket to port    */
2341 /*    nxd_tcp_client_socket_connect         Connect to HTTP  Server       */
2342 /*    nx_tcp_socket_disconnect              Disconnect client socket      */
2343 /*    nx_tcp_client_socket_unbind           Unbind client socket          */
2344 /*    nx_tcp_socket_send                    Send request to Server        */
2345 /*    _nx_utility_string_length_check       Check string length           */
2346 /*                                                                        */
2347 /*  CALLED BY                                                             */
2348 /*                                                                        */
2349 /*    Application Code                                                    */
2350 /*                                                                        */
2351 /*  RELEASE HISTORY                                                       */
2352 /*                                                                        */
2353 /*    DATE              NAME                      DESCRIPTION             */
2354 /*                                                                        */
2355 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2356 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
2357 /*                                            verified memcpy use cases,  */
2358 /*                                            resulting in version 6.1    */
2359 /*  04-02-2021     Yuxin Zhou               Modified comment(s), and      */
2360 /*                                            improved the logic of       */
2361 /*                                            parsing base64,             */
2362 /*                                            resulting in version 6.1.6  */
2363 /*                                                                        */
2364 /**************************************************************************/
_nxd_http_client_put_start_extended(NX_HTTP_CLIENT * client_ptr,NXD_ADDRESS * server_ip,CHAR * resource,UINT resource_length,CHAR * username,UINT username_length,CHAR * password,UINT password_length,ULONG total_bytes,ULONG wait_option)2365 UINT  _nxd_http_client_put_start_extended(NX_HTTP_CLIENT *client_ptr, NXD_ADDRESS *server_ip, CHAR *resource,
2366                                           UINT resource_length, CHAR *username, UINT username_length,
2367                                           CHAR *password, UINT password_length, ULONG total_bytes, ULONG wait_option)
2368 
2369 {
2370 
2371 NX_PACKET   *packet_ptr;
2372 CHAR        string1[NX_HTTP_MAX_NAME + NX_HTTP_MAX_PASSWORD + 2];
2373 CHAR        string2[NX_HTTP_MAX_STRING + 1];
2374 CHAR        crlf[2] = {13,10};
2375 UINT        status;
2376 UINT        string1_length;
2377 UINT        string2_length;
2378 UINT        temp_resource_length = 0;
2379 UINT        temp_username_length = 0;
2380 UINT        temp_password_length = 0;
2381 
2382 
2383 
2384     /* Determine if the client is in a ready state.  */
2385     if (client_ptr -> nx_http_client_state != NX_HTTP_CLIENT_STATE_READY)
2386     {
2387 
2388         /* Client not ready, return error.  */
2389         return(NX_HTTP_NOT_READY);
2390     }
2391 
2392     if ((username) && (password))
2393     {
2394 
2395         /* Make sure there is enough room in the destination string.  */
2396         if (_nx_utility_string_length_check(username, &temp_username_length, username_length) ||
2397             _nx_utility_string_length_check(password, &temp_password_length, password_length))
2398         {
2399 
2400             /* Error, return to caller.  */
2401             return(NX_HTTP_USERNAME_TOO_LONG);
2402         }
2403 
2404         /* Validate string length. */
2405         if ((username_length != temp_username_length) ||
2406             (password_length != temp_password_length))
2407         {
2408             return(NX_HTTP_ERROR);
2409         }
2410     }
2411 
2412     /* Check resource length.  */
2413     if (_nx_utility_string_length_check(resource, &temp_resource_length, resource_length))
2414     {
2415         return(NX_HTTP_ERROR);
2416     }
2417 
2418     /* Validate string length. */
2419     if (resource_length != temp_resource_length)
2420     {
2421         return(NX_HTTP_ERROR);
2422     }
2423 
2424     /* Otherwise, attempt to bind the client socket.  */
2425     status =  nx_tcp_client_socket_bind(&(client_ptr -> nx_http_client_socket), NX_ANY_PORT, wait_option);
2426 
2427     /* Check status of the bind.  */
2428     if (status != NX_SUCCESS)
2429     {
2430 
2431         /* Error binding to a port, return to caller.  */
2432         return(status);
2433     }
2434 
2435     /* Connect to the HTTP server.  */
2436 
2437     /* Invoke the 'Duo' (supports IPv6/IPv4) connection call. */
2438     status = nxd_tcp_client_socket_connect(&(client_ptr -> nx_http_client_socket), server_ip,
2439                                              client_ptr -> nx_http_client_connect_port, wait_option);
2440 
2441     /* Check for connection status.  */
2442     if (status != NX_SUCCESS)
2443     {
2444 
2445         /* Error, unbind the port and return an error.  */
2446         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
2447         return(status);
2448     }
2449 
2450     /* At this point we have a connection setup with an HTTP server!  */
2451 
2452     /* Allocate a packet for the PUT message.  */
2453     if (server_ip -> nxd_ip_version == NX_IP_VERSION_V4)
2454     {
2455         status =  nx_packet_allocate(client_ptr -> nx_http_client_packet_pool_ptr, &packet_ptr,
2456                                      NX_IPv4_TCP_PACKET, wait_option);
2457     }
2458     else
2459     {
2460 
2461         status =  nx_packet_allocate(client_ptr -> nx_http_client_packet_pool_ptr, &packet_ptr,
2462                                     NX_IPv6_TCP_PACKET, wait_option);
2463     }
2464 
2465     /* Check allocation status.  */
2466     if (status != NX_SUCCESS)
2467     {
2468 
2469         /* Error, unbind the port and return an error.  */
2470         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
2471         return(status);
2472     }
2473 
2474     /* Build the PUT request.  */
2475     nx_packet_data_append(packet_ptr, "PUT ", 4,
2476                           client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2477 
2478     /* Determine if this is a root directory based URI string. */
2479     if (resource[0] != '/')
2480     {
2481 
2482         /* Then check if this another website e.g. begins with http and has a colon. */
2483         if  (
2484              ((resource[0] == 'h') || (resource[0] == 'H')) &&
2485              ((resource[1] == 't') || (resource[1] == 'T')) &&
2486              ((resource[2] == 't') || (resource[2] == 'T')) &&
2487              ((resource[3] == 'p') || (resource[3] == 'P'))  &&
2488              (resource[4] == ':')
2489             )
2490         {
2491 
2492             /* Yes, ok to send this string as is. */
2493         }
2494         else
2495         {
2496 
2497             /* This URI is a root directory based file but it needs a leading / character.  */
2498             nx_packet_data_append(packet_ptr, "/", 1, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2499         }
2500     }
2501 
2502     /* (Else the URI begins with a '/' and is ok to send as is.) */
2503 
2504     /* Place the resource in the header.  */
2505     nx_packet_data_append(packet_ptr, resource, resource_length,
2506                           client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2507 
2508     /* Place the HTTP version in the header.  */
2509     nx_packet_data_append(packet_ptr, " HTTP/1.0", 9,
2510                           client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2511 
2512     /* Place the end of line character in the header.  */
2513     nx_packet_data_append(packet_ptr, crlf, 2,
2514                           client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2515 
2516     /* Determine if basic authentication is required.  */
2517     if ((username) && (password))
2518     {
2519 
2520         /* Yes, attempt to build basic authentication.  */
2521         nx_packet_data_append(packet_ptr, "Authorization: Basic ", 21,
2522                               client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2523 
2524         /* Encode and append the "name:password" into next.  */
2525 
2526         /* Place the name and password in a single string.  */
2527 
2528         /* Copy the name into the merged string.  */
2529         memcpy(string1, username, username_length); /* Use case of memcpy is verified. */
2530 
2531         /* Insert the colon.  */
2532         string1[username_length] =  ':';
2533 
2534         /* Copy the password into the merged string.  */
2535         memcpy(&string1[username_length + 1], password, password_length); /* Use case of memcpy is verified. */
2536 
2537         /* Make combined string NULL terminated.  */
2538         string1[username_length + password_length + 1] =  NX_NULL;
2539 
2540         /* Now encode the username:password string.  */
2541         _nx_utility_base64_encode((UCHAR *)string1, username_length + password_length + 1, (UCHAR *)string2, sizeof(string2), &string2_length);
2542         nx_packet_data_append(packet_ptr, string2, string2_length,
2543                               client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2544         nx_packet_data_append(packet_ptr, crlf, 2, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2545     }
2546 
2547     /* Now build the content-type entry.  */
2548     nx_packet_data_append(packet_ptr, "Content-Type: ", 14,
2549                           client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2550     string1_length = _nx_http_client_type_get(resource, string1);
2551     nx_packet_data_append(packet_ptr, string1, string1_length, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2552     nx_packet_data_append(packet_ptr, crlf, 2, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2553 
2554     /* Now build the content-length entry.  */
2555     nx_packet_data_append(packet_ptr, "Content-Length: ", 16,
2556                           client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2557     string1_length =  _nx_http_client_number_convert(total_bytes, string1);
2558     nx_packet_data_append(packet_ptr, string1, string1_length, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2559     nx_packet_data_append(packet_ptr, crlf, 2, client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2560 
2561     /* Place an extra cr/lf to signal the end of the HTTP header.  */
2562     nx_packet_data_append(packet_ptr, crlf, 2,
2563                           client_ptr -> nx_http_client_packet_pool_ptr, NX_WAIT_FOREVER);
2564 
2565     /* Now send the packet to the HTTP server.  */
2566     status =  nx_tcp_socket_send(&(client_ptr -> nx_http_client_socket), packet_ptr, wait_option);
2567 
2568     /* Determine if the send was successful.  */
2569     if (status != NX_SUCCESS)
2570     {
2571 
2572         /* No, send was not successful.  */
2573 
2574         /* Release the packet.  */
2575         nx_packet_release(packet_ptr);
2576 
2577         /* Disconnect and unbind the socket.  */
2578         nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
2579         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
2580 
2581         /* Return an error.  */
2582         return(status);
2583     }
2584 
2585     /* Store the total number of bytes to send.  */
2586     client_ptr -> nx_http_client_total_transfer_bytes =     total_bytes;
2587     client_ptr -> nx_http_client_actual_bytes_transferred =  0;
2588 
2589     /* Enter the PUT state.  */
2590     client_ptr -> nx_http_client_state =  NX_HTTP_CLIENT_STATE_PUT;
2591 
2592     /* Return success to the caller.  */
2593     return(NX_SUCCESS);
2594 }
2595 
2596 
2597 /**************************************************************************/
2598 /*                                                                        */
2599 /*  FUNCTION                                               RELEASE        */
2600 /*                                                                        */
2601 /*    _nxe_http_client_put_packet                         PORTABLE C      */
2602 /*                                                           6.1          */
2603 /*  AUTHOR                                                                */
2604 /*                                                                        */
2605 /*    Yuxin Zhou, Microsoft Corporation                                   */
2606 /*                                                                        */
2607 /*  DESCRIPTION                                                           */
2608 /*                                                                        */
2609 /*    This function checks for errors in the HTTP client put packet call. */
2610 /*                                                                        */
2611 /*                                                                        */
2612 /*  INPUT                                                                 */
2613 /*                                                                        */
2614 /*    client_ptr                            Pointer to HTTP client        */
2615 /*    packet_ptr                            Resource data packet pointer  */
2616 /*    wait_option                           Suspension option             */
2617 /*                                                                        */
2618 /*  OUTPUT                                                                */
2619 /*                                                                        */
2620 /*    status                                Completion status             */
2621 /*                                                                        */
2622 /*  CALLS                                                                 */
2623 /*                                                                        */
2624 /*    _nx_http_client_put_packet            Actual client put packet call */
2625 /*                                                                        */
2626 /*  CALLED BY                                                             */
2627 /*                                                                        */
2628 /*    Application Code                                                    */
2629 /*                                                                        */
2630 /*  RELEASE HISTORY                                                       */
2631 /*                                                                        */
2632 /*    DATE              NAME                      DESCRIPTION             */
2633 /*                                                                        */
2634 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2635 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2636 /*                                            resulting in version 6.1    */
2637 /*                                                                        */
2638 /**************************************************************************/
_nxe_http_client_put_packet(NX_HTTP_CLIENT * client_ptr,NX_PACKET * packet_ptr,ULONG wait_option)2639 UINT  _nxe_http_client_put_packet(NX_HTTP_CLIENT *client_ptr, NX_PACKET *packet_ptr, ULONG wait_option)
2640 {
2641 
2642 UINT    status;
2643 
2644 
2645     /* Check for invalid input pointers.  */
2646     if ((client_ptr == NX_NULL) || (client_ptr -> nx_http_client_id != NXD_HTTP_CLIENT_ID) ||
2647         (packet_ptr == NX_NULL))
2648         return(NX_PTR_ERROR);
2649 
2650     /* Check for appropriate caller.  */
2651     NX_THREADS_ONLY_CALLER_CHECKING
2652 
2653     /* Ensure there is enough room for the TCP packet header.  */
2654     if ((packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start) < NX_TCP_PACKET)
2655     {
2656 
2657         /* Return an invalid packet error.  */
2658         return(NX_INVALID_PACKET);
2659     }
2660 
2661     /* Call actual PUT data routine.  */
2662     status =  _nx_http_client_put_packet(client_ptr, packet_ptr, wait_option);
2663 
2664     /* Return completion status.  */
2665     return(status);
2666 }
2667 
2668 
2669 /**************************************************************************/
2670 /*                                                                        */
2671 /*  FUNCTION                                               RELEASE        */
2672 /*                                                                        */
2673 /*    _nx_http_client_put_packet                          PORTABLE C      */
2674 /*                                                           6.1          */
2675 /*  AUTHOR                                                                */
2676 /*                                                                        */
2677 /*    Yuxin Zhou, Microsoft Corporation                                   */
2678 /*                                                                        */
2679 /*  DESCRIPTION                                                           */
2680 /*                                                                        */
2681 /*    This function processes a packet of resource data associated with   */
2682 /*    the previous PUT request.                                           */
2683 /*                                                                        */
2684 /*                                                                        */
2685 /*  INPUT                                                                 */
2686 /*                                                                        */
2687 /*    client_ptr                            Pointer to HTTP client        */
2688 /*    packet_ptr                            Resource data packet pointer  */
2689 /*    wait_option                           Suspension option             */
2690 /*                                                                        */
2691 /*  OUTPUT                                                                */
2692 /*                                                                        */
2693 /*    status                                Completion status             */
2694 /*                                                                        */
2695 /*  CALLS                                                                 */
2696 /*                                                                        */
2697 /*    nx_packet_release                     Release the packet            */
2698 /*    nx_tcp_client_socket_unbind           Unbind the client socket      */
2699 /*    nx_tcp_socket_disconnect              Disconnect form Server        */
2700 /*    nx_tcp_socket_receive                 Receive response from Server  */
2701 /*    nx_tcp_socket_send                    Send resource data packet     */
2702 /*                                                                        */
2703 /*  CALLED BY                                                             */
2704 /*                                                                        */
2705 /*    Application Code                                                    */
2706 /*                                                                        */
2707 /*  RELEASE HISTORY                                                       */
2708 /*                                                                        */
2709 /*    DATE              NAME                      DESCRIPTION             */
2710 /*                                                                        */
2711 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2712 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2713 /*                                            resulting in version 6.1    */
2714 /*                                                                        */
2715 /**************************************************************************/
_nx_http_client_put_packet(NX_HTTP_CLIENT * client_ptr,NX_PACKET * packet_ptr,ULONG wait_option)2716 UINT  _nx_http_client_put_packet(NX_HTTP_CLIENT *client_ptr, NX_PACKET *packet_ptr, ULONG wait_option)
2717 {
2718 
2719 NX_PACKET   *response_packet_ptr;
2720 CHAR        *buffer_ptr;
2721 UINT        length;
2722 UINT        status;
2723 
2724 
2725     /* First, check and see if the client instance is still in the PUT state.  */
2726     if (client_ptr -> nx_http_client_state != NX_HTTP_CLIENT_STATE_PUT)
2727     {
2728 
2729         /* Client not ready, return error.  */
2730         return(NX_HTTP_NOT_READY);
2731     }
2732 
2733     /* Next, check and see if there is a response from the Server.  */
2734     status =  nx_tcp_socket_receive(&(client_ptr -> nx_http_client_socket), &response_packet_ptr, NX_NO_WAIT);
2735 
2736     /* Check for an early response from the Server.  */
2737     if (status == NX_SUCCESS)
2738     {
2739 
2740         /* This is an error condition since the Server should not respond until the PUT is complete.  */
2741 
2742         /* Setup pointer to server response.  */
2743         buffer_ptr =  (CHAR *) response_packet_ptr -> nx_packet_prepend_ptr;
2744 
2745         /* Determine if it is an authentication error.  */
2746         if (((buffer_ptr + 11) < (CHAR *)response_packet_ptr -> nx_packet_append_ptr) &&
2747             (buffer_ptr[9] == '4') && (buffer_ptr[10] == '0') && (buffer_ptr[11] == '1'))
2748         {
2749 
2750             /* Inform caller of an authentication error.  */
2751             status =  NX_HTTP_AUTHENTICATION_ERROR;
2752         }
2753         else
2754         {
2755 
2756             /* Inform caller of general Server failure.  */
2757             status =  NX_HTTP_INCOMPLETE_PUT_ERROR;
2758         }
2759 
2760         /* Release the packet.  */
2761         nx_packet_release(response_packet_ptr);
2762 
2763         /* Disconnect and unbind the socket.  */
2764         nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
2765         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
2766 
2767         /* Return to the READY state.  */
2768         client_ptr -> nx_http_client_state =  NX_HTTP_CLIENT_STATE_READY;
2769 
2770         /* Return error to caller.  */
2771         return(status);
2772     }
2773 
2774     /* Otherwise, determine if the packet length fits in the available bytes to send.  */
2775     if (packet_ptr -> nx_packet_length >
2776             (client_ptr -> nx_http_client_total_transfer_bytes - client_ptr -> nx_http_client_actual_bytes_transferred))
2777     {
2778 
2779         /* Request doesn't fit into the remaining transfer window.  */
2780         return(NX_HTTP_BAD_PACKET_LENGTH);
2781     }
2782 
2783     /* Remember the packet length.  */
2784     length =  packet_ptr -> nx_packet_length;
2785 
2786     /* Now send the packet out.  */
2787     status =  nx_tcp_socket_send(&(client_ptr -> nx_http_client_socket), packet_ptr, wait_option);
2788 
2789     /* Determine if the send was successful.  */
2790     if (status != NX_SUCCESS)
2791     {
2792 
2793         /* No, send was not successful.  */
2794 
2795         /* Release the packet.  */
2796         nx_packet_release(packet_ptr);
2797 
2798         /* Disconnect and unbind the socket.  */
2799         nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
2800         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
2801 
2802         /* Return to the READY state.  */
2803         client_ptr -> nx_http_client_state =  NX_HTTP_CLIENT_STATE_READY;
2804 
2805         /* Return an error.  */
2806         return(status);
2807     }
2808 
2809     /* Otherwise, update the actual bytes transferred.  */
2810     client_ptr ->  nx_http_client_actual_bytes_transferred =  client_ptr ->  nx_http_client_actual_bytes_transferred + length;
2811 
2812     /* Are we finished?  */
2813     if (client_ptr -> nx_http_client_total_transfer_bytes > client_ptr -> nx_http_client_actual_bytes_transferred)
2814     {
2815 
2816         /* No, we are not finished so just return success to the caller.  */
2817         return(NX_SUCCESS);
2818     }
2819 
2820     /* We are finished sending the PUT data.  Now wait for a response from the Server.  */
2821     status =  nx_tcp_socket_receive(&(client_ptr -> nx_http_client_socket), &response_packet_ptr, wait_option);
2822 
2823     if (status != NX_SUCCESS)
2824     {
2825         /* Disconnect and unbind the socket.  */
2826         nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
2827         nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
2828 
2829         /* Return to the READY state.  */
2830         client_ptr -> nx_http_client_state =  NX_HTTP_CLIENT_STATE_READY;
2831 
2832         /* Return status to caller.  */
2833         return(status);
2834     }
2835 
2836 
2837     /* Setup pointer to server response.  */
2838     buffer_ptr =  (CHAR *) response_packet_ptr -> nx_packet_prepend_ptr;
2839 
2840     /* Determine if the request was successful.  */
2841     if (((buffer_ptr + 9) >= (CHAR *) response_packet_ptr -> nx_packet_append_ptr) ||
2842         (buffer_ptr[9] != '2'))
2843     {
2844 
2845         /* Inform caller of a successful completion.  */
2846         status =  NX_HTTP_REQUEST_UNSUCCESSFUL_CODE;
2847     }
2848 
2849     /* Release the packet.  */
2850     nx_packet_release(response_packet_ptr);
2851 
2852     /* Disconnect and unbind the socket.  */
2853     nx_tcp_socket_disconnect(&(client_ptr -> nx_http_client_socket), wait_option);
2854     nx_tcp_client_socket_unbind(&(client_ptr -> nx_http_client_socket));
2855 
2856     /* Return to the READY state.  */
2857     client_ptr -> nx_http_client_state =  NX_HTTP_CLIENT_STATE_READY;
2858 
2859     /* Return status to caller.  */
2860     return(status);
2861 }
2862 
2863 
2864 /**************************************************************************/
2865 /*                                                                        */
2866 /*  FUNCTION                                               RELEASE        */
2867 /*                                                                        */
2868 /*    _nx_http_client_type_get                            PORTABLE C      */
2869 /*                                                           6.1          */
2870 /*  AUTHOR                                                                */
2871 /*                                                                        */
2872 /*    Yuxin Zhou, Microsoft Corporation                                   */
2873 /*                                                                        */
2874 /*  DESCRIPTION                                                           */
2875 /*                                                                        */
2876 /*    This function derives the type of the resource.                     */
2877 /*                                                                        */
2878 /*  INPUT                                                                 */
2879 /*                                                                        */
2880 /*    name                                  Name string                   */
2881 /*    http_type_string                      Destination HTTP type string  */
2882 /*                                                                        */
2883 /*  OUTPUT                                                                */
2884 /*                                                                        */
2885 /*    Size                                  Number of bytes in string     */
2886 /*                                                                        */
2887 /*  CALLS                                                                 */
2888 /*                                                                        */
2889 /*    None                                                                */
2890 /*                                                                        */
2891 /*  CALLED BY                                                             */
2892 /*                                                                        */
2893 /*    _nx_http_client_put_start_extended    Start the PUT process         */
2894 /*                                                                        */
2895 /*  RELEASE HISTORY                                                       */
2896 /*                                                                        */
2897 /*    DATE              NAME                      DESCRIPTION             */
2898 /*                                                                        */
2899 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2900 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2901 /*                                            resulting in version 6.1    */
2902 /*                                                                        */
2903 /**************************************************************************/
_nx_http_client_type_get(CHAR * name,CHAR * http_type_string)2904 UINT  _nx_http_client_type_get(CHAR *name, CHAR *http_type_string)
2905 {
2906 
2907 UINT    i;
2908 
2909 
2910     /* First find the end of the string.  */
2911     i =  0;
2912     while (name[i] != (CHAR) NX_NULL)
2913     {
2914         i++;
2915     }
2916 
2917     /* Now look backwards to find the last period that signals the
2918        file extension.  */
2919     while ((i) && (name[i] != '.'))
2920     {
2921         i--;
2922     }
2923 
2924     /* Position forward again, past the period.  */
2925     i++;
2926 
2927     /* Now see what HTTP file type to return.  */
2928 
2929     /* Check for .txt file extension.  */
2930     if (((name[i] ==   't') || (name[i] ==   'T')) &&
2931         ((name[i+1] == 'x') || (name[i+1] == 'X')) &&
2932         ((name[i+2] == 't') || (name[i+2] == 'T')))
2933     {
2934 
2935         /* Yes, we have a plain text file.  */
2936         http_type_string[0] =  't';
2937         http_type_string[1] =  'e';
2938         http_type_string[2] =  'x';
2939         http_type_string[3] =  't';
2940         http_type_string[4] =  '/';
2941         http_type_string[5] =  'p';
2942         http_type_string[6] =  'l';
2943         http_type_string[7] =  'a';
2944         http_type_string[8] =  'i';
2945         http_type_string[9] =  'n';
2946 
2947         /* Return the size of the HTTP ASCII type string.  */
2948         return(10);
2949     }
2950 
2951     /* Check for .htm[l] file extension.  */
2952     else if (((name[i] ==   'h') || (name[i] ==   'H')) &&
2953         ((name[i+1] == 't') || (name[i+1] == 'T')) &&
2954         ((name[i+2] == 'm') || (name[i+2] == 'M')))
2955     {
2956 
2957         /* Yes, we have an HTML text file.  */
2958         http_type_string[0] =  't';
2959         http_type_string[1] =  'e';
2960         http_type_string[2] =  'x';
2961         http_type_string[3] =  't';
2962         http_type_string[4] =  '/';
2963         http_type_string[5] =  'h';
2964         http_type_string[6] =  't';
2965         http_type_string[7] =  'm';
2966         http_type_string[8] =  'l';
2967 
2968         /* Return the size of the HTTP ASCII type string.  */
2969         return(9);
2970     }
2971 
2972     /* Check for .gif file extension.  */
2973     else if (((name[i] ==   'g') || (name[i] ==   'G')) &&
2974         ((name[i+1] == 'i') || (name[i+1] == 'I')) &&
2975         ((name[i+2] == 'f') || (name[i+2] == 'F')))
2976     {
2977 
2978         /* Yes, we have a GIF image file.  */
2979         http_type_string[0] =  'i';
2980         http_type_string[1] =  'm';
2981         http_type_string[2] =  'a';
2982         http_type_string[3] =  'g';
2983         http_type_string[4] =  'e';
2984         http_type_string[5] =  '/';
2985         http_type_string[6] =  'g';
2986         http_type_string[7] =  'i';
2987         http_type_string[8] =  'f';
2988 
2989         /* Return the size of the HTTP ASCII type string.  */
2990         return(9);
2991     }
2992 
2993     /* Check for .xbm file extension.  */
2994     else if (((name[i] ==   'x') || (name[i] ==   'X')) &&
2995         ((name[i+1] == 'b') || (name[i+1] == 'B')) &&
2996         ((name[i+2] == 'm') || (name[i+2] == 'M')))
2997     {
2998 
2999         /* Yes, we have a x-xbitmap image file.  */
3000         http_type_string[0] =  'i';
3001         http_type_string[1] =  'm';
3002         http_type_string[2] =  'a';
3003         http_type_string[3] =  'g';
3004         http_type_string[4] =  'e';
3005         http_type_string[5] =  '/';
3006         http_type_string[6] =  'x';
3007         http_type_string[7] =  '-';
3008         http_type_string[8] =  'x';
3009         http_type_string[9] =  'b';
3010         http_type_string[10] = 'i';
3011         http_type_string[11] = 't';
3012         http_type_string[12] = 'm';
3013         http_type_string[13] = 'a';
3014         http_type_string[14] = 'p';
3015 
3016         /* Return the size of the HTTP ASCII type string.  */
3017         return(15);
3018     }
3019 
3020     /* Default to plain text.  */
3021     else
3022     {
3023 
3024         /* Default to plain text.  */
3025         http_type_string[0] =  't';
3026         http_type_string[1] =  'e';
3027         http_type_string[2] =  'x';
3028         http_type_string[3] =  't';
3029         http_type_string[4] =  '/';
3030         http_type_string[5] =  'p';
3031         http_type_string[6] =  'l';
3032         http_type_string[7] =  'a';
3033         http_type_string[8] =  'i';
3034         http_type_string[9] =  'n';
3035 
3036         /* Return the size of the HTTP ASCII type string.  */
3037         return(10);
3038     }
3039 }
3040 
3041 
3042 /**************************************************************************/
3043 /*                                                                        */
3044 /*  FUNCTION                                               RELEASE        */
3045 /*                                                                        */
3046 /*    _nx_http_client_content_length_get                  PORTABLE C      */
3047 /*                                                           6.1          */
3048 /*  AUTHOR                                                                */
3049 /*                                                                        */
3050 /*    Yuxin Zhou, Microsoft Corporation                                   */
3051 /*                                                                        */
3052 /*  DESCRIPTION                                                           */
3053 /*                                                                        */
3054 /*    This function returns the content length of the supplied HTTP       */
3055 /*    response packet.  If the packet is no content or the packet is      */
3056 /*    invalid, a zero is returned.                                        */
3057 /*                                                                        */
3058 /*                                                                        */
3059 /*  INPUT                                                                 */
3060 /*                                                                        */
3061 /*    packet_ptr                            Pointer to HTTP request packet*/
3062 /*                                                                        */
3063 /*  OUTPUT                                                                */
3064 /*                                                                        */
3065 /*    length                                Length of content             */
3066 /*                                                                        */
3067 /*  CALLS                                                                 */
3068 /*                                                                        */
3069 /*    None                                                                */
3070 /*                                                                        */
3071 /*  CALLED BY                                                             */
3072 /*                                                                        */
3073 /*    _nx_http_client_get_start             Start the GET operation       */
3074 /*                                                                        */
3075 /*  RELEASE HISTORY                                                       */
3076 /*                                                                        */
3077 /*    DATE              NAME                      DESCRIPTION             */
3078 /*                                                                        */
3079 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3080 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3081 /*                                            resulting in version 6.1    */
3082 /*                                                                        */
3083 /**************************************************************************/
_nx_http_client_content_length_get(NX_PACKET * packet_ptr)3084 UINT  _nx_http_client_content_length_get(NX_PACKET *packet_ptr)
3085 {
3086 
3087 UINT    length;
3088 CHAR   *buffer_ptr;
3089 UINT    found = NX_FALSE;
3090 
3091 
3092     /* Default the content length to an invalid value.  */
3093     length =  0;
3094 
3095     /* Setup pointer to buffer.  */
3096     buffer_ptr = (CHAR *)packet_ptr -> nx_packet_prepend_ptr;
3097 
3098     /* Find the "Content-length:" token first.  */
3099     while ((buffer_ptr+14) < (CHAR *)packet_ptr -> nx_packet_append_ptr)
3100     {
3101 
3102         /* Check for the Content-length token.  */
3103         if (((*buffer_ptr ==      'c') || (*buffer_ptr ==      'C')) &&
3104             ((*(buffer_ptr+1) ==  'o') || (*(buffer_ptr+1) ==  'O')) &&
3105             ((*(buffer_ptr+2) ==  'n') || (*(buffer_ptr+2) ==  'N')) &&
3106             ((*(buffer_ptr+3) ==  't') || (*(buffer_ptr+3) ==  'T')) &&
3107             ((*(buffer_ptr+4) ==  'e') || (*(buffer_ptr+4) ==  'E')) &&
3108             ((*(buffer_ptr+5) ==  'n') || (*(buffer_ptr+5) ==  'N')) &&
3109             ((*(buffer_ptr+6) ==  't') || (*(buffer_ptr+6) ==  'T')) &&
3110             (*(buffer_ptr+7) ==  '-') &&
3111             ((*(buffer_ptr+8) ==  'l') || (*(buffer_ptr+8) ==  'L')) &&
3112             ((*(buffer_ptr+9) ==  'e') || (*(buffer_ptr+9) ==  'E')) &&
3113             ((*(buffer_ptr+10) == 'n') || (*(buffer_ptr+10) == 'N')) &&
3114             ((*(buffer_ptr+11) == 'g') || (*(buffer_ptr+11) == 'G')) &&
3115             ((*(buffer_ptr+12) == 't') || (*(buffer_ptr+12) == 'T')) &&
3116             ((*(buffer_ptr+13) == 'h') || (*(buffer_ptr+13) == 'H')) &&
3117             (*(buffer_ptr+14) == ':'))
3118         {
3119 
3120             /* Yes, found content-length token.  */
3121             found = NX_TRUE;
3122 
3123             /* Move past the Content-Length: field. Exit the loop. */
3124             buffer_ptr += 15;
3125             break;
3126         }
3127 
3128         /* Move the pointer up to the next character.  */
3129         buffer_ptr++;
3130     }
3131 
3132     /* Check if found the content-length token.  */
3133     if (found != NX_TRUE)
3134     {
3135 
3136         /* No, return an invalid length indicating a bad HTTP packet. */
3137         return(length);
3138     }
3139 
3140     /* Now skip over white space. */
3141     while ((buffer_ptr < (CHAR *)packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
3142     {
3143         buffer_ptr++;
3144     }
3145 
3146     /* Now convert the length into a numeric value.  */
3147     while ((buffer_ptr < (CHAR *)packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr >= '0') && (*buffer_ptr <= '9'))
3148     {
3149 
3150         /* Update the content length.  */
3151         length =  length * 10;
3152         length =  length + (((UINT) (*buffer_ptr)) - 0x30);
3153 
3154         /* Move the buffer pointer forward.  */
3155         buffer_ptr++;
3156     }
3157 
3158     /* Determine if the content length was picked up properly.  */
3159     if ((buffer_ptr >= (CHAR *)packet_ptr -> nx_packet_append_ptr) ||
3160         ((*buffer_ptr != ' ') && (*buffer_ptr != (CHAR)13)))
3161     {
3162 
3163         /* Error, set the length to zero.  */
3164         length =  0;
3165     }
3166 
3167     /* Return the length to the caller.  */
3168     return(length);
3169 }
3170 
3171 
3172 /**************************************************************************/
3173 /*                                                                        */
3174 /*  FUNCTION                                               RELEASE        */
3175 /*                                                                        */
3176 /*    _nx_http_client_calculate_content_offset            PORTABLE C      */
3177 /*                                                           6.1          */
3178 /*  AUTHOR                                                                */
3179 /*                                                                        */
3180 /*    Yuxin Zhou, Microsoft Corporation                                   */
3181 /*                                                                        */
3182 /*  DESCRIPTION                                                           */
3183 /*                                                                        */
3184 /*    This function calculates the byte offset to the start of the        */
3185 /*    HTTP request content area.  This area immediately follows the HTTP  */
3186 /*    request header (which ends with a blank line).                      */
3187 /*                                                                        */
3188 /*                                                                        */
3189 /*  INPUT                                                                 */
3190 /*                                                                        */
3191 /*    packet_ptr                            Pointer to request packet     */
3192 /*                                                                        */
3193 /*  OUTPUT                                                                */
3194 /*                                                                        */
3195 /*    Byte Offset                           (0 implies no content)        */
3196 /*                                                                        */
3197 /*  CALLS                                                                 */
3198 /*                                                                        */
3199 /*    None                                                                */
3200 /*                                                                        */
3201 /*  CALLED BY                                                             */
3202 /*                                                                        */
3203 /*    _nx_http_client_get_start             Start GET processing          */
3204 /*                                                                        */
3205 /*  RELEASE HISTORY                                                       */
3206 /*                                                                        */
3207 /*    DATE              NAME                      DESCRIPTION             */
3208 /*                                                                        */
3209 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3210 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3211 /*                                            resulting in version 6.1    */
3212 /*                                                                        */
3213 /**************************************************************************/
_nx_http_client_calculate_content_offset(NX_PACKET * packet_ptr)3214 UINT  _nx_http_client_calculate_content_offset(NX_PACKET *packet_ptr)
3215 {
3216 
3217 UINT    offset;
3218 CHAR    *buffer_ptr;
3219 
3220 
3221     /* Default the content offset to zero.  */
3222     offset =  0;
3223 
3224     /* Setup pointer to buffer.  */
3225     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
3226 
3227     /* Find the "cr,lf,cr,lf" token.  */
3228     while (((buffer_ptr+3) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
3229     {
3230 
3231         /* Check for the <cr,lf,cr,lf> token.  This signals a blank line, which also
3232            specifies the start of the content.  */
3233         if ((*buffer_ptr ==      (CHAR) 13) &&
3234             (*(buffer_ptr+1) ==  (CHAR) 10) &&
3235             (*(buffer_ptr+2) ==  (CHAR) 13) &&
3236             (*(buffer_ptr+3) ==  (CHAR) 10))
3237         {
3238 
3239             /* Adjust the offset.  */
3240             offset =  offset + 4;
3241             break;
3242         }
3243 
3244         /* Move the pointer up to the next character.  */
3245         buffer_ptr++;
3246 
3247         /* Increment the offset.  */
3248         offset++;
3249     }
3250 
3251     /* Return the offset to the caller.  */
3252     return(offset);
3253 }
3254 
3255 
3256 /**************************************************************************/
3257 /*                                                                        */
3258 /*  FUNCTION                                               RELEASE        */
3259 /*                                                                        */
3260 /*    _nx_http_client_number_convert                      PORTABLE C      */
3261 /*                                                           6.1          */
3262 /*  AUTHOR                                                                */
3263 /*                                                                        */
3264 /*    Yuxin Zhou, Microsoft Corporation                                   */
3265 /*                                                                        */
3266 /*  DESCRIPTION                                                           */
3267 /*                                                                        */
3268 /*    This function converts a number into an ASCII string.               */
3269 /*                                                                        */
3270 /*  INPUT                                                                 */
3271 /*                                                                        */
3272 /*    number                                Unsigned integer number       */
3273 /*    string                                Destination string            */
3274 /*                                                                        */
3275 /*  OUTPUT                                                                */
3276 /*                                                                        */
3277 /*    Size                                  Number of bytes in string     */
3278 /*                                           (0 implies an error)         */
3279 /*                                                                        */
3280 /*  CALLS                                                                 */
3281 /*                                                                        */
3282 /*    None                                                                */
3283 /*                                                                        */
3284 /*  CALLED BY                                                             */
3285 /*                                                                        */
3286 /*    _nx_http_client_get_start_extended    Start GET processing          */
3287 /*    _nx_http_client_put_start_extended    Start PUT processing          */
3288 /*                                                                        */
3289 /*  RELEASE HISTORY                                                       */
3290 /*                                                                        */
3291 /*    DATE              NAME                      DESCRIPTION             */
3292 /*                                                                        */
3293 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3294 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3295 /*                                            resulting in version 6.1    */
3296 /*                                                                        */
3297 /**************************************************************************/
_nx_http_client_number_convert(UINT number,CHAR * string)3298 UINT  _nx_http_client_number_convert(UINT number, CHAR *string)
3299 {
3300 
3301 UINT    j;
3302 UINT    digit;
3303 UINT    size;
3304 
3305 
3306     /* Default string to return '0'.  */
3307     string[0] = '0';
3308 
3309     /* Initialize counters.  */
3310     size =  0;
3311 
3312     /* Loop to convert the number to ASCII.  */
3313     while ((size < 10) && (number))
3314     {
3315 
3316         /* Shift the current digits over one.  */
3317         for (j = size; j != 0; j--)
3318         {
3319 
3320             /* Move each digit over one place.  */
3321             string[j] =  string[j-1];
3322         }
3323 
3324         /* Compute the next decimal digit.  */
3325         digit =  number % 10;
3326 
3327         /* Update the input number.  */
3328         number =  number / 10;
3329 
3330         /* Store the new digit in ASCII form.  */
3331         string[0] =  (CHAR) (digit + 0x30);
3332 
3333         /* Increment the size.  */
3334         size++;
3335     }
3336 
3337     /* Make the string NULL terminated.  */
3338     string[size] =  (CHAR) NX_NULL;
3339 
3340     /* Determine if there is an overflow error.  */
3341     if (number)
3342     {
3343 
3344         /* Error, return bad values to user.  */
3345         size =  0;
3346         string[0] = '0';
3347     }
3348 
3349     /* Return size to caller.  */
3350     return(size);
3351 }
3352