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