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