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 #include    "nx_api.h"
35 #include    "nx_ip.h"
36 #include    "nxd_http_server.h"
37 #include    "stdio.h"
38 #include    "string.h"
39 #ifdef NX_HTTP_DIGEST_ENABLE
40 #include   "nx_md5.h"
41 #endif
42 
43 #ifdef  NX_HTTP_DIGEST_ENABLE
44 
45 /* Use for mapping random nonces to printable characters.  */
46 static CHAR _nx_http_server_base64_array[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
47 #endif
48 
49 /* Define date strings. */
50 const CHAR *_nx_http_server_weekday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
51 const CHAR *_nx_http_server_month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
52 
53 /* Define basic MIME maps. */
54 static NX_HTTP_SERVER_MIME_MAP _nx_http_server_mime_maps[] =
55 {
56     {"html",     "text/html"},
57     {"htm",      "text/html"},
58     {"txt",      "text/plain"},
59     {"gif",      "image/gif"},
60     {"jpg",      "image/jpeg"},
61     {"ico",      "image/x-icon"},
62 };
63 
64 
65 /* Create two arrays to hold encoded and decoded username/password data. */
66 static CHAR  authorization_request[NX_HTTP_MAX_STRING + 1];
67 static CHAR  authorization_decoded[NX_HTTP_MAX_NAME + NX_HTTP_MAX_PASSWORD + 2];
68 
69 /* Bring in externs for caller checking code.  */
70 
71 NX_CALLER_CHECKING_EXTERNS
72 
73 
74 /**************************************************************************/
75 /*                                                                        */
76 /*  FUNCTION                                               RELEASE        */
77 /*                                                                        */
78 /*    _nxe_http_server_content_get                        PORTABLE C      */
79 /*                                                           6.1          */
80 /*  AUTHOR                                                                */
81 /*                                                                        */
82 /*    Yuxin Zhou, Microsoft Corporation                                   */
83 /*                                                                        */
84 /*  DESCRIPTION                                                           */
85 /*                                                                        */
86 /*    This function checks for errors in the HTTP content get call.       */
87 /*                                                                        */
88 /*                                                                        */
89 /*  INPUT                                                                 */
90 /*                                                                        */
91 /*    server_ptr                            Pointer to HTTP server        */
92 /*    packet_ptr                            Pointer to HTTP request packet*/
93 /*    byte_offset                           Byte offset into content      */
94 /*    destination_ptr                       Pointer to content destination*/
95 /*    destination_size                      Maximum size of destination   */
96 /*    actual_size                           Actual amount of content      */
97 /*                                                                        */
98 /*  OUTPUT                                                                */
99 /*                                                                        */
100 /*    status                                Completion status             */
101 /*                                                                        */
102 /*  CALLS                                                                 */
103 /*                                                                        */
104 /*    _nx_http_server_content_get           Actual server content get call*/
105 /*                                                                        */
106 /*  CALLED BY                                                             */
107 /*                                                                        */
108 /*    Application Code                                                    */
109 /*                                                                        */
110 /*  RELEASE HISTORY                                                       */
111 /*                                                                        */
112 /*    DATE              NAME                      DESCRIPTION             */
113 /*                                                                        */
114 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
115 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
116 /*                                            resulting in version 6.1    */
117 /*                                                                        */
118 /**************************************************************************/
_nxe_http_server_content_get(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,ULONG byte_offset,CHAR * destination_ptr,UINT destination_size,UINT * actual_size)119 UINT  _nxe_http_server_content_get(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, ULONG byte_offset, CHAR *destination_ptr, UINT destination_size, UINT *actual_size)
120 {
121 
122 UINT    status;
123 
124 
125     /* Check for invalid input pointers.  */
126     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) ||
127         (packet_ptr == NX_NULL) || (destination_ptr == NX_NULL) || (actual_size == NX_NULL))
128         return(NX_PTR_ERROR);
129 
130     /* Check for appropriate caller.  */
131     NX_THREADS_ONLY_CALLER_CHECKING
132 
133     /* Call actual server content get function.  */
134     status =  _nx_http_server_content_get(server_ptr, packet_ptr, byte_offset, destination_ptr, destination_size, actual_size);
135 
136     /* Return completion status.  */
137     return(status);
138 }
139 
140 
141 /**************************************************************************/
142 /*                                                                        */
143 /*  FUNCTION                                               RELEASE        */
144 /*                                                                        */
145 /*    _nx_http_server_content_get                         PORTABLE C      */
146 /*                                                           6.1          */
147 /*  AUTHOR                                                                */
148 /*                                                                        */
149 /*    Yuxin Zhou, Microsoft Corporation                                   */
150 /*                                                                        */
151 /*  DESCRIPTION                                                           */
152 /*                                                                        */
153 /*    This function returns the user's specified portion of the HTTP      */
154 /*    content. Content is typically included in POST and PUT requests     */
155 /*    from the client. This routine is designed to be called from the     */
156 /*    application's request notify callback.                              */
157 /*                                                                        */
158 /*                                                                        */
159 /*  INPUT                                                                 */
160 /*                                                                        */
161 /*    server_ptr                            Pointer to HTTP server        */
162 /*    packet_ptr                            Pointer to HTTP request packet*/
163 /*    byte_offset                           Byte offset into content      */
164 /*    destination_ptr                       Pointer to content destination*/
165 /*    destination_size                      Maximum size of destination   */
166 /*    actual_size                           Actual amount of content      */
167 /*                                                                        */
168 /*  OUTPUT                                                                */
169 /*                                                                        */
170 /*    status                                Completion status             */
171 /*                                                                        */
172 /*  CALLS                                                                 */
173 /*                                                                        */
174 /*    nx_tcp_socket_receive                 Receive another packet        */
175 /*    _nx_http_server_content_length_get    Pickup the content length     */
176 /*    _nx_http_server_calculate_content_offset Pickup content offset      */
177 /*                                                                        */
178 /*  CALLED BY                                                             */
179 /*                                                                        */
180 /*    Application Code                                                    */
181 /*                                                                        */
182 /*  RELEASE HISTORY                                                       */
183 /*                                                                        */
184 /*    DATE              NAME                      DESCRIPTION             */
185 /*                                                                        */
186 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
187 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
188 /*                                            resulting in version 6.1    */
189 /*                                                                        */
190 /**************************************************************************/
_nx_http_server_content_get(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,ULONG byte_offset,CHAR * destination_ptr,UINT destination_size,UINT * actual_size)191 UINT  _nx_http_server_content_get(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, ULONG byte_offset, CHAR *destination_ptr, UINT destination_size, UINT *actual_size)
192 {
193 
194 ULONG       content_length;
195 ULONG       get_offset;
196 ULONG       offset;
197 #ifndef NX_DISABLE_PACKET_CHAIN
198 UINT        status;
199 #endif /* NX_DISABLE_PACKET_CHAIN */
200 UINT        remaining_bytes;
201 NX_PACKET   *new_packet_ptr;
202 CHAR        *buffer_ptr;
203 
204 
205     /* Default the actual size to zero.  */
206     *actual_size =  0;
207 
208     /* Determine if there is content in this HTTP request.  */
209     content_length =  (ULONG) _nx_http_server_content_length_get(packet_ptr);
210 
211     /* Make sure the content length is at least greater than the byte offset supplied.  */
212     if (content_length <= byte_offset)
213     {
214 
215         /* No more data in this buffer.  */
216         return(NX_HTTP_DATA_END);
217     }
218 
219     /* Determine if the destination size is greater than the content length.  */
220     if (destination_size > content_length)
221     {
222 
223         /* Yes, make the destination size equal to the content length.  */
224         destination_size =  content_length;
225     }
226 
227     /* Calculate the offset to the requested content area.  */
228     get_offset =  ((ULONG) _nx_http_server_calculate_content_offset(packet_ptr)) + byte_offset;
229 
230     /* Determine if we need to read one or more additional packets.  */
231     while (get_offset >= packet_ptr -> nx_packet_length)
232     {
233 
234 #ifdef NX_DISABLE_PACKET_CHAIN
235         NX_PARAMETER_NOT_USED(server_ptr);
236 
237         return NX_HTTP_ERROR;
238 #else
239         /* Read another packet because the offset reaches past the current packet
240            length.  */
241         status =  nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), &new_packet_ptr, NX_HTTP_SERVER_TIMEOUT_RECEIVE);
242 
243         /* Check the return status.  */
244         if (status != NX_SUCCESS)
245         {
246 
247             /* Error, return to caller.  */
248             return(NX_HTTP_TIMEOUT);
249         }
250 
251         /* Otherwise, we have a new packet to append to the head packet.  */
252 
253         /* Determine if the current packet is already chained.  */
254         if (packet_ptr -> nx_packet_next)
255         {
256 
257             /* Yes, link the current last packet to the new packet.  */
258             (packet_ptr -> nx_packet_last) -> nx_packet_next =  new_packet_ptr;
259         }
260         else
261         {
262 
263             /* Otherwise, this is our first chained packet.  Link to the head.  */
264             packet_ptr -> nx_packet_next =  new_packet_ptr;
265         }
266 
267         /* Is the new packet chained?  */
268         if (new_packet_ptr -> nx_packet_next)
269         {
270 
271             /* Yes, there is a last packet pointer.  Point to this from the head packet.  */
272             packet_ptr -> nx_packet_last =  new_packet_ptr -> nx_packet_last;
273         }
274         else
275         {
276 
277             /* No, there isn't a last packet pointer.  Point to new packet from the head packet.  */
278             packet_ptr -> nx_packet_last =  new_packet_ptr;
279         }
280 
281         /* Update the packet length.  */
282         packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length + new_packet_ptr -> nx_packet_length;
283 #endif /* NX_DISABLE_PACKET_CHAIN */
284     }
285 
286     /* Default the buffer pointer to NULL.  */
287     buffer_ptr =  NX_NULL;
288 
289     /* Now find the packet that contains the offset.  */
290     offset =  0;
291     new_packet_ptr =  packet_ptr;
292     do
293     {
294 
295         /* Determine if the get request falls into this packet.  */
296         if (get_offset < (offset + (ULONG)(new_packet_ptr -> nx_packet_append_ptr - new_packet_ptr -> nx_packet_prepend_ptr)))
297         {
298 
299             /* Yes, the get offset is in this packet.  */
300 
301             /* Setup the starting byte pointer.  */
302             buffer_ptr =  ((CHAR *) new_packet_ptr -> nx_packet_prepend_ptr) + (get_offset - offset);
303             break;
304         }
305 
306         /* Otherwise update the offset.  */
307         offset =  offset + (ULONG)(new_packet_ptr -> nx_packet_append_ptr - new_packet_ptr -> nx_packet_prepend_ptr);
308 
309 #ifdef NX_DISABLE_PACKET_CHAIN
310         new_packet_ptr =  NX_NULL;
311 #else
312         /* Move to next packet in the chain.  */
313         new_packet_ptr =  new_packet_ptr -> nx_packet_next;
314 #endif /* NX_DISABLE_PACKET_CHAIN */
315 
316     } while (new_packet_ptr);
317 
318     /* Determine if an error occurred in the search.  */
319     if ((buffer_ptr == (CHAR *) NX_NULL) || (new_packet_ptr == NX_NULL))
320         return(NX_HTTP_ERROR);
321 
322     /* Now determine if the maximum buffer size has to be adjusted.  */
323     if (destination_size > (UINT) (new_packet_ptr -> nx_packet_append_ptr - (UCHAR *) buffer_ptr))
324     {
325 
326         /* Adjust the destination size downward.  */
327         destination_size =  (UINT) (new_packet_ptr -> nx_packet_append_ptr - (UCHAR *) buffer_ptr);
328     }
329 
330     /* Initialize the remaining bytes.  */
331     remaining_bytes =  destination_size;
332 
333     /* Otherwise copy the bytes from the offset to the end of the packet pointer.  */
334     while (remaining_bytes--)
335     {
336 
337         /* Copy a byte to the destination.  */
338         *destination_ptr++ =  *buffer_ptr++;
339     }
340 
341     /* Successful completion.  */
342     *actual_size =  destination_size;
343     return(NX_SUCCESS);
344 }
345 
346 
347 
348 
349 /**************************************************************************/
350 /*                                                                        */
351 /*  FUNCTION                                               RELEASE        */
352 /*                                                                        */
353 /*    _nxe_http_server_packet_content_find                PORTABLE C      */
354 /*                                                           6.1          */
355 /*  AUTHOR                                                                */
356 /*                                                                        */
357 /*    Yuxin Zhou, Microsoft Corporation                                   */
358 /*                                                                        */
359 /*  DESCRIPTION                                                           */
360 /*                                                                        */
361 /*    This function checks for errors in the HTTP packet content find     */
362 /*    call.                                                               */
363 /*                                                                        */
364 /*                                                                        */
365 /*  INPUT                                                                 */
366 /*                                                                        */
367 /*    server_ptr                            Pointer to HTTP server        */
368 /*    packet_ptr                            Pointer to pointer to the     */
369 /*                                            packet that contains the    */
370 /*                                            HTTP header                 */
371 /*    content_length                        Pointer to content length     */
372 /*                                                                        */
373 /*  OUTPUT                                                                */
374 /*                                                                        */
375 /*    status                                Completion status             */
376 /*                                                                        */
377 /*  CALLS                                                                 */
378 /*                                                                        */
379 /*    _nx_http_server_packet_content_find   Actual server packet content  */
380 /*                                            find call                   */
381 /*                                                                        */
382 /*  CALLED BY                                                             */
383 /*                                                                        */
384 /*    Application Code                                                    */
385 /*                                                                        */
386 /*  RELEASE HISTORY                                                       */
387 /*                                                                        */
388 /*    DATE              NAME                      DESCRIPTION             */
389 /*                                                                        */
390 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
391 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
392 /*                                            resulting in version 6.1    */
393 /*                                                                        */
394 /**************************************************************************/
_nxe_http_server_packet_content_find(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr,ULONG * content_length)395 UINT  _nxe_http_server_packet_content_find(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr, ULONG *content_length)
396 {
397 
398 
399     /* Check for invalid packet pointer.  */
400     if((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) ||
401        (packet_ptr == NX_NULL) || (*packet_ptr == NX_NULL))
402         return(NX_PTR_ERROR);
403 
404     /* Call actual server content length get function.  */
405     return(_nx_http_server_packet_content_find(server_ptr, packet_ptr, content_length));
406 
407 }
408 
409 /**************************************************************************/
410 /*                                                                        */
411 /*  FUNCTION                                               RELEASE        */
412 /*                                                                        */
413 /*    _nx_http_server_packet_content_find                 PORTABLE C      */
414 /*                                                           6.1          */
415 /*  AUTHOR                                                                */
416 /*                                                                        */
417 /*    Yuxin Zhou, Microsoft Corporation                                   */
418 /*                                                                        */
419 /*  DESCRIPTION                                                           */
420 /*                                                                        */
421 /*    This function finds the content length specified in the HTTP        */
422 /*    header, and move the nx_packet_prepend_ptr to the beginning of      */
423 /*    the content.  If the beginning of the content is not in the packet, */
424 /*    this function attempts to read the HTTP server socket for the       */
425 /*    next packet.                                                        */
426 /*                                                                        */
427 /*                                                                        */
428 /*  INPUT                                                                 */
429 /*                                                                        */
430 /*    server_ptr                            Pointer to HTTP server        */
431 /*    packet_ptr                            Pointer to pointer to the     */
432 /*                                            packet that contains the    */
433 /*                                            HTTP header                 */
434 /*    content_length                        Pointer to content length     */
435 /*                                                                        */
436 /*  OUTPUT                                                                */
437 /*                                                                        */
438 /*    status                                Completion status             */
439 /*                                                                        */
440 /*  CALLS                                                                 */
441 /*                                                                        */
442 /*    nx_tcp_socket_receive                 Receive another packet        */
443 /*    _nx_http_server_calculate_content_offset Pickup content offset      */
444 /*    nx_packet_release                     Release the packet            */
445 /*                                                                        */
446 /*  CALLED BY                                                             */
447 /*                                                                        */
448 /*    Application Code                                                    */
449 /*                                                                        */
450 /*  RELEASE HISTORY                                                       */
451 /*                                                                        */
452 /*    DATE              NAME                      DESCRIPTION             */
453 /*                                                                        */
454 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
455 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
456 /*                                            resulting in version 6.1    */
457 /*                                                                        */
458 /**************************************************************************/
_nx_http_server_packet_content_find(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr,ULONG * content_length)459 UINT  _nx_http_server_packet_content_find(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr, ULONG *content_length)
460 {
461 
462 ULONG       get_offset;
463 UINT        status;
464 
465     /* Determine if there is content in this HTTP request.  */
466     if(content_length)
467         *content_length =  (ULONG) _nx_http_server_content_length_get(*packet_ptr);
468 
469 
470     get_offset = (ULONG)_nx_http_server_calculate_content_offset(*packet_ptr);
471 
472     while((*packet_ptr) -> nx_packet_length <= get_offset)
473     {
474         /* Data is not present in this packet. So we have to read the next packet from the socket. */
475         get_offset -= (*packet_ptr) -> nx_packet_length;
476 
477         /* Release this packet. */
478         nx_packet_release(*packet_ptr);
479 
480         /* Make the receive call to obtain the next packet. */
481         status = nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), packet_ptr, NX_HTTP_SERVER_TIMEOUT_RECEIVE);
482 
483         if(status != NX_SUCCESS)
484         {
485             return(NX_HTTP_TIMEOUT);
486         }
487 
488     }
489 
490     (*packet_ptr) -> nx_packet_prepend_ptr += get_offset;
491     (*packet_ptr) -> nx_packet_length -= get_offset;
492 
493 
494     return(NX_SUCCESS);
495 }
496 
497 
498 /**************************************************************************/
499 /*                                                                        */
500 /*  FUNCTION                                               RELEASE        */
501 /*                                                                        */
502 /*    _nxe_http_server_packet_get                         PORTABLE C      */
503 /*                                                           6.1          */
504 /*  AUTHOR                                                                */
505 /*                                                                        */
506 /*    Yuxin Zhou, Microsoft Corporation                                   */
507 /*                                                                        */
508 /*  DESCRIPTION                                                           */
509 /*                                                                        */
510 /*    This function checks for errors in the HTTP server packet get call. */
511 /*                                                                        */
512 /*                                                                        */
513 /*  INPUT                                                                 */
514 /*                                                                        */
515 /*    server_ptr                            Pointer to HTTP server        */
516 /*    packet_ptr                            Pointer to the packet to      */
517 /*                                            be returned.                */
518 /*                                                                        */
519 /*  OUTPUT                                                                */
520 /*                                                                        */
521 /*    status                                Completion status             */
522 /*                                                                        */
523 /*  CALLS                                                                 */
524 /*                                                                        */
525 /*    _nx_http_server_packet_get            Actual server packet get call */
526 /*                                                                        */
527 /*  CALLED BY                                                             */
528 /*                                                                        */
529 /*    Application Code                                                    */
530 /*                                                                        */
531 /*  RELEASE HISTORY                                                       */
532 /*                                                                        */
533 /*    DATE              NAME                      DESCRIPTION             */
534 /*                                                                        */
535 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
536 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
537 /*                                            resulting in version 6.1    */
538 /*                                                                        */
539 /**************************************************************************/
_nxe_http_server_packet_get(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr)540 UINT  _nxe_http_server_packet_get(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr)
541 {
542 
543 
544     /* Check for invalid packet pointer.  */
545     if((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) ||
546        (packet_ptr == NX_NULL))
547         return(NX_PTR_ERROR);
548 
549     /* Call actual server content length get function.  */
550     return(_nx_http_server_packet_get(server_ptr, packet_ptr));
551 
552 }
553 
554 
555 /**************************************************************************/
556 /*                                                                        */
557 /*  FUNCTION                                               RELEASE        */
558 /*                                                                        */
559 /*    _nx_http_server_packet_get                          PORTABLE C      */
560 /*                                                           6.1          */
561 /*  AUTHOR                                                                */
562 /*                                                                        */
563 /*    Yuxin Zhou, Microsoft Corporation                                   */
564 /*                                                                        */
565 /*  DESCRIPTION                                                           */
566 /*                                                                        */
567 /*    This function obtains the next packet from the HTTP server socket.  */
568 /*                                                                        */
569 /*                                                                        */
570 /*  INPUT                                                                 */
571 /*                                                                        */
572 /*    server_ptr                            Pointer to HTTP server        */
573 /*    packet_ptr                            Pointer to the packet to      */
574 /*                                            be returned.                */
575 /*                                                                        */
576 /*  OUTPUT                                                                */
577 /*                                                                        */
578 /*    status                                Completion status             */
579 /*                                                                        */
580 /*  CALLS                                                                 */
581 /*                                                                        */
582 /*    nx_tcp_socket_receive                 Receive another packet        */
583 /*    nx_packet_release                     Packet release                */
584 /*                                                                        */
585 /*  CALLED BY                                                             */
586 /*                                                                        */
587 /*    Application Code                                                    */
588 /*                                                                        */
589 /*  RELEASE HISTORY                                                       */
590 /*                                                                        */
591 /*    DATE              NAME                      DESCRIPTION             */
592 /*                                                                        */
593 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
594 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
595 /*                                            resulting in version 6.1    */
596 /*                                                                        */
597 /**************************************************************************/
_nx_http_server_packet_get(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr)598 UINT _nx_http_server_packet_get(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr)
599 {
600 NX_PACKET *new_packet_ptr;
601 UINT       status;
602 
603     status =  nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), &new_packet_ptr, NX_HTTP_SERVER_TIMEOUT_RECEIVE);
604 
605     /* Check the return status.  */
606     if (status != NX_SUCCESS)
607     {
608 
609         /* Error, return to caller.  */
610         return(NX_HTTP_TIMEOUT);
611     }
612 
613     *packet_ptr = new_packet_ptr;
614 
615     return(NX_SUCCESS);
616 
617 }
618 
619 
620 /**************************************************************************/
621 /*                                                                        */
622 /*  FUNCTION                                               RELEASE        */
623 /*                                                                        */
624 /*    _nxe_http_server_content_length_get                 PORTABLE C      */
625 /*                                                           6.1          */
626 /*  AUTHOR                                                                */
627 /*                                                                        */
628 /*    Yuxin Zhou, Microsoft Corporation                                   */
629 /*                                                                        */
630 /*  DESCRIPTION                                                           */
631 /*                                                                        */
632 /*    This function checks for errors in the HTTP content length get      */
633 /*    call.                                                               */
634 /*                                                                        */
635 /*                                                                        */
636 /*  INPUT                                                                 */
637 /*                                                                        */
638 /*    packet_ptr                            Pointer to HTTP request packet*/
639 /*                                                                        */
640 /*  OUTPUT                                                                */
641 /*                                                                        */
642 /*    status                                Completion status             */
643 /*                                                                        */
644 /*  CALLS                                                                 */
645 /*                                                                        */
646 /*    _nx_http_server_content_length_get    Actual server content length  */
647 /*                                            call                        */
648 /*                                                                        */
649 /*  CALLED BY                                                             */
650 /*                                                                        */
651 /*    Application Code                                                    */
652 /*                                                                        */
653 /*  RELEASE HISTORY                                                       */
654 /*                                                                        */
655 /*    DATE              NAME                      DESCRIPTION             */
656 /*                                                                        */
657 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
658 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
659 /*                                            resulting in version 6.1    */
660 /*                                                                        */
661 /**************************************************************************/
_nxe_http_server_content_length_get(NX_PACKET * packet_ptr)662 UINT  _nxe_http_server_content_length_get(NX_PACKET *packet_ptr)
663 {
664 
665 UINT    length;
666 
667     /* Check for invalid packet pointer.  */
668     if (packet_ptr == NX_NULL)
669         return(0);
670 
671     /* Call actual server content length get function.  */
672     length =  _nx_http_server_content_length_get(packet_ptr);
673 
674     /* Return the length.  */
675     return(length);
676 }
677 
678 
679 /**************************************************************************/
680 /*                                                                        */
681 /*  FUNCTION                                               RELEASE        */
682 /*                                                                        */
683 /*    _nx_http_server_content_length_get                  PORTABLE C      */
684 /*                                                           6.1          */
685 /*  AUTHOR                                                                */
686 /*                                                                        */
687 /*    Yuxin Zhou, Microsoft Corporation                                   */
688 /*                                                                        */
689 /*  DESCRIPTION                                                           */
690 /*                                                                        */
691 /*    This function returns the content length of the supplied HTTP       */
692 /*    request packet.  If the packet is no content or the packet is       */
693 /*    invalid, a zero is returned.                                        */
694 /*                                                                        */
695 /*                                                                        */
696 /*  INPUT                                                                 */
697 /*                                                                        */
698 /*    packet_ptr                            Pointer to HTTP request packet*/
699 /*                                                                        */
700 /*  OUTPUT                                                                */
701 /*                                                                        */
702 /*    length                                Length of content             */
703 /*                                                                        */
704 /*  CALLS                                                                 */
705 /*                                                                        */
706 /*    None                                                                */
707 /*                                                                        */
708 /*  CALLED BY                                                             */
709 /*                                                                        */
710 /*    Application Code                                                    */
711 /*                                                                        */
712 /*  RELEASE HISTORY                                                       */
713 /*                                                                        */
714 /*    DATE              NAME                      DESCRIPTION             */
715 /*                                                                        */
716 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
717 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
718 /*                                            resulting in version 6.1    */
719 /*                                                                        */
720 /**************************************************************************/
_nx_http_server_content_length_get(NX_PACKET * packet_ptr)721 UINT  _nx_http_server_content_length_get(NX_PACKET *packet_ptr)
722 {
723 
724 UINT    length;
725 CHAR    *buffer_ptr;
726 
727 
728     /* Default the content length to zero.  */
729     length =  0;
730 
731     /* Setup pointer to buffer.  */
732     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
733 
734     /* Find the "Content-length: " token first.  */
735     while (((buffer_ptr+17) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
736     {
737 
738         /* Check for the Content-length token.  */
739         if (((*buffer_ptr ==      'c') || (*buffer_ptr ==      'C')) &&
740             ((*(buffer_ptr+1) ==  'o') || (*(buffer_ptr+1) ==  'O')) &&
741             ((*(buffer_ptr+2) ==  'n') || (*(buffer_ptr+2) ==  'N')) &&
742             ((*(buffer_ptr+3) ==  't') || (*(buffer_ptr+3) ==  'T')) &&
743             ((*(buffer_ptr+4) ==  'e') || (*(buffer_ptr+4) ==  'E')) &&
744             ((*(buffer_ptr+5) ==  'n') || (*(buffer_ptr+5) ==  'N')) &&
745             ((*(buffer_ptr+6) ==  't') || (*(buffer_ptr+6) ==  'T')) &&
746             (*(buffer_ptr+7) ==  '-') &&
747             ((*(buffer_ptr+8) ==  'l') || (*(buffer_ptr+8) ==  'L')) &&
748             ((*(buffer_ptr+9) ==  'e') || (*(buffer_ptr+9) ==  'E')) &&
749             ((*(buffer_ptr+10) == 'n') || (*(buffer_ptr+10) == 'N')) &&
750             ((*(buffer_ptr+11) == 'g') || (*(buffer_ptr+11) == 'G')) &&
751             ((*(buffer_ptr+12) == 't') || (*(buffer_ptr+12) == 'T')) &&
752             ((*(buffer_ptr+13) == 'h') || (*(buffer_ptr+13) == 'H')) &&
753             (*(buffer_ptr+14) == ':') &&
754             (*(buffer_ptr+15) == ' '))
755         {
756 
757             /* Move the pointer up to the length token.  */
758             buffer_ptr =  buffer_ptr + 16;
759             break;
760         }
761 
762         /* Move the pointer up to the next character.  */
763         buffer_ptr++;
764     }
765 
766     /* Now convert the length into a numeric value.  */
767     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr >= '0') && (*buffer_ptr <= '9'))
768     {
769 
770         /* Update the content length.  */
771         length =  length * 10;
772         length =  length + (((UINT) (*buffer_ptr)) - 0x30);
773 
774         /* Move the buffer pointer forward.  */
775         buffer_ptr++;
776     }
777 
778     /* Determine if the content length was picked up properly.  */
779     if ((*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13))
780     {
781 
782         /* Error, set the length to zero.  */
783         length =  0;
784     }
785 
786     /* Return the length to the caller.  */
787     return(length);
788 }
789 /**************************************************************************/
790 /*                                                                        */
791 /*  FUNCTION                                               RELEASE        */
792 /*                                                                        */
793 /*    _nxe_http_server_content_get_extended               PORTABLE C      */
794 /*                                                           6.1          */
795 /*  AUTHOR                                                                */
796 /*                                                                        */
797 /*    Yuxin Zhou, Microsoft Corporation                                   */
798 /*                                                                        */
799 /*  DESCRIPTION                                                           */
800 /*                                                                        */
801 /*    This function checks for errors in the HTTP extended get content    */
802 /*    service.                                                            */
803 /*                                                                        */
804 /*                                                                        */
805 /*  INPUT                                                                 */
806 /*                                                                        */
807 /*    server_ptr                            Pointer to HTTP server        */
808 /*    packet_ptr                            Pointer to HTTP request packet*/
809 /*    byte_offset                           Byte offset into content      */
810 /*    destination_ptr                       Pointer to content destination*/
811 /*    destination_size                      Maximum size of destination   */
812 /*    actual_size                           Actual amount of content      */
813 /*                                                                        */
814 /*  OUTPUT                                                                */
815 /*                                                                        */
816 /*    status                                Completion status             */
817 /*                                                                        */
818 /*  CALLS                                                                 */
819 /*                                                                        */
820 /*    _nx_http_server_content_get_extended  Actual extended get content   */
821 /*                                              get service               */
822 /*                                                                        */
823 /*  CALLED BY                                                             */
824 /*                                                                        */
825 /*    Application Code                                                    */
826 /*                                                                        */
827 /*  RELEASE HISTORY                                                       */
828 /*                                                                        */
829 /*    DATE              NAME                      DESCRIPTION             */
830 /*                                                                        */
831 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
832 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
833 /*                                            resulting in version 6.1    */
834 /*                                                                        */
835 /**************************************************************************/
_nxe_http_server_content_get_extended(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,ULONG byte_offset,CHAR * destination_ptr,UINT destination_size,UINT * actual_size)836 UINT  _nxe_http_server_content_get_extended(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, ULONG byte_offset,
837                                             CHAR *destination_ptr, UINT destination_size, UINT *actual_size)
838 {
839 
840 UINT    status;
841 
842 
843     /* Check for invalid input pointers.  */
844     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) ||
845         (packet_ptr == NX_NULL) || (destination_ptr == NX_NULL) || (actual_size == NX_NULL))
846         return(NX_PTR_ERROR);
847 
848     /* Check for appropriate caller.  */
849     NX_THREADS_ONLY_CALLER_CHECKING
850 
851     /* Call actual server content get function.  */
852     status =  _nx_http_server_content_get_extended(server_ptr, packet_ptr, byte_offset, destination_ptr, destination_size, actual_size);
853 
854     /* Return completion status.  */
855     return(status);
856 }
857 
858 
859 /**************************************************************************/
860 /*                                                                        */
861 /*  FUNCTION                                               RELEASE        */
862 /*                                                                        */
863 /*    _nx_http_server_content_get_extended                PORTABLE C      */
864 /*                                                           6.1          */
865 /*  AUTHOR                                                                */
866 /*                                                                        */
867 /*    Yuxin Zhou, Microsoft Corporation                                   */
868 /*                                                                        */
869 /*  DESCRIPTION                                                           */
870 /*                                                                        */
871 /*    This function returns the user's specified portion of the HTTP      */
872 /*    content. Content is typically included in POST and PUT requests     */
873 /*    from the client. This routine is designed to be called from the     */
874 /*    application's request notify callback.                              */
875 /*                                                                        */
876 /*    This API is identical to _nx_http_server_content_get service except */
877 /*    for detecting a valid Content Length of length zero.  In this case, */
878 /*    it sets the actual_size pointer to that value and returns a         */
879 /*    successful outcome (empty POST requests are allowed in HTTP         */
880 /*    1.0/1.1).  If this is called from a request notify callback the     */
881 /*    caller is responsible for responding to the HTTP Client.            */
882 /*                                                                        */
883 /*  INPUT                                                                 */
884 /*                                                                        */
885 /*    server_ptr                            Pointer to HTTP server        */
886 /*    packet_ptr                            Pointer to HTTP request packet*/
887 /*    byte_offset                           Byte offset into content      */
888 /*    destination_ptr                       Pointer to content destination*/
889 /*    destination_size                      Maximum size of destination   */
890 /*    actual_size                           Actual amount of content      */
891 /*                                                                        */
892 /*  OUTPUT                                                                */
893 /*                                                                        */
894 /*    status                                Completion status             */
895 /*                                                                        */
896 /*  CALLS                                                                 */
897 /*                                                                        */
898 /*    nx_tcp_socket_receive                 Receive another packet        */
899 /*    _nx_http_server_content_length_get_extended                         */
900 /*                                          Get content length with error */
901 /*                                          status returned separately    */
902 /*                                          content length value.         */
903 /*    _nx_http_server_calculate_content_offset                            */
904 /*                                          Pickup content offset         */
905 /*                                                                        */
906 /*  CALLED BY                                                             */
907 /*                                                                        */
908 /*    Application Code                                                    */
909 /*                                                                        */
910 /*  RELEASE HISTORY                                                       */
911 /*                                                                        */
912 /*    DATE              NAME                      DESCRIPTION             */
913 /*                                                                        */
914 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
915 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
916 /*                                            resulting in version 6.1    */
917 /*                                                                        */
918 /**************************************************************************/
_nx_http_server_content_get_extended(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,ULONG byte_offset,CHAR * destination_ptr,UINT destination_size,UINT * actual_size)919 UINT  _nx_http_server_content_get_extended(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, ULONG byte_offset,
920                                            CHAR *destination_ptr, UINT destination_size, UINT *actual_size)
921 {
922 
923 ULONG       content_length;
924 ULONG       get_offset;
925 ULONG       offset;
926 UINT        status;
927 UINT        remaining_bytes;
928 NX_PACKET   *new_packet_ptr;
929 CHAR        *buffer_ptr;
930 
931 
932     /* Default the actual size to zero.  */
933     *actual_size =  0;
934 
935     /* Determine if there is content in this HTTP request.  */
936     status =  (ULONG) _nx_http_server_content_length_get_extended(packet_ptr, &content_length);
937 
938     if (status != NX_SUCCESS)
939     {
940         return status;
941     }
942 
943     /* Check for a empty POST request. */
944     if (content_length == 0)
945     {
946 
947         /* Return the zero message body (content-length) size. */
948         *actual_size =  content_length;
949 
950         /* No more data in this buffer.  */
951         return(NX_SUCCESS);
952     }
953 
954     /* Make sure the content length is at least greater than the byte offset supplied.  */
955     if (content_length <= byte_offset)
956     {
957 
958         /* No more data in this buffer.  */
959         return(NX_HTTP_DATA_END);
960     }
961 
962     /* Determine if the destination size is greater than the content length.  */
963     if (destination_size > content_length)
964     {
965 
966         /* Yes, make the destination size equal to the content length.  */
967         destination_size =  content_length;
968     }
969 
970     /* Calculate the offset to the requested content area.  */
971     get_offset =  ((ULONG) _nx_http_server_calculate_content_offset(packet_ptr)) + byte_offset;
972 
973     /* Determine if we need to read one or more additional packets.  */
974     while (get_offset >= packet_ptr -> nx_packet_length)
975     {
976 
977 #ifdef NX_DISABLE_PACKET_CHAIN
978         NX_PARAMETER_NOT_USED(server_ptr);
979 
980         return NX_HTTP_ERROR;
981 #else
982         /* Read another packet because the offset reaches past the current packet
983            length.  */
984         status =  nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), &new_packet_ptr, NX_HTTP_SERVER_TIMEOUT_RECEIVE);
985 
986         /* Check the return status.  */
987         if (status != NX_SUCCESS)
988         {
989 
990             /* Error, return to caller.  */
991             return(NX_HTTP_TIMEOUT);
992         }
993 
994         /* Otherwise, we have a new packet to append to the head packet.  */
995 
996         /* Determine if the current packet is already chained.  */
997         if (packet_ptr -> nx_packet_next)
998         {
999 
1000             /* Yes, link the current last packet to the new packet.  */
1001             (packet_ptr -> nx_packet_last) -> nx_packet_next =  new_packet_ptr;
1002         }
1003         else
1004         {
1005 
1006             /* Otherwise, this is our first chained packet.  Link to the head.  */
1007             packet_ptr -> nx_packet_next =  new_packet_ptr;
1008         }
1009 
1010         /* Is the new packet chained?  */
1011         if (new_packet_ptr -> nx_packet_next)
1012         {
1013 
1014             /* Yes, there is a last packet pointer.  Point to this from the head packet.  */
1015             packet_ptr -> nx_packet_last =  new_packet_ptr -> nx_packet_last;
1016         }
1017         else
1018         {
1019 
1020             /* No, there isn't a last packet pointer.  Point to new packet from the head packet.  */
1021             packet_ptr -> nx_packet_last =  new_packet_ptr;
1022         }
1023 
1024         /* Update the packet length.  */
1025         packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length + new_packet_ptr -> nx_packet_length;
1026 #endif /* NX_DISABLE_PACKET_CHAIN */
1027     }
1028 
1029     /* Default the buffer pointer to NULL.  */
1030     buffer_ptr =  NX_NULL;
1031 
1032     /* Now find the packet that contains the offset.  */
1033     offset =  0;
1034     new_packet_ptr =  packet_ptr;
1035     do
1036     {
1037 
1038         /* Determine if the get request falls into this packet.  */
1039         if (get_offset < (offset + (ULONG)(new_packet_ptr -> nx_packet_append_ptr - new_packet_ptr -> nx_packet_prepend_ptr)))
1040         {
1041 
1042             /* Yes, the get offset is in this packet.  */
1043 
1044             /* Setup the starting byte pointer.  */
1045             buffer_ptr =  ((CHAR *) new_packet_ptr -> nx_packet_prepend_ptr) + (get_offset - offset);
1046             break;
1047         }
1048 
1049         /* Otherwise update the offset.  */
1050         offset =  offset + (ULONG)(new_packet_ptr -> nx_packet_append_ptr - new_packet_ptr -> nx_packet_prepend_ptr);
1051 
1052 #ifdef NX_DISABLE_PACKET_CHAIN
1053         new_packet_ptr =  NX_NULL;
1054 #else
1055         /* Move to next packet in the chain.  */
1056         new_packet_ptr =  new_packet_ptr -> nx_packet_next;
1057 #endif /* NX_DISABLE_PACKET_CHAIN */
1058 
1059     } while (new_packet_ptr);
1060 
1061     /* Determine if an error occurred in the search.  */
1062     if ((buffer_ptr == (CHAR *) NX_NULL) || (new_packet_ptr == NX_NULL))
1063         return(NX_HTTP_ERROR);
1064 
1065     /* Now determine if the maximum buffer size has to be adjusted.  */
1066     if (destination_size > (UINT) (new_packet_ptr -> nx_packet_append_ptr - (UCHAR *) buffer_ptr))
1067     {
1068 
1069         /* Adjust the destination size downward.  */
1070         destination_size =  (UINT) (new_packet_ptr -> nx_packet_append_ptr - (UCHAR *) buffer_ptr);
1071     }
1072 
1073     /* Initialize the remaining bytes.  */
1074     remaining_bytes =  destination_size;
1075 
1076     /* Otherwise copy the bytes from the offset to the end of the packet pointer.  */
1077     while (remaining_bytes--)
1078     {
1079 
1080         /* Copy a byte to the destination.  */
1081         *destination_ptr++ =  *buffer_ptr++;
1082     }
1083 
1084     /* Successful completion.  */
1085     *actual_size =  destination_size;
1086     return(NX_SUCCESS);
1087 }
1088 
1089 
1090 /**************************************************************************/
1091 /*                                                                        */
1092 /*  FUNCTION                                               RELEASE        */
1093 /*                                                                        */
1094 /*    _nxe_http_server_content_length_get_extended        PORTABLE C      */
1095 /*                                                           6.1          */
1096 /*  AUTHOR                                                                */
1097 /*                                                                        */
1098 /*    Yuxin Zhou, Microsoft Corporation                                   */
1099 /*                                                                        */
1100 /*  DESCRIPTION                                                           */
1101 /*                                                                        */
1102 /*    This function checks for errors in the extended HTTP content length */
1103 /*    service.                                                            */
1104 /*                                                                        */
1105 /*                                                                        */
1106 /*  INPUT                                                                 */
1107 /*                                                                        */
1108 /*    packet_ptr                            Pointer to HTTP paclet        */
1109 /*    content_length                        Pointer for returning content */
1110 /*                                             length value               */
1111 /*                                                                        */
1112 /*  OUTPUT                                                                */
1113 /*                                                                        */
1114 /*    status                                Completion status             */
1115 /*                                                                        */
1116 /*  CALLS                                                                 */
1117 /*                                                                        */
1118 /*    _nx_http_server_content_length_get_extended                         */
1119 /*                                          Actual extended get content   */
1120 /*                                            length service              */
1121 /*                                                                        */
1122 /*  CALLED BY                                                             */
1123 /*                                                                        */
1124 /*    Application Code                                                    */
1125 /*                                                                        */
1126 /*  RELEASE HISTORY                                                       */
1127 /*                                                                        */
1128 /*    DATE              NAME                      DESCRIPTION             */
1129 /*                                                                        */
1130 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1131 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1132 /*                                            resulting in version 6.1    */
1133 /*                                                                        */
1134 /**************************************************************************/
1135 
_nxe_http_server_content_length_get_extended(NX_PACKET * packet_ptr,ULONG * content_length)1136 UINT  _nxe_http_server_content_length_get_extended(NX_PACKET *packet_ptr, ULONG *content_length)
1137 {
1138 
1139 UINT    status;
1140 
1141 
1142     /* Check for invalid input pointers.  */
1143     if ((packet_ptr == NX_NULL) || (content_length == NX_NULL))
1144         return(NX_PTR_ERROR);
1145 
1146     /* Call actual server content length get function.  */
1147     status =  _nx_http_server_content_length_get_extended(packet_ptr, content_length);
1148 
1149     /* Return completion status. */
1150     return status;
1151 }
1152 
1153 /**************************************************************************/
1154 /*                                                                        */
1155 /*  FUNCTION                                               RELEASE        */
1156 /*                                                                        */
1157 /*    _nx_http_server_content_length_get_extended         PORTABLE C      */
1158 /*                                                           6.1          */
1159 /*  AUTHOR                                                                */
1160 /*                                                                        */
1161 /*    Yuxin Zhou, Microsoft Corporation                                   */
1162 /*                                                                        */
1163 /*  DESCRIPTION                                                           */
1164 /*                                                                        */
1165 /*    This function find a valid content length field and returns a       */
1166 /*    successful completion status (NX_SUCCESS) if so. Otherwise it       */
1167 /*    it returns an error status.  A valid content length value is        */
1168 /*    zero or more and matches the size of the message body.              */
1169 /*                                                                        */
1170 /*                                                                        */
1171 /*  INPUT                                                                 */
1172 /*                                                                        */
1173 /*    packet_ptr                            Pointer to HTTP request packet*/
1174 /*    content_length                        Pointer to a valid Content    */
1175 /*                                              Length value              */
1176 /*                                                                        */
1177 /*  OUTPUT                                                                */
1178 /*                                                                        */
1179 /*    NX_SUCCESS                            Content length extracted      */
1180 /*    status                                Invalid content length        */
1181 /*                                                                        */
1182 /*  CALLS                                                                 */
1183 /*                                                                        */
1184 /*    None                                                                */
1185 /*                                                                        */
1186 /*  CALLED BY                                                             */
1187 /*                                                                        */
1188 /*    Threads                                                             */
1189 /*                                                                        */
1190 /*  RELEASE HISTORY                                                       */
1191 /*                                                                        */
1192 /*    DATE              NAME                      DESCRIPTION             */
1193 /*                                                                        */
1194 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1195 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1196 /*                                            resulting in version 6.1    */
1197 /*                                                                        */
1198 /**************************************************************************/
_nx_http_server_content_length_get_extended(NX_PACKET * packet_ptr,ULONG * length)1199 UINT  _nx_http_server_content_length_get_extended(NX_PACKET *packet_ptr, ULONG *length)
1200 {
1201 
1202 CHAR    *buffer_ptr;
1203 
1204 
1205     /* Default the content length to no data.  */
1206     *length =  0;
1207 
1208     /* Setup pointer to buffer.  */
1209     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
1210 
1211     /* Find the "Content-length: " token first.  */
1212     while (((buffer_ptr+17) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
1213     {
1214 
1215         /* Check for the Content-length token.  */
1216         if (((*buffer_ptr ==      'c') || (*buffer_ptr ==      'C')) &&
1217             ((*(buffer_ptr+1) ==  'o') || (*(buffer_ptr+1) ==  'O')) &&
1218             ((*(buffer_ptr+2) ==  'n') || (*(buffer_ptr+2) ==  'N')) &&
1219             ((*(buffer_ptr+3) ==  't') || (*(buffer_ptr+3) ==  'T')) &&
1220             ((*(buffer_ptr+4) ==  'e') || (*(buffer_ptr+4) ==  'E')) &&
1221             ((*(buffer_ptr+5) ==  'n') || (*(buffer_ptr+5) ==  'N')) &&
1222             ((*(buffer_ptr+6) ==  't') || (*(buffer_ptr+6) ==  'T')) &&
1223             (*(buffer_ptr+7) ==  '-') &&
1224             ((*(buffer_ptr+8) ==  'l') || (*(buffer_ptr+8) ==  'L')) &&
1225             ((*(buffer_ptr+9) ==  'e') || (*(buffer_ptr+9) ==  'E')) &&
1226             ((*(buffer_ptr+10) == 'n') || (*(buffer_ptr+10) == 'N')) &&
1227             ((*(buffer_ptr+11) == 'g') || (*(buffer_ptr+11) == 'G')) &&
1228             ((*(buffer_ptr+12) == 't') || (*(buffer_ptr+12) == 'T')) &&
1229             ((*(buffer_ptr+13) == 'h') || (*(buffer_ptr+13) == 'H')) &&
1230             (*(buffer_ptr+14) == ':') &&
1231             (*(buffer_ptr+15) == ' '))
1232         {
1233 
1234             /* Move the pointer up to the length token.  */
1235             buffer_ptr =  buffer_ptr + 16;
1236             break;
1237         }
1238 
1239         /* Move the pointer up to the next character.  */
1240         buffer_ptr++;
1241     }
1242 
1243     /* Now convert the length into a numeric value.  */
1244     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr >= '0') && (*buffer_ptr <= '9'))
1245     {
1246 
1247         /* Update the content length.  */
1248         *length =  *length * 10;
1249         *length =  *length + (((UINT) (*buffer_ptr)) - 0x30);
1250 
1251         /* Move the buffer pointer forward.  */
1252         buffer_ptr++;
1253     }
1254 
1255      /* Determine if the content length was picked up properly.  */
1256      if ((*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13))
1257      {
1258 
1259          /* Error, set the length to zero.  */
1260          return NX_HTTP_INCOMPLETE_PUT_ERROR;
1261      }
1262 
1263     /* Return successful completion status to the caller.  */
1264     return NX_SUCCESS;
1265 }
1266 
1267 
1268 /**************************************************************************/
1269 /*                                                                        */
1270 /*  FUNCTION                                               RELEASE        */
1271 /*                                                                        */
1272 /*    _nxe_http_server_create                             PORTABLE C      */
1273 /*                                                           6.1          */
1274 /*  AUTHOR                                                                */
1275 /*                                                                        */
1276 /*    Yuxin Zhou, Microsoft Corporation                                   */
1277 /*                                                                        */
1278 /*  DESCRIPTION                                                           */
1279 /*                                                                        */
1280 /*    This function checks for errors in the HTTP server create call.     */
1281 /*                                                                        */
1282 /*                                                                        */
1283 /*  INPUT                                                                 */
1284 /*                                                                        */
1285 /*    http_server_ptr                       Pointer to HTTP server        */
1286 /*    http_server_name                      Name of HTTP server           */
1287 /*    ip_ptr                                Pointer to IP instance        */
1288 /*    media_ptr                             Pointer to media structure    */
1289 /*    stack_ptr                             Server thread's stack pointer */
1290 /*    stack_size                            Server thread's stack size    */
1291 /*    pool_ptr                              Pointer to packet pool        */
1292 /*    authentication_check                  Pointer to application's      */
1293 /*                                            authentication checking     */
1294 /*    request_notify                        Pointer to application's      */
1295 /*                                            request notify service      */
1296 /*    http_server_size                      Size of HTTP server           */
1297 /*                                                                        */
1298 /*  OUTPUT                                                                */
1299 /*                                                                        */
1300 /*    status                                Completion status             */
1301 /*                                                                        */
1302 /*  CALLS                                                                 */
1303 /*                                                                        */
1304 /*    _nx_http_server_create                Actual server create call     */
1305 /*                                                                        */
1306 /*  CALLED BY                                                             */
1307 /*                                                                        */
1308 /*    Application Code                                                    */
1309 /*                                                                        */
1310 /*  RELEASE HISTORY                                                       */
1311 /*                                                                        */
1312 /*    DATE              NAME                      DESCRIPTION             */
1313 /*                                                                        */
1314 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1315 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1316 /*                                            resulting in version 6.1    */
1317 /*                                                                        */
1318 /**************************************************************************/
_nxe_http_server_create(NX_HTTP_SERVER * http_server_ptr,CHAR * http_server_name,NX_IP * ip_ptr,FX_MEDIA * media_ptr,VOID * stack_ptr,ULONG stack_size,NX_PACKET_POOL * pool_ptr,UINT (* authentication_check)(NX_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,CHAR ** password,CHAR ** realm),UINT (* request_notify)(NX_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,NX_PACKET * packet_ptr),UINT http_server_size)1319 UINT  _nxe_http_server_create(NX_HTTP_SERVER *http_server_ptr, CHAR *http_server_name, NX_IP *ip_ptr, FX_MEDIA *media_ptr, VOID *stack_ptr, ULONG stack_size, NX_PACKET_POOL *pool_ptr,
1320                                 UINT (*authentication_check)(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, CHAR **password, CHAR **realm),
1321                                 UINT (*request_notify)(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr),
1322                                 UINT http_server_size)
1323 {
1324 
1325 NX_PACKET   *packet_ptr;
1326 UINT        status;
1327 
1328 
1329     /* Check for invalid input pointers.  */
1330     if ((ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
1331         (http_server_ptr == NX_NULL) || (http_server_ptr -> nx_http_server_id == NXD_HTTP_SERVER_ID) ||
1332         (stack_ptr == NX_NULL) || (pool_ptr == NX_NULL) ||
1333         (http_server_size != sizeof(NX_HTTP_SERVER)))
1334         return(NX_PTR_ERROR);
1335 
1336     /* Pickup a packet from the supplied packet pool.  */
1337     packet_ptr =  pool_ptr -> nx_packet_pool_available_list;
1338 
1339     /* Determine if the packet payload is equal to or greater than the maximum HTTP header supported.  */
1340     if (((packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_data_start) - NX_PHYSICAL_TRAILER)
1341                                                                                             < NX_HTTP_SERVER_MIN_PACKET_SIZE)
1342         return(NX_HTTP_POOL_ERROR);
1343 
1344     /* Call actual server create function.  */
1345     status =  _nx_http_server_create(http_server_ptr, http_server_name, ip_ptr, media_ptr, stack_ptr, stack_size, pool_ptr,
1346                             authentication_check, request_notify);
1347 
1348     /* Return completion status.  */
1349     return(status);
1350 }
1351 
1352 
1353 /**************************************************************************/
1354 /*                                                                        */
1355 /*  FUNCTION                                               RELEASE        */
1356 /*                                                                        */
1357 /*    _nx_http_server_create                              PORTABLE C      */
1358 /*                                                           6.1          */
1359 /*  AUTHOR                                                                */
1360 /*                                                                        */
1361 /*    Yuxin Zhou, Microsoft Corporation                                   */
1362 /*                                                                        */
1363 /*  DESCRIPTION                                                           */
1364 /*                                                                        */
1365 /*    This function creates a HTTP server on the specified IP. In doing   */
1366 /*    so this function creates an TCP socket for subsequent HTTP          */
1367 /*    transfers and a thread for the HTTP server.                         */
1368 /*                                                                        */
1369 /*                                                                        */
1370 /*  INPUT                                                                 */
1371 /*                                                                        */
1372 /*    http_server_ptr                       Pointer to HTTP server        */
1373 /*    http_server_name                      Name of HTTP server           */
1374 /*    ip_ptr                                Pointer to IP instance        */
1375 /*    media_ptr                             Pointer to media structure    */
1376 /*    stack_ptr                             Server thread's stack pointer */
1377 /*    stack_size                            Server thread's stack size    */
1378 /*    pool_ptr                              Pointer to packet pool        */
1379 /*    authentication_check                  Pointer to application's      */
1380 /*                                            authentication checking     */
1381 /*    request_notify                        Pointer to application's      */
1382 /*                                            request notify service      */
1383 /*                                                                        */
1384 /*  OUTPUT                                                                */
1385 /*                                                                        */
1386 /*    status                                Completion status             */
1387 /*                                                                        */
1388 /*  CALLS                                                                 */
1389 /*                                                                        */
1390 /*    nx_tcp_socket_create                  Create HTTP server socket     */
1391 /*    nx_tcp_socket_delete                  Delete the HTTP server socket */
1392 /*    tx_thread_create                      Create the HTTP server thread */
1393 /*                                                                        */
1394 /*  CALLED BY                                                             */
1395 /*                                                                        */
1396 /*    Application Code                                                    */
1397 /*                                                                        */
1398 /*  RELEASE HISTORY                                                       */
1399 /*                                                                        */
1400 /*    DATE              NAME                      DESCRIPTION             */
1401 /*                                                                        */
1402 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1403 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1404 /*                                            resulting in version 6.1    */
1405 /*                                                                        */
1406 /**************************************************************************/
_nx_http_server_create(NX_HTTP_SERVER * http_server_ptr,CHAR * http_server_name,NX_IP * ip_ptr,FX_MEDIA * media_ptr,VOID * stack_ptr,ULONG stack_size,NX_PACKET_POOL * pool_ptr,UINT (* authentication_check)(NX_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,CHAR ** password,CHAR ** realm),UINT (* request_notify)(NX_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,NX_PACKET * packet_ptr))1407 UINT  _nx_http_server_create(NX_HTTP_SERVER *http_server_ptr, CHAR *http_server_name, NX_IP *ip_ptr, FX_MEDIA *media_ptr, VOID *stack_ptr, ULONG stack_size, NX_PACKET_POOL *pool_ptr,
1408                                 UINT (*authentication_check)(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, CHAR **password, CHAR **realm),
1409                                 UINT (*request_notify)(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr))
1410 {
1411 
1412 UINT        status;
1413 
1414 
1415     /* Clear the HTTP server structure.  */
1416     memset((void *) http_server_ptr, 0, sizeof(NX_HTTP_SERVER));
1417 
1418     /* Create the Server's TCP socket.  */
1419     status =  nx_tcp_socket_create(ip_ptr, &(http_server_ptr -> nx_http_server_socket), http_server_name,
1420                           NX_HTTP_TYPE_OF_SERVICE,  NX_HTTP_FRAGMENT_OPTION, NX_HTTP_TIME_TO_LIVE,
1421                           NX_HTTP_SERVER_WINDOW_SIZE, NX_NULL, NX_NULL);
1422 
1423     /* Determine if an error occurred.   */
1424     if (status != NX_SUCCESS)
1425     {
1426 
1427         /* Yes, return error code.  */
1428         return(status);
1429     }
1430 
1431     /* Now create the HTTP Server thread.  */
1432     status =  tx_thread_create(&(http_server_ptr -> nx_http_server_thread), "HTTP Server Thread", _nx_http_server_thread_entry,
1433                     (ULONG) http_server_ptr, stack_ptr, stack_size, NX_HTTP_SERVER_PRIORITY, NX_HTTP_SERVER_PRIORITY,
1434                     NX_HTTP_SERVER_THREAD_TIME_SLICE, TX_DONT_START);
1435 
1436     /* Determine if an error occurred creating the thread.  */
1437     if (status != NX_SUCCESS)
1438     {
1439 
1440         /* Delete the TCP socket.  */
1441         nx_tcp_socket_delete(&(http_server_ptr -> nx_http_server_socket));
1442 
1443         /* Yes, return error code.  */
1444         return(status);
1445     }
1446 
1447     /* Save the Server name.  */
1448     http_server_ptr -> nx_http_server_name =  http_server_name;
1449 
1450     /* Save the IP pointer address.  */
1451     http_server_ptr -> nx_http_server_ip_ptr =  ip_ptr;
1452 
1453     /* Save the packet pool pointer.  */
1454     http_server_ptr -> nx_http_server_packet_pool_ptr =  pool_ptr;
1455 
1456     /* Save the media pointer address.  */
1457     http_server_ptr -> nx_http_server_media_ptr =  media_ptr;
1458 
1459     /* Save the user-supplied routines, if specified.  */
1460     http_server_ptr -> nx_http_server_authentication_check =  authentication_check;
1461     http_server_ptr -> nx_http_server_request_notify =        request_notify;
1462 
1463 
1464     /* Remember this server structure in the TCP socket.  */
1465     http_server_ptr -> nx_http_server_socket.nx_tcp_socket_reserved_ptr =  (void *) http_server_ptr;
1466 
1467     /* Set the server ID to indicate the HTTP server thread is ready.  */
1468     http_server_ptr -> nx_http_server_id =  NXD_HTTP_SERVER_ID;
1469 
1470     /* Return successful completion.  */
1471     return(NX_SUCCESS);
1472 }
1473 
1474 
1475 /**************************************************************************/
1476 /*                                                                        */
1477 /*  FUNCTION                                               RELEASE        */
1478 /*                                                                        */
1479 /*    _nxe_http_server_delete                             PORTABLE C      */
1480 /*                                                           6.1          */
1481 /*  AUTHOR                                                                */
1482 /*                                                                        */
1483 /*    Yuxin Zhou, Microsoft Corporation                                   */
1484 /*                                                                        */
1485 /*  DESCRIPTION                                                           */
1486 /*                                                                        */
1487 /*    This function checks for errors in the HTTP server delete call.     */
1488 /*                                                                        */
1489 /*                                                                        */
1490 /*  INPUT                                                                 */
1491 /*                                                                        */
1492 /*    http_server_ptr                       Pointer to HTTP server        */
1493 /*                                                                        */
1494 /*  OUTPUT                                                                */
1495 /*                                                                        */
1496 /*    status                                Completion status             */
1497 /*                                                                        */
1498 /*  CALLS                                                                 */
1499 /*                                                                        */
1500 /*    _nx_http_server_delete                Actual server delete call     */
1501 /*                                                                        */
1502 /*  CALLED BY                                                             */
1503 /*                                                                        */
1504 /*    Application Code                                                    */
1505 /*                                                                        */
1506 /*  RELEASE HISTORY                                                       */
1507 /*                                                                        */
1508 /*    DATE              NAME                      DESCRIPTION             */
1509 /*                                                                        */
1510 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1511 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1512 /*                                            resulting in version 6.1    */
1513 /*                                                                        */
1514 /**************************************************************************/
_nxe_http_server_delete(NX_HTTP_SERVER * http_server_ptr)1515 UINT  _nxe_http_server_delete(NX_HTTP_SERVER *http_server_ptr)
1516 {
1517 
1518 UINT    status;
1519 
1520 
1521     /* Check for invalid input pointers.  */
1522     if ((http_server_ptr == NX_NULL) || (http_server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID))
1523         return(NX_PTR_ERROR);
1524 
1525     /* Check for appropriate caller.  */
1526     NX_THREADS_ONLY_CALLER_CHECKING
1527 
1528     /* Call actual server delete function.  */
1529     status =  _nx_http_server_delete(http_server_ptr);
1530 
1531     /* Return completion status.  */
1532     return(status);
1533 }
1534 
1535 
1536 /**************************************************************************/
1537 /*                                                                        */
1538 /*  FUNCTION                                               RELEASE        */
1539 /*                                                                        */
1540 /*    _nx_http_server_delete                              PORTABLE C      */
1541 /*                                                           6.2.0        */
1542 /*  AUTHOR                                                                */
1543 /*                                                                        */
1544 /*    Yuxin Zhou, Microsoft Corporation                                   */
1545 /*                                                                        */
1546 /*  DESCRIPTION                                                           */
1547 /*                                                                        */
1548 /*    This function deletes a previously created HTTP server on the       */
1549 /*    specified IP.                                                       */
1550 /*                                                                        */
1551 /*                                                                        */
1552 /*  INPUT                                                                 */
1553 /*                                                                        */
1554 /*    http_server_ptr                       Pointer to HTTP server        */
1555 /*                                                                        */
1556 /*  OUTPUT                                                                */
1557 /*                                                                        */
1558 /*    status                                Completion status             */
1559 /*                                                                        */
1560 /*  CALLS                                                                 */
1561 /*                                                                        */
1562 /*    nx_tcp_socket_delete                  Delete the HTTP server socket */
1563 /*    _nx_http_server_disconnect            Disconnect HTTP server socket */
1564 /*    nx_tcp_server_socket_unlisten         Unlisten on the HTTP port     */
1565 /*    tx_thread_delete                      Delete the HTTP server thread */
1566 /*    tx_thread_suspend                     Suspend the HTTP server thread*/
1567 /*    tx_thread_terminate                   Terminate the HTTP server     */
1568 /*                                            thread                      */
1569 /*                                                                        */
1570 /*  CALLED BY                                                             */
1571 /*                                                                        */
1572 /*    Application Code                                                    */
1573 /*                                                                        */
1574 /*  RELEASE HISTORY                                                       */
1575 /*                                                                        */
1576 /*    DATE              NAME                      DESCRIPTION             */
1577 /*                                                                        */
1578 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1579 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1580 /*                                            resulting in version 6.1    */
1581 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
1582 /*                                            supported random nonce,     */
1583 /*                                            resulting in version 6.2.0  */
1584 /*                                                                        */
1585 /**************************************************************************/
_nx_http_server_delete(NX_HTTP_SERVER * http_server_ptr)1586 UINT  _nx_http_server_delete(NX_HTTP_SERVER *http_server_ptr)
1587 {
1588 
1589 
1590     /* Clear the server ID to indicate the HTTP server is no longer ready.  */
1591     http_server_ptr -> nx_http_server_id =  0;
1592 
1593     /* Disconnect the TCP socket.  */
1594     _nx_http_server_disconnect(http_server_ptr, NX_HTTP_SERVER_TIMEOUT_DISCONNECT);
1595 
1596     /* Delete the TCP socket.  */
1597     nx_tcp_socket_delete(&(http_server_ptr -> nx_http_server_socket));
1598 
1599     /* Unlisten on the HTTP server port.  */
1600     nx_tcp_server_socket_unlisten(http_server_ptr -> nx_http_server_ip_ptr, NX_HTTP_SERVER_PORT);
1601 
1602     /* Suspend the HTTP server thread.  */
1603     tx_thread_suspend(&(http_server_ptr -> nx_http_server_thread));
1604 
1605     /* Terminate server thread. */
1606     tx_thread_terminate(&(http_server_ptr -> nx_http_server_thread));
1607 
1608     /* Delete server thread.  */
1609     tx_thread_delete(&(http_server_ptr -> nx_http_server_thread));
1610 
1611     /* Return successful completion.  */
1612     return(NX_SUCCESS);
1613 }
1614 
1615 
1616 /**************************************************************************/
1617 /*                                                                        */
1618 /*  FUNCTION                                               RELEASE        */
1619 /*                                                                        */
1620 /*    _nxe_http_server_param_get                          PORTABLE C      */
1621 /*                                                           6.1          */
1622 /*  AUTHOR                                                                */
1623 /*                                                                        */
1624 /*    Yuxin Zhou, Microsoft Corporation                                   */
1625 /*                                                                        */
1626 /*  DESCRIPTION                                                           */
1627 /*                                                                        */
1628 /*    This function checks for errors in the HTTP parameter get call.     */
1629 /*                                                                        */
1630 /*                                                                        */
1631 /*  INPUT                                                                 */
1632 /*                                                                        */
1633 /*    packet_ptr                            Pointer to HTTP request packet*/
1634 /*    param_number                          Parameter number (start at 0) */
1635 /*    param_ptr                             Pointer to destination        */
1636 /*    max_param_size                        Maximum size of destination   */
1637 /*                                                                        */
1638 /*  OUTPUT                                                                */
1639 /*                                                                        */
1640 /*    status                                Completion status             */
1641 /*                                                                        */
1642 /*  CALLS                                                                 */
1643 /*                                                                        */
1644 /*    _nx_http_server_param_get             Actual server parameter get   */
1645 /*                                            call                        */
1646 /*                                                                        */
1647 /*  CALLED BY                                                             */
1648 /*                                                                        */
1649 /*    Application Code                                                    */
1650 /*                                                                        */
1651 /*  RELEASE HISTORY                                                       */
1652 /*                                                                        */
1653 /*    DATE              NAME                      DESCRIPTION             */
1654 /*                                                                        */
1655 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1656 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1657 /*                                            resulting in version 6.1    */
1658 /*                                                                        */
1659 /**************************************************************************/
_nxe_http_server_param_get(NX_PACKET * packet_ptr,UINT param_number,CHAR * param_ptr,UINT max_param_size)1660 UINT  _nxe_http_server_param_get(NX_PACKET *packet_ptr, UINT param_number, CHAR *param_ptr, UINT max_param_size)
1661 {
1662 
1663 UINT    status;
1664 
1665 
1666     /* Check for invalid input pointers.  */
1667     if ((packet_ptr == NX_NULL) || (param_ptr == NX_NULL))
1668         return(NX_PTR_ERROR);
1669 
1670     /* Check for appropriate caller.  */
1671     NX_THREADS_ONLY_CALLER_CHECKING
1672 
1673     /* Call actual server parameter get function.  */
1674     status =  _nx_http_server_param_get(packet_ptr, param_number, param_ptr, max_param_size);
1675 
1676     /* Return completion status.  */
1677     return(status);
1678 }
1679 
1680 
1681 /**************************************************************************/
1682 /*                                                                        */
1683 /*  FUNCTION                                               RELEASE        */
1684 /*                                                                        */
1685 /*    _nx_http_server_param_get                           PORTABLE C      */
1686 /*                                                           6.1          */
1687 /*  AUTHOR                                                                */
1688 /*                                                                        */
1689 /*    Yuxin Zhou, Microsoft Corporation                                   */
1690 /*                                                                        */
1691 /*  DESCRIPTION                                                           */
1692 /*                                                                        */
1693 /*    This function returns the requested parameter specified in the URL  */
1694 /*    requested by the client. If the specified parameter is not present, */
1695 /*    a not found error is returned to the caller.                        */
1696 /*                                                                        */
1697 /*                                                                        */
1698 /*  INPUT                                                                 */
1699 /*                                                                        */
1700 /*    packet_ptr                            Pointer to HTTP request packet*/
1701 /*    param_number                          Parameter number (start at 0) */
1702 /*    param_ptr                             Pointer to destination        */
1703 /*    max_param_size                        Maximum size of destination   */
1704 /*                                                                        */
1705 /*  OUTPUT                                                                */
1706 /*                                                                        */
1707 /*    status                                Completion status             */
1708 /*                                                                        */
1709 /*  CALLS                                                                 */
1710 /*                                                                        */
1711 /*    None                                                                */
1712 /*                                                                        */
1713 /*  CALLED BY                                                             */
1714 /*                                                                        */
1715 /*    Application Code                                                    */
1716 /*                                                                        */
1717 /*  RELEASE HISTORY                                                       */
1718 /*                                                                        */
1719 /*    DATE              NAME                      DESCRIPTION             */
1720 /*                                                                        */
1721 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1722 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1723 /*                                            resulting in version 6.1    */
1724 /*                                                                        */
1725 /**************************************************************************/
_nx_http_server_param_get(NX_PACKET * packet_ptr,UINT param_number,CHAR * param_ptr,UINT max_param_size)1726 UINT  _nx_http_server_param_get(NX_PACKET *packet_ptr, UINT param_number, CHAR *param_ptr, UINT max_param_size)
1727 {
1728 
1729 UINT    i;
1730 UINT    current_param;
1731 CHAR    *buffer_ptr;
1732 
1733 
1734     /* Set the destination string to NULL.  */
1735     param_ptr[0] =  (CHAR) NX_NULL;
1736 
1737     /* Set current parameter to 0.  */
1738     current_param =  0;
1739 
1740     /* Setup a pointer to the HTTP buffer.  */
1741     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
1742 
1743     /* Position to the start of the URL.  */
1744     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != '/'))
1745     {
1746 
1747         /* Move the buffer pointer.  */
1748         buffer_ptr++;
1749     }
1750 
1751     /* Not find URL.  */
1752     if (buffer_ptr >= (CHAR *) packet_ptr -> nx_packet_append_ptr)
1753     {
1754         return(NX_HTTP_NOT_FOUND);
1755     }
1756 
1757     /* Loop through the buffer to search for the specified parameter.  */
1758     do
1759     {
1760 
1761         /* Determine if the character is a semicolon, indicating a parameter
1762            is present.  */
1763         if (*buffer_ptr == ';')
1764         {
1765 
1766             /* Yes, a parameter is present.  */
1767 
1768             /* Move the buffer pointer forward.  */
1769             buffer_ptr++;
1770 
1771             /* Is this the parameter requested?  */
1772             if (current_param == param_number)
1773             {
1774 
1775 
1776                 /* Yes, we have found the parameter.  */
1777                 for (i = 0; i < max_param_size; i++)
1778                 {
1779 
1780                     /* Check if reach the end of the packet data.  */
1781                     if (buffer_ptr >= (CHAR *)packet_ptr -> nx_packet_append_ptr)
1782                     {
1783                         return(NX_HTTP_NOT_FOUND);
1784                     }
1785 
1786                     /* Check for end of parameter.  */
1787                     if ((*buffer_ptr == ';') || (*buffer_ptr == '?') ||
1788                         (*buffer_ptr == '&') || (*buffer_ptr == ' ') ||
1789                         (*buffer_ptr == (CHAR) 13))
1790                     {
1791 
1792                         /* Yes, we are finished and need to get out of the loop.  */
1793                         break;
1794                     }
1795 
1796                     /* Otherwise, store the character in the destination.  */
1797                     param_ptr[i] =  *buffer_ptr++;
1798                 }
1799 
1800                 /* NULL terminate the parameter.  */
1801                 if (i < max_param_size)
1802                     param_ptr[i] =  (CHAR) NX_NULL;
1803 
1804                 /* Return to caller.  */
1805                 if (param_ptr[i] == (CHAR) NX_NULL)
1806                     return(NX_SUCCESS);
1807                 else
1808                     return(NX_HTTP_IMPROPERLY_TERMINATED_PARAM);
1809             }
1810             else
1811             {
1812 
1813                 /* Increment the current parameter.  */
1814                 current_param++;
1815             }
1816         }
1817         else
1818         {
1819 
1820             /* Check for any other character that signals the end of the param list.  */
1821             if ((*buffer_ptr == '?') || (*buffer_ptr == ' ') || (*buffer_ptr == '&'))
1822                 break;
1823 
1824             /* Update the buffer pointer.  */
1825             buffer_ptr++;
1826         }
1827 
1828     } while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 13));
1829 
1830     /* Return a not found error.  */
1831     return(NX_HTTP_NOT_FOUND);
1832 }
1833 
1834 
1835 /**************************************************************************/
1836 /*                                                                        */
1837 /*  FUNCTION                                               RELEASE        */
1838 /*                                                                        */
1839 /*    _nxe_http_server_query_get                          PORTABLE C      */
1840 /*                                                           6.1          */
1841 /*  AUTHOR                                                                */
1842 /*                                                                        */
1843 /*    Yuxin Zhou, Microsoft Corporation                                   */
1844 /*                                                                        */
1845 /*  DESCRIPTION                                                           */
1846 /*                                                                        */
1847 /*    This function checks for errors in the HTTP query get call.         */
1848 /*                                                                        */
1849 /*                                                                        */
1850 /*  INPUT                                                                 */
1851 /*                                                                        */
1852 /*    packet_ptr                            Pointer to HTTP request packet*/
1853 /*    query_number                          Query number (start at 0)     */
1854 /*    query_ptr                             Pointer to destination        */
1855 /*    max_query_size                        Maximum size of destination   */
1856 /*                                                                        */
1857 /*  OUTPUT                                                                */
1858 /*                                                                        */
1859 /*    status                                Completion status             */
1860 /*                                                                        */
1861 /*  CALLS                                                                 */
1862 /*                                                                        */
1863 /*    _nx_http_server_query_get             Actual server query get       */
1864 /*                                            call                        */
1865 /*                                                                        */
1866 /*  CALLED BY                                                             */
1867 /*                                                                        */
1868 /*    Application Code                                                    */
1869 /*                                                                        */
1870 /*  RELEASE HISTORY                                                       */
1871 /*                                                                        */
1872 /*    DATE              NAME                      DESCRIPTION             */
1873 /*                                                                        */
1874 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1875 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1876 /*                                            resulting in version 6.1    */
1877 /*                                                                        */
1878 /**************************************************************************/
_nxe_http_server_query_get(NX_PACKET * packet_ptr,UINT query_number,CHAR * query_ptr,UINT max_query_size)1879 UINT  _nxe_http_server_query_get(NX_PACKET *packet_ptr, UINT query_number, CHAR *query_ptr, UINT max_query_size)
1880 {
1881 
1882 UINT    status;
1883 
1884 
1885     /* Check for invalid input pointers.  */
1886     if ((packet_ptr == NX_NULL) || (query_ptr == NX_NULL))
1887         return(NX_PTR_ERROR);
1888 
1889     /* Check for appropriate caller.  */
1890     NX_THREADS_ONLY_CALLER_CHECKING
1891 
1892     /* Call actual server query get function.  */
1893     status =  _nx_http_server_query_get(packet_ptr, query_number, query_ptr, max_query_size);
1894 
1895     /* Return completion status.  */
1896     return(status);
1897 }
1898 
1899 
1900 /**************************************************************************/
1901 /*                                                                        */
1902 /*  FUNCTION                                               RELEASE        */
1903 /*                                                                        */
1904 /*    _nx_http_server_query_get                           PORTABLE C      */
1905 /*                                                           6.1          */
1906 /*  AUTHOR                                                                */
1907 /*                                                                        */
1908 /*    Yuxin Zhou, Microsoft Corporation                                   */
1909 /*                                                                        */
1910 /*  DESCRIPTION                                                           */
1911 /*                                                                        */
1912 /*    This function returns the requested query specified in the URL      */
1913 /*    requested by the client. If the specified query is not present,     */
1914 /*    a not found error is returned to the caller.                        */
1915 /*                                                                        */
1916 /*                                                                        */
1917 /*  INPUT                                                                 */
1918 /*                                                                        */
1919 /*    packet_ptr                            Pointer to HTTP request packet*/
1920 /*    query_number                          Query number (start at 0)     */
1921 /*    query_ptr                             Pointer to destination        */
1922 /*    max_query_size                        Maximum size of destination   */
1923 /*                                                                        */
1924 /*  OUTPUT                                                                */
1925 /*                                                                        */
1926 /*    status                                Completion status             */
1927 /*                                                                        */
1928 /*  CALLS                                                                 */
1929 /*                                                                        */
1930 /*    None                                                                */
1931 /*                                                                        */
1932 /*  CALLED BY                                                             */
1933 /*                                                                        */
1934 /*    Application Code                                                    */
1935 /*                                                                        */
1936 /*  RELEASE HISTORY                                                       */
1937 /*                                                                        */
1938 /*    DATE              NAME                      DESCRIPTION             */
1939 /*                                                                        */
1940 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1941 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1942 /*                                            resulting in version 6.1    */
1943 /*                                                                        */
1944 /**************************************************************************/
_nx_http_server_query_get(NX_PACKET * packet_ptr,UINT query_number,CHAR * query_ptr,UINT max_query_size)1945 UINT  _nx_http_server_query_get(NX_PACKET *packet_ptr, UINT query_number, CHAR *query_ptr, UINT max_query_size)
1946 {
1947 
1948 UINT    i;
1949 UINT    current_query;
1950 CHAR    *buffer_ptr;
1951 
1952 
1953     /* Set the destination string to NULL.  */
1954     query_ptr[0] =  (CHAR) NX_NULL;
1955 
1956     /* Set current query number to 0.  */
1957     current_query =  0;
1958 
1959     /* Setup a pointer to the HTTP buffer.  */
1960     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
1961 
1962     /* Position to the start of the URL.  */
1963     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != '/'))
1964     {
1965 
1966         /* Move the buffer pointer.  */
1967         buffer_ptr++;
1968     }
1969 
1970     /* Not find URL.  */
1971     if (buffer_ptr >= (CHAR *) packet_ptr -> nx_packet_append_ptr)
1972     {
1973         return(NX_HTTP_NOT_FOUND);
1974     }
1975 
1976     /* Loop through the buffer to search for the specified query instance.  */
1977     do
1978     {
1979 
1980         /* Determine if the character is a '?' or a '&', indicating a query
1981            is present.  */
1982         if (((*buffer_ptr == '?') && (current_query == 0)) ||
1983             ((*buffer_ptr == '&') && (current_query != 0)))
1984         {
1985 
1986             /* Yes, a query is present.  */
1987 
1988             /* Move the buffer pointer forward.  */
1989             buffer_ptr++;
1990 
1991             /* Is this the query requested?  */
1992             if (current_query == query_number)
1993             {
1994 
1995 
1996                 /* Yes, we have found the query.  */
1997                 for (i = 0; i < max_query_size; i++)
1998                 {
1999 
2000                     /* Check if reach the end of the packet data.  */
2001                     if (buffer_ptr >= (CHAR *)packet_ptr -> nx_packet_append_ptr)
2002                     {
2003                         return(NX_HTTP_NOT_FOUND);
2004                     }
2005 
2006                     /* Check for end of query.  */
2007                     if ((*buffer_ptr == ';') || (*buffer_ptr == '?') ||
2008                         (*buffer_ptr == '&') || (*buffer_ptr == ' ') ||
2009                         (*buffer_ptr == (CHAR) 13))
2010                     {
2011 
2012                         /* Yes, we are finished and need to get out of the loop.  */
2013                         break;
2014                     }
2015 
2016                     /* Otherwise, store the character in the destination.  */
2017                     query_ptr[i] =  *buffer_ptr++;
2018                 }
2019 
2020                 /* NULL terminate the query.  */
2021                 query_ptr[i] =  (CHAR) NX_NULL;
2022 
2023                 /* Return to caller.  */
2024                 if (i)
2025                     return(NX_SUCCESS);
2026                 else
2027                     return(NX_HTTP_NO_QUERY_PARSED);
2028             }
2029             else
2030             {
2031 
2032                 /* Increment the current query.  */
2033                 current_query++;
2034             }
2035         }
2036         else
2037         {
2038 
2039             /* Check for any other character that signals the end of the query list.  */
2040             if ((*buffer_ptr == '?') || (*buffer_ptr == ' ') || (*buffer_ptr == ';'))
2041                 break;
2042 
2043             /* Update the buffer pointer.  */
2044             buffer_ptr++;
2045         }
2046 
2047     } while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 13));
2048 
2049     /* Return a not found error.  */
2050     return(NX_HTTP_NOT_FOUND);
2051 }
2052 
2053 
2054 /**************************************************************************/
2055 /*                                                                        */
2056 /*  FUNCTION                                               RELEASE        */
2057 /*                                                                        */
2058 /*    _nxe_http_server_start                              PORTABLE C      */
2059 /*                                                           6.1          */
2060 /*  AUTHOR                                                                */
2061 /*                                                                        */
2062 /*    Yuxin Zhou, Microsoft Corporation                                   */
2063 /*                                                                        */
2064 /*  DESCRIPTION                                                           */
2065 /*                                                                        */
2066 /*    This function checks for errors in the HTTP server start call.      */
2067 /*                                                                        */
2068 /*                                                                        */
2069 /*  INPUT                                                                 */
2070 /*                                                                        */
2071 /*    http_server_ptr                       Pointer to HTTP server        */
2072 /*                                                                        */
2073 /*  OUTPUT                                                                */
2074 /*                                                                        */
2075 /*    status                                Completion status             */
2076 /*                                                                        */
2077 /*  CALLS                                                                 */
2078 /*                                                                        */
2079 /*    _nx_http_server_start                 Actual server start call      */
2080 /*                                                                        */
2081 /*  CALLED BY                                                             */
2082 /*                                                                        */
2083 /*    Application Code                                                    */
2084 /*                                                                        */
2085 /*  RELEASE HISTORY                                                       */
2086 /*                                                                        */
2087 /*    DATE              NAME                      DESCRIPTION             */
2088 /*                                                                        */
2089 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2090 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2091 /*                                            resulting in version 6.1    */
2092 /*                                                                        */
2093 /**************************************************************************/
_nxe_http_server_start(NX_HTTP_SERVER * http_server_ptr)2094 UINT  _nxe_http_server_start(NX_HTTP_SERVER *http_server_ptr)
2095 {
2096 
2097 UINT    status;
2098 
2099 
2100     /* Check for invalid input pointers.  */
2101     if ((http_server_ptr == NX_NULL) || (http_server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID))
2102         return(NX_PTR_ERROR);
2103 
2104     /* Call actual server start function.  */
2105     status =  _nx_http_server_start(http_server_ptr);
2106 
2107     /* Return completion status.  */
2108     return(status);
2109 }
2110 
2111 
2112 /**************************************************************************/
2113 /*                                                                        */
2114 /*  FUNCTION                                               RELEASE        */
2115 /*                                                                        */
2116 /*    _nx_http_server_start                               PORTABLE C      */
2117 /*                                                           6.1          */
2118 /*  AUTHOR                                                                */
2119 /*                                                                        */
2120 /*    Yuxin Zhou, Microsoft Corporation                                   */
2121 /*                                                                        */
2122 /*  DESCRIPTION                                                           */
2123 /*                                                                        */
2124 /*    This function starts a previously created HTTP server on the        */
2125 /*    specified IP.                                                       */
2126 /*                                                                        */
2127 /*                                                                        */
2128 /*  INPUT                                                                 */
2129 /*                                                                        */
2130 /*    http_server_ptr                       Pointer to HTTP server        */
2131 /*                                                                        */
2132 /*  OUTPUT                                                                */
2133 /*                                                                        */
2134 /*    status                                Completion status             */
2135 /*                                                                        */
2136 /*  CALLS                                                                 */
2137 /*                                                                        */
2138 /*    nx_tcp_server_socket_listen           Start listening on HTTP port  */
2139 /*    tx_thread_resume                      Resume the HTTP server thread */
2140 /*                                                                        */
2141 /*  CALLED BY                                                             */
2142 /*                                                                        */
2143 /*    Application Code                                                    */
2144 /*                                                                        */
2145 /*  RELEASE HISTORY                                                       */
2146 /*                                                                        */
2147 /*    DATE              NAME                      DESCRIPTION             */
2148 /*                                                                        */
2149 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2150 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2151 /*                                            resulting in version 6.1    */
2152 /*                                                                        */
2153 /**************************************************************************/
_nx_http_server_start(NX_HTTP_SERVER * http_server_ptr)2154 UINT  _nx_http_server_start(NX_HTTP_SERVER *http_server_ptr)
2155 {
2156 
2157 UINT    status;
2158 
2159 
2160 
2161     /* Start listening on the HTTP server port.  */
2162     status =  nx_tcp_server_socket_listen(http_server_ptr -> nx_http_server_ip_ptr, NX_HTTP_SERVER_PORT,
2163                                 &(http_server_ptr -> nx_http_server_socket), NX_HTTP_SERVER_MAX_PENDING,
2164                                 _nx_http_server_connection_present);
2165 
2166     /* Determine if the listen was unsuccessful.  */
2167     if (status != NX_SUCCESS)
2168     {
2169 
2170         /* Just return an HTTP error.  */
2171         return(status);
2172     }
2173 
2174     /* Start the HTTP server thread.  */
2175     tx_thread_resume(&(http_server_ptr -> nx_http_server_thread));
2176 
2177     /* Return successful completion.  */
2178     return(NX_SUCCESS);
2179 }
2180 
2181 
2182 /**************************************************************************/
2183 /*                                                                        */
2184 /*  FUNCTION                                               RELEASE        */
2185 /*                                                                        */
2186 /*    _nxe_http_server_stop                               PORTABLE C      */
2187 /*                                                           6.1          */
2188 /*  AUTHOR                                                                */
2189 /*                                                                        */
2190 /*    Yuxin Zhou, Microsoft Corporation                                   */
2191 /*                                                                        */
2192 /*  DESCRIPTION                                                           */
2193 /*                                                                        */
2194 /*    This function checks for errors in the HTTP server stop call.       */
2195 /*                                                                        */
2196 /*                                                                        */
2197 /*  INPUT                                                                 */
2198 /*                                                                        */
2199 /*    http_server_ptr                       Pointer to HTTP server        */
2200 /*                                                                        */
2201 /*  OUTPUT                                                                */
2202 /*                                                                        */
2203 /*    status                                Completion status             */
2204 /*                                                                        */
2205 /*  CALLS                                                                 */
2206 /*                                                                        */
2207 /*    _nx_http_server_stop                  Actual server stop call       */
2208 /*                                                                        */
2209 /*  CALLED BY                                                             */
2210 /*                                                                        */
2211 /*    Application Code                                                    */
2212 /*                                                                        */
2213 /*  RELEASE HISTORY                                                       */
2214 /*                                                                        */
2215 /*    DATE              NAME                      DESCRIPTION             */
2216 /*                                                                        */
2217 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2218 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2219 /*                                            resulting in version 6.1    */
2220 /*                                                                        */
2221 /**************************************************************************/
_nxe_http_server_stop(NX_HTTP_SERVER * http_server_ptr)2222 UINT  _nxe_http_server_stop(NX_HTTP_SERVER *http_server_ptr)
2223 {
2224 
2225 UINT    status;
2226 
2227 
2228     /* Check for invalid input pointers.  */
2229     if ((http_server_ptr == NX_NULL) || (http_server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID))
2230         return(NX_PTR_ERROR);
2231 
2232     /* Check for appropriate caller.  */
2233     NX_THREADS_ONLY_CALLER_CHECKING
2234 
2235     /* Call actual server stop function.  */
2236     status =  _nx_http_server_stop(http_server_ptr);
2237 
2238     /* Return completion status.  */
2239     return(status);
2240 }
2241 
2242 
2243 /**************************************************************************/
2244 /*                                                                        */
2245 /*  FUNCTION                                               RELEASE        */
2246 /*                                                                        */
2247 /*    _nx_http_server_stop                                PORTABLE C      */
2248 /*                                                           6.2.0        */
2249 /*  AUTHOR                                                                */
2250 /*                                                                        */
2251 /*    Yuxin Zhou, Microsoft Corporation                                   */
2252 /*                                                                        */
2253 /*  DESCRIPTION                                                           */
2254 /*                                                                        */
2255 /*    This function stops a previously started HTTP server on the         */
2256 /*    specified IP.                                                       */
2257 /*                                                                        */
2258 /*                                                                        */
2259 /*  INPUT                                                                 */
2260 /*                                                                        */
2261 /*    http_server_ptr                       Pointer to HTTP server        */
2262 /*                                                                        */
2263 /*  OUTPUT                                                                */
2264 /*                                                                        */
2265 /*    status                                Completion status             */
2266 /*                                                                        */
2267 /*  CALLS                                                                 */
2268 /*                                                                        */
2269 /*    _nx_http_server_disconnect            Disconnect HTTP server socket */
2270 /*    nx_tcp_server_socket_unlisten         Unlisten on the HTTP port     */
2271 /*    tx_thread_suspend                     Suspend the HTTP server thread*/
2272 /*                                                                        */
2273 /*  CALLED BY                                                             */
2274 /*                                                                        */
2275 /*    Application Code                                                    */
2276 /*                                                                        */
2277 /*  RELEASE HISTORY                                                       */
2278 /*                                                                        */
2279 /*    DATE              NAME                      DESCRIPTION             */
2280 /*                                                                        */
2281 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2282 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2283 /*                                            resulting in version 6.1    */
2284 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
2285 /*                                            supported random nonce,     */
2286 /*                                            resulting in version 6.2.0  */
2287 /*                                                                        */
2288 /**************************************************************************/
_nx_http_server_stop(NX_HTTP_SERVER * http_server_ptr)2289 UINT  _nx_http_server_stop(NX_HTTP_SERVER *http_server_ptr)
2290 {
2291 
2292     /* Disconnect the TCP socket.  */
2293     _nx_http_server_disconnect(http_server_ptr, NX_NO_WAIT);
2294 
2295     /* Unlisten on the HTTP server port.  */
2296     nx_tcp_server_socket_unlisten(http_server_ptr -> nx_http_server_ip_ptr, NX_HTTP_SERVER_PORT);
2297 
2298     /* Suspend the HTTP server thread.  */
2299     tx_thread_suspend(&(http_server_ptr -> nx_http_server_thread));
2300 
2301     /* Return successful completion.  */
2302     return(NX_SUCCESS);
2303 }
2304 
2305 
2306 /**************************************************************************/
2307 /*                                                                        */
2308 /*  FUNCTION                                               RELEASE        */
2309 /*                                                                        */
2310 /*    _nx_http_server_disconnect                          PORTABLE C      */
2311 /*                                                           6.2.0        */
2312 /*  AUTHOR                                                                */
2313 /*                                                                        */
2314 /*    Yuxin Zhou, Microsoft Corporation                                   */
2315 /*                                                                        */
2316 /*  DESCRIPTION                                                           */
2317 /*                                                                        */
2318 /*    This function disconnects the HTTP server socket.                   */
2319 /*                                                                        */
2320 /*                                                                        */
2321 /*  INPUT                                                                 */
2322 /*                                                                        */
2323 /*    http_server_ptr                       Pointer to HTTP server        */
2324 /*    wait_option                           Wait option                   */
2325 /*                                                                        */
2326 /*  OUTPUT                                                                */
2327 /*                                                                        */
2328 /*    status                                Completion status             */
2329 /*                                                                        */
2330 /*  CALLS                                                                 */
2331 /*                                                                        */
2332 /*    nx_tcp_socket_disconnect              Disconnect HTTP server socket */
2333 /*    nx_tcp_socket_unaccept                Unaccept HTTP server connect  */
2334 /*                                                                        */
2335 /*  CALLED BY                                                             */
2336 /*                                                                        */
2337 /*    Application Code                                                    */
2338 /*                                                                        */
2339 /*  RELEASE HISTORY                                                       */
2340 /*                                                                        */
2341 /*    DATE              NAME                      DESCRIPTION             */
2342 /*                                                                        */
2343 /*  10-31-2022     Yuxin Zhou               Initial Version 6.2.0         */
2344 /*                                                                        */
2345 /**************************************************************************/
_nx_http_server_disconnect(NX_HTTP_SERVER * http_server_ptr,UINT wait_option)2346 UINT  _nx_http_server_disconnect(NX_HTTP_SERVER *http_server_ptr, UINT wait_option)
2347 {
2348 
2349 #ifdef NX_HTTP_DIGEST_ENABLE
2350 UINT i;
2351 
2352     /* Once the nonce has been accepted, set the state as invalid. */
2353     for (i = 0; i < NX_HTTP_SERVER_NONCE_MAX; i++)
2354     {
2355         if (http_server_ptr -> nx_http_server_nonces[i].nonce_state == NX_HTTP_SERVER_NONCE_ACCEPTED)
2356         {
2357             http_server_ptr -> nx_http_server_nonces[i].nonce_state = NX_HTTP_SERVER_NONCE_INVALID;
2358             break;
2359         }
2360     }
2361 #endif /* NX_HTTP_DIGEST_ENABLE  */
2362 
2363     /* Disconnect the TCP socket.  */
2364     nx_tcp_socket_disconnect(&(http_server_ptr -> nx_http_server_socket), wait_option);
2365 
2366     /* Unaccept any remaining connection on the TCP socket.  */
2367     nx_tcp_server_socket_unaccept(&(http_server_ptr -> nx_http_server_socket));
2368 
2369     /* Return successful completion.  */
2370     return(NX_SUCCESS);
2371 }
2372 
2373 
2374 /**************************************************************************/
2375 /*                                                                        */
2376 /*  FUNCTION                                               RELEASE        */
2377 /*                                                                        */
2378 /*    _nxe_http_server_callback_data_send                 PORTABLE C      */
2379 /*                                                           6.1          */
2380 /*  AUTHOR                                                                */
2381 /*                                                                        */
2382 /*    Yuxin Zhou, Microsoft Corporation                                   */
2383 /*                                                                        */
2384 /*  DESCRIPTION                                                           */
2385 /*                                                                        */
2386 /*    This function checks errors for sending data.                       */
2387 /*                                                                        */
2388 /*                                                                        */
2389 /*  INPUT                                                                 */
2390 /*                                                                        */
2391 /*    http_server_ptr                       Pointer to HTTP server        */
2392 /*    data_ptr                              Pointer to data to send       */
2393 /*    data_length                           Length of data to send        */
2394 /*                                                                        */
2395 /*  OUTPUT                                                                */
2396 /*                                                                        */
2397 /*    status                                Completion status             */
2398 /*                                                                        */
2399 /*  CALLS                                                                 */
2400 /*                                                                        */
2401 /*    _nx_http_server_callback_data_send    Actual data send call         */
2402 /*                                                                        */
2403 /*  CALLED BY                                                             */
2404 /*                                                                        */
2405 /*    Application Code                                                    */
2406 /*                                                                        */
2407 /*  RELEASE HISTORY                                                       */
2408 /*                                                                        */
2409 /*    DATE              NAME                      DESCRIPTION             */
2410 /*                                                                        */
2411 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2412 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2413 /*                                            resulting in version 6.1    */
2414 /*                                                                        */
2415 /**************************************************************************/
_nxe_http_server_callback_data_send(NX_HTTP_SERVER * server_ptr,VOID * data_ptr,ULONG data_length)2416 UINT  _nxe_http_server_callback_data_send(NX_HTTP_SERVER *server_ptr, VOID *data_ptr, ULONG data_length)
2417 {
2418 UINT    status;
2419 
2420 
2421     /* Check for invalid input pointers.  */
2422     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID))
2423         return(NX_PTR_ERROR);
2424 
2425     /* Check for appropriate caller.  */
2426     NX_THREADS_ONLY_CALLER_CHECKING
2427 
2428     /* Call actual data send function.  */
2429     status =  _nx_http_server_callback_data_send(server_ptr, data_ptr, data_length);
2430 
2431     /* Return completion status.  */
2432     return(status);
2433 }
2434 
2435 
2436 /**************************************************************************/
2437 /*                                                                        */
2438 /*  FUNCTION                                               RELEASE        */
2439 /*                                                                        */
2440 /*    _nx_http_server_callback_data_send                  PORTABLE C      */
2441 /*                                                           6.1          */
2442 /*  AUTHOR                                                                */
2443 /*                                                                        */
2444 /*    Yuxin Zhou, Microsoft Corporation                                   */
2445 /*                                                                        */
2446 /*  DESCRIPTION                                                           */
2447 /*                                                                        */
2448 /*    This function sends data to the client from the application         */
2449 /*    callback function. This is typically done to satisfy a GET or       */
2450 /*    POST request that is processed completely by the application        */
2451 /*    callback function.                                                  */
2452 /*                                                                        */
2453 /*                                                                        */
2454 /*  INPUT                                                                 */
2455 /*                                                                        */
2456 /*    http_server_ptr                       Pointer to HTTP server        */
2457 /*    data_ptr                              Pointer to data to send       */
2458 /*    data_length                           Length of data to send        */
2459 /*                                                                        */
2460 /*  OUTPUT                                                                */
2461 /*                                                                        */
2462 /*    status                                Completion status             */
2463 /*                                                                        */
2464 /*  CALLS                                                                 */
2465 /*                                                                        */
2466 /*    nx_packet_allocate                    Allocate a NetX packet        */
2467 /*    nx_packet_data_append                 Append data to packet         */
2468 /*    nx_tcp_socket_send                    Send TCP data                 */
2469 /*                                                                        */
2470 /*  CALLED BY                                                             */
2471 /*                                                                        */
2472 /*    Application Code                                                    */
2473 /*                                                                        */
2474 /*  RELEASE HISTORY                                                       */
2475 /*                                                                        */
2476 /*    DATE              NAME                      DESCRIPTION             */
2477 /*                                                                        */
2478 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2479 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2480 /*                                            resulting in version 6.1    */
2481 /*                                                                        */
2482 /**************************************************************************/
_nx_http_server_callback_data_send(NX_HTTP_SERVER * server_ptr,VOID * data_ptr,ULONG data_length)2483 UINT  _nx_http_server_callback_data_send(NX_HTTP_SERVER *server_ptr, VOID *data_ptr, ULONG data_length)
2484 {
2485 
2486 NX_PACKET   *new_packet_ptr;
2487 UINT        status;
2488 
2489 
2490     /* Allocate a new packet for data.  */
2491     status =  nx_packet_allocate(server_ptr -> nx_http_server_packet_pool_ptr, &new_packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER);
2492 
2493     /* Determine if an error is present.  */
2494     if (status != NX_SUCCESS)
2495     {
2496 
2497         /* Indicate an allocation error occurred.  */
2498         server_ptr -> nx_http_server_allocation_errors++;
2499 
2500         /* Error, return to caller.  */
2501         return(NX_HTTP_ERROR);
2502     }
2503 
2504     /* Now append the data to the packet.  */
2505     status =  nx_packet_data_append(new_packet_ptr, data_ptr, data_length,
2506                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
2507 
2508     /* Determine if an error is present.  */
2509     if (status != NX_SUCCESS)
2510     {
2511 
2512         /* Indicate an allocation error occurred.  */
2513         server_ptr -> nx_http_server_allocation_errors++;
2514 
2515         /* Release the initial packet.  */
2516         nx_packet_release(new_packet_ptr);
2517 
2518         /* Error, return to caller.  */
2519         return(status);
2520     }
2521 
2522     /* Send the data back to the client.  */
2523     status =  nx_tcp_socket_send(&(server_ptr -> nx_http_server_socket), new_packet_ptr, NX_HTTP_SERVER_TIMEOUT_SEND);
2524 
2525     /* Determine if this is successful.  */
2526     if (status != NX_SUCCESS)
2527     {
2528 
2529         /* Map the status to the generic HTTP error.  */
2530         status =  status;
2531 
2532         /* Release the packet.  */
2533         nx_packet_release(new_packet_ptr);
2534     }
2535 
2536     /* Return completion status.  */
2537     return(status);
2538 }
2539 
2540 
2541 /**************************************************************************/
2542 /*                                                                        */
2543 /*  FUNCTION                                               RELEASE        */
2544 /*                                                                        */
2545 /*    _nxe_http_server_callback_response_send             PORTABLE C      */
2546 /*                                                           6.1          */
2547 /*  AUTHOR                                                                */
2548 /*                                                                        */
2549 /*    Yuxin Zhou, Microsoft Corporation                                   */
2550 /*                                                                        */
2551 /*  DESCRIPTION                                                           */
2552 /*                                                                        */
2553 /*    This function checks errors for sending HTTP response.              */
2554 /*                                                                        */
2555 /*                                                                        */
2556 /*  INPUT                                                                 */
2557 /*                                                                        */
2558 /*    http_server_ptr                       Pointer to HTTP server        */
2559 /*    header                                Pointer to HTTP header string */
2560 /*    information                           Pointer to HTTP info string   */
2561 /*    additional_information                Pointer to additional HTTP    */
2562 /*                                            information                 */
2563 /*                                                                        */
2564 /*  OUTPUT                                                                */
2565 /*                                                                        */
2566 /*    status                                Completion status             */
2567 /*                                                                        */
2568 /*  CALLS                                                                 */
2569 /*                                                                        */
2570 /*    _nx_http_server_callback_response_send                              */
2571 /*                                          Actual HTTP response send call*/
2572 /*                                                                        */
2573 /*  CALLED BY                                                             */
2574 /*                                                                        */
2575 /*    Application Code                                                    */
2576 /*                                                                        */
2577 /*  RELEASE HISTORY                                                       */
2578 /*                                                                        */
2579 /*    DATE              NAME                      DESCRIPTION             */
2580 /*                                                                        */
2581 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2582 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2583 /*                                            resulting in version 6.1    */
2584 /*                                                                        */
2585 /**************************************************************************/
_nxe_http_server_callback_response_send(NX_HTTP_SERVER * server_ptr,CHAR * header,CHAR * information,CHAR * additional_info)2586 UINT  _nxe_http_server_callback_response_send(NX_HTTP_SERVER *server_ptr, CHAR *header, CHAR *information, CHAR *additional_info)
2587 {
2588 UINT    status;
2589 
2590 
2591     /* Check for invalid input pointers.  */
2592     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) || (header == NX_NULL))
2593         return(NX_PTR_ERROR);
2594 
2595     /* Check for appropriate caller.  */
2596     NX_THREADS_ONLY_CALLER_CHECKING
2597 
2598     /* Call actual data send function.  */
2599     status =  _nx_http_server_callback_response_send(server_ptr, header, information, additional_info);
2600 
2601     /* Return completion status.  */
2602     return(status);
2603 }
2604 
2605 
2606 /**************************************************************************/
2607 /*                                                                        */
2608 /*  FUNCTION                                               RELEASE        */
2609 /*                                                                        */
2610 /*    _nx_http_server_callback_response_send              PORTABLE C      */
2611 /*                                                           6.1          */
2612 /*  AUTHOR                                                                */
2613 /*                                                                        */
2614 /*    Yuxin Zhou, Microsoft Corporation                                   */
2615 /*                                                                        */
2616 /*  DESCRIPTION                                                           */
2617 /*                                                                        */
2618 /*    This function sends the completion response to the client from the  */
2619 /*    application callback function. This is typically done to satisfy a  */
2620 /*    GET or POST request that is processed completely by the application */
2621 /*    callback function.                                                  */
2622 /*                                                                        */
2623 /*                                                                        */
2624 /*  INPUT                                                                 */
2625 /*                                                                        */
2626 /*    http_server_ptr                       Pointer to HTTP server        */
2627 /*    header                                Pointer to HTTP header string */
2628 /*    information                           Pointer to HTTP info string   */
2629 /*    additional_information                Pointer to additional HTTP    */
2630 /*                                            information                 */
2631 /*                                                                        */
2632 /*  OUTPUT                                                                */
2633 /*                                                                        */
2634 /*    status                                Completion status             */
2635 /*                                                                        */
2636 /*  CALLS                                                                 */
2637 /*                                                                        */
2638 /*    _nx_http_server_response_send         Send HTTP response            */
2639 /*    _nx_utility_string_length_check       Check string length           */
2640 /*                                                                        */
2641 /*  CALLED BY                                                             */
2642 /*                                                                        */
2643 /*    Application Code                                                    */
2644 /*                                                                        */
2645 /*  RELEASE HISTORY                                                       */
2646 /*                                                                        */
2647 /*    DATE              NAME                      DESCRIPTION             */
2648 /*                                                                        */
2649 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2650 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2651 /*                                            resulting in version 6.1    */
2652 /*                                                                        */
2653 /**************************************************************************/
_nx_http_server_callback_response_send(NX_HTTP_SERVER * server_ptr,CHAR * header,CHAR * information,CHAR * additional_info)2654 UINT  _nx_http_server_callback_response_send(NX_HTTP_SERVER *server_ptr, CHAR *header, CHAR *information, CHAR *additional_info)
2655 {
2656 
2657 UINT header_length = 0;
2658 UINT information_length = 0;
2659 UINT additional_info_length = 0;
2660 UINT status;
2661 
2662     /* Check length of header, information and additional information.  */
2663     if (_nx_utility_string_length_check(header, &header_length, NX_MAX_STRING_LENGTH) ||
2664         (information && _nx_utility_string_length_check(information, &information_length, NX_MAX_STRING_LENGTH)) ||
2665         (additional_info && _nx_utility_string_length_check(additional_info, &additional_info_length, NX_MAX_STRING_LENGTH)))
2666     {
2667         return(NX_HTTP_ERROR);
2668     }
2669 
2670     /* Call the internal HTTP response send function.  */
2671     status = _nx_http_server_response_send(server_ptr, header, header_length, information, information_length, additional_info, additional_info_length);
2672 
2673     /* Return status.  */
2674     return(status);
2675 }
2676 
2677 
2678 /**************************************************************************/
2679 /*                                                                        */
2680 /*  FUNCTION                                               RELEASE        */
2681 /*                                                                        */
2682 /*    _nxe_http_server_callback_response_send_extended    PORTABLE C      */
2683 /*                                                           6.1          */
2684 /*  AUTHOR                                                                */
2685 /*                                                                        */
2686 /*    Yuxin Zhou, Microsoft Corporation                                   */
2687 /*                                                                        */
2688 /*  DESCRIPTION                                                           */
2689 /*                                                                        */
2690 /*    This function checks errors for sending HTTP response.              */
2691 /*                                                                        */
2692 /*                                                                        */
2693 /*  INPUT                                                                 */
2694 /*                                                                        */
2695 /*    http_server_ptr                       Pointer to HTTP server        */
2696 /*    header                                Pointer to HTTP header string */
2697 /*    header_length                         Length of HTTP header string  */
2698 /*    information                           Pointer to HTTP info string   */
2699 /*    information_length                    Length of HTTP info string    */
2700 /*    additional_info                       Pointer to additional HTTP    */
2701 /*                                            information                 */
2702 /*    additional_info_length                Length of additional HTTP     */
2703 /*                                            information                 */
2704 /*                                                                        */
2705 /*  OUTPUT                                                                */
2706 /*                                                                        */
2707 /*    status                                Completion status             */
2708 /*                                                                        */
2709 /*  CALLS                                                                 */
2710 /*                                                                        */
2711 /*    _nx_http_server_callback_response_send_extended                     */
2712 /*                                          Actual HTTP response send call*/
2713 /*                                                                        */
2714 /*  CALLED BY                                                             */
2715 /*                                                                        */
2716 /*    Application Code                                                    */
2717 /*                                                                        */
2718 /*  RELEASE HISTORY                                                       */
2719 /*                                                                        */
2720 /*    DATE              NAME                      DESCRIPTION             */
2721 /*                                                                        */
2722 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2723 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2724 /*                                            resulting in version 6.1    */
2725 /*                                                                        */
2726 /**************************************************************************/
_nxe_http_server_callback_response_send_extended(NX_HTTP_SERVER * server_ptr,CHAR * header,UINT header_length,CHAR * information,UINT information_length,CHAR * additional_info,UINT additional_info_length)2727 UINT  _nxe_http_server_callback_response_send_extended(NX_HTTP_SERVER *server_ptr, CHAR *header, UINT header_length, CHAR *information,
2728                                                       UINT information_length, CHAR *additional_info, UINT additional_info_length)
2729 {
2730 UINT    status;
2731 
2732 
2733     /* Check for invalid input pointers.  */
2734     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) || (header == NX_NULL))
2735         return(NX_PTR_ERROR);
2736 
2737     /* Check for appropriate caller.  */
2738     NX_THREADS_ONLY_CALLER_CHECKING
2739 
2740     /* Call actual data send function.  */
2741     status =  _nx_http_server_callback_response_send_extended(server_ptr, header, header_length, information,
2742                                                               information_length, additional_info, additional_info_length);
2743 
2744     /* Return completion status.  */
2745     return(status);
2746 }
2747 
2748 
2749 /**************************************************************************/
2750 /*                                                                        */
2751 /*  FUNCTION                                               RELEASE        */
2752 /*                                                                        */
2753 /*    _nx_http_server_callback_response_send_extended     PORTABLE C      */
2754 /*                                                           6.1          */
2755 /*  AUTHOR                                                                */
2756 /*                                                                        */
2757 /*    Yuxin Zhou, Microsoft Corporation                                   */
2758 /*                                                                        */
2759 /*  DESCRIPTION                                                           */
2760 /*                                                                        */
2761 /*    This function sends the completion response to the client from the  */
2762 /*    application callback function. This is typically done to satisfy a  */
2763 /*    GET or POST request that is processed completely by the application */
2764 /*    callback function.                                                  */
2765 /*                                                                        */
2766 /*    Note: The strings of header, information and additional info must   */
2767 /*    be NULL-terminated and length of this string matches the length     */
2768 /*    specified in the argument list.                                     */
2769 /*                                                                        */
2770 /*                                                                        */
2771 /*  INPUT                                                                 */
2772 /*                                                                        */
2773 /*    http_server_ptr                       Pointer to HTTP server        */
2774 /*    header                                Pointer to HTTP header string */
2775 /*    header_length                         Length of HTTP header string  */
2776 /*    information                           Pointer to HTTP info string   */
2777 /*    information_length                    Length of HTTP info string    */
2778 /*    additional_info                       Pointer to additional HTTP    */
2779 /*                                            information                 */
2780 /*    additional_info_length                Length of additional HTTP     */
2781 /*                                            information                 */
2782 /*                                                                        */
2783 /*  OUTPUT                                                                */
2784 /*                                                                        */
2785 /*    status                                Completion status             */
2786 /*                                                                        */
2787 /*  CALLS                                                                 */
2788 /*                                                                        */
2789 /*    _nx_http_server_response_send         Send HTTP response            */
2790 /*    _nx_utility_string_length_check       Check string length           */
2791 /*                                                                        */
2792 /*  CALLED BY                                                             */
2793 /*                                                                        */
2794 /*    Application Code                                                    */
2795 /*                                                                        */
2796 /*  RELEASE HISTORY                                                       */
2797 /*                                                                        */
2798 /*    DATE              NAME                      DESCRIPTION             */
2799 /*                                                                        */
2800 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2801 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2802 /*                                            resulting in version 6.1    */
2803 /*                                                                        */
2804 /**************************************************************************/
_nx_http_server_callback_response_send_extended(NX_HTTP_SERVER * server_ptr,CHAR * header,UINT header_length,CHAR * information,UINT information_length,CHAR * additional_info,UINT additional_info_length)2805 UINT  _nx_http_server_callback_response_send_extended(NX_HTTP_SERVER *server_ptr, CHAR *header, UINT header_length, CHAR *information,
2806                                                       UINT information_length, CHAR *additional_info, UINT additional_info_length)
2807 {
2808 UINT status;
2809 UINT temp_header_length = 0;
2810 UINT temp_information_length = 0;
2811 UINT temp_additional_info_length = 0;
2812 
2813     /* Check length of header, information and additional information.  */
2814     if (_nx_utility_string_length_check(header, &temp_header_length, NX_MAX_STRING_LENGTH) ||
2815         (information && _nx_utility_string_length_check(information, &temp_information_length, NX_MAX_STRING_LENGTH)) ||
2816         (additional_info && _nx_utility_string_length_check(additional_info, &temp_additional_info_length, NX_MAX_STRING_LENGTH)))
2817     {
2818         return(NX_HTTP_ERROR);
2819     }
2820 
2821     /* Validate string length.  */
2822     if ((temp_header_length != header_length) ||
2823         (information && (temp_information_length != information_length)) ||
2824         (additional_info && (temp_additional_info_length != additional_info_length)))
2825     {
2826         return(NX_HTTP_ERROR);
2827     }
2828 
2829     /* Call the internal HTTP response send function.  */
2830     status = _nx_http_server_response_send(server_ptr, header, header_length, information, information_length, additional_info, additional_info_length);
2831 
2832     /* Return status.  */
2833     return(status);
2834 }
2835 
2836 
2837 /**************************************************************************/
2838 /*                                                                        */
2839 /*  FUNCTION                                               RELEASE        */
2840 /*                                                                        */
2841 /*    _nx_http_server_connection_present                  PORTABLE C      */
2842 /*                                                           6.1          */
2843 /*  AUTHOR                                                                */
2844 /*                                                                        */
2845 /*    Yuxin Zhou, Microsoft Corporation                                   */
2846 /*                                                                        */
2847 /*  DESCRIPTION                                                           */
2848 /*                                                                        */
2849 /*    This function is the callback function executed whenever a client   */
2850 /*    connection appears on the HTTP Server port.  It is responsible for  */
2851 /*    waking up the HTTP Server thread.                                   */
2852 /*                                                                        */
2853 /*                                                                        */
2854 /*  INPUT                                                                 */
2855 /*                                                                        */
2856 /*    socket_ptr                            Pointer to HTTP Server socket */
2857 /*    port                                  HTTP Server port              */
2858 /*                                                                        */
2859 /*  OUTPUT                                                                */
2860 /*                                                                        */
2861 /*    None                                                                */
2862 /*                                                                        */
2863 /*  CALLS                                                                 */
2864 /*                                                                        */
2865 /*    tx_thread_resume                      Server thread resume          */
2866 /*                                                                        */
2867 /*  CALLED BY                                                             */
2868 /*                                                                        */
2869 /*    NetX                                                                */
2870 /*                                                                        */
2871 /*  RELEASE HISTORY                                                       */
2872 /*                                                                        */
2873 /*    DATE              NAME                      DESCRIPTION             */
2874 /*                                                                        */
2875 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2876 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2877 /*                                            resulting in version 6.1    */
2878 /*                                                                        */
2879 /**************************************************************************/
_nx_http_server_connection_present(NX_TCP_SOCKET * socket_ptr,UINT port)2880 VOID  _nx_http_server_connection_present(NX_TCP_SOCKET *socket_ptr, UINT port)
2881 {
2882 
2883 NX_HTTP_SERVER *server_ptr;
2884 
2885     NX_PARAMETER_NOT_USED(port);
2886 
2887     /* Pickup the server pointer.  */
2888     server_ptr =  (NX_HTTP_SERVER *) socket_ptr -> nx_tcp_socket_reserved_ptr;
2889 
2890     /* Set the connection pending flag.  */
2891     server_ptr -> nx_http_connection_pending =  NX_TRUE;
2892 
2893     /* Resume the HTTP Server thread.  */
2894     tx_thread_resume(&(server_ptr -> nx_http_server_thread));
2895 }
2896 
2897 
2898 /**************************************************************************/
2899 /*                                                                        */
2900 /*  FUNCTION                                               RELEASE        */
2901 /*                                                                        */
2902 /*    _nx_http_server_thread_entry                        PORTABLE C      */
2903 /*                                                           6.2.0        */
2904 /*  AUTHOR                                                                */
2905 /*                                                                        */
2906 /*    Yuxin Zhou, Microsoft Corporation                                   */
2907 /*                                                                        */
2908 /*  DESCRIPTION                                                           */
2909 /*                                                                        */
2910 /*    This function is the entry of the HTTP server.  All basic           */
2911 /*    processing is initiated by this function.                           */
2912 /*                                                                        */
2913 /*                                                                        */
2914 /*  INPUT                                                                 */
2915 /*                                                                        */
2916 /*    http_server_address                   Pointer to HTTP server        */
2917 /*                                                                        */
2918 /*  OUTPUT                                                                */
2919 /*                                                                        */
2920 /*    status                                Completion status             */
2921 /*                                                                        */
2922 /*  CALLS                                                                 */
2923 /*                                                                        */
2924 /*    _nx_http_server_delete_process        Process client DELETE request */
2925 /*    _nx_http_server_get_client_request    Get complete HTTP request     */
2926 /*    _nx_http_server_get_process           Process client GET request    */
2927 /*    _nx_http_server_put_process           Process client PUT request    */
2928 /*    _nx_http_server_response_send         Send HTTP Server response     */
2929 /*    nx_packet_release                     Release request packet        */
2930 /*    nx_tcp_server_socket_accept           Accept HTTP client connect    */
2931 /*    _nx_http_server_disconnect            Disconnect HTTP server socket */
2932 /*    nx_tcp_server_socket_relisten         Relisten for another HTTP     */
2933 /*                                            client connection           */
2934 /*    tx_thread_preemption_change           Disable/restore preemption    */
2935 /*    tx_thread_suspend                     Self suspend HTTP thread      */
2936 /*                                                                        */
2937 /*  CALLED BY                                                             */
2938 /*                                                                        */
2939 /*    ThreadX                                                             */
2940 /*                                                                        */
2941 /*  RELEASE HISTORY                                                       */
2942 /*                                                                        */
2943 /*    DATE              NAME                      DESCRIPTION             */
2944 /*                                                                        */
2945 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2946 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2947 /*                                            resulting in version 6.1    */
2948 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
2949 /*                                            supported random nonce,     */
2950 /*                                            resulting in version 6.2.0  */
2951 /*                                                                        */
2952 /**************************************************************************/
_nx_http_server_thread_entry(ULONG http_server)2953 VOID  _nx_http_server_thread_entry(ULONG http_server)
2954 {
2955 
2956 NX_HTTP_SERVER          *server_ptr;
2957 NX_PACKET               *packet_ptr;
2958 UCHAR                   *buffer_ptr;
2959 UINT                    original_threshold;
2960 UINT                    status;
2961 UINT                    loop_endlessly = NX_TRUE;
2962 
2963 
2964     /* Set the HTTP server pointer.  */
2965     server_ptr =  (NX_HTTP_SERVER *) http_server;
2966 
2967     /* Loop to process HTTP Server requests.  */
2968     while(loop_endlessly)
2969     {
2970 
2971         /* Temporarily disable preemption.  */
2972         tx_thread_preemption_change(&(server_ptr -> nx_http_server_thread), 0, &original_threshold);
2973 
2974         /* Is the connection pending flag not set?  */
2975         if (server_ptr -> nx_http_connection_pending == NX_FALSE)
2976         {
2977 
2978             /* If not, suspend the server thread.  */
2979             tx_thread_suspend(&(server_ptr -> nx_http_server_thread));
2980         }
2981 
2982         /* Clear the connection pending flag.  */
2983         server_ptr -> nx_http_connection_pending = NX_FALSE;
2984 
2985         /* Restore preemption.  */
2986         tx_thread_preemption_change(&(server_ptr -> nx_http_server_thread), original_threshold, &original_threshold);
2987 
2988         /* Wait for connection on HTTP Server port.  */
2989         status =  nx_tcp_server_socket_accept(&(server_ptr -> nx_http_server_socket), NX_HTTP_SERVER_TIMEOUT_ACCEPT);
2990 
2991         /* Determine if we have an HTTP connection error.  */
2992         if (status != NX_SUCCESS)
2993         {
2994 
2995             /* Increment the number of failed connections.  */
2996             server_ptr -> nx_http_server_connection_failures++;
2997 
2998             /* Unaccept the connection.  */
2999             nx_tcp_server_socket_unaccept(&(server_ptr -> nx_http_server_socket));
3000 
3001             /* Relisten on the HTTP Server port.  */
3002             nx_tcp_server_socket_relisten(server_ptr -> nx_http_server_ip_ptr, NX_HTTP_SERVER_PORT,
3003                                                                 &(server_ptr -> nx_http_server_socket));
3004             /* Restart the loop.  */
3005             continue;
3006         }
3007 
3008         /* Increment the number of successful connections.  */
3009         server_ptr -> nx_http_server_connection_successes++;
3010 
3011         /* Get the complete HTTP client request.  */
3012         status =  _nx_http_server_get_client_request(server_ptr, &packet_ptr);
3013 
3014         /* Check if the HTTP request is valid.  */
3015         if (status == NX_SUCCESS)
3016         {
3017             if (packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr < 7)
3018             {
3019                 nx_packet_release(packet_ptr);
3020                 status = NX_HTTP_ERROR;
3021             }
3022         }
3023 
3024         /* Determine if it was successful.  */
3025         if (status != NX_SUCCESS)
3026         {
3027 
3028             if(status != NX_NO_PACKET)
3029             {
3030 
3031                 /* Increment the number of invalid HTTP requests.  */
3032                 server_ptr -> nx_http_server_invalid_http_headers++;
3033             }
3034 
3035             /* Disconnect from the current connection.  */
3036             _nx_http_server_disconnect(server_ptr, NX_HTTP_SERVER_TIMEOUT_DISCONNECT);
3037 
3038             /* Relisten on the HTTP Server port.  */
3039             nx_tcp_server_socket_relisten(server_ptr -> nx_http_server_ip_ptr, NX_HTTP_SERVER_PORT,
3040                                                                 &(server_ptr -> nx_http_server_socket));
3041             /* Restart the loop.  */
3042             continue;
3043         }
3044 
3045         /* Otherwise, we have received an HTTP client request successfully.  */
3046 
3047         /* Setup a pointer to packet buffer area.  */
3048         buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
3049 
3050         /* Determine what type of request is present.  */
3051 
3052         /* Check for a GET request.  */
3053         if ((buffer_ptr[0] == 'G') && (buffer_ptr[1] == 'E') && (buffer_ptr[2] == 'T') && (buffer_ptr[3] == ' '))
3054         {
3055 
3056             /* We have a HTTP GET request to get a resource from this HTTP Server.  */
3057             server_ptr -> nx_http_server_request_type = NX_HTTP_SERVER_GET_REQUEST;
3058 
3059             /* Increment the number of GET requests.  */
3060             server_ptr -> nx_http_server_get_requests++;
3061 
3062             /* Process the GET request.  */
3063             _nx_http_server_get_process(server_ptr, NX_HTTP_SERVER_GET_REQUEST, packet_ptr);
3064         }
3065 
3066         /* Check for a PUT request.  */
3067         else if ((buffer_ptr[0] == 'P') && (buffer_ptr[1] == 'U') && (buffer_ptr[2] == 'T') && (buffer_ptr[3] == ' '))
3068         {
3069 
3070             /* We have a HTTP PUT request to store a resource on this HTTP Server.  */
3071             server_ptr -> nx_http_server_request_type = NX_HTTP_SERVER_PUT_REQUEST;
3072 
3073             /* Increment the number of PUT requests.  */
3074             server_ptr -> nx_http_server_put_requests++;
3075 
3076             /* Process the PUT request.  */
3077             _nx_http_server_put_process(server_ptr, packet_ptr);
3078         }
3079 
3080         /* Check for a DELETE request.  */
3081         else if ((buffer_ptr[0] == 'D') && (buffer_ptr[1] == 'E') && (buffer_ptr[2] == 'L') && (buffer_ptr[3] == 'E') &&
3082                  (buffer_ptr[4] == 'T') && (buffer_ptr[5] == 'E') && (buffer_ptr[6] == ' '))
3083         {
3084 
3085             /* We have a HTTP DELETE request to delete a resource from this HTTP Server.  */
3086             server_ptr -> nx_http_server_request_type = NX_HTTP_SERVER_DELETE_REQUEST;
3087 
3088             /* Increment the number of DELETE requests.  */
3089             server_ptr -> nx_http_server_delete_requests++;
3090 
3091             /* Process the Delete request.  */
3092             _nx_http_server_delete_process(server_ptr, packet_ptr);
3093         }
3094 
3095         /* Check for a POST request.  */
3096         else if ((buffer_ptr[0] == 'P') && (buffer_ptr[1] == 'O') && (buffer_ptr[2] == 'S') &&
3097                  (buffer_ptr[3] == 'T') && (buffer_ptr[4] == ' '))
3098         {
3099 
3100             /* We have a HTTP POST request to send data to this HTTP Server for processing.  Note that the POST
3101                request is nearly identical to the GET request, except the parameter/query data is found in the
3102                content rather than as part of the URL (resource). */
3103             server_ptr -> nx_http_server_request_type = NX_HTTP_SERVER_POST_REQUEST;
3104 
3105             /* Increment the number of POST requests.  */
3106             server_ptr -> nx_http_server_post_requests++;
3107 
3108 #ifdef NX_HTTP_MULTIPART_ENABLE
3109 
3110             /* Reset last received multipart packet. */
3111             server_ptr -> nx_http_server_multipart.nx_http_server_multipart_last_packet = NX_NULL;
3112 #endif /* NX_HTTP_MULTIPART_ENABLE */
3113 
3114             /* Process the POST request.  */
3115             _nx_http_server_get_process(server_ptr, NX_HTTP_SERVER_POST_REQUEST, packet_ptr);
3116 
3117 #ifdef NX_HTTP_MULTIPART_ENABLE
3118             /* Restore the packet to release. */
3119             if (server_ptr -> nx_http_server_multipart.nx_http_server_multipart_last_packet)
3120                 packet_ptr = server_ptr -> nx_http_server_multipart.nx_http_server_multipart_last_packet;
3121 #endif /* NX_HTTP_MULTIPART_ENABLE */
3122         }
3123 
3124         /* Check for a HEAD request.  */
3125         else if ((buffer_ptr[0] == 'H') && (buffer_ptr[1] == 'E') && (buffer_ptr[2] == 'A') &&
3126                  (buffer_ptr[3] == 'D') && (buffer_ptr[4] == ' '))
3127         {
3128 
3129             /* We have a HTTP HEAD request to get a resource header from this HTTP Server.  Note that the HEAD
3130                request is nearly identical to the GET request, except the requested content is not returned to
3131                the client.  */
3132             server_ptr -> nx_http_server_request_type = NX_HTTP_SERVER_HEAD_REQUEST;
3133 
3134             /* Increment the number of HEAD requests.  */
3135             server_ptr -> nx_http_server_head_requests++;
3136 
3137             /* Process the HEAD request.  */
3138             _nx_http_server_get_process(server_ptr, NX_HTTP_SERVER_HEAD_REQUEST, packet_ptr);
3139         }
3140 
3141         /* Unhandled request.  */
3142         else
3143         {
3144 
3145             /* We have an unhandled HTTP request.  */
3146             server_ptr -> nx_http_server_request_type = NX_HTTP_SERVER_UNKNOWN_REQUEST;
3147 
3148             /* Send response back to HTTP Client.  */
3149             _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_NOT_IMPLEMENTED, sizeof(NX_HTTP_STATUS_NOT_IMPLEMENTED) - 1,
3150                                           "NetX HTTP Request Not Implemented", sizeof("NetX HTTP Request Not Implemented") - 1, NX_NULL, 0);
3151 
3152             /* Increment the number of unhandled requests.  */
3153             server_ptr -> nx_http_server_unknown_requests++;
3154         }
3155 
3156         /* Release the packet.  */
3157         nx_packet_release(packet_ptr);
3158 
3159         /* Disconnect from the current connection.  */
3160         _nx_http_server_disconnect(server_ptr, NX_HTTP_SERVER_TIMEOUT_DISCONNECT);
3161 
3162         /* Relisten on the HTTP Server port.  */
3163         nx_tcp_server_socket_relisten(server_ptr -> nx_http_server_ip_ptr, NX_HTTP_SERVER_PORT,
3164                                                                 &(server_ptr -> nx_http_server_socket));
3165     }
3166 
3167     return;
3168 }
3169 
3170 
3171 /**************************************************************************/
3172 /*                                                                        */
3173 /*  FUNCTION                                               RELEASE        */
3174 /*                                                                        */
3175 /*    _nx_http_server_get_client_request                  PORTABLE C      */
3176 /*                                                           6.1          */
3177 /*  AUTHOR                                                                */
3178 /*                                                                        */
3179 /*    Yuxin Zhou, Microsoft Corporation                                   */
3180 /*                                                                        */
3181 /*  DESCRIPTION                                                           */
3182 /*                                                                        */
3183 /*    This function builds the complete HTTP client request in a single   */
3184 /*    NetX packet.  Doing this makes the other parsing and searching      */
3185 /*    routines simple.                                                    */
3186 /*                                                                        */
3187 /*                                                                        */
3188 /*  INPUT                                                                 */
3189 /*                                                                        */
3190 /*    server_ptr                            HTTP Server pointer           */
3191 /*    packet_ptr                            Destination for request       */
3192 /*                                            packet pointer              */
3193 /*                                                                        */
3194 /*  OUTPUT                                                                */
3195 /*                                                                        */
3196 /*    status                                Completion status             */
3197 /*                                                                        */
3198 /*  CALLS                                                                 */
3199 /*                                                                        */
3200 /*    nx_packet_copy                        Copy packet                   */
3201 /*    nx_packet_data_append                 Move data into packet         */
3202 /*    nx_packet_release                     Release packet                */
3203 /*    nx_tcp_socket_receive                 Receive an HTTP request packet*/
3204 /*                                                                        */
3205 /*  CALLED BY                                                             */
3206 /*                                                                        */
3207 /*    _nx_http_server_thread_entry          HTTP Server thread            */
3208 /*                                                                        */
3209 /*  RELEASE HISTORY                                                       */
3210 /*                                                                        */
3211 /*    DATE              NAME                      DESCRIPTION             */
3212 /*                                                                        */
3213 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3214 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3215 /*                                            resulting in version 6.1    */
3216 /*                                                                        */
3217 /**************************************************************************/
_nx_http_server_get_client_request(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr)3218 UINT  _nx_http_server_get_client_request(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr)
3219 {
3220 
3221 NX_PACKET   *head_packet_ptr;
3222 NX_PACKET   *new_packet_ptr;
3223 CHAR        *buffer_ptr;
3224 UINT        status;
3225 NX_PACKET   *work_ptr;
3226 UINT        crlf_found = 0;
3227 NX_PACKET   *tmp_ptr;
3228 
3229 
3230     /* Default the return packet pointer to NULL.  */
3231     *packet_ptr =  NX_NULL;
3232 
3233     /* Wait for a request on the HTTP TCP well know port 80.  */
3234     status =  nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), &head_packet_ptr, NX_HTTP_SERVER_TIMEOUT_RECEIVE);
3235 
3236     /* At this point we have a connection setup with an HTTP server!  */
3237 
3238     /* Check the return status.  */
3239     if (status != NX_SUCCESS)
3240     {
3241 
3242         /* Return an error condition.  */
3243         return(status);
3244     }
3245 
3246     /* Setup pointer to start of buffer.  */
3247     buffer_ptr =  (CHAR *) head_packet_ptr -> nx_packet_prepend_ptr;
3248 
3249     /* Determine if the packet is an HTTP request.  */
3250     if ((buffer_ptr[0] != 'G') && (buffer_ptr[0] != 'g') && (buffer_ptr[0] != 'P') && (buffer_ptr[0] != 'p') &&
3251         (buffer_ptr[0] != 'D') && (buffer_ptr[0] != 'd') && (buffer_ptr[0] != 'H') && (buffer_ptr[0] != 'h') &&
3252         (buffer_ptr[0] != 'T') && (buffer_ptr[0] != 't'))
3253     {
3254 
3255         /* Invalid first packet for HTTP request.  */
3256 
3257         /* Release the packet.  */
3258         nx_packet_release(head_packet_ptr);
3259 
3260         /* Return an error.  */
3261         return(NX_HTTP_ERROR);
3262     }
3263 
3264      /* Determine if this packet is large enough.  */
3265      if (((head_packet_ptr -> nx_packet_data_end - head_packet_ptr -> nx_packet_data_start) -
3266           NX_PHYSICAL_TRAILER)< NX_HTTP_SERVER_MIN_PACKET_SIZE)
3267      {
3268 
3269          /* Copy the packet into a packet allocated from the Server's packet pool (which must have packets
3270             with a payload size >= NX_HTTP_SERVER_MIN_PACKET_SIZE.  */
3271          status =  nx_packet_copy(head_packet_ptr, &new_packet_ptr, server_ptr -> nx_http_server_packet_pool_ptr, NX_HTTP_SERVER_TIMEOUT);
3272 
3273          /* Determine if the packet copy was successful.  */
3274          if (status != NX_SUCCESS)
3275          {
3276 
3277              /* Error in packet copy.  Release packet and return an error.  */
3278              nx_packet_release(head_packet_ptr);
3279              return(status);
3280          }
3281 
3282          /* Copy is successful, release the original pointer and move the new pointer to the head pointer.  */
3283          nx_packet_release(head_packet_ptr);
3284          head_packet_ptr =  new_packet_ptr;
3285     }
3286 
3287     crlf_found = 0;
3288     work_ptr = head_packet_ptr;
3289 
3290     /* Build a pointer to the buffer area.  */
3291     buffer_ptr =  (CHAR *) work_ptr -> nx_packet_prepend_ptr;
3292 
3293     do
3294     {
3295 
3296         /* See if there is a blank line present in the buffer.  */
3297         /* Search the buffer for a cr/lf pair.  */
3298         while (buffer_ptr < (CHAR *) work_ptr -> nx_packet_append_ptr)
3299         {
3300             if (!(crlf_found & 1) && (*buffer_ptr == (CHAR)13))
3301             {
3302 
3303                 /* Found CR. */
3304                 crlf_found++;
3305             }
3306             else if((crlf_found & 1) && (*buffer_ptr == (CHAR)10))
3307             {
3308 
3309                 /* Found LF. */
3310                 crlf_found++;
3311             }
3312             else
3313             {
3314 
3315                 /* Reset the CRLF marker. */
3316                 crlf_found = 0;
3317             }
3318 
3319             if (crlf_found == 4)
3320             {
3321 
3322                 /* Yes, we have found the end of the HTTP request header.  */
3323 
3324                 /* Set the return packet pointer.  */
3325                 *packet_ptr =  head_packet_ptr;
3326 
3327                 /* Return a successful completion.  */
3328                 return(NX_SUCCESS);
3329             }
3330 
3331             /* Move the buffer pointer up.  */
3332             buffer_ptr++;
3333         }
3334 
3335         /* Determine if the packet has already overflowed into another packet.  */
3336 
3337 #ifndef NX_DISABLE_PACKET_CHAIN
3338 
3339         if (work_ptr -> nx_packet_next != NX_NULL)
3340         {
3341             /* Get the next packet in the chain. */
3342             work_ptr  = work_ptr -> nx_packet_next;
3343             buffer_ptr =  (CHAR *) work_ptr -> nx_packet_prepend_ptr;
3344         }
3345         else
3346 
3347 #endif
3348         {
3349             /* Receive another packet from the HTTP server port.  */
3350             status =  nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), &new_packet_ptr, NX_HTTP_SERVER_TIMEOUT_RECEIVE);
3351 
3352             /* Check the return status.  */
3353             if (status != NX_SUCCESS)
3354             {
3355 
3356                 /* Release the current head packet.  */
3357                 nx_packet_release(head_packet_ptr);
3358 
3359                 /* Return an error condition.  */
3360                 return(status);
3361             }
3362 
3363             /* Successfully received another packet.  Its contents now need to be placed in the head packet.  */
3364             tmp_ptr = new_packet_ptr;
3365 #ifndef NX_DISABLE_PACKET_CHAIN
3366             while (tmp_ptr)
3367             {
3368 #endif /* NX_DISABLE_PACKET_CHAIN */
3369 
3370                 /* Copy the contents of the current packet into the head packet.  */
3371                 status =  nx_packet_data_append(head_packet_ptr, (VOID *) tmp_ptr -> nx_packet_prepend_ptr,
3372                                                 (ULONG)(tmp_ptr -> nx_packet_append_ptr - tmp_ptr -> nx_packet_prepend_ptr),
3373                                                 server_ptr -> nx_http_server_packet_pool_ptr, NX_HTTP_SERVER_TIMEOUT);
3374 
3375                 /* Determine if an error occurred.  */
3376                 if (status != NX_SUCCESS)
3377                 {
3378 
3379                     /* Yes, an error is present.  */
3380 
3381                     /* Release both packets.  */
3382                     nx_packet_release(head_packet_ptr);
3383                     nx_packet_release(new_packet_ptr);
3384 
3385                     /* Return an error condition.  */
3386                     return(status);
3387                 }
3388 
3389 #ifndef NX_DISABLE_PACKET_CHAIN
3390                 tmp_ptr = tmp_ptr -> nx_packet_next;
3391             }
3392 #endif /* NX_DISABLE_PACKET_CHAIN */
3393 
3394             /* Release the new packet. */
3395             nx_packet_release(new_packet_ptr);
3396         }
3397 
3398     } while (status == NX_SUCCESS);
3399 
3400     /* Release the packet.  */
3401     nx_packet_release(head_packet_ptr);
3402 
3403     return NX_HTTP_ERROR;
3404 }
3405 
3406 
3407 /**************************************************************************/
3408 /*                                                                        */
3409 /*  FUNCTION                                               RELEASE        */
3410 /*                                                                        */
3411 /*    _nx_http_server_get_process                         PORTABLE C      */
3412 /*                                                           6.1          */
3413 /*  AUTHOR                                                                */
3414 /*                                                                        */
3415 /*    Yuxin Zhou, Microsoft Corporation                                   */
3416 /*                                                                        */
3417 /*  DESCRIPTION                                                           */
3418 /*                                                                        */
3419 /*    This function processes the GET, POST, and HEAD HTTP client         */
3420 /*    requests.                                                           */
3421 /*                                                                        */
3422 /*                                                                        */
3423 /*  INPUT                                                                 */
3424 /*                                                                        */
3425 /*    server_ptr                            HTTP Server pointer           */
3426 /*    request_type                          Type of request (GET, POST,   */
3427 /*                                            or HEAD)                    */
3428 /*    packet_ptr                            Request packet pointer        */
3429 /*                                                                        */
3430 /*  OUTPUT                                                                */
3431 /*                                                                        */
3432 /*    None                                                                */
3433 /*                                                                        */
3434 /*  CALLS                                                                 */
3435 /*                                                                        */
3436 /*    _nx_http_server_basic_authenticate    Process basic authentication  */
3437 /*    _nx_http_server_digest_authenticate   Process digest authentication */
3438 /*    _nx_http_server_calculate_content_offset Retrieve content offset    */
3439 /*    _nx_http_server_content_length_get    Retrieve content length       */
3440 /*    _nx_http_server_response_send         Send response back to client  */
3441 /*    _nx_http_server_retrieve_resource     Retrieve resource from request*/
3442 /*    _nx_http_server_type_get_extended     Derive file type              */
3443 /*    fx_directory_information_get          Get length of resource file   */
3444 /*    fx_file_close                         Close resource file           */
3445 /*    fx_file_open                          Open resource file            */
3446 /*    fx_file_read                          Read data from resource file  */
3447 /*    nx_packet_allocate                    Allocate a new packet         */
3448 /*    nx_packet_data_append                 Append information to response*/
3449 /*    nx_packet_release                     Release packet                */
3450 /*    nx_tcp_socket_send                    Send HTTP Server response     */
3451 /*                                                                        */
3452 /*  CALLED BY                                                             */
3453 /*                                                                        */
3454 /*    _nx_http_server_thread_entry          HTTP Server thread            */
3455 /*                                                                        */
3456 /*  RELEASE HISTORY                                                       */
3457 /*                                                                        */
3458 /*    DATE              NAME                      DESCRIPTION             */
3459 /*                                                                        */
3460 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3461 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3462 /*                                            resulting in version 6.1    */
3463 /*                                                                        */
3464 /**************************************************************************/
_nx_http_server_get_process(NX_HTTP_SERVER * server_ptr,UINT request_type,NX_PACKET * packet_ptr)3465 VOID  _nx_http_server_get_process(NX_HTTP_SERVER *server_ptr, UINT request_type, NX_PACKET *packet_ptr)
3466 {
3467 
3468 ULONG       length = 0;
3469 UINT        status;
3470 NX_PACKET   *new_packet_ptr;
3471 CHAR        *name_ptr;
3472 CHAR        *password_ptr;
3473 CHAR        *realm_ptr;
3474 ULONG       temp;
3475 CHAR        temp_string[30];
3476 UINT        auth_request_present = NX_FALSE;
3477 UINT        resource_length;
3478 UINT        name_length = 0;
3479 UINT        password_length = 0;
3480 UINT        realm_length = 0;
3481 UINT        temp_name_length = 0;
3482 UINT        temp_password_length = 0;
3483 UINT        temp_realm_length = 0;
3484 
3485 
3486     /* Pickup the URL (resource) from the request.  */
3487     status =  _nx_http_server_retrieve_resource(packet_ptr, server_ptr -> nx_http_server_request_resource, NX_HTTP_MAX_RESOURCE + 1);
3488 
3489     /* Determine if the resource was extracted successfully.  */
3490     if (status != NX_SUCCESS)
3491     {
3492 
3493         /* Send response back to HTTP Client.  */
3494         _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_BAD_REQUEST, sizeof(NX_HTTP_STATUS_BAD_REQUEST) - 1,
3495                                       "NetX HTTP URL Bad", sizeof("NetX HTTP URL Bad") - 1, NX_NULL, 0);
3496 
3497         /* Error, return to caller.  */
3498         return;
3499     }
3500 
3501     /* Determine if a POST is present.  */
3502     if (request_type == NX_HTTP_SERVER_POST_REQUEST)
3503     {
3504 
3505         /* It is. Check for a valid content-length field. */
3506         status = _nx_http_server_content_length_get_extended(packet_ptr, &length);
3507 
3508         /* Check for errors.  */
3509         if ( status != NX_SUCCESS)
3510         {
3511 
3512             /* Send response back to HTTP Client.  */
3513             _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_BAD_REQUEST, sizeof(NX_HTTP_STATUS_BAD_REQUEST) - 1,
3514                                           "NetX HTTP Invalid Content Length", sizeof("NetX HTTP Invalid Content Length") - 1, NX_NULL, 0);
3515 
3516             /* Error, return to caller.  */
3517             return;
3518         }
3519 
3520         /* Check for an invalid content offset .  */
3521         if (_nx_http_server_calculate_content_offset(packet_ptr) == 0)
3522         {
3523 
3524             /* Send response back to HTTP Client.  */
3525             _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_BAD_REQUEST, sizeof(NX_HTTP_STATUS_BAD_REQUEST) - 1,
3526                                           "NetX HTTP Invalid Content Offset", sizeof("NetX HTTP Invalid Content Offset") - 1, NX_NULL, 0);
3527 
3528             /* Error, return to caller.  */
3529             return;
3530         }
3531 
3532 #ifdef  NX_HTTP_MULTIPART_ENABLE
3533         /* Cleanup the multipart field. */
3534         memset(&server_ptr -> nx_http_server_multipart, 0, sizeof(NX_HTTP_SERVER_MULTIPART));
3535 #endif /* NX_HTTP_MULTIPART_ENABLE */
3536     }
3537 
3538     /* Determine if the application has specified an authentication function for this server.  */
3539     if (server_ptr -> nx_http_server_authentication_check ||
3540         server_ptr -> nx_http_server_authentication_check_extended)
3541     {
3542 
3543         /* Determine if authentication is required for the specified resource.  */
3544         if (server_ptr -> nx_http_server_authentication_check_extended)
3545         {
3546             status = (server_ptr -> nx_http_server_authentication_check_extended)(server_ptr, request_type, server_ptr -> nx_http_server_request_resource,
3547                                                                                   &name_ptr, &name_length, &password_ptr, &password_length, &realm_ptr, &realm_length);
3548         }
3549         else
3550         {
3551             status = (server_ptr -> nx_http_server_authentication_check)(server_ptr, request_type, server_ptr -> nx_http_server_request_resource,
3552                                                                          &name_ptr, &password_ptr, &realm_ptr);
3553         }
3554 
3555         if (status == NX_HTTP_BASIC_AUTHENTICATE ||
3556             status == NX_HTTP_DIGEST_AUTHENTICATE)
3557         {
3558 
3559             /* Check name, password and realm string.  */
3560             if (_nx_utility_string_length_check(name_ptr, &temp_name_length, NX_HTTP_MAX_NAME) ||
3561                 _nx_utility_string_length_check(password_ptr, &temp_password_length, NX_HTTP_MAX_PASSWORD) ||
3562                 _nx_utility_string_length_check(realm_ptr, &temp_realm_length, NX_MAX_STRING_LENGTH))
3563             {
3564 
3565                 /* Error, return to caller.  */
3566                 return;
3567             }
3568 
3569             /* Validate string length. */
3570             if (server_ptr -> nx_http_server_authentication_check_extended &&
3571                 ((realm_length != temp_realm_length) ||
3572                  (name_length != temp_name_length) ||
3573                  (password_length != temp_password_length)))
3574             {
3575                 return;
3576             }
3577         }
3578 
3579         /* Determine what kind - if any - authentication is requested for this resource.  */
3580         if (status == NX_HTTP_BASIC_AUTHENTICATE)
3581         {
3582 
3583             /* Process basic authentication request.  */
3584             status =  _nx_http_server_basic_authenticate(server_ptr, packet_ptr, name_ptr, password_ptr, realm_ptr, temp_realm_length, &auth_request_present);
3585         }
3586 #ifdef  NX_HTTP_DIGEST_ENABLE
3587         else if (status == NX_HTTP_DIGEST_AUTHENTICATE)
3588         {
3589 
3590             /* Process digest authentication request.  */
3591             status =  _nx_http_server_digest_authenticate(server_ptr, packet_ptr, name_ptr, temp_name_length, password_ptr, temp_password_length, realm_ptr, temp_realm_length, &auth_request_present);
3592         }
3593 #endif
3594 
3595         /* Determine if the authentication failed.  */
3596         if ((status != NX_HTTP_DONT_AUTHENTICATE) && (status != NX_SUCCESS))
3597         {
3598 
3599             /*  Yes it did. Inform the HTTP server application about the failed authentication. */
3600             if (server_ptr -> nx_http_server_invalid_username_password_callback && auth_request_present)
3601             {
3602 
3603             NXD_ADDRESS client_nxd_address;
3604             ULONG       client_port;
3605 
3606                 /* Get the IP address of the client:  */
3607                 status =   nxd_tcp_socket_peer_info_get(&(server_ptr->nx_http_server_socket), &client_nxd_address , &client_port);
3608 
3609                 if (status == NX_SUCCESS)
3610                 {
3611                     /* Send this information to the host application. */
3612                     (server_ptr -> nx_http_server_invalid_username_password_callback)(server_ptr -> nx_http_server_request_resource, &client_nxd_address, request_type);
3613                 }
3614             }
3615 
3616             return;
3617         }
3618     }
3619 
3620     /* Check whether a full response is necessary. */
3621     if((server_ptr -> nx_http_server_cache_info_get) &&
3622        (server_ptr -> nx_http_server_request_type == NX_HTTP_SERVER_GET_REQUEST))
3623     {
3624 
3625         /* Searching for "If-Modified-Since" header. */
3626         if(_nx_http_server_field_value_get(packet_ptr, (UCHAR *)"if-modified-since", 17, (UCHAR *)temp_string, sizeof(temp_string)) == NX_SUCCESS)
3627         {
3628         UINT max_age;
3629         NX_HTTP_SERVER_DATE date;
3630         CHAR date_string[30];
3631 
3632             /* Get last modified date of this resource. */
3633             if(server_ptr -> nx_http_server_cache_info_get(server_ptr -> nx_http_server_request_resource, &max_age, &date) == NX_TRUE)
3634             {
3635 
3636                 /* Convert date to string, return length is always 29. */
3637                 temp = _nx_http_server_date_to_string(&date, date_string);
3638                 date_string[temp] = 0;
3639 
3640                 /* Check the last modified date with if-modified-since. */
3641                 if(memcmp(temp_string, date_string, temp + 1) == 0)
3642                 {
3643 
3644                     /* Send not modified.  */
3645                     _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_NOT_MODIFIED, sizeof(NX_HTTP_STATUS_NOT_MODIFIED) - 1, NX_NULL, 0, NX_NULL, 0);
3646 
3647                     /* Return to caller.  */
3648                     return;
3649                 }
3650             }
3651         }
3652     }
3653 
3654     /* Setup the server socket with a specific packet transmit retry logic.  */
3655     nx_tcp_socket_transmit_configure(&(server_ptr -> nx_http_server_socket),
3656                                     NX_HTTP_SERVER_TRANSMIT_QUEUE_DEPTH,
3657                                     NX_HTTP_SERVER_RETRY_SECONDS*NX_IP_PERIODIC_RATE,
3658                                     NX_HTTP_SERVER_RETRY_MAX,
3659                                     NX_HTTP_SERVER_RETRY_SHIFT);
3660 
3661     /* At this point, either there isn't any required authentication for this resource or the authentication is
3662        complete.  */
3663 
3664     /* If the HTTP server receives an empty POST request (no message body, content length = 0, it is the
3665        responsibility of the request notify callback to send a response (if any) to the HTTP Client.
3666        The HTTP server will process the request no further. */
3667 
3668     /* Determine if a user supplied get function has been specified.  */
3669     if (server_ptr -> nx_http_server_request_notify)
3670     {
3671 
3672         /* Call the user supplied function to notify the user of the get request.  */
3673         status =  (server_ptr -> nx_http_server_request_notify)(server_ptr, request_type, server_ptr -> nx_http_server_request_resource, packet_ptr);
3674 
3675 #ifdef  NX_HTTP_MULTIPART_ENABLE
3676         /* Release the packet that is not processed by callback function. */
3677         if(server_ptr -> nx_http_server_multipart.nx_http_server_multipart_next_packet)
3678             nx_packet_release(server_ptr -> nx_http_server_multipart.nx_http_server_multipart_next_packet);
3679 #endif /* NX_HTTP_MULTIPART_ENABLE */
3680 
3681         /* Determine if the user supplied routine is requesting the get should be aborted.  */
3682         if (status != NX_SUCCESS)
3683         {
3684 
3685             /* Determine if the user callback routine successfully completed the request processing.  */
3686             if (status == NX_HTTP_CALLBACK_COMPLETED)
3687             {
3688 
3689                 /* User callback routine already sent success response back to HTTP Client.  */
3690                 return;
3691             }
3692 
3693             /* Send response back to HTTP Client.  */
3694             _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
3695                                           "NetX HTTP Request Aborted", sizeof("NetX HTTP Request Aborted") - 1, NX_NULL, 0);
3696 
3697             /* Yes, error was detected. Abort the remainder of the get processing.  */
3698             return;
3699         }
3700     }
3701 
3702     /* Was there a message body in the request? */
3703     if ((request_type == NX_HTTP_SERVER_POST_REQUEST) && (length == 0))
3704     {
3705 
3706         /* No. Regardless if a reply was sent via the request notify callback, we are done with this packet. */
3707         return;
3708     }
3709 
3710     /* Get the length of request resource.  */
3711     if (_nx_utility_string_length_check(server_ptr -> nx_http_server_request_resource,  &resource_length,
3712                                         sizeof(server_ptr -> nx_http_server_request_resource) - 1))
3713     {
3714         return;
3715     }
3716 
3717     /* Open the specified file for reading.  */
3718     status =  fx_file_open(server_ptr -> nx_http_server_media_ptr, &(server_ptr -> nx_http_server_file), server_ptr -> nx_http_server_request_resource, FX_OPEN_FOR_READ);
3719 
3720     /* Check for error condition.  */
3721     if (status != NX_SUCCESS)
3722     {
3723 
3724         /* Send response back to HTTP Client.  */
3725         _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_NOT_FOUND, sizeof(NX_HTTP_STATUS_NOT_FOUND) - 1,
3726                                       "NetX HTTP Server unable to find file: ", sizeof("NetX HTTP Server unable to find file: ") - 1, server_ptr -> nx_http_server_request_resource, resource_length);
3727 
3728         /* Error, return to caller.  */
3729         return;
3730     }
3731 
3732     /* Calculate the size of the file.  */
3733     length =  0;
3734     fx_directory_information_get(server_ptr -> nx_http_server_media_ptr, server_ptr -> nx_http_server_request_resource, FX_NULL,
3735                                  &length, FX_NULL, FX_NULL, FX_NULL, FX_NULL, FX_NULL, FX_NULL);
3736 
3737     /* Derive the file type.  */
3738     temp =  (ULONG) _nx_http_server_type_get_extended(server_ptr, server_ptr -> nx_http_server_request_resource, resource_length, temp_string, sizeof(temp_string));
3739     temp_string[temp] = 0;
3740 
3741     /* Now build a response header.  */
3742     status = _nx_http_server_generate_response_header(server_ptr, &new_packet_ptr, NX_HTTP_STATUS_OK, sizeof(NX_HTTP_STATUS_OK) - 1, length, temp_string, temp, NX_NULL, 0);
3743     if(status)
3744     {
3745 
3746         /* Send response back to HTTP Client.  */
3747         _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
3748                                       "NetX HTTP Request Aborted", sizeof("NetX HTTP Request Aborted") - 1, NX_NULL, 0);
3749 
3750         /* Close the file.  */
3751         fx_file_close(&(server_ptr -> nx_http_server_file));
3752 
3753         /* Error, return to caller.  */
3754         return;
3755     }
3756 
3757     /* Check to see if only a response is required.  */
3758     if ((!length) || (request_type == NX_HTTP_SERVER_HEAD_REQUEST))
3759     {
3760 
3761         /* Yes, only a response is required... send it!  */
3762         status =  nx_tcp_socket_send(&(server_ptr -> nx_http_server_socket), new_packet_ptr, NX_HTTP_SERVER_TIMEOUT_SEND);
3763 
3764         /* Determine if this is successful.  */
3765         if (status != NX_SUCCESS)
3766         {
3767 
3768             /* Release the packet.  */
3769             nx_packet_release(new_packet_ptr);
3770 
3771             /* Force zero length.  */
3772             length = 0;
3773         }
3774     }
3775 
3776     /* Get length of packet */
3777     temp = new_packet_ptr -> nx_packet_length;
3778 
3779     /* Now, loop to send the data contents.  If the request type is "HEAD", skip this loop to output the
3780        file contents.  */
3781     while ((length) && (request_type != NX_HTTP_SERVER_HEAD_REQUEST))
3782     {
3783 
3784         /* Determine if we need to allocate a new packet for data.  */
3785         if (!temp)
3786         {
3787 
3788             /* Yes, allocate a new packet.  */
3789             status =  nx_packet_allocate(server_ptr -> nx_http_server_packet_pool_ptr, &new_packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER);
3790 
3791             /* Determine if an error is present.  */
3792             if (status != NX_SUCCESS)
3793             {
3794 
3795                 /* Indicate an allocation error occurred.  */
3796                 server_ptr -> nx_http_server_allocation_errors++;
3797 
3798                 /* Error, return to caller.  */
3799                 break;
3800             }
3801         }
3802 
3803         /* Calculate the maximum length.  */
3804         temp =  ((ULONG) (new_packet_ptr -> nx_packet_data_end - new_packet_ptr -> nx_packet_append_ptr)) - NX_PHYSICAL_TRAILER;
3805 
3806         /* Determine if this exceeds the MSS of the peer.  */
3807         if (temp > server_ptr -> nx_http_server_socket.nx_tcp_socket_connect_mss)
3808         {
3809 
3810             /* Yes, reduce the maximum size to the mss size.  */
3811             temp =  server_ptr -> nx_http_server_socket.nx_tcp_socket_connect_mss;
3812         }
3813 
3814         /* Read data from the file.  */
3815         status =  fx_file_read(&(server_ptr -> nx_http_server_file), new_packet_ptr -> nx_packet_append_ptr,
3816                                         temp, &temp);
3817 
3818         /* Check for an error.  */
3819         if (status != NX_SUCCESS)
3820         {
3821 
3822             /* Release the packet.  */
3823             nx_packet_release(new_packet_ptr);
3824 
3825             /* Error, return.  */
3826             break;
3827         }
3828 
3829         /* Update the packet information with the data read.  */
3830         new_packet_ptr -> nx_packet_length =  new_packet_ptr -> nx_packet_length + temp;
3831         new_packet_ptr -> nx_packet_append_ptr =  new_packet_ptr -> nx_packet_append_ptr + temp;
3832 
3833         /* Send the packet out.  */
3834         status =  nx_tcp_socket_send(&(server_ptr -> nx_http_server_socket), new_packet_ptr, NX_HTTP_SERVER_TIMEOUT_SEND);
3835 
3836         /* Check for success.  */
3837         if (status != NX_SUCCESS)
3838         {
3839 
3840             /* Release the packet.  */
3841             nx_packet_release(new_packet_ptr);
3842 
3843             /* Return to caller.  */
3844             break;
3845         }
3846 
3847         /* Increment the bytes sent count.  */
3848         server_ptr -> nx_http_server_total_bytes_sent =  server_ptr -> nx_http_server_total_bytes_sent + temp;
3849 
3850         /* Adjust the file length based on what we have sent.  */
3851         length =  length - temp;
3852 
3853         /* Indicate new packet needed */
3854         temp = 0;
3855     }
3856 
3857     /* Close the file.  */
3858     fx_file_close(&(server_ptr -> nx_http_server_file));
3859 }
3860 
3861 
3862 /**************************************************************************/
3863 /*                                                                        */
3864 /*  FUNCTION                                               RELEASE        */
3865 /*                                                                        */
3866 /*    _nx_http_server_put_process                         PORTABLE C      */
3867 /*                                                           6.1          */
3868 /*  AUTHOR                                                                */
3869 /*                                                                        */
3870 /*    Yuxin Zhou, Microsoft Corporation                                   */
3871 /*                                                                        */
3872 /*  DESCRIPTION                                                           */
3873 /*                                                                        */
3874 /*    This function processes the PUT HTTP client requests.               */
3875 /*                                                                        */
3876 /*                                                                        */
3877 /*  INPUT                                                                 */
3878 /*                                                                        */
3879 /*    server_ptr                            HTTP Server pointer           */
3880 /*    packet_ptr                            Request packet pointer        */
3881 /*                                                                        */
3882 /*  OUTPUT                                                                */
3883 /*                                                                        */
3884 /*    None                                                                */
3885 /*                                                                        */
3886 /*  CALLS                                                                 */
3887 /*                                                                        */
3888 /*    _nx_http_server_basic_authenticate    Process basic authentication  */
3889 /*    _nx_http_server_digest_authenticate   Process digest authentication */
3890 /*    _nx_http_server_calculate_content_offset Retrieve content offset    */
3891 /*    _nx_http_server_content_length_get    Retrieve content length       */
3892 /*    _nx_http_server_response_send         Send response back to client  */
3893 /*    _nx_http_server_retrieve_resource     Retrieve resource from request*/
3894 /*    fx_file_close                         Close resource file           */
3895 /*    fx_file_create                        Create resource file          */
3896 /*    fx_file_open                          Open resource file            */
3897 /*    fx_file_write                         Write data to resource file   */
3898 /*    nx_packet_allocate                    Allocate a new packet         */
3899 /*    nx_packet_data_append                 Append information to response*/
3900 /*    nx_packet_release                     Release packet                */
3901 /*    nx_tcp_socket_receive                 Receive HTTP data from client */
3902 /*    nx_tcp_socket_send                    Send HTTP Server response     */
3903 /*                                                                        */
3904 /*  CALLED BY                                                             */
3905 /*                                                                        */
3906 /*    _nx_http_server_content_get           Content get processing        */
3907 /*    _nx_http_server_get_process           GET request processing        */
3908 /*    _nx_http_server_put_process           PUT request processing        */
3909 /*                                                                        */
3910 /*  RELEASE HISTORY                                                       */
3911 /*                                                                        */
3912 /*    DATE              NAME                      DESCRIPTION             */
3913 /*                                                                        */
3914 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3915 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3916 /*                                            resulting in version 6.1    */
3917 /*                                                                        */
3918 /**************************************************************************/
_nx_http_server_put_process(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr)3919 VOID  _nx_http_server_put_process(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr)
3920 {
3921 
3922 UINT        status;
3923 ULONG       length;
3924 UINT        offset;
3925 CHAR        *name_ptr;
3926 CHAR        *password_ptr;
3927 CHAR        *realm_ptr;
3928 NX_PACKET   *data_packet_ptr;
3929 NX_PACKET   *next_packet_ptr;
3930 UINT        auth_request_present = NX_FALSE;
3931 UINT        name_length = 0;
3932 UINT        password_length = 0;
3933 UINT        realm_length = 0;
3934 UINT        temp_name_length = 0;
3935 UINT        temp_password_length = 0;
3936 UINT        temp_realm_length = 0;
3937 
3938 
3939     /* Pickup the URL (resource) from the request.  */
3940     status =  _nx_http_server_retrieve_resource(packet_ptr, server_ptr -> nx_http_server_request_resource, NX_HTTP_MAX_RESOURCE + 1);
3941 
3942     /* Determine if the resource was extracted successfully.  */
3943     if (status != NX_SUCCESS)
3944     {
3945 
3946         /* Send response back to HTTP Client.  */
3947         _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_BAD_REQUEST, sizeof(NX_HTTP_STATUS_BAD_REQUEST) - 1,
3948                                       "NetX HTTP URL Bad", sizeof("NetX HTTP URL Bad") - 1, NX_NULL, 0);
3949 
3950         /* Error, return to caller.  */
3951         return;
3952     }
3953 
3954     /* Calculate the content length from the request.  */
3955     status =  _nx_http_server_content_length_get_extended(packet_ptr, &length);
3956 
3957     /* Determine if the content length is valid.  */
3958     if (status != NX_SUCCESS)
3959     {
3960 
3961         /* Send response back to HTTP Client.  */
3962         _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_BAD_REQUEST, sizeof(NX_HTTP_STATUS_BAD_REQUEST) - 1,
3963                                       "NetX HTTP Invalid Content Length", sizeof("NetX HTTP Invalid Content Length") - 1, NX_NULL, 0);
3964 
3965         /* Error, return to caller.  */
3966         return;
3967     }
3968 
3969     /* Calculate the offset to the content (the two Cr LF tokens) in the request.  */
3970     offset =  _nx_http_server_calculate_content_offset(packet_ptr);
3971 
3972     /* Determine if the offset to the content is valid.  */
3973     if (offset == 0)
3974     {
3975 
3976         /* Send response back to HTTP Client.  */
3977         _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_BAD_REQUEST, sizeof(NX_HTTP_STATUS_BAD_REQUEST) - 1,
3978                                       "NetX HTTP Invalid Content Offset", sizeof("NetX HTTP Invalid Content Offset") - 1, NX_NULL, 0);
3979 
3980         /* Error, return to caller.  */
3981         return;
3982     }
3983 
3984     /* Determine if the application has specified an authentication function for this server.  */
3985     if (server_ptr -> nx_http_server_authentication_check ||
3986         server_ptr -> nx_http_server_authentication_check_extended)
3987     {
3988 
3989         /* Determine if authentication is required for the specified resource.  */
3990         if (server_ptr -> nx_http_server_authentication_check_extended)
3991         {
3992             status = (server_ptr -> nx_http_server_authentication_check_extended)(server_ptr, NX_HTTP_SERVER_PUT_REQUEST, server_ptr -> nx_http_server_request_resource,
3993                                                                                   &name_ptr, &name_length, &password_ptr, &password_length, &realm_ptr, &realm_length);
3994         }
3995         else
3996         {
3997             status = (server_ptr -> nx_http_server_authentication_check)(server_ptr, NX_HTTP_SERVER_PUT_REQUEST, server_ptr -> nx_http_server_request_resource,
3998                                                                          &name_ptr, &password_ptr, &realm_ptr);
3999         }
4000 
4001         if (status == NX_HTTP_BASIC_AUTHENTICATE ||
4002             status == NX_HTTP_DIGEST_AUTHENTICATE)
4003         {
4004 
4005             /* Check name, password and realm string.  */
4006             if (_nx_utility_string_length_check(name_ptr, &temp_name_length, NX_HTTP_MAX_NAME) ||
4007                 _nx_utility_string_length_check(password_ptr, &temp_password_length, NX_HTTP_MAX_PASSWORD) ||
4008                 _nx_utility_string_length_check(realm_ptr, &temp_realm_length, NX_MAX_STRING_LENGTH))
4009             {
4010 
4011                 /* Error, return to caller.  */
4012                 return;
4013             }
4014 
4015             /* Validate string length. */
4016             if (server_ptr -> nx_http_server_authentication_check_extended &&
4017                 ((realm_length != temp_realm_length) ||
4018                  (name_length != temp_name_length) ||
4019                  (password_length != temp_password_length)))
4020             {
4021                 return;
4022             }
4023         }
4024 
4025         /* Determine what kind - if any - authentication is requested for this resource.  */
4026         if (status == NX_HTTP_BASIC_AUTHENTICATE)
4027         {
4028 
4029             /* Process basic authentication request.  */
4030             status =  _nx_http_server_basic_authenticate(server_ptr, packet_ptr, name_ptr, password_ptr, realm_ptr, temp_realm_length, &auth_request_present);
4031         }
4032 #ifdef  NX_HTTP_DIGEST_ENABLE
4033         else if (status == NX_HTTP_DIGEST_AUTHENTICATE)
4034         {
4035 
4036             /* Process digest authentication request.  */
4037             status =  _nx_http_server_digest_authenticate(server_ptr, packet_ptr, name_ptr, temp_name_length, password_ptr, temp_password_length, realm_ptr, temp_realm_length, &auth_request_present);
4038         }
4039 #endif
4040 
4041         /* Determine if the authentication is currently in progress.  */
4042         if ((status != NX_HTTP_DONT_AUTHENTICATE) && (status != NX_SUCCESS))
4043         {
4044 
4045             /* Yes, authentication is in progress.  The HTTP 401 has already been sent.  */
4046             if (server_ptr -> nx_http_server_invalid_username_password_callback && auth_request_present)
4047             {
4048 
4049             NXD_ADDRESS client_nxd_address;
4050             ULONG       client_port;
4051 
4052                 /* Get the IP address of the client:  */
4053                 status =   nxd_tcp_socket_peer_info_get(&(server_ptr->nx_http_server_socket), &client_nxd_address , &client_port);
4054 
4055                 if (status == NX_SUCCESS)
4056                 {
4057                     /* Send this information to the host application. */
4058                     (server_ptr -> nx_http_server_invalid_username_password_callback)(server_ptr -> nx_http_server_request_resource, &client_nxd_address, NX_HTTP_SERVER_PUT_REQUEST);
4059                 }
4060             }
4061 
4062             return;
4063         }
4064     }
4065 
4066     /* At this point, either there isn't any required authentication for this resource or the authentication is
4067        complete.  */
4068 
4069     /* If the request is empty (content-length = 0) the request notify callback is where a response is generated
4070        to return to the Client.  NetX HTTP Server will not process an empty request further. */
4071 
4072     /* Determine if a user supplied get function has been specified.  */
4073     if (server_ptr -> nx_http_server_request_notify)
4074     {
4075 
4076         /* Call the user supplied function to notify the user of the put request.  */
4077         status =  (server_ptr -> nx_http_server_request_notify)(server_ptr, NX_HTTP_SERVER_PUT_REQUEST, server_ptr -> nx_http_server_request_resource, packet_ptr);
4078 
4079         /* Determine if the user supplied routine is requesting the put should be aborted.  */
4080         if (status != NX_SUCCESS)
4081         {
4082 
4083             /* Determine if the user callback routine successfully completed the request processing.  */
4084             if (status == NX_HTTP_CALLBACK_COMPLETED)
4085             {
4086 
4087                 /* Send success response back to HTTP Client.  */
4088                 _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_OK, sizeof(NX_HTTP_STATUS_OK) - 1, NX_NULL, 0, NX_NULL, 0);
4089                 return;
4090             }
4091 
4092             /* No, an error was detected. Abort the remainder of the get processing.  */
4093             _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
4094                                           "NetX HTTP Request Aborted", sizeof("NetX HTTP Request Aborted") - 1, NX_NULL, 0);
4095             return;
4096         }
4097     }
4098 
4099     /* Was there a message body in the request? */
4100     if (length == 0)
4101     {
4102 
4103         /* No. Regardless if a reply was sent via the request notify callback, we are done with this packet. */
4104         return;
4105     }
4106 
4107     /* Otherwise, everything is okay...  complete the request.  */
4108 
4109     /* Create the specified file.  */
4110     status = fx_file_create(server_ptr -> nx_http_server_media_ptr, server_ptr -> nx_http_server_request_resource);
4111 
4112 
4113     if (status != NX_SUCCESS)
4114     {
4115         /* Send response back to HTTP Client.  */
4116         _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
4117                                       "NetX HTTP File Create Failed", sizeof("NetX HTTP File Create Failed") - 1, NX_NULL, 0);
4118 
4119         /* Error, return to caller.  */
4120         return;
4121     }
4122 
4123     /* Open the specified file for writing.  */
4124     status =  fx_file_open(server_ptr -> nx_http_server_media_ptr, &(server_ptr -> nx_http_server_file), server_ptr -> nx_http_server_request_resource, FX_OPEN_FOR_WRITE);
4125 
4126     /* Check for error condition.  */
4127     if (status != NX_SUCCESS)
4128     {
4129 
4130         /* Send response back to HTTP Client.  */
4131         _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
4132                                       "NetX HTTP File Open Failed", sizeof("NetX HTTP File Open Failed") - 1, NX_NULL, 0);
4133 
4134         /* Error, return to caller.  */
4135         return;
4136     }
4137 
4138 
4139     /* Determine if there is any content in the first packet.  */
4140     if ((UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) > offset)
4141     {
4142 
4143         /* Write the content found in this packet.  */
4144         status =  fx_file_write(&(server_ptr -> nx_http_server_file), (packet_ptr -> nx_packet_prepend_ptr + offset),
4145                                 ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) - offset));
4146 
4147         /* Check the status.  */
4148         if (status != NX_SUCCESS)
4149         {
4150 
4151             /* Send response back to HTTP Client.  */
4152             _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
4153                                           "NetX HTTP File Write Failed", sizeof("NetX HTTP File Write Failed") - 1, NX_NULL, 0);
4154 
4155             /* Error, return to caller.  */
4156             return;
4157         }
4158 
4159         /* Update the length.  */
4160         length =  length - ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) - offset);
4161 
4162         /* Increment the bytes received count.  */
4163         server_ptr -> nx_http_server_total_bytes_received =  server_ptr -> nx_http_server_total_bytes_received +
4164                                                              ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) - offset);
4165     }
4166 
4167 
4168 #ifndef NX_DISABLE_PACKET_CHAIN
4169     /* Loop to write chained packets out to the file.  */
4170     next_packet_ptr =  packet_ptr -> nx_packet_next;
4171     while ((length) && (next_packet_ptr))
4172     {
4173 
4174         /* Write the content of the next packet.  */
4175         status =  fx_file_write(&(server_ptr -> nx_http_server_file), next_packet_ptr -> nx_packet_prepend_ptr,
4176                                 (ULONG)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr));
4177 
4178         /* Check the status.  */
4179         if (status != NX_SUCCESS)
4180         {
4181 
4182             /* Send response back to HTTP Client.  */
4183             _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
4184                                           "NetX HTTP File Write Failed", sizeof("NetX HTTP File Write Failed") - 1, NX_NULL, 0);
4185 
4186             /* Error, return to caller.  */
4187             return;
4188         }
4189 
4190         /* Update the length.  */
4191         length =  length - (ULONG)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr);
4192 
4193         /* Increment the bytes received count.  */
4194         server_ptr -> nx_http_server_total_bytes_received =  server_ptr -> nx_http_server_total_bytes_received +
4195                                         (ULONG)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr);
4196 
4197         /* Move to the next pointer.  */
4198         next_packet_ptr =  next_packet_ptr -> nx_packet_next;
4199     }
4200 #endif /* NX_DISABLE_PACKET_CHAIN */
4201 
4202     /* If necessary, receive more packets from the TCP socket to complete the write request.  */
4203     while (length)
4204     {
4205 
4206         /* Wait for a request on the HTTP TCP well know port 80.  */
4207         status =  nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), &data_packet_ptr, NX_HTTP_SERVER_TIMEOUT_RECEIVE);
4208 
4209         /* Check the return status.  */
4210         if (status != NX_SUCCESS)
4211         {
4212 
4213             /* Send response back to HTTP Client.  */
4214             _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
4215                                           "NetX HTTP Receive Timeout", sizeof("NetX HTTP Receive Timeout") - 1, NX_NULL, 0);
4216 
4217             /* Error, return to caller.  */
4218             return;
4219         }
4220 
4221         /* Loop to write the packet chain out to the file.  */
4222         next_packet_ptr =  data_packet_ptr;
4223         do
4224         {
4225 
4226             /* Write the content of this packet.  */
4227             status =  fx_file_write(&(server_ptr -> nx_http_server_file), next_packet_ptr -> nx_packet_prepend_ptr,
4228                                                (ULONG)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr));
4229 
4230             /* Check the status.  */
4231             if (status != NX_SUCCESS)
4232             {
4233 
4234                 /* Send response back to HTTP Client.  */
4235                 _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
4236                                               "NetX HTTP File Write Failed", sizeof("NetX HTTP File Write Failed") - 1, NX_NULL, 0);
4237 
4238                 /* Release the previous data packet.  */
4239                 nx_packet_release(data_packet_ptr);
4240 
4241                 /* Error, return to caller.  */
4242                 return;
4243             }
4244 
4245             /* Update the length.  */
4246             length =  length - (UINT)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr);
4247 
4248             /* Increment the bytes received count.  */
4249             server_ptr -> nx_http_server_total_bytes_received =  server_ptr -> nx_http_server_total_bytes_received +
4250                                         (ULONG)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr);
4251 
4252 #ifdef NX_DISABLE_PACKET_CHAIN
4253             next_packet_ptr =  NX_NULL;
4254 #else
4255             /* Move to the next pointer.  */
4256             next_packet_ptr =  next_packet_ptr -> nx_packet_next;
4257 #endif /* NX_DISABLE_PACKET_CHAIN */
4258 
4259         } while ((length) && (next_packet_ptr));
4260 
4261         /* Release the previous data packet.  */
4262         nx_packet_release(data_packet_ptr);
4263     }
4264 
4265     /* Success, at this point close the file and prepare a successful response for the client.  */
4266     fx_file_close(&(server_ptr -> nx_http_server_file));
4267 
4268 
4269     /* Now build a response header.  */
4270     status = _nx_http_server_generate_response_header(server_ptr, &data_packet_ptr, NX_HTTP_STATUS_OK, sizeof(NX_HTTP_STATUS_OK) - 1, 0, NX_NULL, 0, NX_NULL, 0);
4271     if (status == NX_SUCCESS)
4272     {
4273 
4274         /* Send the response back to the client.  */
4275         status =  nx_tcp_socket_send(&(server_ptr -> nx_http_server_socket), data_packet_ptr, NX_HTTP_SERVER_TIMEOUT_SEND);
4276 
4277         /* Check for an error.  */
4278         if (status != NX_SUCCESS)
4279         {
4280 
4281             /* Just release the packet.  */
4282             nx_packet_release(data_packet_ptr);
4283         }
4284     }
4285 
4286 }
4287 
4288 
4289 /**************************************************************************/
4290 /*                                                                        */
4291 /*  FUNCTION                                               RELEASE        */
4292 /*                                                                        */
4293 /*    _nx_http_server_delete_process                      PORTABLE C      */
4294 /*                                                           6.1          */
4295 /*  AUTHOR                                                                */
4296 /*                                                                        */
4297 /*    Yuxin Zhou, Microsoft Corporation                                   */
4298 /*                                                                        */
4299 /*  DESCRIPTION                                                           */
4300 /*                                                                        */
4301 /*    This function processes the DELETE HTTP client requests.            */
4302 /*                                                                        */
4303 /*                                                                        */
4304 /*  INPUT                                                                 */
4305 /*                                                                        */
4306 /*    server_ptr                            HTTP Server pointer           */
4307 /*    packet_ptr                            Request packet pointer        */
4308 /*                                                                        */
4309 /*  OUTPUT                                                                */
4310 /*                                                                        */
4311 /*    None                                                                */
4312 /*                                                                        */
4313 /*  CALLS                                                                 */
4314 /*                                                                        */
4315 /*    _nx_http_server_basic_authenticate    Process basic authentication  */
4316 /*    _nx_http_server_digest_authenticate   Process digest authentication */
4317 /*    _nx_http_server_response_send         Send response back to client  */
4318 /*    _nx_http_server_retrieve_resource     Retrieve resource from request*/
4319 /*    fx_file_delete                        Delete resource file          */
4320 /*    nx_packet_allocate                    Allocate a new packet         */
4321 /*    nx_packet_data_append                 Append information to response*/
4322 /*    nx_packet_release                     Release packet                */
4323 /*    nx_tcp_socket_send                    Send HTTP Server response     */
4324 /*                                                                        */
4325 /*  CALLED BY                                                             */
4326 /*                                                                        */
4327 /*    _nx_http_server_thread_entry          HTTP Server thread            */
4328 /*                                                                        */
4329 /*  RELEASE HISTORY                                                       */
4330 /*                                                                        */
4331 /*    DATE              NAME                      DESCRIPTION             */
4332 /*                                                                        */
4333 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4334 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4335 /*                                            resulting in version 6.1    */
4336 /*                                                                        */
4337 /**************************************************************************/
_nx_http_server_delete_process(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr)4338 VOID  _nx_http_server_delete_process(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr)
4339 {
4340 
4341 UINT        status;
4342 CHAR        *name_ptr;
4343 CHAR        *password_ptr;
4344 CHAR        *realm_ptr;
4345 NX_PACKET   *response_ptr;
4346 UINT        auth_request_present = NX_FALSE;
4347 UINT        name_length = 0;
4348 UINT        password_length = 0;
4349 UINT        realm_length = 0;
4350 UINT        temp_name_length = 0;
4351 UINT        temp_password_length = 0;
4352 UINT        temp_realm_length = 0;
4353 
4354 
4355     /* Pickup the URL (resource) from the request.  */
4356     status =  _nx_http_server_retrieve_resource(packet_ptr, server_ptr -> nx_http_server_request_resource, NX_HTTP_MAX_RESOURCE + 1);
4357 
4358     /* Determine if the resource was extracted successfully.  */
4359     if (status != NX_SUCCESS)
4360     {
4361 
4362         /* Send response back to HTTP Client.  */
4363         _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_BAD_REQUEST, sizeof(NX_HTTP_STATUS_BAD_REQUEST) - 1,
4364                                       "NetX HTTP URL Bad", sizeof("NetX HTTP URL Bad") - 1, NX_NULL, 0);
4365 
4366         /* Error, return to caller.  */
4367         return;
4368     }
4369 
4370     /* Determine if the application has specified an authentication function for this server.  */
4371     if (server_ptr -> nx_http_server_authentication_check ||
4372         server_ptr -> nx_http_server_authentication_check_extended)
4373     {
4374 
4375         /* Determine if authentication is required for the specified resource.  */
4376         if (server_ptr -> nx_http_server_authentication_check_extended)
4377         {
4378             status = (server_ptr -> nx_http_server_authentication_check_extended)(server_ptr, NX_HTTP_SERVER_DELETE_REQUEST, server_ptr -> nx_http_server_request_resource,
4379                                                                                   &name_ptr, &name_length, &password_ptr, &password_length, &realm_ptr, &realm_length);
4380         }
4381         else
4382         {
4383             status = (server_ptr -> nx_http_server_authentication_check)(server_ptr, NX_HTTP_SERVER_DELETE_REQUEST, server_ptr -> nx_http_server_request_resource,
4384                                                                          &name_ptr, &password_ptr, &realm_ptr);
4385         }
4386 
4387         if (status == NX_HTTP_BASIC_AUTHENTICATE ||
4388             status == NX_HTTP_DIGEST_AUTHENTICATE)
4389         {
4390 
4391             /* Check name, password and realm string.  */
4392             if (_nx_utility_string_length_check(name_ptr, &temp_name_length, NX_HTTP_MAX_NAME) ||
4393                 _nx_utility_string_length_check(password_ptr, &temp_password_length, NX_HTTP_MAX_PASSWORD) ||
4394                 _nx_utility_string_length_check(realm_ptr, &temp_realm_length, NX_MAX_STRING_LENGTH))
4395             {
4396 
4397                 /* Error, return to caller.  */
4398                 return;
4399             }
4400 
4401             /* Validate string length. */
4402             if (server_ptr -> nx_http_server_authentication_check_extended &&
4403                 ((realm_length != temp_realm_length) ||
4404                  (name_length != temp_name_length) ||
4405                  (password_length != temp_password_length)))
4406             {
4407                 return;
4408             }
4409         }
4410 
4411         /* Determine what kind - if any - authentication is requested for this resource.  */
4412         if (status == NX_HTTP_BASIC_AUTHENTICATE)
4413         {
4414 
4415             /* Process basic authentication request.  */
4416             status =  _nx_http_server_basic_authenticate(server_ptr, packet_ptr, name_ptr, password_ptr, realm_ptr, temp_realm_length, &auth_request_present);
4417         }
4418 #ifdef  NX_HTTP_DIGEST_ENABLE
4419         else if (status == NX_HTTP_DIGEST_AUTHENTICATE)
4420         {
4421 
4422             /* Process digest authentication request.  */
4423             status =  _nx_http_server_digest_authenticate(server_ptr, packet_ptr, name_ptr, temp_name_length, password_ptr, temp_password_length, realm_ptr, temp_realm_length, &auth_request_present);
4424         }
4425 #endif
4426 
4427         /* Determine if the authentication is currently in progress.  */
4428         if ((status != NX_HTTP_DONT_AUTHENTICATE) && (status != NX_SUCCESS))
4429         {
4430 
4431             /* Yes, authentication is in progress.  The HTTP 401 has already been sent.  */
4432             if (server_ptr -> nx_http_server_invalid_username_password_callback && auth_request_present)
4433             {
4434 
4435             NXD_ADDRESS client_nxd_address;
4436             ULONG       client_port;
4437 
4438                 /* Get the IP address of the client:  */
4439                 status =   nxd_tcp_socket_peer_info_get(&(server_ptr->nx_http_server_socket), &client_nxd_address , &client_port);
4440 
4441                 if (status == NX_SUCCESS)
4442                 {
4443                     /* Send this information to the host application. */
4444                     (server_ptr -> nx_http_server_invalid_username_password_callback)(server_ptr -> nx_http_server_request_resource, &client_nxd_address, NX_HTTP_SERVER_DELETE_REQUEST);
4445                 }
4446             }
4447 
4448             return;
4449         }
4450     }
4451 
4452     /* Determine if a user supplied notify function has been specified.  */
4453     if (server_ptr -> nx_http_server_request_notify)
4454     {
4455 
4456         /* Call the user supplied function to notify the user of the delete request.  */
4457         status =  (server_ptr -> nx_http_server_request_notify)(server_ptr, NX_HTTP_SERVER_DELETE_REQUEST, server_ptr -> nx_http_server_request_resource, packet_ptr);
4458 
4459         /* Determine if the user supplied routine is requesting the delete should be aborted.  */
4460         if (status != NX_SUCCESS)
4461         {
4462 
4463             /* Determine if the user callback routine successfully completed the request processing.  */
4464             if (status == NX_HTTP_CALLBACK_COMPLETED)
4465             {
4466 
4467                 /* Send success response back to HTTP Client.  */
4468                 _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_OK, sizeof(NX_HTTP_STATUS_OK) - 1, NX_NULL, 0, NX_NULL, 0);
4469                 return;
4470             }
4471 
4472             /* Send response back to HTTP Client.  */
4473             _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
4474                                           "NetX HTTP Request Aborted", sizeof("NetX HTTP Request Aborted") - 1, NX_NULL, 0);
4475 
4476             /* Yes, error was detected. Abort the remainder of the delete processing.  */
4477             return;
4478         }
4479     }
4480 
4481     /* Otherwise, everything is okay...  complete the request.  */
4482 
4483     /* Delete the specified file.  */
4484     status =  fx_file_delete(server_ptr -> nx_http_server_media_ptr, server_ptr -> nx_http_server_request_resource);
4485 
4486     /* Check for error condition.  */
4487     if (status != NX_SUCCESS)
4488     {
4489 
4490         /* Send response back to HTTP Client.  */
4491         _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
4492                                       "NetX HTTP File Delete Failed", sizeof("NetX HTTP File Delete Failed") - 1, NX_NULL, 0);
4493 
4494         /* Error, return to caller.  */
4495         return;
4496     }
4497 
4498     /* Now build a response header.  */
4499     status = _nx_http_server_generate_response_header(server_ptr, &response_ptr, NX_HTTP_STATUS_OK, sizeof(NX_HTTP_STATUS_OK) - 1, 0, NX_NULL, 0, NX_NULL, 0);
4500     if (status == NX_SUCCESS)
4501     {
4502 
4503         /* Send the response back to the client.  */
4504         status =  nx_tcp_socket_send(&(server_ptr -> nx_http_server_socket), response_ptr, NX_HTTP_SERVER_TIMEOUT_SEND);
4505 
4506         /* Check for an error.  */
4507         if (status != NX_SUCCESS)
4508         {
4509 
4510             /* Just release the packet.  */
4511             nx_packet_release(response_ptr);
4512         }
4513     }
4514 }
4515 
4516 
4517 /**************************************************************************/
4518 /*                                                                        */
4519 /*  FUNCTION                                               RELEASE        */
4520 /*                                                                        */
4521 /*    _nxe_http_server_invalid_userpassword_notify_set     PORTABLE C     */
4522 /*                                                           6.1          */
4523 /*  AUTHOR                                                                */
4524 /*                                                                        */
4525 /*    Yuxin Zhou, Microsoft Corporation                                   */
4526 /*                                                                        */
4527 /*  DESCRIPTION                                                           */
4528 /*                                                                        */
4529 /*    This function performs error checking for service to set invalid    */
4530 /*    username password callback function.                                */
4531 /*                                                                        */
4532 /*                                                                        */
4533 /*  INPUT                                                                 */
4534 /*                                                                        */
4535 /*    http_server_ptr                       Pointer to HTTP server        */
4536 /*    invalid_username_password_callback    Pointer to application's      */
4537 /*                                          invalid username password     */
4538 /*                                          callback function             */
4539 /*                                                                        */
4540 /*  OUTPUT                                                                */
4541 /*                                                                        */
4542 /*    status                                Completion status             */
4543 /*                                                                        */
4544 /*  CALLED BY                                                             */
4545 /*                                                                        */
4546 /*    Application Code                                                    */
4547 /*                                                                        */
4548 /*  RELEASE HISTORY                                                       */
4549 /*                                                                        */
4550 /*    DATE              NAME                      DESCRIPTION             */
4551 /*                                                                        */
4552 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4553 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4554 /*                                            resulting in version 6.1    */
4555 /*                                                                        */
4556 /**************************************************************************/
_nxe_http_server_invalid_userpassword_notify_set(NX_HTTP_SERVER * http_server_ptr,UINT (* invalid_username_password_callback)(CHAR * resource,NXD_ADDRESS * client_nxd_address,UINT request_type))4557 UINT _nxe_http_server_invalid_userpassword_notify_set(NX_HTTP_SERVER *http_server_ptr,
4558                                                     UINT (*invalid_username_password_callback)(CHAR *resource, NXD_ADDRESS *client_nxd_address, UINT request_type))
4559 {
4560 
4561 UINT status;
4562 
4563 
4564     if ((http_server_ptr == NX_NULL) || (invalid_username_password_callback == NX_NULL))
4565     {
4566         return NX_PTR_ERROR;
4567     }
4568 
4569     status = _nx_http_server_invalid_userpassword_notify_set(http_server_ptr, invalid_username_password_callback);
4570 
4571     return status;
4572 }
4573 
4574 
4575 /**************************************************************************/
4576 /*                                                                        */
4577 /*  FUNCTION                                               RELEASE        */
4578 /*                                                                        */
4579 /*    nx_http_server_invalid_userpassword_notify_set      PORTABLE C      */
4580 /*                                                           6.1          */
4581 /*  AUTHOR                                                                */
4582 /*                                                                        */
4583 /*    Yuxin Zhou, Microsoft Corporation                                   */
4584 /*                                                                        */
4585 /*  DESCRIPTION                                                           */
4586 /*                                                                        */
4587 /*    This function sets invalid username password callback function.     */
4588 /*                                                                        */
4589 /*    Note: The string length of resource in                              */
4590 /*    invalid_username_password_callback is limited by                    */
4591 /*    NX_HTTP_MAX_RESOURCE.                                               */
4592 /*                                                                        */
4593 /*                                                                        */
4594 /*  INPUT                                                                 */
4595 /*                                                                        */
4596 /*    http_server_ptr                       Pointer to HTTP server        */
4597 /*    invalid_username_password_callback    Pointer to application's      */
4598 /*                                          invalid username password     */
4599 /*                                          callback function             */
4600 /*                                                                        */
4601 /*  OUTPUT                                                                */
4602 /*                                                                        */
4603 /*    status                                Completion status             */
4604 /*                                                                        */
4605 /*  CALLED BY                                                             */
4606 /*                                                                        */
4607 /*    Application Code                                                    */
4608 /*                                                                        */
4609 /*  RELEASE HISTORY                                                       */
4610 /*                                                                        */
4611 /*    DATE              NAME                      DESCRIPTION             */
4612 /*                                                                        */
4613 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4614 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4615 /*                                            resulting in version 6.1    */
4616 /*                                                                        */
4617 /**************************************************************************/
_nx_http_server_invalid_userpassword_notify_set(NX_HTTP_SERVER * http_server_ptr,UINT (* invalid_username_password_callback)(CHAR * resource,NXD_ADDRESS * client_nxd_address,UINT request_type))4618 UINT _nx_http_server_invalid_userpassword_notify_set(NX_HTTP_SERVER *http_server_ptr,
4619                                                     UINT (*invalid_username_password_callback)(CHAR *resource, NXD_ADDRESS *client_nxd_address, UINT request_type))
4620 {
4621 
4622     http_server_ptr -> nx_http_server_invalid_username_password_callback = invalid_username_password_callback;
4623 
4624     return NX_SUCCESS;
4625 }
4626 
4627 
4628 /**************************************************************************/
4629 /*                                                                        */
4630 /*  FUNCTION                                               RELEASE        */
4631 /*                                                                        */
4632 /*    _nx_http_server_response_send                       PORTABLE C      */
4633 /*                                                           6.1          */
4634 /*  AUTHOR                                                                */
4635 /*                                                                        */
4636 /*    Yuxin Zhou, Microsoft Corporation                                   */
4637 /*                                                                        */
4638 /*  DESCRIPTION                                                           */
4639 /*                                                                        */
4640 /*    This function sends the specified Server response to the requesting */
4641 /*    HTTP client.                                                        */
4642 /*                                                                        */
4643 /*    Note: The strings of status code, information and additional info   */
4644 /*    must be NULL-terminated and length of this string matches the length*/
4645 /*    specified in the argument list.                                     */
4646 /*                                                                        */
4647 /*  INPUT                                                                 */
4648 /*                                                                        */
4649 /*    server_ptr                            HTTP Server pointer           */
4650 /*    status_code                           Status-code and reason-phrase */
4651 /*    information                           Pointer to HTTP info string   */
4652 /*    information_length                    Length of HTTP info string    */
4653 /*    additional_information                Pointer to additional HTTP    */
4654 /*                                            information                 */
4655 /*    additional_info_length                Length of additional HTTP     */
4656 /*                                            information                 */
4657 /*                                                                        */
4658 /*  OUTPUT                                                                */
4659 /*                                                                        */
4660 /*    None                                                                */
4661 /*                                                                        */
4662 /*  CALLS                                                                 */
4663 /*                                                                        */
4664 /*    nx_packet_allocate                    Allocate a new packet         */
4665 /*    nx_packet_data_append                 Append information to response*/
4666 /*    nx_packet_release                     Release packet                */
4667 /*    nx_tcp_socket_send                    Send HTTP Server response     */
4668 /*    _nx_utility_string_length_check       Check string length           */
4669 /*                                                                        */
4670 /*  CALLED BY                                                             */
4671 /*                                                                        */
4672 /*    _nx_http_server_thread_entry          HTTP Server thread            */
4673 /*    _nx_http_server_get_process           Process GET request           */
4674 /*    _nx_http_server_put_process           Process PUT request           */
4675 /*    _nx_http_server_delete_process        Process DELETE request        */
4676 /*                                                                        */
4677 /*  RELEASE HISTORY                                                       */
4678 /*                                                                        */
4679 /*    DATE              NAME                      DESCRIPTION             */
4680 /*                                                                        */
4681 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4682 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4683 /*                                            resulting in version 6.1    */
4684 /*                                                                        */
4685 /**************************************************************************/
_nx_http_server_response_send(NX_HTTP_SERVER * server_ptr,CHAR * status_code,UINT status_code_length,CHAR * information,UINT information_length,CHAR * additional_information,UINT additional_info_length)4686 UINT  _nx_http_server_response_send(NX_HTTP_SERVER *server_ptr, CHAR *status_code, UINT status_code_length, CHAR *information,
4687                                     UINT information_length, CHAR *additional_information, UINT additional_info_length)
4688 {
4689 
4690 UINT        status;
4691 UINT        length;
4692 NX_PACKET   *packet_ptr;
4693 
4694 
4695     /* Determine if there is additional information.  */
4696     if(information)
4697     {
4698 
4699         /* Calculate the size of the information field.  */
4700         length = information_length;
4701 
4702         /* Determine if there is additional information.  */
4703         if (additional_information)
4704         {
4705 
4706             /* Update the length with it as well.  */
4707             length = length + additional_info_length;
4708         }
4709     }
4710     else
4711         length = 0;
4712 
4713     /* Generate response header. */
4714     status = _nx_http_server_generate_response_header(server_ptr, &packet_ptr, status_code, status_code_length, length, NX_NULL, 0, NX_NULL, 0);
4715 
4716     /* Determine if an error occurred.  */
4717     if (status != NX_SUCCESS)
4718     {
4719 
4720         /* Just return.  */
4721         return(NX_HTTP_ERROR);
4722     }
4723 
4724     /* Determine if there is additional information.  */
4725     if (information)
4726     {
4727 
4728         /* Place the first informational field.  */
4729         status = nx_packet_data_append(packet_ptr, information, information_length,
4730                                        server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4731 
4732         /* If there is additional information, place it in the buffer as well.  */
4733         if (additional_information)
4734         {
4735 
4736             /* Now, place the additional informational field.  */
4737             status += nx_packet_data_append(packet_ptr, additional_information, additional_info_length,
4738                                             server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4739         }
4740     }
4741 
4742     /* Check for an error.  */
4743     if (status != NX_SUCCESS)
4744     {
4745 
4746         /* Just release the packet and return.  */
4747         nx_packet_release(packet_ptr);
4748         return(NX_HTTP_ERROR);
4749     }
4750 
4751     /* Send the response back to the client.  */
4752     status =  nx_tcp_socket_send(&(server_ptr -> nx_http_server_socket), packet_ptr, NX_HTTP_SERVER_TIMEOUT_SEND);
4753 
4754     /* Check for an error.  */
4755     if (status != NX_SUCCESS)
4756     {
4757 
4758         /* Just release the packet.  */
4759         nx_packet_release(packet_ptr);
4760     }
4761 
4762     return(status);
4763 }
4764 
4765 
4766 /**************************************************************************/
4767 /*                                                                        */
4768 /*  FUNCTION                                               RELEASE        */
4769 /*                                                                        */
4770 /*    _nx_http_server_basic_authenticate                  PORTABLE C      */
4771 /*                                                           6.2.0        */
4772 /*  AUTHOR                                                                */
4773 /*                                                                        */
4774 /*    Yuxin Zhou, Microsoft Corporation                                   */
4775 /*                                                                        */
4776 /*  DESCRIPTION                                                           */
4777 /*                                                                        */
4778 /*    This function checks for basic (name & password) authentication.    */
4779 /*    If found and correct, it returns a success.  Otherwise, it returns  */
4780 /*    an authentication request to the requesting client.                 */
4781 /*                                                                        */
4782 /*                                                                        */
4783 /*  INPUT                                                                 */
4784 /*                                                                        */
4785 /*    server_ptr                            HTTP Server pointer           */
4786 /*    packet_ptr                            Request packet pointer        */
4787 /*    name_ptr                              Pointer to name string        */
4788 /*    password_ptr                          Pointer to password string    */
4789 /*    realm_ptr                             Pointer to realm string       */
4790 /*    realm_length                          Length of realm string        */
4791 /*    auth_request_present                  Indicate if authentication    */
4792 /*                                                  must be performed     */
4793 /*                                                                        */
4794 /*  OUTPUT                                                                */
4795 /*                                                                        */
4796 /*    status                                Completion status             */
4797 /*                                                                        */
4798 /*  CALLS                                                                 */
4799 /*                                                                        */
4800 /*   _nx_http_server_retrieve_basic_authorization Pickup authorization    */
4801 /*   _nx_http_base64_decode                 Decode authorization          */
4802 /*    nx_packet_allocate                    Allocate a new packet         */
4803 /*    nx_packet_data_append                 Append information to response*/
4804 /*    nx_packet_release                     Release packet                */
4805 /*    nx_tcp_socket_send                    Send HTTP Server response     */
4806 /*                                                                        */
4807 /*  CALLED BY                                                             */
4808 /*                                                                        */
4809 /*    _nx_http_server_get_process           Process GET request           */
4810 /*    _nx_http_server_put_process           Process PUT request           */
4811 /*    _nx_http_server_delete_process        Process DELETE request        */
4812 /*                                                                        */
4813 /*  RELEASE HISTORY                                                       */
4814 /*                                                                        */
4815 /*    DATE              NAME                      DESCRIPTION             */
4816 /*                                                                        */
4817 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4818 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4819 /*                                            resulting in version 6.1    */
4820 /*  04-02-2021     Yuxin Zhou               Modified comment(s), and      */
4821 /*                                            improved the logic of       */
4822 /*                                            parsing base64,             */
4823 /*                                            resulting in version 6.1.6  */
4824 /*  10-31-2022     Yuxin Zhou               Modified comment(s), fixed    */
4825 /*                                            the issue of processing     */
4826 /*                                            empty password,             */
4827 /*                                            resulting in version 6.2.0  */
4828 /*                                                                        */
4829 /**************************************************************************/
_nx_http_server_basic_authenticate(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,CHAR * name_ptr,CHAR * password_ptr,CHAR * realm_ptr,UINT realm_length,UINT * auth_request_present)4830 UINT  _nx_http_server_basic_authenticate(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, CHAR *name_ptr, CHAR *password_ptr, CHAR *realm_ptr, UINT realm_length, UINT *auth_request_present)
4831 {
4832 
4833 UINT        i, j;
4834 UINT        status, status1;
4835 CHAR        quote[2] = {0x22, 0};
4836 CHAR        crlf[2] = {13,10};
4837 UINT        match;
4838 UINT        length;
4839 UINT        authorization_decoded_size;
4840 
4841     /* Default to no authentication request detected. */
4842     *auth_request_present = NX_FALSE;
4843 
4844     /* Default the status to authenticate.  */
4845     status =  NX_HTTP_BASIC_AUTHENTICATE;
4846 
4847     memset(&authorization_request[0], 0, sizeof(authorization_request));
4848 
4849     memset(&authorization_decoded[0], 0, sizeof(authorization_decoded));
4850 
4851     /* Is the authorization request present?  */
4852     length = _nx_http_server_retrieve_basic_authorization(packet_ptr, authorization_request);
4853     if (length)
4854     {
4855 
4856         /* Yes, an authorization request is present.  */
4857         *auth_request_present = NX_TRUE;
4858 
4859         /* Convert the request from Base64 representation to ASCII.  */
4860         _nx_utility_base64_decode((UCHAR *)authorization_request, length, (UCHAR *)authorization_decoded, sizeof(authorization_decoded), &authorization_decoded_size);
4861 
4862         /* See if it is valid.  */
4863 
4864         /* Compare the name.  */
4865         i =  0;
4866         match = NX_TRUE;
4867         while (name_ptr[i] && (i < authorization_decoded_size))
4868         {
4869 
4870             /* Is there a mismatch?  */
4871             if (name_ptr[i] != authorization_decoded[i])
4872             {
4873 
4874                 /* Name mismatch. Continue to avoid timing attack. */
4875                 match = NX_FALSE;
4876             }
4877 
4878             /* Move to next character.  */
4879             i++;
4880         }
4881 
4882         /* Determine if everything matches.  */
4883         if (match && (i < authorization_decoded_size) && (authorization_decoded[i] == ':'))
4884         {
4885 
4886             /* Move the authorization index past the semicolon.  */
4887             i++;
4888 
4889             /* Now compare the passwords.  */
4890             j =  0;
4891             match = NX_TRUE;
4892             while (password_ptr[j] && (i < authorization_decoded_size))
4893             {
4894 
4895                 /* Is there a mismatch?  */
4896                 if (password_ptr[j] != authorization_decoded[i])
4897                 {
4898 
4899                     /* Password mismatch. Continue to avoid timing attack. */
4900                     match = NX_FALSE;
4901                 }
4902 
4903                 /* Move to next character.  */
4904                 i++;
4905                 j++;
4906             }
4907 
4908             /* Determine if we have a match.  */
4909             if (match && (i == authorization_decoded_size) &&
4910                 (authorization_decoded[i] == (CHAR) NX_NULL) &&
4911                 (password_ptr[j] == (CHAR) NX_NULL))
4912             {
4913 
4914                 /* Yes, we have successful authorization!!  */
4915                 status =  NX_SUCCESS;
4916             }
4917         }
4918     }
4919 
4920     /* Determine if we need to send back an unauthorized request.  */
4921     if (status == NX_HTTP_BASIC_AUTHENTICATE)
4922     {
4923 
4924         /* We need authorization so build the HTTP 401 Unauthorized message to send to the server.  */
4925 
4926         /* Allocate a packet for sending the response back.  */
4927         status1 =  nx_packet_allocate(server_ptr -> nx_http_server_packet_pool_ptr, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER);
4928 
4929         /* Determine if an error occurred in the packet allocation.  */
4930         if (status1 != NX_SUCCESS)
4931         {
4932 
4933             /* Indicate an allocation error occurred.  */
4934             server_ptr -> nx_http_server_allocation_errors++;
4935 
4936             /* Just return.  */
4937             return(status1);
4938         }
4939 
4940         /* Insert the response header.  */
4941         nx_packet_data_append(packet_ptr, NX_HTTP_VERSION, sizeof(NX_HTTP_VERSION) - 1,
4942                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4943         nx_packet_data_append(packet_ptr, " ", 1, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4944         nx_packet_data_append(packet_ptr, NX_HTTP_STATUS_UNAUTHORIZED, sizeof(NX_HTTP_STATUS_UNAUTHORIZED) - 1,
4945                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4946 
4947         /* Place the <cr,lf> into the buffer.  */
4948         nx_packet_data_append(packet_ptr, crlf, 2,
4949                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4950 
4951         /* Insert the type of authentication requested.  */
4952         nx_packet_data_append(packet_ptr, "WWW-Authenticate: Basic realm=", 30,
4953                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4954 
4955         /* Insert the double quote.  */
4956         nx_packet_data_append(packet_ptr, quote, 1,
4957                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4958 
4959         /* Place the realm string into the buffer.  */
4960         nx_packet_data_append(packet_ptr, realm_ptr, realm_length,
4961                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4962 
4963         /* Insert the double quote.  */
4964         nx_packet_data_append(packet_ptr, quote, 1,
4965                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4966 
4967         /* Place the <cr,lf> into the buffer.  */
4968         nx_packet_data_append(packet_ptr, crlf, 2,
4969                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4970 
4971         /* Place another <cr,lf> into the buffer to signal end of FULL HTTP response.  */
4972         nx_packet_data_append(packet_ptr, crlf, 2,
4973                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
4974 
4975         /* Send the response back to the client.  */
4976         status1 =  nx_tcp_socket_send(&(server_ptr -> nx_http_server_socket), packet_ptr, NX_HTTP_SERVER_TIMEOUT_SEND);
4977 
4978         /* Check for an error.  */
4979         if (status1)
4980         {
4981 
4982             /* Return the internal NetX error. */
4983             status = status1;
4984 
4985             /* Just release the packet.  */
4986             nx_packet_release(packet_ptr);
4987         }
4988     }
4989 
4990     /* Return the result of the authentication request.  */
4991     return(status);
4992 }
4993 
4994 
4995 /**************************************************************************/
4996 /*                                                                        */
4997 /*  FUNCTION                                               RELEASE        */
4998 /*                                                                        */
4999 /*    _nx_http_server_retrieve_basic_authorization        PORTABLE C      */
5000 /*                                                           6.1.10       */
5001 /*  AUTHOR                                                                */
5002 /*                                                                        */
5003 /*    Yuxin Zhou, Microsoft Corporation                                   */
5004 /*                                                                        */
5005 /*  DESCRIPTION                                                           */
5006 /*                                                                        */
5007 /*    This function retrieves basic authentication information from the   */
5008 /*    HTTP request packet.                                                */
5009 /*                                                                        */
5010 /*                                                                        */
5011 /*  INPUT                                                                 */
5012 /*                                                                        */
5013 /*    packet_ptr                            Request packet pointer        */
5014 /*    authorization_request_ptr             Pointer to destination for    */
5015 /*                                            authorization string        */
5016 /*                                                                        */
5017 /*  OUTPUT                                                                */
5018 /*                                                                        */
5019 /*    status                                Completion status             */
5020 /*                                                                        */
5021 /*  CALLS                                                                 */
5022 /*                                                                        */
5023 /*   None                                                                 */
5024 /*                                                                        */
5025 /*  CALLED BY                                                             */
5026 /*                                                                        */
5027 /*    _nx_http_server_basic_authenticate    Basic authenticate processing */
5028 /*                                                                        */
5029 /*  RELEASE HISTORY                                                       */
5030 /*                                                                        */
5031 /*    DATE              NAME                      DESCRIPTION             */
5032 /*                                                                        */
5033 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5034 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5035 /*                                            resulting in version 6.1    */
5036 /*  01-31-2022     Yuxin Zhou               Modified comment(s),  fixed   */
5037 /*                                            the HTTP Server state issue */
5038 /*                                            with basic authorization,   */
5039 /*                                            resulting in version 6.1.10 */
5040 /*                                                                        */
5041 /**************************************************************************/
_nx_http_server_retrieve_basic_authorization(NX_PACKET * packet_ptr,CHAR * authorization_request_ptr)5042 UINT  _nx_http_server_retrieve_basic_authorization(NX_PACKET *packet_ptr, CHAR *authorization_request_ptr)
5043 {
5044 
5045 UINT    length;
5046 UINT    found;
5047 CHAR    *buffer_ptr;
5048 
5049 
5050     /* Set the found flag to false.  */
5051     found =  NX_FALSE;
5052 
5053     /* Default the authorization request to zero.  */
5054     length =  0;
5055 
5056     /* Set the authorization request string to NULL.  */
5057     authorization_request_ptr[0] =  NX_NULL;
5058 
5059     /* Setup pointer to buffer.  */
5060     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
5061 
5062 
5063     /* Find the "Authorization: " token first.  */
5064     while (((buffer_ptr+15) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
5065     {
5066 
5067         /* Check for the Authorization: token.  */
5068         if (((*buffer_ptr ==      'a') || (*buffer_ptr ==      'A')) &&
5069             ((*(buffer_ptr+1) ==  'u') || (*(buffer_ptr+1) ==  'U')) &&
5070             ((*(buffer_ptr+2) ==  't') || (*(buffer_ptr+2) ==  'T')) &&
5071             ((*(buffer_ptr+3) ==  'h') || (*(buffer_ptr+3) ==  'H')) &&
5072             ((*(buffer_ptr+4) ==  'o') || (*(buffer_ptr+4) ==  'O')) &&
5073             ((*(buffer_ptr+5) ==  'r') || (*(buffer_ptr+5) ==  'R')) &&
5074             ((*(buffer_ptr+6) ==  'i') || (*(buffer_ptr+6) ==  'I')) &&
5075             ((*(buffer_ptr+7) ==  'z') || (*(buffer_ptr+7) ==  'Z')) &&
5076             ((*(buffer_ptr+8) ==  'a') || (*(buffer_ptr+8) ==  'A')) &&
5077             ((*(buffer_ptr+9) ==  't') || (*(buffer_ptr+9) ==  'T')) &&
5078             ((*(buffer_ptr+10) == 'i') || (*(buffer_ptr+10) == 'I')) &&
5079             ((*(buffer_ptr+11) == 'o') || (*(buffer_ptr+11) == 'O')) &&
5080             ((*(buffer_ptr+12) == 'n') || (*(buffer_ptr+12) == 'N')) &&
5081             (*(buffer_ptr+13) == ':') &&
5082             (*(buffer_ptr+14) == ' '))
5083         {
5084 
5085             /* Move the pointer up to the length token.  */
5086             buffer_ptr =  buffer_ptr + 15;
5087 
5088             /* Set the found flag.  */
5089             found =  NX_TRUE;
5090             break;
5091         }
5092 
5093         /* Move the pointer up to the next character.  */
5094         buffer_ptr++;
5095     }
5096 
5097     /* Determine if the first token was found.  */
5098     if (!found)
5099     {
5100 
5101         /* No, authorization is not present.  Return a zero length.  */
5102         return(length);
5103     }
5104 
5105     /* Set the found flag back to false.  */
5106     found =  NX_FALSE;
5107 
5108     /* Now remove any extra blanks.  */
5109     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
5110     {
5111 
5112         /* Move the pointer up one character.  */
5113         buffer_ptr++;
5114     }
5115 
5116     /* Now check for the "Basic " token.  */
5117     while (((buffer_ptr+6) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
5118     {
5119 
5120         /* Check for the Basic token.  */
5121         if (((*buffer_ptr ==      'b') || (*buffer_ptr ==      'B')) &&
5122             ((*(buffer_ptr+1) ==  'a') || (*(buffer_ptr+1) ==  'A')) &&
5123             ((*(buffer_ptr+2) ==  's') || (*(buffer_ptr+2) ==  'S')) &&
5124             ((*(buffer_ptr+3) ==  'i') || (*(buffer_ptr+3) ==  'I')) &&
5125             ((*(buffer_ptr+4) ==  'c') || (*(buffer_ptr+4) ==  'C')) &&
5126             (*(buffer_ptr+5) == ' '))
5127         {
5128 
5129             /* Move the pointer up to the actual authorization string.  */
5130             buffer_ptr =  buffer_ptr + 6;
5131 
5132             /* Set the found flag.  */
5133             found =  NX_TRUE;
5134             break;
5135         }
5136 
5137         /* Move the pointer up to the next character.  */
5138         buffer_ptr++;
5139     }
5140 
5141     /* Determine if the first token was found.  */
5142     if (!found)
5143     {
5144 
5145         /* No, authorization is not present.  Return a zero length.  */
5146         return(length);
5147     }
5148 
5149     /* Now remove any extra blanks.  */
5150     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
5151     {
5152 
5153         /* Move the pointer up one character.  */
5154         buffer_ptr++;
5155     }
5156 
5157     /* Now pickup the authorization string.  */
5158     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13) && (length < NX_HTTP_MAX_STRING))
5159     {
5160 
5161         /* Copy a character of the authorization string into the destination.  */
5162         authorization_request_ptr[length] =  *buffer_ptr++;
5163         length++;
5164     }
5165 
5166     /* Return the length to the caller.  */
5167     return(length);
5168 }
5169 
5170 
5171 /**************************************************************************/
5172 /*                                                                        */
5173 /*  FUNCTION                                               RELEASE        */
5174 /*                                                                        */
5175 /*    _nx_http_server_retrieve_resource                   PORTABLE C      */
5176 /*                                                           6.1          */
5177 /*  AUTHOR                                                                */
5178 /*                                                                        */
5179 /*    Yuxin Zhou, Microsoft Corporation                                   */
5180 /*                                                                        */
5181 /*  DESCRIPTION                                                           */
5182 /*                                                                        */
5183 /*    This function retrieves the resource (URL) portion of the request   */
5184 /*    and places it in the destination.                                   */
5185 /*                                                                        */
5186 /*                                                                        */
5187 /*  INPUT                                                                 */
5188 /*                                                                        */
5189 /*    server_ptr                            HTTP Server pointer           */
5190 /*    destination                           Destination for resource      */
5191 /*    max_size                              Maximum size of destination   */
5192 /*                                                                        */
5193 /*  OUTPUT                                                                */
5194 /*                                                                        */
5195 /*    Status                                Completion status             */
5196 /*                                                                        */
5197 /*  CALLS                                                                 */
5198 /*                                                                        */
5199 /*    None                                                                */
5200 /*                                                                        */
5201 /*  CALLED BY                                                             */
5202 /*                                                                        */
5203 /*    _nx_http_server_get_process           Process GET request           */
5204 /*    _nx_http_server_put_process           Process PUT request           */
5205 /*    _nx_http_server_delete_process        Process DELETE request        */
5206 /*                                                                        */
5207 /*  RELEASE HISTORY                                                       */
5208 /*                                                                        */
5209 /*    DATE              NAME                      DESCRIPTION             */
5210 /*                                                                        */
5211 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5212 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5213 /*                                            resulting in version 6.1    */
5214 /*                                                                        */
5215 /**************************************************************************/
_nx_http_server_retrieve_resource(NX_PACKET * packet_ptr,CHAR * destination,UINT max_size)5216 UINT  _nx_http_server_retrieve_resource(NX_PACKET *packet_ptr, CHAR *destination, UINT max_size)
5217 {
5218 
5219 UINT    i;
5220 CHAR    *buffer_ptr;
5221 
5222 
5223     /* Set the destination to NULL.  */
5224     destination[0] =  (CHAR) 0;
5225 
5226     /* Setup pointer to buffer.  */
5227     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
5228 
5229     /* Find the first space which is the start position of URI. */
5230     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != ' '))
5231     {
5232 
5233         /* Move the pointer up to the next character.  */
5234         buffer_ptr++;
5235     }
5236 
5237     /* Check for an error condition.  */
5238     if (buffer_ptr >= (CHAR *) packet_ptr -> nx_packet_append_ptr)
5239         return(NX_HTTP_ERROR);
5240 
5241     buffer_ptr++;
5242 
5243     if ((buffer_ptr + 7 < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != '/'))
5244     {
5245 
5246         /* Check whether it is an absoluteURI*/
5247         if (((*buffer_ptr == 'h') || (*buffer_ptr == 'H')) &&
5248             ((*(buffer_ptr + 1) == 't') || (*(buffer_ptr + 1) == 'T')) &&
5249             ((*(buffer_ptr + 2) == 't') || (*(buffer_ptr + 1) == 'T')) &&
5250             ((*(buffer_ptr + 3) == 'p') || (*(buffer_ptr + 1) == 'P')) &&
5251             (*(buffer_ptr + 4) == ':') &&
5252             (*(buffer_ptr + 5) == '/') &&
5253             (*(buffer_ptr + 6) == '/'))
5254         {
5255 
5256             /* Yes it is. Find the absolute path. */
5257             buffer_ptr += 7;
5258 
5259             /* Find the first slash character.  The first slash marks the beginning of the URL.  */
5260             while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != '/'))
5261             {
5262 
5263                 /* Move the pointer up to the next character.  */
5264                 buffer_ptr++;
5265             }
5266         }
5267     }
5268 
5269     /* Check for an error condition.  */
5270     if ((buffer_ptr >= (CHAR *) packet_ptr -> nx_packet_append_ptr) || (*buffer_ptr != '/'))
5271         return(NX_HTTP_ERROR);
5272 
5273     /* Copy the rest of the resource to the destination.  Space, semicolon, and question mark characters signal the
5274        end of the resource.  */
5275     i =  0;
5276     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != ' ') && (*buffer_ptr != ';') && (*buffer_ptr != '?') && (i < (max_size-1)))
5277     {
5278 
5279         /* Check escape characters. */
5280         if(*buffer_ptr == '%')
5281         {
5282 
5283             /* It is an escape character. */
5284             if((buffer_ptr + 2) < (CHAR *)packet_ptr -> nx_packet_append_ptr)
5285             {
5286 
5287                 /* Convert the HEX number. */
5288                 buffer_ptr++;
5289                 if((*buffer_ptr >= '0') && (*buffer_ptr <= '9'))
5290                     destination[i] = (CHAR)(*buffer_ptr - '0');
5291                 else if((*buffer_ptr >= 'a') && (*buffer_ptr <= 'f'))
5292                     destination[i] = (CHAR)(*buffer_ptr - 'a' + 10);
5293                 else if((*buffer_ptr >= 'A') && (*buffer_ptr <= 'F'))
5294                     destination[i] = (CHAR)(*buffer_ptr - 'A' + 10);
5295                 else
5296                 {
5297 
5298                     /* Error picking up the resource.  */
5299                     destination[0] =  (CHAR) 0;
5300                     return(NX_HTTP_ERROR);
5301                 }
5302                 destination[i] = (CHAR)(destination[i] << 4);
5303 
5304                 /* Convert the HEX number. */
5305                 buffer_ptr++;
5306                 if((*buffer_ptr >= '0') && (*buffer_ptr <= '9'))
5307                     destination[i] = (CHAR)(destination[i] + (*buffer_ptr - '0'));
5308                 else if((*buffer_ptr >= 'a') && (*buffer_ptr <= 'f'))
5309                     destination[i] = (CHAR)(destination[i] + (*buffer_ptr - 'a' + 10));
5310                 else if((*buffer_ptr >= 'A') && (*buffer_ptr <= 'F'))
5311                     destination[i] = (CHAR)(destination[i] + (*buffer_ptr - 'A' + 10));
5312                 else
5313                 {
5314 
5315                     /* Error picking up the resource.  */
5316                     destination[0] =  (CHAR) 0;
5317                     return(NX_HTTP_ERROR);
5318                 }
5319 
5320                 /* Move to the next byte. */
5321                 i++;
5322                 buffer_ptr++;
5323             }
5324             else
5325             {
5326 
5327                 /* Error picking up the resource.  */
5328                 destination[0] =  (CHAR) 0;
5329                 return(NX_HTTP_ERROR);
5330             }
5331         }
5332         else
5333         {
5334 
5335             /* Copy the URL name into the destination.  */
5336             destination[i++] =  *buffer_ptr++;
5337         }
5338     }
5339 
5340     /* Determine if the resource was retrieved.  */
5341     if ((destination[0] == (CHAR) 0) || (buffer_ptr >= (CHAR *)packet_ptr -> nx_packet_append_ptr) || ((*buffer_ptr != ' ') && (*buffer_ptr != '?') && (*buffer_ptr != ';')))
5342     {
5343 
5344         /* Error picking up the resource.  */
5345         destination[0] =  (CHAR) 0;
5346         return(NX_HTTP_ERROR);
5347     }
5348 
5349     /* Everything is okay, place a NULL at the end of the resource.  */
5350     destination[i] =  (CHAR) 0;
5351 
5352     /* Return success.  */
5353     return(NX_SUCCESS);
5354 }
5355 
5356 
5357 /**************************************************************************/
5358 /*                                                                        */
5359 /*  FUNCTION                                               RELEASE        */
5360 /*                                                                        */
5361 /*    _nx_http_server_calculate_content_offset            PORTABLE C      */
5362 /*                                                           6.1          */
5363 /*  AUTHOR                                                                */
5364 /*                                                                        */
5365 /*    Yuxin Zhou, Microsoft Corporation                                   */
5366 /*                                                                        */
5367 /*  DESCRIPTION                                                           */
5368 /*                                                                        */
5369 /*    This function calculates the byte offset to the start of the        */
5370 /*    HTTP request content area.  This area immediately follows the HTTP  */
5371 /*    request header (which ends with a blank line).                      */
5372 /*                                                                        */
5373 /*                                                                        */
5374 /*  INPUT                                                                 */
5375 /*                                                                        */
5376 /*    packet_ptr                            Pointer to request packet     */
5377 /*                                                                        */
5378 /*  OUTPUT                                                                */
5379 /*                                                                        */
5380 /*    Byte Offset                           (0 implies no content)        */
5381 /*                                                                        */
5382 /*  CALLS                                                                 */
5383 /*                                                                        */
5384 /*    None                                                                */
5385 /*                                                                        */
5386 /*  CALLED BY                                                             */
5387 /*                                                                        */
5388 /*    _nx_http_server_content_get           Application content get       */
5389 /*    _nx_http_server_get_process           Process GET request           */
5390 /*    _nx_http_server_put_process           Process PUT request           */
5391 /*                                                                        */
5392 /*  RELEASE HISTORY                                                       */
5393 /*                                                                        */
5394 /*    DATE              NAME                      DESCRIPTION             */
5395 /*                                                                        */
5396 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5397 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5398 /*                                            resulting in version 6.1    */
5399 /*                                                                        */
5400 /**************************************************************************/
_nx_http_server_calculate_content_offset(NX_PACKET * packet_ptr)5401 UINT  _nx_http_server_calculate_content_offset(NX_PACKET *packet_ptr)
5402 {
5403 
5404 UINT    offset;
5405 CHAR    *buffer_ptr;
5406 
5407 
5408     /* Default the content offset to zero.  */
5409     offset =  0;
5410 
5411     /* Setup pointer to buffer.  */
5412     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
5413 
5414     /* Find the "cr,lf,cr,lf" token.  */
5415     while (((buffer_ptr+3) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
5416     {
5417 
5418         /* Check for the <cr,lf,cr,lf> token.  This signals a blank line, which also
5419            specifies the start of the content.  */
5420         if ((*buffer_ptr ==      (CHAR) 13) &&
5421             (*(buffer_ptr+1) ==  (CHAR) 10) &&
5422             (*(buffer_ptr+2) ==  (CHAR) 13) &&
5423             (*(buffer_ptr+3) ==  (CHAR) 10))
5424         {
5425 
5426             /* Adjust the offset.  */
5427             offset =  offset + 4;
5428             break;
5429         }
5430 
5431         /* Move the pointer up to the next character.  */
5432         buffer_ptr++;
5433 
5434         /* Increment the offset.  */
5435         offset++;
5436     }
5437 
5438     /* Return the offset to the caller.  */
5439     return(offset);
5440 }
5441 
5442 
5443 /**************************************************************************/
5444 /*                                                                        */
5445 /*  FUNCTION                                               RELEASE        */
5446 /*                                                                        */
5447 /*    _nxe_http_server_type_get                           PORTABLE C      */
5448 /*                                                           6.1          */
5449 /*  AUTHOR                                                                */
5450 /*                                                                        */
5451 /*    Yuxin Zhou, Microsoft Corporation                                   */
5452 /*                                                                        */
5453 /*  DESCRIPTION                                                           */
5454 /*                                                                        */
5455 /*    This function checks error for deriving the type of the resource.   */
5456 /*                                                                        */
5457 /*  INPUT                                                                 */
5458 /*                                                                        */
5459 /*    server_ptr                            HTTP Server pointer           */
5460 /*    name                                  Name string                   */
5461 /*    http_type_string                      Destination HTTP type string  */
5462 /*                                                                        */
5463 /*  OUTPUT                                                                */
5464 /*                                                                        */
5465 /*    Size                                  Number of bytes in string     */
5466 /*                                                                        */
5467 /*  CALLS                                                                 */
5468 /*                                                                        */
5469 /*    _nx_http_server_type_get                                            */
5470 /*                                                                        */
5471 /*  CALLED BY                                                             */
5472 /*                                                                        */
5473 /*    Application Code                                                    */
5474 /*                                                                        */
5475 /*  RELEASE HISTORY                                                       */
5476 /*                                                                        */
5477 /*    DATE              NAME                      DESCRIPTION             */
5478 /*                                                                        */
5479 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5480 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5481 /*                                            resulting in version 6.1    */
5482 /*                                                                        */
5483 /**************************************************************************/
_nxe_http_server_type_get(NX_HTTP_SERVER * server_ptr,CHAR * name,CHAR * http_type_string)5484 UINT  _nxe_http_server_type_get(NX_HTTP_SERVER *server_ptr, CHAR *name, CHAR *http_type_string)
5485 {
5486 
5487     /* Check for invalid input pointers.  */
5488     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) || (name == NX_NULL) || (http_type_string == NX_NULL))
5489         return(0);
5490 
5491     return _nx_http_server_type_get(server_ptr, name, http_type_string);
5492 }
5493 
5494 
5495 /**************************************************************************/
5496 /*                                                                        */
5497 /*  FUNCTION                                               RELEASE        */
5498 /*                                                                        */
5499 /*    _nx_http_server_type_get                            PORTABLE C      */
5500 /*                                                           6.1          */
5501 /*  AUTHOR                                                                */
5502 /*                                                                        */
5503 /*    Yuxin Zhou, Microsoft Corporation                                   */
5504 /*                                                                        */
5505 /*  DESCRIPTION                                                           */
5506 /*                                                                        */
5507 /*    This function derives the type of the resource.                     */
5508 /*                                                                        */
5509 /*  INPUT                                                                 */
5510 /*                                                                        */
5511 /*    server_ptr                            HTTP Server pointer           */
5512 /*    name                                  Name string                   */
5513 /*    http_type_string                      Destination HTTP type string  */
5514 /*                                                                        */
5515 /*  OUTPUT                                                                */
5516 /*                                                                        */
5517 /*    Size                                  Number of bytes in string     */
5518 /*                                                                        */
5519 /*  CALLS                                                                 */
5520 /*                                                                        */
5521 /*    _nx_http_server_type_get_extended                                   */
5522 /*    _nx_utility_string_length_check                                     */
5523 /*                                                                        */
5524 /*  CALLED BY                                                             */
5525 /*                                                                        */
5526 /*    _nx_http_server_get_process           Process GET request           */
5527 /*    Application Code                                                    */
5528 /*                                                                        */
5529 /*  RELEASE HISTORY                                                       */
5530 /*                                                                        */
5531 /*    DATE              NAME                      DESCRIPTION             */
5532 /*                                                                        */
5533 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5534 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5535 /*                                            resulting in version 6.1    */
5536 /*                                                                        */
5537 /**************************************************************************/
_nx_http_server_type_get(NX_HTTP_SERVER * server_ptr,CHAR * name,CHAR * http_type_string)5538 UINT  _nx_http_server_type_get(NX_HTTP_SERVER *server_ptr, CHAR *name, CHAR *http_type_string)
5539 {
5540 UINT name_length = 0;
5541 
5542     if (_nx_utility_string_length_check(name, &name_length, NX_MAX_STRING_LENGTH))
5543     {
5544         return(0);
5545     }
5546 
5547     return _nx_http_server_type_get_extended(server_ptr, name, name_length, http_type_string, NX_MAX_STRING_LENGTH + 1);
5548 }
5549 
5550 
5551 /**************************************************************************/
5552 /*                                                                        */
5553 /*  FUNCTION                                               RELEASE        */
5554 /*                                                                        */
5555 /*    _nxe_http_server_type_get_extended                  PORTABLE C      */
5556 /*                                                           6.1          */
5557 /*  AUTHOR                                                                */
5558 /*                                                                        */
5559 /*    Yuxin Zhou, Microsoft Corporation                                   */
5560 /*                                                                        */
5561 /*  DESCRIPTION                                                           */
5562 /*                                                                        */
5563 /*    This function checks error for deriving the type of the resource.   */
5564 /*                                                                        */
5565 /*  INPUT                                                                 */
5566 /*                                                                        */
5567 /*    server_ptr                            HTTP Server pointer           */
5568 /*    name                                  Name string                   */
5569 /*    name_length                           Length of name string         */
5570 /*    http_type_string                      Destination HTTP type string  */
5571 /*    http_type_string_max_size             Size of the destination string*/
5572 /*                                                                        */
5573 /*  OUTPUT                                                                */
5574 /*                                                                        */
5575 /*    Size                                  Number of bytes in string, or */
5576 /*                                           0 if http_type_string is too */
5577 /*                                           small for the resource string*/
5578 /*                                                                        */
5579 /*  CALLS                                                                 */
5580 /*                                                                        */
5581 /*    _nx_http_server_type_get_extended                                   */
5582 /*                                                                        */
5583 /*  CALLED BY                                                             */
5584 /*                                                                        */
5585 /*    Application Code                                                    */
5586 /*                                                                        */
5587 /*  RELEASE HISTORY                                                       */
5588 /*                                                                        */
5589 /*    DATE              NAME                      DESCRIPTION             */
5590 /*                                                                        */
5591 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5592 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5593 /*                                            resulting in version 6.1    */
5594 /*                                                                        */
5595 /**************************************************************************/
_nxe_http_server_type_get_extended(NX_HTTP_SERVER * server_ptr,CHAR * name,UINT name_length,CHAR * http_type_string,UINT http_type_string_max_size)5596 UINT  _nxe_http_server_type_get_extended(NX_HTTP_SERVER *server_ptr, CHAR *name, UINT name_length, CHAR *http_type_string, UINT http_type_string_max_size)
5597 {
5598 
5599     /* Check for invalid input pointers.  */
5600     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) || (name == NX_NULL) || (http_type_string == NX_NULL))
5601         return(0);
5602 
5603     /* Check for appropriate caller.  */
5604     NX_THREADS_ONLY_CALLER_CHECKING
5605 
5606     return _nx_http_server_type_get_extended(server_ptr, name, name_length, http_type_string, http_type_string_max_size);
5607 }
5608 
5609 
5610 /**************************************************************************/
5611 /*                                                                        */
5612 /*  FUNCTION                                               RELEASE        */
5613 /*                                                                        */
5614 /*    _nx_http_server_type_get_extended                   PORTABLE C      */
5615 /*                                                           6.1          */
5616 /*  AUTHOR                                                                */
5617 /*                                                                        */
5618 /*    Yuxin Zhou, Microsoft Corporation                                   */
5619 /*                                                                        */
5620 /*  DESCRIPTION                                                           */
5621 /*                                                                        */
5622 /*    This function derives the type of the resource.                     */
5623 /*                                                                        */
5624 /*    Note: The string of name must be NULL-terminated and length of each */
5625 /*    string matches the length specified in the argument list.           */
5626 /*                                                                        */
5627 /*  INPUT                                                                 */
5628 /*                                                                        */
5629 /*    server_ptr                            HTTP Server pointer           */
5630 /*    name                                  Name string                   */
5631 /*    name_length                           Length of name string         */
5632 /*    http_type_string                      Destination HTTP type string  */
5633 /*    http_type_string_max_size             Size of the destination string*/
5634 /*                                                                        */
5635 /*  OUTPUT                                                                */
5636 /*                                                                        */
5637 /*    Size                                  Number of bytes in string, or */
5638 /*                                           0 if http_type_string is too */
5639 /*                                           small for the resource       */
5640 /*                                           string, or name exceeds      */
5641 /*                                           NX_HTTP_MAX_RESOURCE         */
5642 /*                                                                        */
5643 /*  CALLS                                                                 */
5644 /*                                                                        */
5645 /*    _nx_http_server_memicmp                                             */
5646 /*    _nx_utility_string_length_check                                     */
5647 /*                                                                        */
5648 /*  CALLED BY                                                             */
5649 /*                                                                        */
5650 /*    _nx_http_server_get_process           Process GET request           */
5651 /*    Application Code                                                    */
5652 /*                                                                        */
5653 /*  RELEASE HISTORY                                                       */
5654 /*                                                                        */
5655 /*    DATE              NAME                      DESCRIPTION             */
5656 /*                                                                        */
5657 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5658 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
5659 /*                                            verified memcpy use cases,  */
5660 /*                                            resulting in version 6.1    */
5661 /*                                                                        */
5662 /**************************************************************************/
_nx_http_server_type_get_extended(NX_HTTP_SERVER * server_ptr,CHAR * name,UINT name_length,CHAR * http_type_string,UINT http_type_string_max_size)5663 UINT  _nx_http_server_type_get_extended(NX_HTTP_SERVER *server_ptr, CHAR *name, UINT name_length, CHAR *http_type_string, UINT http_type_string_max_size)
5664 {
5665 
5666 UINT    i;
5667 CHAR   *ch;
5668 UINT    ext_length;
5669 UINT    map_ext_length;
5670 UINT    map_type_length;
5671 UINT    temp_name_length;
5672 
5673     /* Check name length.  */
5674     if (_nx_utility_string_length_check(name, &temp_name_length, name_length))
5675     {
5676         return(NX_HTTP_ERROR);
5677     }
5678 
5679     /* Validate string length. */
5680     if (name_length != temp_name_length)
5681     {
5682         return(NX_HTTP_ERROR);
5683     }
5684 
5685     /* First find the end of the string.  */
5686     ch = name + name_length;
5687 
5688     /* Now look backwards to find the last period that signals the
5689        file extension.  */
5690     ext_length = 0;
5691     while ((ch >= name) && (*ch != '.') &&(*ch != '/'))
5692     {
5693         ch--;
5694         ext_length++;
5695     }
5696 
5697     if(*ch != '.')
5698     {
5699 
5700         /* No extension is found. Return the default mime type. */
5701         if(http_type_string_max_size < (sizeof(NX_HTTP_SERVER_DEFAULT_MIME)))
5702         {
5703             /* NX_HTTP_SERVER_DEFAULT_MIME does not fit into
5704                the caller-supplied http_type_string. */
5705             return (0);
5706         }
5707 
5708         /* return the default MIME type. */
5709         memcpy(http_type_string, NX_HTTP_SERVER_DEFAULT_MIME, sizeof(NX_HTTP_SERVER_DEFAULT_MIME)); /* Use case of memcpy is verified. */
5710         return(sizeof(NX_HTTP_SERVER_DEFAULT_MIME) - 1);
5711     }
5712 
5713     /* Position forward again, past the period.  */
5714     ch++;
5715     ext_length--;
5716 
5717     /* Now see what HTTP file type to return.  */
5718     /* Search user defined MIME maps first. */
5719     if(server_ptr -> nx_http_server_mime_maps_additional &&
5720        (server_ptr -> nx_http_server_mime_maps_additional_num > 0))
5721     {
5722         for(i = 0; i < server_ptr -> nx_http_server_mime_maps_additional_num; i++)
5723         {
5724             /* Check map extension and type length.  */
5725             if (_nx_utility_string_length_check(server_ptr -> nx_http_server_mime_maps_additional[i].nx_http_server_mime_map_extension,
5726                                                 &map_ext_length, ext_length) ||
5727                 _nx_utility_string_length_check(server_ptr -> nx_http_server_mime_maps_additional[i].nx_http_server_mime_map_type,
5728                                                 &map_type_length, http_type_string_max_size - 1))
5729             {
5730                 continue;
5731             }
5732 
5733             if(_nx_http_server_memicmp((UCHAR *)ch, ext_length,
5734                                        (UCHAR *)server_ptr -> nx_http_server_mime_maps_additional[i].nx_http_server_mime_map_extension,
5735                                        map_ext_length) == NX_SUCCESS)
5736             {
5737 
5738                 /* Find the extension. Return the mapped MIME type. */
5739                 memcpy(http_type_string, server_ptr -> nx_http_server_mime_maps_additional[i].nx_http_server_mime_map_type, map_type_length + 1); /* Use case of memcpy is verified. */
5740                 return(map_type_length);
5741             }
5742         }
5743     }
5744 
5745     /* Search default MIME maps. */
5746     for(i = 0; i < sizeof(_nx_http_server_mime_maps) / sizeof(NX_HTTP_SERVER_MIME_MAP); i++)
5747     {
5748 
5749         /* Check map extension and type length.  */
5750         if (_nx_utility_string_length_check(_nx_http_server_mime_maps[i].nx_http_server_mime_map_extension,
5751                                             &map_ext_length, ext_length) ||
5752             _nx_utility_string_length_check(_nx_http_server_mime_maps[i].nx_http_server_mime_map_type,
5753                                             &map_type_length, http_type_string_max_size - 1))
5754         {
5755             continue;
5756         }
5757 
5758         if(_nx_http_server_memicmp((UCHAR *)ch, ext_length,
5759                                    (UCHAR *)_nx_http_server_mime_maps[i].nx_http_server_mime_map_extension,
5760                                    map_ext_length) == NX_SUCCESS)
5761         {
5762 
5763             /* Find the extension. Return the mapped MIME type. */
5764             memcpy(http_type_string, _nx_http_server_mime_maps[i].nx_http_server_mime_map_type, map_type_length + 1); /* Use case of memcpy is verified. */
5765             return(map_type_length);
5766         }
5767     }
5768 
5769     /* No extension matches. Return the default mime type. */
5770     if(http_type_string_max_size < (sizeof(NX_HTTP_SERVER_DEFAULT_MIME)))
5771     {
5772         /* NX_HTTP_SERVER_DEFAULT_MIME does not fit into
5773            the caller-supplied http_type_string. */
5774         return (0);
5775     }
5776 
5777     /* return the default MIME type. */
5778     memcpy(http_type_string, NX_HTTP_SERVER_DEFAULT_MIME, sizeof(NX_HTTP_SERVER_DEFAULT_MIME)); /* Use case of memcpy is verified. */
5779     return(sizeof(NX_HTTP_SERVER_DEFAULT_MIME) - 1);
5780 }
5781 
5782 #ifdef NX_HTTP_DIGEST_ENABLE
5783 /**************************************************************************/
5784 /*                                                                        */
5785 /*  FUNCTION                                               RELEASE        */
5786 /*                                                                        */
5787 /*    _nx_http_server_nonce_allocate                      PORTABLE C      */
5788 /*                                                           6.2.0        */
5789 /*  AUTHOR                                                                */
5790 /*                                                                        */
5791 /*    Yuxin Zhou, Microsoft Corporation                                   */
5792 /*                                                                        */
5793 /*  DESCRIPTION                                                           */
5794 /*                                                                        */
5795 /*    This function allocate a new nonce for digest authentication.       */
5796 /*                                                                        */
5797 /*  INPUT                                                                 */
5798 /*                                                                        */
5799 /*    server_ptr                            HTTP Server pointer           */
5800 /*    nonce_ptr                             Allocated nonce pointer       */
5801 /*                                                                        */
5802 /*  OUTPUT                                                                */
5803 /*                                                                        */
5804 /*    None                                                                */
5805 /*                                                                        */
5806 /*  CALLS                                                                 */
5807 /*                                                                        */
5808 /*    tx_time_get                           Get system time               */
5809 /*                                                                        */
5810 /*  CALLED BY                                                             */
5811 /*                                                                        */
5812 /*    _nx_http_server_digest_authenticate   Digest authentication         */
5813 /*                                                                        */
5814 /*  RELEASE HISTORY                                                       */
5815 /*                                                                        */
5816 /*    DATE              NAME                      DESCRIPTION             */
5817 /*                                                                        */
5818 /*  10-31-2022     Yuxin Zhou               Initial Version 6.2.0         */
5819 /*                                                                        */
5820 /**************************************************************************/
_nx_http_server_nonce_allocate(NX_HTTP_SERVER * server_ptr,NX_HTTP_SERVER_NONCE ** nonce_ptr)5821 UINT _nx_http_server_nonce_allocate(NX_HTTP_SERVER *server_ptr, NX_HTTP_SERVER_NONCE **nonce_ptr)
5822 {
5823 UINT i;
5824 UCHAR random_value;
5825 NX_HTTP_SERVER_NONCE *nonces_list = server_ptr -> nx_http_server_nonces;
5826 
5827 
5828     /* Search if there is free entry for new nonce.  */
5829     for (i = 0; i < NX_HTTP_SERVER_NONCE_MAX; i++)
5830     {
5831         if (nonces_list[i].nonce_state == NX_HTTP_SERVER_NONCE_INVALID)
5832         {
5833             *nonce_ptr = &(nonces_list[i]);
5834             break;
5835         }
5836     }
5837 
5838     if (i == NX_HTTP_SERVER_NONCE_MAX)
5839     {
5840 
5841         /* If no free entry, check the timeout of allocated nonces.  */
5842         for (i = 0; i < NX_HTTP_SERVER_NONCE_MAX; i++)
5843         {
5844             if (nonces_list[i].nonce_state == NX_HTTP_SERVER_NONCE_VALID)
5845             {
5846                 if (tx_time_get() > nonces_list[i].nonce_timestamp + NX_HTTP_SERVER_NONCE_TIMEOUT)
5847                 {
5848 
5849                     /* If this nonce is timed out, free up this entry for new nonce.  */
5850                     *nonce_ptr = &(nonces_list[i]);
5851                     break;
5852                 }
5853             }
5854         }
5855 
5856         /* If no entry can be allocated, return error.  */
5857         if (i == NX_HTTP_SERVER_NONCE_MAX)
5858         {
5859             return(NX_NOT_FOUND);
5860         }
5861     }
5862 
5863     /* Generate new nonce for digest authentication. */
5864     for (i = 0; i < NX_HTTP_SERVER_NONCE_SIZE; i++)
5865     {
5866         random_value = (UCHAR)NX_RAND() % (sizeof(_nx_http_server_base64_array) - 1);
5867         (*nonce_ptr) -> nonce_buffer[i] = (UCHAR)_nx_http_server_base64_array[random_value];
5868     }
5869 
5870     /* Reset the timestamp and state for the new nonce.  */
5871     (*nonce_ptr) -> nonce_timestamp = tx_time_get();
5872     (*nonce_ptr) -> nonce_state = NX_HTTP_SERVER_NONCE_VALID;
5873 
5874     return(NX_SUCCESS);
5875 }
5876 
5877 /**************************************************************************/
5878 /*                                                                        */
5879 /*  FUNCTION                                               RELEASE        */
5880 /*                                                                        */
5881 /*    _nx_http_server_digest_authenticate                 PORTABLE C      */
5882 /*                                                           6.2.0        */
5883 /*  AUTHOR                                                                */
5884 /*                                                                        */
5885 /*    Yuxin Zhou, Microsoft Corporation                                   */
5886 /*                                                                        */
5887 /*  DESCRIPTION                                                           */
5888 /*                                                                        */
5889 /*    This function checks for digest (MD5 only) authentication.          */
5890 /*    If the digest is correct, it returns a success.  Otherwise, it      */
5891 /*    returns an authentication request to the requesting client.         */
5892 /*                                                                        */
5893 /*                                                                        */
5894 /*  INPUT                                                                 */
5895 /*                                                                        */
5896 /*    server_ptr                            HTTP Server pointer           */
5897 /*    packet_ptr                            Request packet pointer        */
5898 /*    name_ptr                              Pointer to name string        */
5899 /*    name_length                           Length of name string         */
5900 /*    password_ptr                          Pointer to password string    */
5901 /*    password_length                       Length of password string     */
5902 /*    realm_ptr                             Pointer to realm string       */
5903 /*    realm_length                          Length of realm string        */
5904 /*    auth_request_present                  Indicate if authentication    */
5905 /*                                                  must be performed     */
5906 /*                                                                        */
5907 /*  OUTPUT                                                                */
5908 /*                                                                        */
5909 /*    status                                Completion status             */
5910 /*                                                                        */
5911 /*  CALLS                                                                 */
5912 /*                                                                        */
5913 /*   _nx_http_server_retrieve_digest_authorization Pickup authorization   */
5914 /*   _nx_http_server_digest_response_calculate Calculate the digest       */
5915 /*    nx_packet_allocate                    Allocate a new packet         */
5916 /*    nx_packet_data_append                 Append information to response*/
5917 /*    nx_packet_release                     Release packet                */
5918 /*    nx_tcp_socket_send                    Send HTTP Server response     */
5919 /*                                                                        */
5920 /*  CALLED BY                                                             */
5921 /*                                                                        */
5922 /*    _nx_http_server_get_process           Process GET request           */
5923 /*    _nx_http_server_put_process           Process PUT request           */
5924 /*    _nx_http_server_delete_process        Process DELETE request        */
5925 /*                                                                        */
5926 /*  RELEASE HISTORY                                                       */
5927 /*                                                                        */
5928 /*    DATE              NAME                      DESCRIPTION             */
5929 /*                                                                        */
5930 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5931 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5932 /*                                            resulting in version 6.1    */
5933 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
5934 /*                                            supported random nonce,     */
5935 /*                                            resulting in version 6.2.0  */
5936 /*                                                                        */
5937 /**************************************************************************/
_nx_http_server_digest_authenticate(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,CHAR * name_ptr,UINT name_length,CHAR * password_ptr,UINT password_length,CHAR * realm_ptr,UINT realm_length,UINT * auth_request_present)5938 UINT  _nx_http_server_digest_authenticate(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, CHAR *name_ptr, UINT name_length, CHAR *password_ptr, UINT password_length, CHAR *realm_ptr, UINT realm_length, UINT *auth_request_present)
5939 {
5940 
5941 CHAR        authorization_response[NX_HTTP_MAX_ASCII_MD5 + 1];
5942 CHAR        calculated_response[NX_HTTP_MAX_ASCII_MD5 + 1];
5943 CHAR        authorization_uri[NX_HTTP_MAX_RESOURCE + 1];
5944 CHAR        method[8];
5945 CHAR        quote[2] = {0x22, 0};
5946 CHAR        *buffer_ptr;
5947 UINT        i;
5948 UINT        status, status1, callback_status;
5949 CHAR        crlf[2] = {13,10};
5950 CHAR        authorization_nc[NX_HTTP_MAX_RESOURCE + 1];
5951 CHAR        authorization_cnonce[NX_HTTP_MAX_RESOURCE + 1];
5952 NX_HTTP_SERVER_NONCE *nonce_ptr = NX_NULL;
5953 
5954 
5955     /* Default to no authentication request detected. */
5956     *auth_request_present =  NX_FALSE;
5957 
5958     /* Default the status to authenticate.  */
5959     status =  NX_HTTP_DIGEST_AUTHENTICATE;
5960 
5961     /* Is the authorization request present?  */
5962     if (_nx_http_server_retrieve_digest_authorization(server_ptr, packet_ptr, authorization_response, authorization_uri, authorization_nc, authorization_cnonce, &nonce_ptr))
5963     {
5964 
5965         /* Yes, an authorization request is present.  */
5966         *auth_request_present =  NX_TRUE;
5967 
5968         /* Pickup method from the packet.  */
5969         buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
5970         i = 0;
5971         while (((buffer_ptr + i) < (CHAR *)packet_ptr -> nx_packet_append_ptr) && (buffer_ptr[i] != ' ') && (i < (sizeof(method) - 1)))
5972         {
5973 
5974             /* Copy bytes of method. */
5975             method[i] =  buffer_ptr[i];
5976             i++;
5977         }
5978 
5979         /* Null terminate method.  */
5980         method[i] =  (CHAR) NX_NULL;
5981 
5982         /* If the digest authenticate callback function is set, invoke the callback function. */
5983         if(server_ptr -> nx_http_server_digest_authenticate_callback)
5984         {
5985             callback_status = (server_ptr -> nx_http_server_digest_authenticate_callback)(server_ptr, name_ptr, realm_ptr, password_ptr, method, authorization_uri, authorization_nc, authorization_cnonce);
5986         }
5987         else
5988         {
5989 
5990             /* If the digest authenticate callback is not set, assume it is success, for backward
5991                compatibility reasons. */
5992             callback_status = NX_SUCCESS;
5993         }
5994 
5995 
5996         /* Calculate what the MD5 should be.  */
5997         _nx_http_server_digest_response_calculate(server_ptr, name_ptr, name_length, realm_ptr, realm_length, password_ptr, password_length, (CHAR *)(nonce_ptr -> nonce_buffer), method, authorization_uri, authorization_nc, authorization_cnonce, calculated_response);
5998 
5999         /* Determine if the calculated response is the same as the received response.  */
6000         i =  0;
6001         status = NX_SUCCESS;
6002         while (i < NX_HTTP_MAX_ASCII_MD5 + 1)
6003         {
6004             /* Is there a mismatch?  */
6005             if (calculated_response[i] != authorization_response[i])
6006             {
6007 
6008                 /* Authorization mismatch. Continue to avoid timing attack. */
6009                 status = NX_HTTP_DIGEST_AUTHENTICATE;
6010             }
6011 
6012             /* Otherwise, look at next character.  */
6013             i++;
6014         }
6015 
6016         /* If the response is authenticated, mark the nonce as accepted.  */
6017         if (status == NX_SUCCESS)
6018         {
6019             nonce_ptr -> nonce_state = NX_HTTP_SERVER_NONCE_ACCEPTED;
6020         }
6021         else
6022         {
6023             nonce_ptr -> nonce_state = NX_HTTP_SERVER_NONCE_INVALID;
6024         }
6025 
6026         /* If digest authenticate callback function returns non-success value, the request is
6027            considered unauthenticated. */
6028         if(callback_status != NX_SUCCESS)
6029             status = NX_HTTP_DIGEST_AUTHENTICATE;
6030     }
6031 
6032     /* Determine if we need to send back an unauthorized request.  */
6033     if (status == NX_HTTP_DIGEST_AUTHENTICATE)
6034     {
6035 
6036         /* Allocate a new nonce for digest authentication.  */
6037         status1 = _nx_http_server_nonce_allocate(server_ptr, &nonce_ptr);
6038 
6039         /* Determine if an error occurred in the packet allocation.  */
6040         if (status1)
6041         {
6042 
6043             /* Send response back to HTTP Client.  */
6044             _nx_http_server_response_send(server_ptr, NX_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_HTTP_STATUS_INTERNAL_ERROR) - 1,
6045                                           "NetX HTTP Server Internal Error", sizeof("NetX HTTP Server Internal Error") - 1, NX_NULL, 0);
6046 
6047             /* Indicate an allocation error occurred.  */
6048             server_ptr -> nx_http_server_allocation_errors++;
6049 
6050             /* Return the internal NetX error.  */
6051             return(status1);
6052         }
6053 
6054         /* We need authorization so build the HTTP 401 Unauthorized message to send to the server.  */
6055 
6056         /* Allocate a packet for sending the response back.  */
6057         status1 =  nx_packet_allocate(server_ptr -> nx_http_server_packet_pool_ptr, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER);
6058 
6059         /* Determine if an error occurred in the packet allocation.  */
6060         if (status1 != NX_SUCCESS)
6061         {
6062 
6063             /* Indicate an allocation error occurred.  */
6064             server_ptr -> nx_http_server_allocation_errors++;
6065 
6066             /* Return the internal NetX error.  */
6067             return(status1);
6068         }
6069 
6070         /* Insert the response header.  */
6071         nx_packet_data_append(packet_ptr, NX_HTTP_VERSION, sizeof(NX_HTTP_VERSION) - 1,
6072                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6073         nx_packet_data_append(packet_ptr, " ", 1, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6074         nx_packet_data_append(packet_ptr, NX_HTTP_STATUS_UNAUTHORIZED, sizeof(NX_HTTP_STATUS_UNAUTHORIZED) - 1,
6075                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6076 
6077         /* Place the <cr,lf> into the buffer.  */
6078         nx_packet_data_append(packet_ptr, crlf, 2,
6079                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6080 
6081         /* Insert the type of authentication requested.  */
6082         nx_packet_data_append(packet_ptr, "WWW-Authenticate: Digest realm=", 31,
6083                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6084 
6085         /* Insert the double quote.  */
6086         nx_packet_data_append(packet_ptr, quote, 1,
6087                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6088 
6089         /* Place the realm string into the buffer.  */
6090         nx_packet_data_append(packet_ptr, realm_ptr, realm_length,
6091                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6092 
6093         /* Insert the double quote.  */
6094         nx_packet_data_append(packet_ptr, quote, 1,
6095                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6096 
6097         /* Place a comma into the buffer.  */
6098         nx_packet_data_append(packet_ptr, ",", 1,
6099                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6100 
6101         /* Insert the algorithm into the buffer.  */
6102         nx_packet_data_append(packet_ptr, " algorithm=", 11,
6103                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6104 
6105         /* Insert the double quote.  */
6106         nx_packet_data_append(packet_ptr, quote, 1,
6107                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6108 
6109         /* Insert the md5 tag into the buffer.  */
6110         nx_packet_data_append(packet_ptr, "md5", 3,
6111                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6112 
6113         /* Insert the double quote.  */
6114         nx_packet_data_append(packet_ptr, quote, 1,
6115                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6116 
6117         /* Place a comma into the buffer.  */
6118         nx_packet_data_append(packet_ptr, ",", 1,
6119                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6120 
6121         /* Insert the nonce into the buffer.  */
6122         nx_packet_data_append(packet_ptr, " nonce=", 7,
6123                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6124 
6125         /* Insert the double quote.  */
6126         nx_packet_data_append(packet_ptr, quote, 1,
6127                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6128 
6129         /* Place the nonce string into the buffer.  */
6130         nx_packet_data_append(packet_ptr, nonce_ptr -> nonce_buffer, NX_HTTP_SERVER_NONCE_SIZE,
6131                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6132 
6133         /* Insert the double quote.  */
6134         nx_packet_data_append(packet_ptr, quote, 1,
6135                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6136 
6137         /* Place the qop="auth" parameter string into the buffer.  */
6138         nx_packet_data_append(packet_ptr, ", qop=\"auth\"", 12,
6139                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6140 
6141         /* Place the <cr,lf> into the buffer.  */
6142         nx_packet_data_append(packet_ptr, crlf, 2,
6143                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6144 
6145         /* Set Content-Length as 0.  */
6146         nx_packet_data_append(packet_ptr, "Content-Length: 0", 17,
6147                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6148 
6149         /* Place the <cr,lf> into the buffer.  */
6150         nx_packet_data_append(packet_ptr, crlf, 2,
6151                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6152 
6153         /* Place another <cr,lf> into the buffer to signal end of FULL HTTP response.  */
6154         nx_packet_data_append(packet_ptr, crlf, 2,
6155                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6156 
6157         /* Send the response back to the client.  */
6158         status1 =  nx_tcp_socket_send(&(server_ptr -> nx_http_server_socket), packet_ptr, NX_HTTP_SERVER_TIMEOUT_SEND);
6159 
6160         /* Check for an error.  */
6161         if (status1)
6162         {
6163 
6164             /* Set the internal NetX error as the status return. */
6165             status = status1;
6166 
6167             /* Just release the packet.  */
6168             nx_packet_release(packet_ptr);
6169         }
6170     }
6171 
6172     /* Return the result of the authentication request.  */
6173     return(status);
6174 }
6175 
6176 
6177 /**************************************************************************/
6178 /*                                                                        */
6179 /*  FUNCTION                                               RELEASE        */
6180 /*                                                                        */
6181 /*    _nx_http_server_digest_response_calculate           PORTABLE C      */
6182 /*                                                           6.2.0        */
6183 /*  AUTHOR                                                                */
6184 /*                                                                        */
6185 /*    Yuxin Zhou, Microsoft Corporation                                   */
6186 /*                                                                        */
6187 /*  DESCRIPTION                                                           */
6188 /*                                                                        */
6189 /*    This function computes the MD5 digest based on the supplied input   */
6190 /*    parameters.                                                         */
6191 /*                                                                        */
6192 /*  INPUT                                                                 */
6193 /*                                                                        */
6194 /*    server_ptr                            HTTP Server pointer           */
6195 /*    username                              Username string               */
6196 /*    realm                                 Realm string                  */
6197 /*    password                              Password string               */
6198 /*    nonce                                 Authentication nonce string   */
6199 /*    method                                Request method string         */
6200 /*    uri                                   Resource request string       */
6201 /*    nc                                    Nonce count string            */
6202 /*    cnonce                                Client nonce string           */
6203 /*    result                                Computed digest string        */
6204 /*                                                                        */
6205 /*  OUTPUT                                                                */
6206 /*                                                                        */
6207 /*    None                                                                */
6208 /*                                                                        */
6209 /*  CALLS                                                                 */
6210 /*                                                                        */
6211 /*   _nx_http_server_hex_ascii_convert      Convert hex to ASCII          */
6212 /*   _nx_md5_initialize                     Initialize MD5 algorithm      */
6213 /*   _nx_md5_update                         Update MD5 digest             */
6214 /*   _nx_md5_digest_calculate               Complete the MD5 algorithm    */
6215 /*    _nx_utility_string_length_check       Check string length           */
6216 /*                                                                        */
6217 /*  CALLED BY                                                             */
6218 /*                                                                        */
6219 /*    _nx_http_server_digest_authenticate   Digest authentication         */
6220 /*                                                                        */
6221 /*  RELEASE HISTORY                                                       */
6222 /*                                                                        */
6223 /*    DATE              NAME                      DESCRIPTION             */
6224 /*                                                                        */
6225 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6226 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6227 /*                                            resulting in version 6.1    */
6228 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
6229 /*                                            supported random nonce,     */
6230 /*                                            resulting in version 6.2.0  */
6231 /*                                                                        */
6232 /**************************************************************************/
_nx_http_server_digest_response_calculate(NX_HTTP_SERVER * server_ptr,CHAR * username,UINT username_length,CHAR * realm,UINT realm_length,CHAR * password,UINT password_length,CHAR * nonce,CHAR * method,CHAR * uri,CHAR * nc,CHAR * cnonce,CHAR * result)6233 VOID  _nx_http_server_digest_response_calculate(NX_HTTP_SERVER *server_ptr, CHAR *username, UINT username_length, CHAR *realm, UINT realm_length, CHAR *password, UINT password_length, CHAR *nonce, CHAR *method, CHAR *uri, CHAR *nc, CHAR *cnonce, CHAR *result)
6234 {
6235 
6236 CHAR    md5_binary[NX_HTTP_MAX_BINARY_MD5];
6237 CHAR    ha1_string[NX_HTTP_MAX_ASCII_MD5 + 1];
6238 CHAR    ha2_string[NX_HTTP_MAX_ASCII_MD5 + 1];
6239 UINT    method_length;
6240 UINT    uri_length;
6241 UINT    nc_length;
6242 UINT    cnonce_length;
6243 
6244     /* Check string length.  */
6245     if (_nx_utility_string_length_check(method, &method_length, 7) ||
6246         _nx_utility_string_length_check(uri, &uri_length, NX_HTTP_MAX_RESOURCE) ||
6247         _nx_utility_string_length_check(nc, &nc_length, NX_HTTP_MAX_RESOURCE) ||
6248         _nx_utility_string_length_check(cnonce, &cnonce_length, NX_HTTP_MAX_RESOURCE))
6249     {
6250         return;
6251     }
6252 
6253 
6254     /* Calculate the H(A1) portion of the digest.  */
6255     _nx_md5_initialize(&(server_ptr -> nx_http_server_md5data));
6256     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) username, username_length);
6257     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) ":", 1);
6258     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) realm, realm_length);
6259     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) ":", 1);
6260     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) password, password_length);
6261     _nx_md5_digest_calculate(&(server_ptr -> nx_http_server_md5data), (unsigned char *) md5_binary);
6262 
6263     /* Convert this H(A1) portion to ASCII Hex representation.  */
6264     _nx_http_server_hex_ascii_convert(md5_binary, NX_HTTP_MAX_BINARY_MD5, ha1_string);
6265 
6266     /* Make the H(A2) portion of the digest.  */
6267     _nx_md5_initialize(&(server_ptr -> nx_http_server_md5data));
6268     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) method, method_length);
6269     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) ":", 1);
6270     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) uri, uri_length);
6271     _nx_md5_digest_calculate(&(server_ptr -> nx_http_server_md5data), (unsigned char *) md5_binary);
6272 
6273     /* Convert this H(A2) portion to ASCII Hex representation.  */
6274     _nx_http_server_hex_ascii_convert(md5_binary, NX_HTTP_MAX_BINARY_MD5, ha2_string);
6275 
6276     /* Now make the final MD5 digest.  */
6277     _nx_md5_initialize(&(server_ptr -> nx_http_server_md5data));
6278     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) ha1_string, sizeof(ha1_string) - 1);
6279     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) ":", 1);
6280     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) nonce, NX_HTTP_SERVER_NONCE_SIZE);
6281 
6282     /* Start of Internet Explorer bug work-around.  */
6283     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) ":", 1);
6284     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) nc, nc_length);
6285     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) ":", 1);
6286     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) cnonce, cnonce_length);
6287     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) ":auth", 5);
6288     /* End of Internet Explorer bug work-around.  */
6289 
6290     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) ":", 1);
6291     _nx_md5_update(&(server_ptr -> nx_http_server_md5data), (unsigned char *) ha2_string, sizeof(ha2_string) - 1);
6292     _nx_md5_digest_calculate(&(server_ptr -> nx_http_server_md5data), (unsigned char *) md5_binary);
6293 
6294     /* Finally, convert the response back to an ASCII string and place in
6295        the destination.  */
6296     _nx_http_server_hex_ascii_convert(md5_binary, NX_HTTP_MAX_BINARY_MD5, result);
6297 }
6298 
6299 
6300 /**************************************************************************/
6301 /*                                                                        */
6302 /*  FUNCTION                                               RELEASE        */
6303 /*                                                                        */
6304 /*    _nx_http_server_retrieve_digest_authorization       PORTABLE C      */
6305 /*                                                           6.2.0        */
6306 /*  AUTHOR                                                                */
6307 /*                                                                        */
6308 /*    Yuxin Zhou, Microsoft Corporation                                   */
6309 /*                                                                        */
6310 /*  DESCRIPTION                                                           */
6311 /*                                                                        */
6312 /*    This function retrieves the MD5 digest parameters from the          */
6313 /*    supplied request packet.                                            */
6314 /*                                                                        */
6315 /*  INPUT                                                                 */
6316 /*                                                                        */
6317 /*    server_ptr                            HTTP Server pointer           */
6318 /*    packet_ptr                            Request packet pointer        */
6319 /*    response                              Digest response pointer       */
6320 /*    uri                                   URI from response pointer     */
6321 /*    nc                                    Nonce count string            */
6322 /*    cnonce                                Client nonce string           */
6323 /*    nonce_ptr                             Server nonce pointer          */
6324 /*                                                                        */
6325 /*  OUTPUT                                                                */
6326 /*                                                                        */
6327 /*    length                                Length of response (should be */
6328 /*                                            32). A value of 0 indicates */
6329 /*                                            an error is present         */
6330 /*                                                                        */
6331 /*  CALLS                                                                 */
6332 /*                                                                        */
6333 /*    None                                                                */
6334 /*                                                                        */
6335 /*  CALLED BY                                                             */
6336 /*                                                                        */
6337 /*    _nx_http_server_digest_authenticate   Digest authentication         */
6338 /*                                                                        */
6339 /*  RELEASE HISTORY                                                       */
6340 /*                                                                        */
6341 /*    DATE              NAME                      DESCRIPTION             */
6342 /*                                                                        */
6343 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6344 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6345 /*                                            resulting in version 6.1    */
6346 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
6347 /*                                            supported random nonce,     */
6348 /*                                            resulting in version 6.2.0  */
6349 /*                                                                        */
6350 /**************************************************************************/
_nx_http_server_retrieve_digest_authorization(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,CHAR * response,CHAR * uri,CHAR * nc,CHAR * cnonce,NX_HTTP_SERVER_NONCE ** nonce_ptr)6351 UINT  _nx_http_server_retrieve_digest_authorization(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, CHAR *response, CHAR *uri, CHAR *nc, CHAR *cnonce, NX_HTTP_SERVER_NONCE **nonce_ptr)
6352 {
6353 
6354 UINT    length;
6355 UINT    found;
6356 CHAR    *buffer_ptr;
6357 CHAR    *saved_buffer_ptr;
6358 UCHAR   *nonce_buffer;
6359 UINT    i;
6360 
6361 
6362     /* Set the found flag to false.  */
6363     found =  NX_FALSE;
6364 
6365     /* Default the authorization request to zero.  */
6366     length =  0;
6367 
6368     /* Set the response and uri strings to NULL.  */
6369     response[0] =  NX_NULL;
6370     uri[0] =       NX_NULL;
6371 
6372     /* Internet Explorer bug work-around.  */
6373     nc[0] =        NX_NULL;
6374     cnonce[0] =    NX_NULL;
6375 
6376     /* Setup pointer to buffer.  */
6377     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
6378 
6379     /* Find the "Authorization: " token first.  */
6380     while (((buffer_ptr+15) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
6381     {
6382 
6383         /* Check for the Authorization: token.  */
6384         if (((*buffer_ptr ==      'a') || (*buffer_ptr ==      'A')) &&
6385             ((*(buffer_ptr+1) ==  'u') || (*(buffer_ptr+1) ==  'U')) &&
6386             ((*(buffer_ptr+2) ==  't') || (*(buffer_ptr+2) ==  'T')) &&
6387             ((*(buffer_ptr+3) ==  'h') || (*(buffer_ptr+3) ==  'H')) &&
6388             ((*(buffer_ptr+4) ==  'o') || (*(buffer_ptr+4) ==  'O')) &&
6389             ((*(buffer_ptr+5) ==  'r') || (*(buffer_ptr+5) ==  'R')) &&
6390             ((*(buffer_ptr+6) ==  'i') || (*(buffer_ptr+6) ==  'I')) &&
6391             ((*(buffer_ptr+7) ==  'z') || (*(buffer_ptr+7) ==  'Z')) &&
6392             ((*(buffer_ptr+8) ==  'a') || (*(buffer_ptr+8) ==  'A')) &&
6393             ((*(buffer_ptr+9) ==  't') || (*(buffer_ptr+9) ==  'T')) &&
6394             ((*(buffer_ptr+10) == 'i') || (*(buffer_ptr+10) == 'I')) &&
6395             ((*(buffer_ptr+11) == 'o') || (*(buffer_ptr+11) == 'O')) &&
6396             ((*(buffer_ptr+12) == 'n') || (*(buffer_ptr+12) == 'N')) &&
6397             (*(buffer_ptr+13) == ':') &&
6398             (*(buffer_ptr+14) == ' '))
6399         {
6400 
6401             /* Move the pointer up to the length token.  */
6402             buffer_ptr =  buffer_ptr + 15;
6403 
6404             /* Set the found flag.  */
6405             found =  NX_TRUE;
6406             break;
6407         }
6408 
6409         /* Move the pointer up to the next character.  */
6410         buffer_ptr++;
6411     }
6412 
6413     /* Determine if the first token was found.  */
6414     if (!found)
6415     {
6416 
6417         /* No, authorization is not present.  Return a zero length.  */
6418         return(length);
6419     }
6420 
6421     /* Set the found flag back to false.  */
6422     found =  NX_FALSE;
6423 
6424     /* Now remove any extra blanks.  */
6425     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
6426     {
6427 
6428         /* Move the pointer up one character.  */
6429         buffer_ptr++;
6430     }
6431 
6432     /* Now check for the "Digest " token.  */
6433     while (((buffer_ptr+7) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
6434     {
6435 
6436         /* Check for the Digest token.  */
6437         if (((*buffer_ptr ==      'd') || (*buffer_ptr ==      'D')) &&
6438             ((*(buffer_ptr+1) ==  'i') || (*(buffer_ptr+1) ==  'I')) &&
6439             ((*(buffer_ptr+2) ==  'g') || (*(buffer_ptr+2) ==  'G')) &&
6440             ((*(buffer_ptr+3) ==  'e') || (*(buffer_ptr+3) ==  'E')) &&
6441             ((*(buffer_ptr+4) ==  's') || (*(buffer_ptr+4) ==  'S')) &&
6442             ((*(buffer_ptr+5) ==  't') || (*(buffer_ptr+5) ==  'T')) &&
6443             (*(buffer_ptr+6) == ' '))
6444         {
6445 
6446             /* Move the pointer up to the actual authorization string.  */
6447             buffer_ptr =  buffer_ptr + 7;
6448 
6449             /* Set the found flag.  */
6450             found =  NX_TRUE;
6451             break;
6452         }
6453 
6454         /* Move the pointer up to the next character.  */
6455         buffer_ptr++;
6456     }
6457 
6458     /* Determine if the second token was found.  */
6459     if (!found)
6460     {
6461 
6462         /* No, digest is not present.  Return a zero length.  */
6463         return(length);
6464     }
6465 
6466     /* Now remove any extra blanks.  */
6467     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
6468     {
6469 
6470         /* Move the pointer up one character.  */
6471         buffer_ptr++;
6472     }
6473 
6474     /* Start of Internet Explorer bug work-around (Parses nc and cnonce parameters).  */
6475 
6476     /* Save current buffer pointer, so each parameter search always starts from here.  */
6477     saved_buffer_ptr =  buffer_ptr;
6478 
6479     while (((buffer_ptr + 6) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
6480     {
6481 
6482         /* Check for the uri token.  */
6483         if (((*(buffer_ptr) ==  'n') || (*(buffer_ptr) ==  'N')) &&
6484             ((*(buffer_ptr+1) ==  'o') || (*(buffer_ptr+1) ==  'O')) &&
6485             ((*(buffer_ptr+2) ==  'n') || (*(buffer_ptr+2) ==  'N')) &&
6486             ((*(buffer_ptr+3) ==  'c') || (*(buffer_ptr+3) ==  'C')) &&
6487             ((*(buffer_ptr+4) ==  'e') || (*(buffer_ptr+4) ==  'E')) &&
6488             (*(buffer_ptr+5) == '='))
6489         {
6490 
6491             /* Move the pointer up to the actual nonce string.  */
6492             buffer_ptr =  buffer_ptr + 6;
6493             found = NX_TRUE;
6494 
6495             break;
6496         }
6497 
6498         /* Move the pointer up to the next character.  */
6499         buffer_ptr++;
6500     }
6501 
6502     /* Check if nonce is found.  */
6503     if (!found)
6504     {
6505         return(0);
6506     }
6507 
6508     /* Now remove any extra blanks and quotes.  */
6509     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
6510     {
6511 
6512         /* Move the pointer up one character.  */
6513         buffer_ptr++;
6514     }
6515 
6516     /* Now pickup the nonce string.  */
6517     length =  0;
6518     nonce_buffer = (UCHAR *)buffer_ptr;
6519     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13))
6520     {
6521 
6522         /* Determine if the ending quote is present.  */
6523         if (*buffer_ptr == (CHAR) 0x22)
6524         {
6525             break;
6526         }
6527 
6528         /* Increase the length.  */
6529         length++;
6530         buffer_ptr++;
6531     }
6532 
6533     /* Check the nonce size.  */
6534     if (length != NX_HTTP_SERVER_NONCE_SIZE)
6535     {
6536         return(0);
6537     }
6538 
6539     /* Check if the nonce is valid.  */
6540     for (i = 0; i < NX_HTTP_SERVER_NONCE_MAX; i++)
6541     {
6542         if ((server_ptr -> nx_http_server_nonces[i].nonce_state != NX_HTTP_SERVER_NONCE_INVALID) &&
6543             (memcmp(server_ptr -> nx_http_server_nonces[i].nonce_buffer, nonce_buffer, NX_HTTP_SERVER_NONCE_SIZE) == 0)) /* Use case of memcmp is verified. */
6544         {
6545             *nonce_ptr = &(server_ptr -> nx_http_server_nonces[i]);
6546             break;
6547         }
6548     }
6549 
6550     /* If the nonca is invalid, just return.  */
6551     if (i == NX_HTTP_SERVER_NONCE_MAX)
6552     {
6553         return(0);
6554     }
6555 
6556     /* Get saved buffer pointer.  */
6557     buffer_ptr =  saved_buffer_ptr;
6558 
6559     /* Now look for the nc in the digest response.  */
6560     while (((buffer_ptr+3) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
6561     {
6562 
6563         /* Check for the nc token.  */
6564         if (((*buffer_ptr ==      'n') || (*buffer_ptr ==      'N')) &&
6565             ((*(buffer_ptr+1) ==  'c') || (*(buffer_ptr+1) ==  'C')) &&
6566             (*(buffer_ptr+2) == '='))
6567         {
6568 
6569             /* Move the pointer up to the actual authorization string.  */
6570             buffer_ptr =  buffer_ptr + 3;
6571 
6572             break;
6573         }
6574 
6575         /* Move the pointer up to the next character.  */
6576         buffer_ptr++;
6577     }
6578 
6579     /* Now remove any extra blanks and quotes (should be no starting quote).  */
6580     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
6581     {
6582 
6583         /* Move the pointer up one character.  */
6584         buffer_ptr++;
6585     }
6586 
6587     /* Now pickup the nc string (should be 8 hex characters; should not be quoted).  */
6588     length =  0;
6589     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13) && (length < NX_HTTP_MAX_RESOURCE))
6590     {
6591 
6592         /* Determine if the ending quote or comma is present (should be no ending quote).  */
6593         if ((*buffer_ptr == (CHAR) 0x22) || (*buffer_ptr == ','))
6594         {
6595 
6596             break;
6597         }
6598 
6599         /* Copy a character of the authorization string into the destination.  */
6600         nc[length++] =  *buffer_ptr++;
6601     }
6602 
6603     /* Null terminate the NC.  */
6604     nc[length] =  (CHAR) NX_NULL;
6605 
6606 
6607     /* Get saved buffer pointer.  */
6608     buffer_ptr =  saved_buffer_ptr;
6609 
6610     /* Now look for the cnonce in the digest response.  */
6611     while (((buffer_ptr+7) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
6612     {
6613 
6614         /* Check for the uri token.  */
6615         if (((*buffer_ptr ==      'c') || (*buffer_ptr ==      'C')) &&
6616             ((*(buffer_ptr+1) ==  'n') || (*(buffer_ptr+1) ==  'N')) &&
6617             ((*(buffer_ptr+2) ==  'o') || (*(buffer_ptr+2) ==  'O')) &&
6618             ((*(buffer_ptr+3) ==  'n') || (*(buffer_ptr+3) ==  'N')) &&
6619             ((*(buffer_ptr+4) ==  'c') || (*(buffer_ptr+4) ==  'C')) &&
6620             ((*(buffer_ptr+5) ==  'e') || (*(buffer_ptr+5) ==  'E')) &&
6621             (*(buffer_ptr+6) == '='))
6622         {
6623 
6624             /* Move the pointer up to the actual authorization string.  */
6625             buffer_ptr =  buffer_ptr + 7;
6626 
6627             break;
6628         }
6629 
6630         /* Move the pointer up to the next character.  */
6631         buffer_ptr++;
6632     }
6633 
6634     /* Now remove any extra blanks and quotes.  */
6635     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
6636     {
6637 
6638         /* Move the pointer up one character.  */
6639         buffer_ptr++;
6640     }
6641 
6642     /* Now pickup the cnonce string.  */
6643     length =  0;
6644     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13) && (length < NX_HTTP_MAX_RESOURCE))
6645     {
6646 
6647         /* Determine if the ending quote is present.  */
6648         if (*buffer_ptr == (CHAR) 0x22)
6649         {
6650 
6651             break;
6652         }
6653 
6654         /* Copy a character of the authorization string into the destination.  */
6655         cnonce[length++] =  *buffer_ptr++;
6656     }
6657 
6658     /* Null terminate the CNONCE.  */
6659     cnonce[length] =  (CHAR) NX_NULL;
6660 
6661     /* End of Internet Explorer bug work-around.  */
6662 
6663     /* Get saved buffer pointer.  */
6664     buffer_ptr =  saved_buffer_ptr;
6665 
6666     /* Now look for the uri in the digest response.  */
6667     while (((buffer_ptr+4) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
6668     {
6669 
6670         /* Check for the uri token.  */
6671         if (((*buffer_ptr ==      'u') || (*buffer_ptr ==      'U')) &&
6672             ((*(buffer_ptr+1) ==  'r') || (*(buffer_ptr+1) ==  'R')) &&
6673             ((*(buffer_ptr+2) ==  'i') || (*(buffer_ptr+2) ==  'I')) &&
6674             (*(buffer_ptr+3) == '='))
6675         {
6676 
6677             /* Move the pointer up to the actual authorization string.  */
6678             buffer_ptr =  buffer_ptr + 4;
6679 
6680             break;
6681         }
6682 
6683         /* Move the pointer up to the next character.  */
6684         buffer_ptr++;
6685     }
6686 
6687     /* Now remove any extra blanks and quotes.  */
6688     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
6689     {
6690 
6691         /* Move the pointer up one character.  */
6692         buffer_ptr++;
6693     }
6694 
6695     /* Now pickup the uri string.  */
6696     length =  0;
6697     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13) && (length < NX_HTTP_MAX_RESOURCE))
6698     {
6699 
6700         /* Determine if the ending quote is present.  */
6701         if (*buffer_ptr == (CHAR) 0x22)
6702         {
6703 
6704             break;
6705         }
6706 
6707         /* Copy a character of the authorization string into the destination.  */
6708         uri[length++] =  *buffer_ptr++;
6709     }
6710 
6711     /* Null terminate the URI.  */
6712     uri[length] =  (CHAR) NX_NULL;
6713 
6714     /* Get saved buffer pointer.  */
6715     buffer_ptr =  saved_buffer_ptr;
6716 
6717     /* Now look for the digest response.  */
6718     while (((buffer_ptr+9) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
6719     {
6720 
6721         /* Check for the uri token.  */
6722         if (((*buffer_ptr ==      'r') || (*buffer_ptr ==      'R')) &&
6723             ((*(buffer_ptr+1) ==  'e') || (*(buffer_ptr+1) ==  'E')) &&
6724             ((*(buffer_ptr+2) ==  's') || (*(buffer_ptr+2) ==  'S')) &&
6725             ((*(buffer_ptr+3) ==  'p') || (*(buffer_ptr+3) ==  'P')) &&
6726             ((*(buffer_ptr+4) ==  'o') || (*(buffer_ptr+4) ==  'O')) &&
6727             ((*(buffer_ptr+5) ==  'n') || (*(buffer_ptr+5) ==  'N')) &&
6728             ((*(buffer_ptr+6) ==  's') || (*(buffer_ptr+6) ==  'S')) &&
6729             ((*(buffer_ptr+7) ==  'e') || (*(buffer_ptr+7) ==  'E')) &&
6730             (*(buffer_ptr+8) == '='))
6731         {
6732 
6733             /* Move the pointer up to the actual authorization string.  */
6734             buffer_ptr =  buffer_ptr + 9;
6735 
6736             break;
6737         }
6738 
6739         /* Move the pointer up to the next character.  */
6740         buffer_ptr++;
6741     }
6742 
6743     /* Now remove any extra blanks and leading quote.  */
6744     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
6745     {
6746 
6747         /* Move the pointer up one character.  */
6748         buffer_ptr++;
6749     }
6750 
6751     /* Finally, pickup the response.  */
6752     length =  0;
6753     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13) && (*buffer_ptr != (CHAR) 0x3A) && (length < NX_HTTP_MAX_ASCII_MD5))
6754     {
6755 
6756         /* Determine if the ending quote is present.  */
6757         if (*buffer_ptr == (CHAR) 0x22)
6758         {
6759 
6760             break;
6761         }
6762 
6763         /* Copy a character of the response string into the destination.  */
6764         response[length++] =  *buffer_ptr++;
6765     }
6766 
6767     /* Null terminate response.  */
6768     response[length] =  (CHAR) NX_NULL;
6769 
6770     /* Check for an error.  */
6771     if ((length != 32) || (buffer_ptr >= (CHAR *) packet_ptr -> nx_packet_append_ptr) || (*buffer_ptr != (CHAR) 0x22))
6772     {
6773 
6774         /* Error, clear the length and the response string.  */
6775         length =  0;
6776         response[0] =  (CHAR) NX_NULL;
6777     }
6778 
6779     /* Return the length to the caller.  */
6780     return(length);
6781 }
6782 
6783 
6784 /**************************************************************************/
6785 /*                                                                        */
6786 /*  FUNCTION                                               RELEASE        */
6787 /*                                                                        */
6788 /*    _nx_http_server_hex_ascii_convert                   PORTABLE C      */
6789 /*                                                           6.1          */
6790 /*  AUTHOR                                                                */
6791 /*                                                                        */
6792 /*    Yuxin Zhou, Microsoft Corporation                                   */
6793 /*                                                                        */
6794 /*  DESCRIPTION                                                           */
6795 /*                                                                        */
6796 /*    This function converts hexadecimal characters into an ASCII string. */
6797 /*                                                                        */
6798 /*  INPUT                                                                 */
6799 /*                                                                        */
6800 /*    source                                Source hex string             */
6801 /*    source_length                         Length of source string       */
6802 /*    destination                           Pointer to destination string */
6803 /*                                                                        */
6804 /*  OUTPUT                                                                */
6805 /*                                                                        */
6806 /*    None                                                                */
6807 /*                                                                        */
6808 /*  CALLS                                                                 */
6809 /*                                                                        */
6810 /*    None                                                                */
6811 /*                                                                        */
6812 /*  CALLED BY                                                             */
6813 /*                                                                        */
6814 /*    _nx_http_server_digest_response_calculate Digest authentication     */
6815 /*                                                                        */
6816 /*  RELEASE HISTORY                                                       */
6817 /*                                                                        */
6818 /*    DATE              NAME                      DESCRIPTION             */
6819 /*                                                                        */
6820 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6821 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6822 /*                                            resulting in version 6.1    */
6823 /*                                                                        */
6824 /**************************************************************************/
_nx_http_server_hex_ascii_convert(CHAR * source,UINT source_length,CHAR * destination)6825 VOID  _nx_http_server_hex_ascii_convert(CHAR *source, UINT source_length, CHAR *destination)
6826 {
6827 
6828 UINT    i,j;
6829 CHAR    digit;
6830 
6831 
6832     /* Setup destination index.  */
6833     j =  0;
6834 
6835     /* Loop to process the entire source string.  */
6836     for (i = 0; i < source_length; i++)
6837     {
6838 
6839         /* Pickup the first nibble.  */
6840         digit =  (source[i] >> 4) & 0xF;
6841 
6842         /* Convert to ASCII and store.  */
6843         if (digit <= 9)
6844             destination[j++] =  (CHAR)(digit + '0');
6845         else
6846             destination[j++] =  (CHAR)(digit + 'a' - 10);
6847 
6848         /* Pickup the second nibble.  */
6849         digit =  source[i] & 0xF;
6850 
6851         /* Convert to ASCII and store.  */
6852         if (digit <= 9)
6853             destination[j++] =  (CHAR)(digit + '0');
6854         else
6855             destination[j++] =  (CHAR)(digit + 'a' - 10);
6856     }
6857 
6858     /* Finally, place a NULL in the destination string.  */
6859     destination[j] =  (CHAR) NX_NULL;
6860 }
6861 #endif
6862 
6863 
6864 /**************************************************************************/
6865 /*                                                                        */
6866 /*  FUNCTION                                               RELEASE        */
6867 /*                                                                        */
6868 /*    _nxe_http_server_get_entity_header                  PORTABLE C      */
6869 /*                                                           6.1          */
6870 /*  AUTHOR                                                                */
6871 /*                                                                        */
6872 /*    Yuxin Zhou, Microsoft Corporation                                   */
6873 /*                                                                        */
6874 /*  DESCRIPTION                                                           */
6875 /*                                                                        */
6876 /*    This function checks error for getting the entity header.           */
6877 /*                                                                        */
6878 /*  INPUT                                                                 */
6879 /*                                                                        */
6880 /*    server_ptr                            Pointer to HTTP server        */
6881 /*    packet_pptr                           Pointer to packet             */
6882 /*    entity_header_buffer                  Buffer to get entity header   */
6883 /*    buffer_size                           Size of buffer                */
6884 /*                                                                        */
6885 /*  OUTPUT                                                                */
6886 /*                                                                        */
6887 /*    status                                Completion status             */
6888 /*                                                                        */
6889 /*  CALLS                                                                 */
6890 /*                                                                        */
6891 /*    _nx_http_server_get_entity_header                                   */
6892 /*                                                                        */
6893 /*  CALLED BY                                                             */
6894 /*                                                                        */
6895 /*    Application Code                                                    */
6896 /*                                                                        */
6897 /*  RELEASE HISTORY                                                       */
6898 /*                                                                        */
6899 /*    DATE              NAME                      DESCRIPTION             */
6900 /*                                                                        */
6901 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6902 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6903 /*                                            resulting in version 6.1    */
6904 /*                                                                        */
6905 /**************************************************************************/
_nxe_http_server_get_entity_header(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,UCHAR * entity_header_buffer,ULONG buffer_size)6906 UINT  _nxe_http_server_get_entity_header(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, UCHAR *entity_header_buffer, ULONG buffer_size)
6907 {
6908 
6909 #ifdef  NX_HTTP_MULTIPART_ENABLE
6910     /* Check for invalid input pointers.  */
6911     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) ||
6912         (packet_pptr == NX_NULL))
6913         return NX_PTR_ERROR;
6914 
6915     /* Check for appropriate caller.  */
6916     NX_THREADS_ONLY_CALLER_CHECKING
6917 
6918     return _nx_http_server_get_entity_header(server_ptr, packet_pptr, entity_header_buffer, buffer_size);
6919 #else
6920     NX_PARAMETER_NOT_USED(server_ptr);
6921     NX_PARAMETER_NOT_USED(packet_pptr);
6922     NX_PARAMETER_NOT_USED(entity_header_buffer);
6923     NX_PARAMETER_NOT_USED(buffer_size);
6924 
6925     return NX_HTTP_ERROR;
6926 #endif /* NX_HTTP_MULTIPART_ENABLE */
6927 }
6928 
6929 
6930 /**************************************************************************/
6931 /*                                                                        */
6932 /*  FUNCTION                                               RELEASE        */
6933 /*                                                                        */
6934 /*    _nx_http_server_get_entity_header                   PORTABLE C      */
6935 /*                                                           6.1.11       */
6936 /*  AUTHOR                                                                */
6937 /*                                                                        */
6938 /*    Yuxin Zhou, Microsoft Corporation                                   */
6939 /*                                                                        */
6940 /*  DESCRIPTION                                                           */
6941 /*                                                                        */
6942 /*    This function gets the entity header and skip header.               */
6943 /*                                                                        */
6944 /*  INPUT                                                                 */
6945 /*                                                                        */
6946 /*    server_ptr                            Pointer to HTTP server        */
6947 /*    packet_pptr                           Pointer to packet             */
6948 /*    entity_header_buffer                  Buffer to get entity header   */
6949 /*    buffer_size                           Size of buffer                */
6950 /*                                                                        */
6951 /*  OUTPUT                                                                */
6952 /*                                                                        */
6953 /*    status                                Completion status             */
6954 /*                                                                        */
6955 /*  CALLS                                                                 */
6956 /*                                                                        */
6957 /*    _nx_http_server_field_value_get                                     */
6958 /*    _nx_http_server_memicmp                                             */
6959 /*    _nx_http_server_boundary_find                                       */
6960 /*    nx_packet_release                                                   */
6961 /*    nx_tcp_socket_receive                                               */
6962 /*    _nx_utility_string_length_check                                     */
6963 /*    memmove                                                             */
6964 /*                                                                        */
6965 /*  CALLED BY                                                             */
6966 /*                                                                        */
6967 /*    Application Code                                                    */
6968 /*                                                                        */
6969 /*  RELEASE HISTORY                                                       */
6970 /*                                                                        */
6971 /*    DATE              NAME                      DESCRIPTION             */
6972 /*                                                                        */
6973 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6974 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
6975 /*                                            fixed write underflow,      */
6976 /*                                            resulting in version 6.1    */
6977 /*  04-25-2022     Yuxin Zhou               Modified comment(s), and      */
6978 /*                                            verified memmove use cases, */
6979 /*                                            resulting in version 6.1.11 */
6980 /*                                                                        */
6981 /**************************************************************************/
_nx_http_server_get_entity_header(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,UCHAR * entity_header_buffer,ULONG buffer_size)6982 UINT  _nx_http_server_get_entity_header(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, UCHAR *entity_header_buffer, ULONG buffer_size)
6983 {
6984 
6985 #ifdef  NX_HTTP_MULTIPART_ENABLE
6986 NX_HTTP_SERVER_MULTIPART   *multipart_ptr;
6987 UINT                        status;
6988 UINT                        offset;
6989 NX_PACKET                  *available_packet;
6990 UINT                        crlf_match_count = 0;
6991 UINT                        end_boundary_count = 2;
6992 UINT                        skip_count = 2;
6993 UCHAR                      *ch;
6994 UINT                        index;
6995 
6996     /* Get multipart context. */
6997     multipart_ptr = &server_ptr -> nx_http_server_multipart;
6998 
6999     /* Is the multipart context initialized? */
7000     if(multipart_ptr -> nx_http_server_multipart_boundary[0] == 0)
7001     {
7002     ULONG   field_length;
7003     UINT    quotation_index;
7004     UINT    i;
7005 
7006         /* No, it is not initialized. */
7007 
7008         /* Get content type. */
7009         status = _nx_http_server_field_value_get(*packet_pptr, (UCHAR *)"content-type", 12,
7010                                                  multipart_ptr -> nx_http_server_multipart_boundary, NX_HTTP_MAX_HEADER_FIELD + 1);
7011         if(status)
7012             return status;
7013 
7014         /* Is the content type "multipart"? */
7015         /* Check the length. The length of "multipart/" is 10. */
7016         if (_nx_utility_string_length_check((CHAR *)multipart_ptr -> nx_http_server_multipart_boundary, (UINT *)&field_length, NX_HTTP_MAX_HEADER_FIELD))
7017             return NX_HTTP_ERROR;
7018         if(field_length < 10)
7019             return NX_HTTP_NOT_FOUND;
7020 
7021         /* Check the data. */
7022         if(_nx_http_server_memicmp(multipart_ptr -> nx_http_server_multipart_boundary, 10,
7023                                    (UCHAR *)"multipart/", 10) != NX_SUCCESS)
7024             return NX_HTTP_NOT_FOUND;
7025 
7026         /* Find the boundary. The length of "boundary=" is 9. */
7027         index = 0;
7028         while((index + 9) < field_length)
7029         {
7030             if(_nx_http_server_memicmp(&multipart_ptr -> nx_http_server_multipart_boundary[index], 9,
7031                                        (UCHAR *)"boundary=", 9) == NX_SUCCESS)
7032             {
7033 
7034                 break;
7035             }
7036 
7037             /* Move the pointer up to the next character.  */
7038             index++;
7039         }
7040 
7041         /* Move the pointer up to the boundary value. */
7042         index += 9;
7043 
7044         /* Is boundary string found? */
7045         if((field_length - index) <= 1)
7046         {
7047 
7048             /* Boundary not found or no boundary value. */
7049             return NX_HTTP_NOT_FOUND;
7050         }
7051 
7052         /* Boundary is started with "CRLF--". */
7053         multipart_ptr -> nx_http_server_multipart_boundary[0] = 13;
7054         multipart_ptr -> nx_http_server_multipart_boundary[1] = 10;
7055         multipart_ptr -> nx_http_server_multipart_boundary[2] = '-';
7056         multipart_ptr -> nx_http_server_multipart_boundary[3] = '-';
7057 
7058         /* Remove quotation. */
7059         if(multipart_ptr -> nx_http_server_multipart_boundary[index] == '"')
7060         {
7061 
7062             /* Find the right quotation. */
7063             index++;
7064             for(quotation_index = field_length; quotation_index > index; quotation_index--)
7065             {
7066                 if(multipart_ptr -> nx_http_server_multipart_boundary[quotation_index] == '"')
7067                     break;
7068             }
7069 
7070             /* Is the right quotation found? */
7071             if(quotation_index > index)
7072                 multipart_ptr -> nx_http_server_multipart_boundary[quotation_index] = 0;
7073             else
7074             {
7075 
7076                 /* Boundary not valid. */
7077                 return NX_HTTP_NOT_FOUND;
7078             }
7079 
7080             /* Leave boundary string only. */
7081             memmove(&multipart_ptr -> nx_http_server_multipart_boundary[4],
7082                     &multipart_ptr -> nx_http_server_multipart_boundary[index],
7083                     quotation_index - index + 1); /* Use case of memmove is verified.  */
7084         }
7085         else
7086         {
7087 
7088             /* Directly copy boundary string to the head field. */
7089             i = 4;
7090             index -= 4;
7091             do
7092             {
7093                 multipart_ptr -> nx_http_server_multipart_boundary[i] = multipart_ptr -> nx_http_server_multipart_boundary[index + i];
7094                 i++;
7095             }while((multipart_ptr -> nx_http_server_multipart_boundary[i - 1] != 0) &&
7096                    (multipart_ptr -> nx_http_server_multipart_boundary[i - 1] != ' '));
7097 
7098             /* Set the terminal character. */
7099             multipart_ptr -> nx_http_server_multipart_boundary[i - 1] = 0;
7100         }
7101     }
7102 
7103     /* Find the boundary. */
7104     while(multipart_ptr -> nx_http_server_multipart_boundary_find == NX_FALSE)
7105     {
7106         if(_nx_http_server_boundary_find(server_ptr, packet_pptr) != NX_SUCCESS)
7107             break;
7108     }
7109 
7110     /* Whether the boundary is found? */
7111     if(multipart_ptr -> nx_http_server_multipart_boundary_find == NX_FALSE)
7112         return NX_HTTP_NOT_FOUND;
7113 
7114     /* Update the packet and offset. */
7115     _nx_http_server_boundary_find(server_ptr, packet_pptr);
7116 
7117     /* Get offset of available data in the packet.  */
7118     offset = multipart_ptr -> nx_http_server_multipart_available_offset;
7119 
7120     /* Skip data that are not header. */
7121     available_packet = *packet_pptr;
7122 
7123     if(offset >= available_packet -> nx_packet_length)
7124     {
7125 
7126         /* Release the packet that has been processed. */
7127         nx_packet_release(*packet_pptr);
7128 
7129         /* All data has been processed. Get a new packet. */
7130         if(nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), &available_packet, NX_HTTP_SERVER_TIMEOUT_RECEIVE) != NX_SUCCESS)
7131         {
7132 
7133             /* Error, return to caller.  */
7134             return(NX_HTTP_TIMEOUT);
7135         }
7136 
7137         /* FIXME: Check if the "offset" should be updated.  */
7138 
7139         /* Store the packet. */
7140         *packet_pptr = available_packet;
7141         server_ptr -> nx_http_server_multipart.nx_http_server_multipart_last_packet = available_packet;
7142     }
7143 #ifndef NX_DISABLE_PACKET_CHAIN
7144     else
7145     {
7146         while((UINT)(available_packet -> nx_packet_append_ptr - available_packet -> nx_packet_prepend_ptr) <= offset)
7147         {
7148             offset -= (UINT)(available_packet -> nx_packet_append_ptr - available_packet -> nx_packet_prepend_ptr);
7149 
7150             /* Get next packet. */
7151             available_packet = available_packet -> nx_packet_next;
7152         }
7153     }
7154 #endif /* NX_DISABLE_PACKET_CHAIN */
7155 
7156     /* Get entity header. */
7157     ch = available_packet -> nx_packet_prepend_ptr + offset;
7158     index = 0;
7159     while((entity_header_buffer == NX_NULL) || (index < buffer_size))
7160     {
7161 
7162         /* Calculate valid CRLF. */
7163         if((*ch == 13) && ((crlf_match_count & 1) == 0))
7164             crlf_match_count++;
7165         else if((*ch == 10) && ((crlf_match_count & 1) == 1))
7166             crlf_match_count++;
7167         else if(*ch == '-')
7168         {
7169 
7170             /* Check whether the last boundary is found. */
7171             if(end_boundary_count < 3)
7172                 end_boundary_count--;
7173 
7174             if(end_boundary_count == 0)
7175                 break;
7176         }
7177         else
7178         {
7179             end_boundary_count = 0xFF;
7180             crlf_match_count = 0;
7181         }
7182 
7183         /* Copy data to buffer. */
7184         if(skip_count >0)
7185             skip_count--;
7186         else
7187         {
7188             if(entity_header_buffer)
7189                 entity_header_buffer[index] = *ch;
7190             index++;
7191         }
7192         multipart_ptr -> nx_http_server_multipart_available_offset++;
7193 
7194         /* Check whether two CRLFs are found. */
7195         if(crlf_match_count == 4)
7196             break;
7197 
7198         /* Get next character. */
7199         if((ch + 1) >= available_packet -> nx_packet_append_ptr)
7200         {
7201 
7202             /* ch points to the end of this packet. */
7203 #ifndef NX_DISABLE_PACKET_CHAIN
7204             if(available_packet -> nx_packet_next)
7205             {
7206 
7207                 /* Copy data from next packet. */
7208                 available_packet = available_packet -> nx_packet_next;
7209             }
7210             else
7211 #endif /* NX_DISABLE_PACKET_CHAIN */
7212             {
7213 
7214                 /* Release the packet that has been processed. */
7215                 nx_packet_release(*packet_pptr);
7216 
7217                 /* Get a new packet and copy data from it. */
7218                 status =  nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), &available_packet, NX_HTTP_SERVER_TIMEOUT_RECEIVE);
7219 
7220                 /* Check the return status.  */
7221                 if (status != NX_SUCCESS)
7222                 {
7223 
7224                     /* Error, return to caller.  */
7225                     return(NX_HTTP_TIMEOUT);
7226                 }
7227 
7228                 /* Store the packet. */
7229                 *packet_pptr = available_packet;
7230                 server_ptr -> nx_http_server_multipart.nx_http_server_multipart_last_packet = available_packet;
7231 
7232                 /* Reset the offset. */
7233                 multipart_ptr -> nx_http_server_multipart_available_offset = 0;
7234             }
7235 
7236             ch = available_packet -> nx_packet_prepend_ptr;
7237         }
7238         else
7239             ch++;
7240 
7241     }
7242 
7243     /* Check whether two CRLFs are found. */
7244     if(crlf_match_count == 4)
7245     {
7246 
7247         /* Set terminal 0. */
7248         if(entity_header_buffer)
7249         {
7250             if (index >= 4)
7251             {
7252                 entity_header_buffer[index - 4] = 0;
7253             }
7254             else
7255             {
7256                 entity_header_buffer[0] = 0;
7257             }
7258         }
7259         return NX_SUCCESS;
7260     }
7261     else
7262         return NX_HTTP_NOT_FOUND;
7263 #else
7264     NX_PARAMETER_NOT_USED(server_ptr);
7265     NX_PARAMETER_NOT_USED(packet_pptr);
7266     NX_PARAMETER_NOT_USED(entity_header_buffer);
7267     NX_PARAMETER_NOT_USED(buffer_size);
7268 
7269     return NX_HTTP_ERROR;
7270 #endif /* NX_HTTP_MULTIPART_ENABLE */
7271 }
7272 
7273 
7274 /**************************************************************************/
7275 /*                                                                        */
7276 /*  FUNCTION                                               RELEASE        */
7277 /*                                                                        */
7278 /*    _nxe_http_server_get_entity_content                 PORTABLE C      */
7279 /*                                                           6.1          */
7280 /*  AUTHOR                                                                */
7281 /*                                                                        */
7282 /*    Yuxin Zhou, Microsoft Corporation                                   */
7283 /*                                                                        */
7284 /*  DESCRIPTION                                                           */
7285 /*                                                                        */
7286 /*    This function checks error for getting the entity content.          */
7287 /*                                                                        */
7288 /*  INPUT                                                                 */
7289 /*                                                                        */
7290 /*    server_ptr                            Pointer to HTTP server        */
7291 /*    packet_pptr                           Pointer to packet             */
7292 /*    available_offset                      Return the offset             */
7293 /*    available_length                      Return the length             */
7294 /*                                                                        */
7295 /*  OUTPUT                                                                */
7296 /*                                                                        */
7297 /*    status                                Completion status             */
7298 /*                                                                        */
7299 /*  CALLS                                                                 */
7300 /*                                                                        */
7301 /*    _nx_http_server_get_entity_content                                  */
7302 /*                                                                        */
7303 /*  CALLED BY                                                             */
7304 /*                                                                        */
7305 /*    Application Code                                                    */
7306 /*                                                                        */
7307 /*  RELEASE HISTORY                                                       */
7308 /*                                                                        */
7309 /*    DATE              NAME                      DESCRIPTION             */
7310 /*                                                                        */
7311 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7312 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7313 /*                                            resulting in version 6.1    */
7314 /*                                                                        */
7315 /**************************************************************************/
_nxe_http_server_get_entity_content(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,ULONG * available_offset,ULONG * available_length)7316 UINT  _nxe_http_server_get_entity_content(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, ULONG *available_offset, ULONG *available_length)
7317 {
7318 
7319 #ifdef  NX_HTTP_MULTIPART_ENABLE
7320     /* Check for invalid input pointers.  */
7321     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) ||
7322         (packet_pptr == NX_NULL) || (available_offset == NX_NULL) || (available_length == NX_NULL))
7323         return(NX_PTR_ERROR);
7324 
7325     /* Check whether boundary is found. */
7326     if(server_ptr -> nx_http_server_multipart.nx_http_server_multipart_boundary[0] == 0)
7327         return(NX_HTTP_ERROR);
7328 
7329     return _nx_http_server_get_entity_content(server_ptr, packet_pptr, available_offset, available_length);
7330 #else
7331     NX_PARAMETER_NOT_USED(server_ptr);
7332     NX_PARAMETER_NOT_USED(packet_pptr);
7333     NX_PARAMETER_NOT_USED(available_offset);
7334     NX_PARAMETER_NOT_USED(available_length);
7335 
7336     return NX_HTTP_ERROR;
7337 #endif /* NX_HTTP_MULTIPART_ENABLE */
7338 }
7339 
7340 
7341 /**************************************************************************/
7342 /*                                                                        */
7343 /*  FUNCTION                                               RELEASE        */
7344 /*                                                                        */
7345 /*    _nx_http_server_get_entity_content                  PORTABLE C      */
7346 /*                                                           6.1          */
7347 /*  AUTHOR                                                                */
7348 /*                                                                        */
7349 /*    Yuxin Zhou, Microsoft Corporation                                   */
7350 /*                                                                        */
7351 /*  DESCRIPTION                                                           */
7352 /*                                                                        */
7353 /*    This function gets the entity content.                              */
7354 /*                                                                        */
7355 /*  INPUT                                                                 */
7356 /*                                                                        */
7357 /*    server_ptr                            Pointer to HTTP server        */
7358 /*    packet_pptr                           Pointer to packet             */
7359 /*    available_offset                      Return the offset             */
7360 /*    available_length                      Return the length             */
7361 /*                                                                        */
7362 /*  OUTPUT                                                                */
7363 /*                                                                        */
7364 /*    status                                Completion status             */
7365 /*                                                                        */
7366 /*  CALLS                                                                 */
7367 /*                                                                        */
7368 /*    _nx_http_server_boundary_find                                       */
7369 /*                                                                        */
7370 /*  CALLED BY                                                             */
7371 /*                                                                        */
7372 /*    Application Code                                                    */
7373 /*                                                                        */
7374 /*  RELEASE HISTORY                                                       */
7375 /*                                                                        */
7376 /*    DATE              NAME                      DESCRIPTION             */
7377 /*                                                                        */
7378 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7379 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7380 /*                                            resulting in version 6.1    */
7381 /*                                                                        */
7382 /**************************************************************************/
_nx_http_server_get_entity_content(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,ULONG * available_offset,ULONG * available_length)7383 UINT  _nx_http_server_get_entity_content(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, ULONG *available_offset, ULONG *available_length)
7384 {
7385 
7386 #ifdef  NX_HTTP_MULTIPART_ENABLE
7387 UINT    status;
7388 
7389     /* Whether the boundary is found? */
7390     if(server_ptr -> nx_http_server_multipart.nx_http_server_multipart_boundary_find == NX_TRUE)
7391         return NX_HTTP_BOUNDARY_ALREADY_FOUND;
7392 
7393     status = _nx_http_server_boundary_find(server_ptr, packet_pptr);
7394     if(status)
7395         return status;
7396 
7397     /* Set the offset and length. */
7398     *available_offset = server_ptr -> nx_http_server_multipart.nx_http_server_multipart_available_offset;
7399     *available_length = server_ptr -> nx_http_server_multipart.nx_http_server_multipart_available_length;
7400 
7401     return NX_SUCCESS;
7402 #else
7403     NX_PARAMETER_NOT_USED(server_ptr);
7404     NX_PARAMETER_NOT_USED(packet_pptr);
7405     NX_PARAMETER_NOT_USED(available_offset);
7406     NX_PARAMETER_NOT_USED(available_length);
7407 
7408     return NX_HTTP_ERROR;
7409 #endif /* NX_HTTP_MULTIPART_ENABLE */
7410 }
7411 
7412 
7413 #ifdef  NX_HTTP_MULTIPART_ENABLE
7414 /**************************************************************************/
7415 /*                                                                        */
7416 /*  FUNCTION                                               RELEASE        */
7417 /*                                                                        */
7418 /*    _nx_http_server_boundary_find                       PORTABLE C      */
7419 /*                                                           6.1          */
7420 /*  AUTHOR                                                                */
7421 /*                                                                        */
7422 /*    Yuxin Zhou, Microsoft Corporation                                   */
7423 /*                                                                        */
7424 /*  DESCRIPTION                                                           */
7425 /*                                                                        */
7426 /*    This function finds boundary in packet even if it is chained.       */
7427 /*                                                                        */
7428 /*  INPUT                                                                 */
7429 /*                                                                        */
7430 /*    server_ptr                            Pointer to HTTP server        */
7431 /*    packet_pptr                           Pointer to packet             */
7432 /*                                                                        */
7433 /*  OUTPUT                                                                */
7434 /*                                                                        */
7435 /*    status                                Completion status             */
7436 /*                                                                        */
7437 /*  CALLS                                                                 */
7438 /*                                                                        */
7439 /*    nx_packet_release                                                   */
7440 /*    nx_tcp_socket_receive                                               */
7441 /*    _nx_http_server_match_string                                        */
7442 /*    _nx_utility_string_length_check                                     */
7443 /*                                                                        */
7444 /*  CALLED BY                                                             */
7445 /*                                                                        */
7446 /*    _nx_http_server_get_entity_header                                   */
7447 /*    _nx_http_server_get_entity_content                                  */
7448 /*                                                                        */
7449 /*  RELEASE HISTORY                                                       */
7450 /*                                                                        */
7451 /*    DATE              NAME                      DESCRIPTION             */
7452 /*                                                                        */
7453 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7454 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7455 /*                                            resulting in version 6.1    */
7456 /*                                                                        */
7457 /**************************************************************************/
_nx_http_server_boundary_find(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr)7458 UINT  _nx_http_server_boundary_find(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr)
7459 {
7460 
7461 NX_HTTP_SERVER_MULTIPART   *multipart_ptr;
7462 NX_PACKET                  *available_packet;
7463 UINT                        offset;
7464 ULONG                       match_count = 0;
7465 UCHAR                      *match_end_ptr;
7466 UINT                        boundary_length;
7467 
7468     /* Get multipart context. */
7469     multipart_ptr = &server_ptr -> nx_http_server_multipart;
7470 
7471     /* Is boundary already found? */
7472     if(multipart_ptr -> nx_http_server_multipart_boundary_find == NX_TRUE)
7473     {
7474 
7475         /* Yes. Update the packet and offset. */
7476         if(multipart_ptr -> nx_http_server_multipart_next_packet != NX_NULL)
7477         {
7478             nx_packet_release(*packet_pptr);
7479             *packet_pptr = multipart_ptr -> nx_http_server_multipart_next_packet;
7480             server_ptr -> nx_http_server_multipart.nx_http_server_multipart_last_packet = multipart_ptr -> nx_http_server_multipart_next_packet;
7481         }
7482 
7483         multipart_ptr -> nx_http_server_multipart_available_offset = multipart_ptr -> nx_http_server_multipart_next_available_offset;
7484 
7485         /* Reset next packet and available offset. */
7486         multipart_ptr -> nx_http_server_multipart_next_packet = NX_NULL;
7487         multipart_ptr -> nx_http_server_multipart_next_available_offset = 0;
7488 
7489         /* Reset boundary find. */
7490         multipart_ptr -> nx_http_server_multipart_boundary_find = NX_FALSE;
7491 
7492         return NX_SUCCESS;
7493     }
7494 
7495     /* Is the boundary in the next packet? */
7496     if(multipart_ptr -> nx_http_server_multipart_next_packet)
7497     {
7498 
7499         /* Yes, we're done with this packet. */
7500         nx_packet_release(*packet_pptr);
7501 
7502         /* Update the packet and multipart offset. */
7503         *packet_pptr = multipart_ptr -> nx_http_server_multipart_next_packet;
7504         server_ptr -> nx_http_server_multipart.nx_http_server_multipart_last_packet = multipart_ptr -> nx_http_server_multipart_next_packet;
7505         multipart_ptr -> nx_http_server_multipart_available_offset = 0;
7506     }
7507     else if(multipart_ptr -> nx_http_server_multipart_next_available_offset)
7508     {
7509 
7510         /* Find boundary in this packet. */
7511         /* Update the offset. */
7512         multipart_ptr -> nx_http_server_multipart_available_offset = multipart_ptr -> nx_http_server_multipart_next_available_offset;
7513     }
7514     else
7515     {
7516 
7517         /* Find boundary from this packet. */
7518         /* Initialize the offset. */
7519         multipart_ptr -> nx_http_server_multipart_next_available_offset = multipart_ptr -> nx_http_server_multipart_available_offset;
7520     }
7521 
7522     /* Reset next packet. */
7523     multipart_ptr -> nx_http_server_multipart_next_packet = NX_NULL;
7524 
7525     /* Reset boundary find. */
7526     multipart_ptr -> nx_http_server_multipart_boundary_find = NX_FALSE;
7527 
7528 
7529     /* Get offset of available data in the packet.  */
7530     offset = multipart_ptr -> nx_http_server_multipart_available_offset;
7531 
7532     /* Skip data that are not header. */
7533     available_packet = *packet_pptr;
7534 
7535     if(offset >= available_packet -> nx_packet_length)
7536     {
7537 
7538         /* Release the packet that has been processed. */
7539         nx_packet_release(*packet_pptr);
7540 
7541         /* All data has been processed. Get a new packet. */
7542         if(nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), &available_packet, NX_HTTP_SERVER_TIMEOUT_RECEIVE) != NX_SUCCESS)
7543         {
7544 
7545             /* Error, return to caller.  */
7546             return(NX_HTTP_TIMEOUT);
7547         }
7548 
7549         /* Store the packet. */
7550         *packet_pptr = available_packet;
7551         server_ptr -> nx_http_server_multipart.nx_http_server_multipart_last_packet = available_packet;
7552 
7553         /* Reset the offset. */
7554         multipart_ptr -> nx_http_server_multipart_available_offset = 0;
7555         multipart_ptr -> nx_http_server_multipart_next_available_offset = 0;
7556         offset = 0;
7557     }
7558     else
7559     {
7560 #ifndef NX_DISABLE_PACKET_CHAIN
7561         while((UINT)(available_packet -> nx_packet_append_ptr - available_packet -> nx_packet_prepend_ptr) <= offset)
7562         {
7563             offset -= (UINT)(available_packet -> nx_packet_append_ptr - available_packet -> nx_packet_prepend_ptr);
7564 
7565             /* Get next packet. */
7566             available_packet = available_packet -> nx_packet_next;
7567         }
7568 #endif /* NX_DISABLE_PACKET_CHAIN */
7569     }
7570 
7571     /* Check boundary length.  */
7572     if (_nx_utility_string_length_check((CHAR *)multipart_ptr->nx_http_server_multipart_boundary, &boundary_length, NX_HTTP_MAX_HEADER_FIELD))
7573     {
7574         return(NX_HTTP_ERROR);
7575     }
7576 
7577     /* Look for the boundary string in the (next) packet. */
7578     while(_nx_http_server_match_string(available_packet -> nx_packet_prepend_ptr + offset,
7579                                        available_packet -> nx_packet_append_ptr,
7580                                        multipart_ptr -> nx_http_server_multipart_boundary,
7581                                        boundary_length,
7582                                        &match_count, &match_end_ptr) != NX_SUCCESS)
7583     {
7584 
7585         /* Match string in the next packet. */
7586 #ifndef NX_DISABLE_PACKET_CHAIN
7587         if(available_packet -> nx_packet_next)
7588         {
7589             multipart_ptr -> nx_http_server_multipart_next_available_offset += (UINT)((UINT)(available_packet -> nx_packet_append_ptr - available_packet -> nx_packet_prepend_ptr) - offset);
7590             available_packet = available_packet -> nx_packet_next;
7591             offset = 0;
7592         }
7593         else
7594 #endif /* NX_DISABLE_PACKET_CHAIN */
7595             break;
7596     }
7597 
7598     /* Is boundary matched? */
7599     if(match_end_ptr)
7600     {
7601 
7602         /* Yes. Found a match. */
7603         multipart_ptr -> nx_http_server_multipart_next_available_offset += (UINT)((UINT)(match_end_ptr - available_packet -> nx_packet_prepend_ptr) - offset);
7604         multipart_ptr -> nx_http_server_multipart_available_length = multipart_ptr -> nx_http_server_multipart_next_available_offset - multipart_ptr -> nx_http_server_multipart_available_offset - match_count;
7605         multipart_ptr -> nx_http_server_multipart_boundary_find = NX_TRUE;
7606 
7607     }
7608     else if(match_count)
7609     {
7610 
7611         /* Set the available length to all remaining data. */
7612         multipart_ptr -> nx_http_server_multipart_available_length = (*packet_pptr) -> nx_packet_length - multipart_ptr -> nx_http_server_multipart_available_offset;
7613 
7614         /* Partial match. Get another packet. */
7615         if(nx_tcp_socket_receive(&(server_ptr -> nx_http_server_socket), &available_packet, NX_HTTP_SERVER_TIMEOUT_RECEIVE) != NX_SUCCESS)
7616         {
7617 
7618             /* Error, return to caller.  */
7619             return(NX_HTTP_TIMEOUT);
7620         }
7621 
7622         /* Match the boundary again. */
7623         if(_nx_http_server_match_string(available_packet -> nx_packet_prepend_ptr,
7624                                         available_packet -> nx_packet_append_ptr,
7625                                         multipart_ptr -> nx_http_server_multipart_boundary,
7626                                         boundary_length,
7627                                         &match_count, &match_end_ptr) == NX_SUCCESS)
7628         {
7629 
7630             /* Yes. Find a match. */
7631             if((ULONG)(match_end_ptr - available_packet -> nx_packet_prepend_ptr) < match_count)
7632             {
7633 
7634                 /* The boundary is between two packets. */
7635                 multipart_ptr -> nx_http_server_multipart_next_available_offset = (UINT)(match_end_ptr - available_packet -> nx_packet_prepend_ptr);
7636                 multipart_ptr -> nx_http_server_multipart_available_length -= boundary_length - multipart_ptr -> nx_http_server_multipart_next_available_offset;
7637                 multipart_ptr -> nx_http_server_multipart_boundary_find = NX_TRUE;
7638             }
7639             else
7640             {
7641 
7642                 /* The boundary is in the next packet. */
7643                 multipart_ptr -> nx_http_server_multipart_next_available_offset = 0;
7644             }
7645         }
7646         else
7647         {
7648 
7649             /* The boundary is not found. */
7650             multipart_ptr -> nx_http_server_multipart_next_available_offset = 0;
7651         }
7652 
7653         /* Store the packet. */
7654         multipart_ptr -> nx_http_server_multipart_next_packet = available_packet;
7655 
7656     }
7657     else
7658     {
7659 
7660         /* Set the available length to all remaining data. */
7661         multipart_ptr -> nx_http_server_multipart_available_length = (*packet_pptr) -> nx_packet_length - multipart_ptr -> nx_http_server_multipart_available_offset;
7662         multipart_ptr -> nx_http_server_multipart_next_available_offset = (*packet_pptr) -> nx_packet_length;
7663     }
7664 
7665     return NX_SUCCESS;
7666 }
7667 #endif /* NX_HTTP_MULTIPART_ENABLE */
7668 
7669 
7670 /**************************************************************************/
7671 /*                                                                        */
7672 /*  FUNCTION                                               RELEASE        */
7673 /*                                                                        */
7674 /*    _nx_http_server_match_string                        PORTABLE C      */
7675 /*                                                           6.1          */
7676 /*  AUTHOR                                                                */
7677 /*                                                                        */
7678 /*    Yuxin Zhou, Microsoft Corporation                                   */
7679 /*                                                                        */
7680 /*  DESCRIPTION                                                           */
7681 /*                                                                        */
7682 /*    This function compares a target string in specified memory area.    */
7683 /*                                                                        */
7684 /*  INPUT                                                                 */
7685 /*                                                                        */
7686 /*    src_start                             Pointer to start of source    */
7687 /*    src_end                               Pointer to end of source      */
7688 /*    target                                Pointer to target             */
7689 /*    target_length                         Length of target              */
7690 /*    match_count                           Return the match count        */
7691 /*    match_end_ptr                         Return the end match position */
7692 /*                                                                        */
7693 /*  OUTPUT                                                                */
7694 /*                                                                        */
7695 /*    status                                Completion status             */
7696 /*                                                                        */
7697 /*  CALLS                                                                 */
7698 /*                                                                        */
7699 /*    _nx_utility_string_length_check                                     */
7700 /*    memcmp                                                              */
7701 /*                                                                        */
7702 /*  CALLED BY                                                             */
7703 /*                                                                        */
7704 /*    _nx_http_server_boundary_find                                       */
7705 /*                                                                        */
7706 /*  RELEASE HISTORY                                                       */
7707 /*                                                                        */
7708 /*    DATE              NAME                      DESCRIPTION             */
7709 /*                                                                        */
7710 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7711 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7712 /*                                            resulting in version 6.1    */
7713 /*                                                                        */
7714 /**************************************************************************/
_nx_http_server_match_string(UCHAR * src_start,UCHAR * src_end,UCHAR * target,ULONG target_length,ULONG * match_count,UCHAR ** match_end_ptr)7715 UINT  _nx_http_server_match_string(UCHAR *src_start, UCHAR *src_end, UCHAR *target, ULONG target_length, ULONG *match_count, UCHAR **match_end_ptr)
7716 {
7717 
7718 UCHAR  *ch;
7719 ULONG   pre_match = *match_count;
7720 ULONG   remain_match;
7721 
7722     /* Initialize. */
7723     *match_end_ptr = NX_NULL;
7724 
7725     /* Process part match. */
7726     while(pre_match)
7727     {
7728 
7729         /* Compare pre-match. */
7730         if(memcmp(target, target + (*match_count - pre_match), pre_match) == 0)
7731         {
7732 
7733             /* Calculate the remain match. */
7734             remain_match = target_length - pre_match;
7735 
7736             /* The pre-match is the same. */
7737             if((ULONG)(src_end - src_start) < remain_match)
7738                 remain_match = (ULONG)(src_end - src_start);
7739 
7740             if(memcmp(target + pre_match, src_start, remain_match) == 0)
7741             {
7742 
7743                 /* Remain part matches. */
7744                 *match_count = pre_match + remain_match;
7745 
7746                 if(*match_count < target_length)
7747                 {
7748 
7749                     /* Part match. */
7750                     return NX_HTTP_NOT_FOUND;
7751                 }
7752 
7753                 /* Full match. */
7754                 *match_end_ptr = src_start + remain_match;
7755                 return NX_SUCCESS;
7756             }
7757         }
7758 
7759         pre_match--;
7760     }
7761 
7762     ch = src_start;
7763 
7764     /* Perform full match. */
7765     *match_count = target_length;
7766     while(ch + *match_count <= src_end)
7767     {
7768         if(memcmp(ch, target, *match_count) == 0)
7769         {
7770 
7771             /* Find a match. */
7772             *match_end_ptr = ch + *match_count;
7773             return NX_SUCCESS;
7774         }
7775 
7776         ch++;
7777     }
7778 
7779     /* Perform part match. */
7780     for(*match_count = target_length - 1; *match_count > 0; *match_count = *match_count - 1)
7781     {
7782         if(ch + *match_count <= src_end)
7783         {
7784             if(memcmp(ch, target, *match_count) == 0)
7785             {
7786 
7787                 /* Find a match. */
7788                 return NX_HTTP_NOT_FOUND;
7789             }
7790 
7791             ch++;
7792         }
7793     }
7794 
7795     return NX_HTTP_NOT_FOUND;
7796 }
7797 
7798 
7799 /**************************************************************************/
7800 /*                                                                        */
7801 /*  FUNCTION                                               RELEASE        */
7802 /*                                                                        */
7803 /*    _nx_http_server_field_value_get                     PORTABLE C      */
7804 /*                                                           6.1          */
7805 /*  AUTHOR                                                                */
7806 /*                                                                        */
7807 /*    Yuxin Zhou, Microsoft Corporation                                   */
7808 /*                                                                        */
7809 /*  DESCRIPTION                                                           */
7810 /*                                                                        */
7811 /*    This function gets field value by field name from HTTP header.      */
7812 /*                                                                        */
7813 /*  INPUT                                                                 */
7814 /*                                                                        */
7815 /*    packet_ptr                            Pointer to packet             */
7816 /*    field_name                            Name of filed in header       */
7817 /*    name_length                           Length of filed name          */
7818 /*    field_value                           Return fieald of value        */
7819 /*    field_value_size                      Size of fieald_value          */
7820 /*                                                                        */
7821 /*  OUTPUT                                                                */
7822 /*                                                                        */
7823 /*    status                                Completion status             */
7824 /*                                                                        */
7825 /*  CALLS                                                                 */
7826 /*                                                                        */
7827 /*    _nx_utility_string_length_check                                     */
7828 /*    _nx_http_server_memicmp                                             */
7829 /*                                                                        */
7830 /*  CALLED BY                                                             */
7831 /*                                                                        */
7832 /*    _nx_http_server_get_process                                         */
7833 /*    _nx_http_server_get_entity_header                                   */
7834 /*                                                                        */
7835 /*  RELEASE HISTORY                                                       */
7836 /*                                                                        */
7837 /*    DATE              NAME                      DESCRIPTION             */
7838 /*                                                                        */
7839 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7840 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7841 /*                                            resulting in version 6.1    */
7842 /*                                                                        */
7843 /**************************************************************************/
_nx_http_server_field_value_get(NX_PACKET * packet_ptr,UCHAR * field_name,ULONG name_length,UCHAR * field_value,ULONG field_value_size)7844 UINT  _nx_http_server_field_value_get(NX_PACKET *packet_ptr, UCHAR *field_name, ULONG name_length, UCHAR *field_value, ULONG field_value_size)
7845 {
7846 
7847 UCHAR  *ch;
7848 UINT    index;
7849 
7850 
7851     /* Initialize. */
7852     ch = packet_ptr -> nx_packet_prepend_ptr;
7853 
7854     /* Loop to find field name. */
7855     while(ch + name_length < packet_ptr -> nx_packet_append_ptr)
7856     {
7857         if(_nx_http_server_memicmp(ch, name_length, field_name, name_length) == NX_SUCCESS)
7858         {
7859 
7860             /* Field name found. */
7861             break;
7862         }
7863 
7864         /* Move the pointer up to the next character.  */
7865         ch++;
7866     }
7867 
7868     /* Skip field name and ':'. */
7869     ch += name_length + 1;
7870 
7871     /* Is field name found? */
7872     if(ch >= packet_ptr -> nx_packet_append_ptr)
7873         return NX_HTTP_NOT_FOUND;
7874 
7875     /* Skip white spaces. */
7876     while(*ch == ' ')
7877     {
7878         if(ch >= packet_ptr -> nx_packet_append_ptr)
7879             return NX_HTTP_NOT_FOUND;
7880 
7881         /* Get next character. */
7882         ch++;
7883     }
7884 
7885     /* Copy field value. */
7886     index = 0;
7887     while(index < field_value_size)
7888     {
7889 
7890         /* Whether the end of line CRLF is not found? */
7891         if(ch + 2 > packet_ptr -> nx_packet_append_ptr)
7892             return NX_HTTP_NOT_FOUND;
7893 
7894         /* Compare CRLF. */
7895         if((*ch == 13) && (*(ch + 1) == 10))
7896             break;
7897 
7898         /* Copy data. */
7899         field_value[index++] = *ch++;
7900     }
7901 
7902     /* Buffer overflow? */
7903     if(index == field_value_size)
7904         return NX_HTTP_NOT_FOUND;
7905 
7906     /* Trim white spaces. */
7907     while((index > 0) && (field_value[index - 1] == ' '))
7908         index--;
7909 
7910     /* Append terminal 0. */
7911     field_value[index] = 0;
7912 
7913 
7914     return NX_SUCCESS;
7915 }
7916 
7917 
7918 /**************************************************************************/
7919 /*                                                                        */
7920 /*  FUNCTION                                               RELEASE        */
7921 /*                                                                        */
7922 /*    _nx_http_server_memicmp                             PORTABLE C      */
7923 /*                                                           6.1          */
7924 /*  AUTHOR                                                                */
7925 /*                                                                        */
7926 /*    Yuxin Zhou, Microsoft Corporation                                   */
7927 /*                                                                        */
7928 /*  DESCRIPTION                                                           */
7929 /*                                                                        */
7930 /*    This function compares two pieces of memory case insensitive.       */
7931 /*                                                                        */
7932 /*  INPUT                                                                 */
7933 /*                                                                        */
7934 /*    src                                   Pointer to source             */
7935 /*    src_length                            Length of source              */
7936 /*    dest                                  Pointer to destination        */
7937 /*    dest_length                           Length of destination         */
7938 /*                                                                        */
7939 /*  OUTPUT                                                                */
7940 /*                                                                        */
7941 /*    status                                Completion status             */
7942 /*                                                                        */
7943 /*  CALLS                                                                 */
7944 /*                                                                        */
7945 /*                                                                        */
7946 /*  CALLED BY                                                             */
7947 /*                                                                        */
7948 /*    _nx_http_server_get_entity_header                                   */
7949 /*    _nx_http_server_field_value_get                                     */
7950 /*                                                                        */
7951 /*  RELEASE HISTORY                                                       */
7952 /*                                                                        */
7953 /*    DATE              NAME                      DESCRIPTION             */
7954 /*                                                                        */
7955 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7956 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7957 /*                                            resulting in version 6.1    */
7958 /*                                                                        */
7959 /**************************************************************************/
_nx_http_server_memicmp(UCHAR * src,ULONG src_length,UCHAR * dest,ULONG dest_length)7960 UINT  _nx_http_server_memicmp(UCHAR *src, ULONG src_length, UCHAR *dest, ULONG dest_length)
7961 {
7962 UCHAR   ch;
7963 
7964     /* Compare the length. */
7965     if(src_length != dest_length)
7966         return NX_HTTP_FAILED;
7967 
7968     while(src_length)
7969     {
7970 
7971         /* Is src lowercase? */
7972         if((*src >= 'a') && (*src <= 'z'))
7973             ch = (UCHAR)(*src - 'a' + 'A');
7974 
7975         /* Is src uppercase? */
7976         else if((*src >= 'A') && (*src <= 'Z'))
7977             ch = (UCHAR)(*src - 'A' + 'a');
7978         else
7979             ch = *src;
7980 
7981         /* Compare case insensitive. */
7982         if((*src != *dest) && (ch != *dest))
7983             return NX_HTTP_FAILED;
7984 
7985         /* Pickup next character. */
7986         src_length--;
7987         src++;
7988         dest++;
7989     }
7990 
7991     return NX_SUCCESS;
7992 }
7993 
7994 
7995 /**************************************************************************/
7996 /*                                                                        */
7997 /*  FUNCTION                                               RELEASE        */
7998 /*                                                                        */
7999 /*    _nx_http_server_generate_response_header            PORTABLE C      */
8000 /*                                                           6.1.8        */
8001 /*  AUTHOR                                                                */
8002 /*                                                                        */
8003 /*    Yuxin Zhou, Microsoft Corporation                                   */
8004 /*                                                                        */
8005 /*  DESCRIPTION                                                           */
8006 /*                                                                        */
8007 /*    This function generates HTTP response header.                       */
8008 /*                                                                        */
8009 /*    Note: The strings of status code, content type length and additional*/
8010 /*    header length must be NULL-terminated and length of this string     */
8011 /*    matches the length specified in the argument list.                  */
8012 /*                                                                        */
8013 /*  INPUT                                                                 */
8014 /*                                                                        */
8015 /*    server_ptr                            Pointer to HTTP server        */
8016 /*    packet_pptr                           Pointer to packet             */
8017 /*    status_code                           Status-code and reason-phrase */
8018 /*    status_code_length                    Length of status-code         */
8019 /*    content_length                        Length of content             */
8020 /*    content_type                          Type of content               */
8021 /*    content_type_length                   Length of content type        */
8022 /*    additional_header                     Other HTTP headers            */
8023 /*    additional_header_length              Length of other HTTP headers  */
8024 /*                                                                        */
8025 /*  OUTPUT                                                                */
8026 /*                                                                        */
8027 /*    status                                Completion status             */
8028 /*                                                                        */
8029 /*  CALLS                                                                 */
8030 /*                                                                        */
8031 /*    nx_packet_allocate                                                  */
8032 /*    nx_packet_data_append                                               */
8033 /*    memcmp                                                              */
8034 /*    _nx_utility_string_length_check                                     */
8035 /*    _nx_utility_uint_to_string                                          */
8036 /*    _nx_http_server_date_to_string                                      */
8037 /*    nx_packet_release                                                   */
8038 /*                                                                        */
8039 /*  CALLED BY                                                             */
8040 /*                                                                        */
8041 /*    _nx_http_server_get_process                                         */
8042 /*    _nx_http_server_put_process                                         */
8043 /*    _nx_http_server_delete_process                                      */
8044 /*    _nx_http_server_response_send                                       */
8045 /*    _nx_http_server_callback_generate_response_header                   */
8046 /*                                                                        */
8047 /*  RELEASE HISTORY                                                       */
8048 /*                                                                        */
8049 /*    DATE              NAME                      DESCRIPTION             */
8050 /*                                                                        */
8051 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8052 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8053 /*                                            resulting in version 6.1    */
8054 /*  08-02-2021     Yuxin Zhou               Modified comment(s),          */
8055 /*                                            improved the logic of       */
8056 /*                                            converting number to string,*/
8057 /*                                            resulting in version 6.1.8  */
8058 /*                                                                        */
8059 /**************************************************************************/
_nx_http_server_generate_response_header(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,CHAR * status_code,UINT status_code_length,UINT content_length,CHAR * content_type,UINT content_type_length,CHAR * additional_header,UINT additional_header_length)8060 UINT  _nx_http_server_generate_response_header(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, CHAR *status_code,
8061                                                UINT status_code_length, UINT content_length, CHAR *content_type,
8062                                                UINT content_type_length, CHAR* additional_header, UINT additional_header_length)
8063 {
8064 
8065 UINT        status;
8066 UINT        temp;
8067 CHAR        temp_string[30];
8068 CHAR        crlf[2] = {13,10};
8069 NX_PACKET  *packet_ptr;
8070 CHAR        status_code_ok;
8071 CHAR        status_code_not_modified;
8072 
8073     /* Allocate a packet for sending the response back.  */
8074     status = nx_packet_allocate(server_ptr -> nx_http_server_packet_pool_ptr, packet_pptr, NX_TCP_PACKET, NX_WAIT_FOREVER);
8075 
8076     /* Determine if an error occurred in the packet allocation.  */
8077     if(status != NX_SUCCESS)
8078     {
8079 
8080         /* Indicate an allocation error occurred.  */
8081         server_ptr -> nx_http_server_allocation_errors++;
8082 
8083         /* Just return.  */
8084         return status;
8085     }
8086     else
8087         packet_ptr = *packet_pptr;
8088 
8089     /* Check status code. */
8090     if(memcmp(status_code, NX_HTTP_STATUS_OK, sizeof(NX_HTTP_STATUS_OK)) == 0)
8091         status_code_ok = NX_TRUE;
8092     else
8093         status_code_ok = NX_FALSE;
8094 
8095     if(memcmp(status_code, NX_HTTP_STATUS_NOT_MODIFIED, sizeof(NX_HTTP_STATUS_NOT_MODIFIED)) == 0)
8096         status_code_not_modified = NX_TRUE;
8097     else
8098         status_code_not_modified = NX_FALSE;
8099 
8100     /* Insert the status line.  */
8101     /* Place HTTP-Version. */
8102     status = nx_packet_data_append(packet_ptr, NX_HTTP_VERSION, sizeof(NX_HTTP_VERSION) - 1,  server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8103 
8104     /* Insert space. */
8105     status += nx_packet_data_append(packet_ptr, " ", 1,  server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8106 
8107     /* Insert Status-Code and Reason-Phrase. */
8108     status += nx_packet_data_append(packet_ptr, status_code, status_code_length,  server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8109 
8110     /* Place the <cr,lf> into the buffer.  */
8111     status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8112 
8113     /* Determine if there is content_type.  */
8114     if(content_type)
8115     {
8116 
8117         /* Insert the content type.  */
8118         status += nx_packet_data_append(packet_ptr, "Content-Type: ", 14,  server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8119         status += nx_packet_data_append(packet_ptr, content_type, content_type_length,  server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8120 
8121         /* Place the <cr,lf> into the buffer.  */
8122         status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8123     }
8124 
8125 #ifndef NX_HTTP_SERVER_OMIT_CONTENT_LENGTH
8126     /* Determine if there is content_length.  */
8127     if(content_length || (status_code_not_modified == NX_TRUE))
8128     {
8129 
8130         /* Close. */
8131         status += nx_packet_data_append(packet_ptr, "Connection: Close", 17,
8132                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8133 
8134         /* Place the <cr,lf> into the buffer.  */
8135         status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8136 
8137         if(content_length)
8138         {
8139 
8140             /* Convert the content_length to ASCII representation.  */
8141             temp = _nx_utility_uint_to_string(content_length, 10, temp_string, sizeof(temp_string));
8142 
8143             /* Place the "Content-Length" field in the header.  */
8144             status += nx_packet_data_append(packet_ptr, "Content-Length: ", 16,
8145                     server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8146             status += nx_packet_data_append(packet_ptr, temp_string, temp,
8147                     server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8148 
8149             /* Place the <cr,lf> into the buffer.  */
8150             status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8151         }
8152 
8153     }
8154     else
8155 #endif /* NX_HTTP_SERVER_OMIT_CONTENT_LENGTH */
8156     {
8157 
8158         /* Place the "Connection" field in the header.  */
8159 
8160         /* Force close the connection since there's no content-length. */
8161         status += nx_packet_data_append(packet_ptr, "Connection: Close", 17,
8162                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8163 
8164         /* Place the <cr,lf> into the buffer.  */
8165         status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8166     }
8167 
8168     /* Insert Date header if callback function is set. */
8169     if(server_ptr -> nx_http_server_gmt_get)
8170     {
8171     NX_HTTP_SERVER_DATE date;
8172 
8173         /* Get current date. */
8174         server_ptr -> nx_http_server_gmt_get(&date);
8175 
8176         /* Convert date to string. */
8177         temp = _nx_http_server_date_to_string(&date, temp_string);
8178 
8179         /* Place the "Date" field in the header.  */
8180         status += nx_packet_data_append(packet_ptr, "Date: ", 6,
8181                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8182 
8183         /* Insert date. */
8184         status += nx_packet_data_append(packet_ptr, temp_string, temp, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8185 
8186         /* Place the <cr,lf> into the buffer.  */
8187         status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8188 
8189         /* Set Cache Control if callback function is set. */
8190         if((server_ptr -> nx_http_server_cache_info_get) &&
8191            ((status_code_ok == NX_TRUE) || (status_code_not_modified == NX_TRUE)) &&
8192            (server_ptr -> nx_http_server_request_type == NX_HTTP_SERVER_GET_REQUEST))
8193         {
8194         UINT max_age;
8195 
8196             /* Get cache infomation. */
8197             if(server_ptr -> nx_http_server_cache_info_get(server_ptr -> nx_http_server_request_resource, &max_age, &date) == NX_TRUE)
8198             {
8199 
8200                 /* Place "Cache-control" header. */
8201                 status += nx_packet_data_append(packet_ptr, "Cache-Control: max-age=", 23,
8202                                                 server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8203 
8204                 /* Convert the max-age to ASCII representation.  */
8205                 temp = _nx_utility_uint_to_string(max_age, 10, temp_string, sizeof(temp_string));
8206                 status += nx_packet_data_append(packet_ptr, temp_string, temp,
8207                                                 server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8208 
8209                 /* Place the <cr,lf> into the buffer.  */
8210                 status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8211 
8212                 if(status_code_ok == NX_TRUE)
8213                 {
8214 
8215                     /* Convert date to string. */
8216                     temp = _nx_http_server_date_to_string(&date, temp_string);
8217 
8218                     /* Place the "Last-Modified" field in the header.  */
8219                     status += nx_packet_data_append(packet_ptr, "Last-Modified: ", 15,
8220                                                     server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8221 
8222                     /* Insert date. */
8223                     status += nx_packet_data_append(packet_ptr, temp_string, temp, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8224 
8225                     /* Place the <cr,lf> into the buffer.  */
8226                     status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8227                 }
8228             }
8229         }
8230     }
8231 
8232     /* Insert additional header. */
8233     if(additional_header)
8234     {
8235 
8236         status += nx_packet_data_append(packet_ptr, additional_header, additional_header_length,
8237                                         server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8238     }
8239 
8240     /* Place the <cr,lf> into the buffer.  */
8241     status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8242 
8243     if (status != NX_SUCCESS)
8244     {
8245 
8246         /* Just release the packet.  */
8247         nx_packet_release(packet_ptr);
8248     }
8249 
8250     return status;
8251 }
8252 
8253 
8254 /**************************************************************************/
8255 /*                                                                        */
8256 /*  FUNCTION                                               RELEASE        */
8257 /*                                                                        */
8258 /*    _nxe_http_server_callback_generate_response_header  PORTABLE C      */
8259 /*                                                           6.1          */
8260 /*  AUTHOR                                                                */
8261 /*                                                                        */
8262 /*    Yuxin Zhou, Microsoft Corporation                                   */
8263 /*                                                                        */
8264 /*  DESCRIPTION                                                           */
8265 /*                                                                        */
8266 /*    This function checks error for generating HTTP response header.     */
8267 /*                                                                        */
8268 /*  INPUT                                                                 */
8269 /*                                                                        */
8270 /*    server_ptr                            Pointer to HTTP server        */
8271 /*    packet_pptr                           Pointer to packet             */
8272 /*    status_code                           Status-code and reason-phrase */
8273 /*    content_length                        Length of content             */
8274 /*    content_type                          Type of content               */
8275 /*    additional_header                     Other HTTP headers            */
8276 /*                                                                        */
8277 /*  OUTPUT                                                                */
8278 /*                                                                        */
8279 /*    status                                Completion status             */
8280 /*                                                                        */
8281 /*  CALLS                                                                 */
8282 /*                                                                        */
8283 /*    _nx_http_server_callback_generate_response_header                   */
8284 /*                                                                        */
8285 /*  CALLED BY                                                             */
8286 /*                                                                        */
8287 /*    Application Code                                                    */
8288 /*                                                                        */
8289 /*  RELEASE HISTORY                                                       */
8290 /*                                                                        */
8291 /*    DATE              NAME                      DESCRIPTION             */
8292 /*                                                                        */
8293 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8294 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8295 /*                                            resulting in version 6.1    */
8296 /*                                                                        */
8297 /**************************************************************************/
_nxe_http_server_callback_generate_response_header(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,CHAR * status_code,UINT content_length,CHAR * content_type,CHAR * additional_header)8298 UINT  _nxe_http_server_callback_generate_response_header(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr,
8299                                                          CHAR *status_code, UINT content_length, CHAR *content_type,
8300                                                          CHAR* additional_header)
8301 {
8302 
8303     /* Check for invalid input pointers.  */
8304     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) ||
8305         (packet_pptr == NX_NULL) || (status_code == NX_NULL))
8306         return(NX_PTR_ERROR);
8307 
8308     /* Check for appropriate caller.  */
8309     NX_THREADS_ONLY_CALLER_CHECKING
8310 
8311     return _nx_http_server_callback_generate_response_header(server_ptr, packet_pptr, status_code, content_length, content_type, additional_header);
8312 }
8313 
8314 
8315 /**************************************************************************/
8316 /*                                                                        */
8317 /*  FUNCTION                                               RELEASE        */
8318 /*                                                                        */
8319 /*    _nxe_http_server_callback_generate_response_header_extended         */
8320 /*                                                        PORTABLE C      */
8321 /*                                                           6.1          */
8322 /*  AUTHOR                                                                */
8323 /*                                                                        */
8324 /*    Yuxin Zhou, Microsoft Corporation                                   */
8325 /*                                                                        */
8326 /*  DESCRIPTION                                                           */
8327 /*                                                                        */
8328 /*    This function checks error for generating HTTP response header.     */
8329 /*                                                                        */
8330 /*  INPUT                                                                 */
8331 /*                                                                        */
8332 /*    server_ptr                            Pointer to HTTP server        */
8333 /*    packet_pptr                           Pointer to packet             */
8334 /*    status_code                           Status-code and reason-phrase */
8335 /*    status_code_length                    Length of status-code         */
8336 /*    content_length                        Length of content             */
8337 /*    content_type                          Type of content               */
8338 /*    content_type_length                   Length of content type        */
8339 /*    additional_header                     Other HTTP headers            */
8340 /*    additional_header_length              Length of other HTTP headers  */
8341 /*                                                                        */
8342 /*  OUTPUT                                                                */
8343 /*                                                                        */
8344 /*    status                                Completion status             */
8345 /*                                                                        */
8346 /*  CALLS                                                                 */
8347 /*                                                                        */
8348 /*    _nx_http_server_callback_generate_response_header_extended          */
8349 /*                                          Actual responder header       */
8350 /*                                            generation function         */
8351 /*                                                                        */
8352 /*  CALLED BY                                                             */
8353 /*                                                                        */
8354 /*    Application Code                                                    */
8355 /*                                                                        */
8356 /*  RELEASE HISTORY                                                       */
8357 /*                                                                        */
8358 /*    DATE              NAME                      DESCRIPTION             */
8359 /*                                                                        */
8360 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8361 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8362 /*                                            resulting in version 6.1    */
8363 /*                                                                        */
8364 /**************************************************************************/
_nxe_http_server_callback_generate_response_header_extended(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,CHAR * status_code,UINT status_code_length,UINT content_length,CHAR * content_type,UINT content_type_length,CHAR * additional_header,UINT additional_header_length)8365 UINT  _nxe_http_server_callback_generate_response_header_extended(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, CHAR *status_code,
8366                                                                   UINT status_code_length, UINT content_length, CHAR *content_type,
8367                                                                   UINT content_type_length, CHAR* additional_header, UINT additional_header_length)
8368 {
8369 
8370     /* Check for invalid input pointers.  */
8371     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) ||
8372         (packet_pptr == NX_NULL) || (status_code == NX_NULL))
8373         return(NX_PTR_ERROR);
8374 
8375     /* Check for appropriate caller.  */
8376     NX_THREADS_ONLY_CALLER_CHECKING
8377 
8378     return _nx_http_server_callback_generate_response_header_extended(server_ptr, packet_pptr, status_code, status_code_length, content_length,
8379                                                                       content_type, content_type_length, additional_header, additional_header_length);
8380 }
8381 
8382 
8383 /**************************************************************************/
8384 /*                                                                        */
8385 /*  FUNCTION                                               RELEASE        */
8386 /*                                                                        */
8387 /*    _nx_http_server_callback_generate_response_header   PORTABLE C      */
8388 /*                                                           6.1          */
8389 /*  AUTHOR                                                                */
8390 /*                                                                        */
8391 /*    Yuxin Zhou, Microsoft Corporation                                   */
8392 /*                                                                        */
8393 /*  DESCRIPTION                                                           */
8394 /*                                                                        */
8395 /*    This function is used in callback function to generate HTTP         */
8396 /*    response header.                                                    */
8397 /*                                                                        */
8398 /*  INPUT                                                                 */
8399 /*                                                                        */
8400 /*    server_ptr                            Pointer to HTTP server        */
8401 /*    packet_pptr                           Pointer to packet             */
8402 /*    status_code                           Status-code and reason-phrase */
8403 /*    content_length                        Length of content             */
8404 /*    content_type                          Type of content               */
8405 /*    additional_header                     Other HTTP headers            */
8406 /*                                                                        */
8407 /*  OUTPUT                                                                */
8408 /*                                                                        */
8409 /*    status                                Completion status             */
8410 /*                                                                        */
8411 /*  CALLS                                                                 */
8412 /*                                                                        */
8413 /*    _nx_http_server_generate_response_header                            */
8414 /*                                          Internal responder header     */
8415 /*                                            generation function         */
8416 /*    _nx_utility_string_length_check       Check string length           */
8417 /*                                                                        */
8418 /*  CALLED BY                                                             */
8419 /*                                                                        */
8420 /*    Application Code                                                    */
8421 /*                                                                        */
8422 /*  RELEASE HISTORY                                                       */
8423 /*                                                                        */
8424 /*    DATE              NAME                      DESCRIPTION             */
8425 /*                                                                        */
8426 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8427 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8428 /*                                            resulting in version 6.1    */
8429 /*                                                                        */
8430 /**************************************************************************/
_nx_http_server_callback_generate_response_header(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,CHAR * status_code,UINT content_length,CHAR * content_type,CHAR * additional_header)8431 UINT  _nx_http_server_callback_generate_response_header(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr,
8432                                                         CHAR *status_code, UINT content_length, CHAR *content_type,
8433                                                         CHAR* additional_header)
8434 {
8435 UINT status_code_length = 0;
8436 UINT content_type_length = 0;
8437 UINT additional_header_length = 0;
8438 
8439     /* Check status code, content type and additional header length.  */
8440     if (_nx_utility_string_length_check(status_code, &status_code_length, NX_MAX_STRING_LENGTH) ||
8441         (content_type && _nx_utility_string_length_check(content_type, &content_type_length, NX_MAX_STRING_LENGTH)) ||
8442         (additional_header && _nx_utility_string_length_check(additional_header, &additional_header_length, NX_MAX_STRING_LENGTH)))
8443     {
8444         return(NX_HTTP_ERROR);
8445     }
8446 
8447     /* Call the internal HTTP response send function.  */
8448     return _nx_http_server_generate_response_header(server_ptr, packet_pptr, status_code, status_code_length, content_length,
8449                                                     content_type, content_type_length, additional_header, additional_header_length);
8450 }
8451 
8452 
8453 /**************************************************************************/
8454 /*                                                                        */
8455 /*  FUNCTION                                               RELEASE        */
8456 /*                                                                        */
8457 /*    _nx_http_server_callback_generate_response_header_extended          */
8458 /*                                                        PORTABLE C      */
8459 /*                                                           6.1          */
8460 /*  AUTHOR                                                                */
8461 /*                                                                        */
8462 /*    Yuxin Zhou, Microsoft Corporation                                   */
8463 /*                                                                        */
8464 /*  DESCRIPTION                                                           */
8465 /*                                                                        */
8466 /*    This function is used in callback function to generate HTTP         */
8467 /*    response header.                                                    */
8468 /*                                                                        */
8469 /*    Note: The strings of status code, content type length and additional*/
8470 /*    header length must be NULL-terminated and length of this string     */
8471 /*    matches the length specified in the argument list.                  */
8472 /*                                                                        */
8473 /*  INPUT                                                                 */
8474 /*                                                                        */
8475 /*    server_ptr                            Pointer to HTTP server        */
8476 /*    packet_pptr                           Pointer to packet             */
8477 /*    status_code                           Status-code and reason-phrase */
8478 /*    status_code_length                    Length of status-code         */
8479 /*    content_length                        Length of content             */
8480 /*    content_type                          Type of content               */
8481 /*    content_type_length                   Length of content type        */
8482 /*    additional_header                     Other HTTP headers            */
8483 /*    additional_header_length              Length of other HTTP headers  */
8484 /*                                                                        */
8485 /*  OUTPUT                                                                */
8486 /*                                                                        */
8487 /*    status                                Completion status             */
8488 /*                                                                        */
8489 /*  CALLS                                                                 */
8490 /*                                                                        */
8491 /*    _nx_http_server_generate_response_header                            */
8492 /*                                          Internal responder header     */
8493 /*                                            generation function         */
8494 /*    _nx_utility_string_length_check       Check string length           */
8495 /*                                                                        */
8496 /*  CALLED BY                                                             */
8497 /*                                                                        */
8498 /*    Application Code                                                    */
8499 /*                                                                        */
8500 /*  RELEASE HISTORY                                                       */
8501 /*                                                                        */
8502 /*    DATE              NAME                      DESCRIPTION             */
8503 /*                                                                        */
8504 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8505 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8506 /*                                            resulting in version 6.1    */
8507 /*                                                                        */
8508 /**************************************************************************/
_nx_http_server_callback_generate_response_header_extended(NX_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,CHAR * status_code,UINT status_code_length,UINT content_length,CHAR * content_type,UINT content_type_length,CHAR * additional_header,UINT additional_header_length)8509 UINT  _nx_http_server_callback_generate_response_header_extended(NX_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, CHAR *status_code,
8510                                                                  UINT status_code_length, UINT content_length, CHAR *content_type,
8511                                                                  UINT content_type_length, CHAR* additional_header, UINT additional_header_length)
8512 {
8513 
8514 UINT temp_status_code_length = 0;
8515 UINT temp_content_type_length = 0;
8516 UINT temp_add_header_length = 0;
8517 
8518     /* Check status code, content type and additional header length.  */
8519     if (_nx_utility_string_length_check(status_code, &temp_status_code_length, status_code_length) ||
8520         (content_type && _nx_utility_string_length_check(content_type, &temp_content_type_length, content_type_length)) ||
8521         (additional_header &&  _nx_utility_string_length_check(additional_header, &temp_add_header_length, additional_header_length)))
8522     {
8523         return(NX_HTTP_ERROR);
8524     }
8525 
8526     /* Validate string length.  */
8527     if ((status_code_length != temp_status_code_length) ||
8528         (content_type && content_type_length != temp_content_type_length) ||
8529         (additional_header && additional_header_length != temp_add_header_length))
8530     {
8531         return(NX_HTTP_ERROR);
8532     }
8533 
8534     /* Call the internal HTTP response send function.  */
8535     return _nx_http_server_generate_response_header(server_ptr, packet_pptr, status_code, status_code_length, content_length,
8536                                                     content_type, content_type_length, additional_header, additional_header_length);
8537 }
8538 
8539 
8540 /**************************************************************************/
8541 /*                                                                        */
8542 /*  FUNCTION                                               RELEASE        */
8543 /*                                                                        */
8544 /*    _nxe_http_server_callback_packet_send               PORTABLE C      */
8545 /*                                                           6.1          */
8546 /*  AUTHOR                                                                */
8547 /*                                                                        */
8548 /*    Yuxin Zhou, Microsoft Corporation                                   */
8549 /*                                                                        */
8550 /*  DESCRIPTION                                                           */
8551 /*                                                                        */
8552 /*    This function checks error for sending a packet.                    */
8553 /*                                                                        */
8554 /*  INPUT                                                                 */
8555 /*                                                                        */
8556 /*    server_ptr                            Pointer to HTTP server        */
8557 /*    packet_ptr                            Pointer to packet             */
8558 /*                                                                        */
8559 /*  OUTPUT                                                                */
8560 /*                                                                        */
8561 /*    status                                Completion status             */
8562 /*                                                                        */
8563 /*  CALLS                                                                 */
8564 /*                                                                        */
8565 /*    _nx_http_server_callback_packet_send                                */
8566 /*                                                                        */
8567 /*  CALLED BY                                                             */
8568 /*                                                                        */
8569 /*    Application Code                                                    */
8570 /*                                                                        */
8571 /*  RELEASE HISTORY                                                       */
8572 /*                                                                        */
8573 /*    DATE              NAME                      DESCRIPTION             */
8574 /*                                                                        */
8575 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8576 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8577 /*                                            resulting in version 6.1    */
8578 /*                                                                        */
8579 /**************************************************************************/
_nxe_http_server_callback_packet_send(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr)8580 UINT  _nxe_http_server_callback_packet_send(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr)
8581 {
8582 
8583     /* Check for invalid input pointers.  */
8584     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) || (packet_ptr == NX_NULL))
8585         return(NX_PTR_ERROR);
8586 
8587     return _nx_http_server_callback_packet_send(server_ptr, packet_ptr);
8588 }
8589 
8590 
8591 /**************************************************************************/
8592 /*                                                                        */
8593 /*  FUNCTION                                               RELEASE        */
8594 /*                                                                        */
8595 /*    _nx_http_server_callback_packet_send                PORTABLE C      */
8596 /*                                                           6.1          */
8597 /*  AUTHOR                                                                */
8598 /*                                                                        */
8599 /*    Yuxin Zhou, Microsoft Corporation                                   */
8600 /*                                                                        */
8601 /*  DESCRIPTION                                                           */
8602 /*                                                                        */
8603 /*    This function is used in callback function to send a packet.        */
8604 /*                                                                        */
8605 /*  INPUT                                                                 */
8606 /*                                                                        */
8607 /*    server_ptr                            Pointer to HTTP server        */
8608 /*    packet_ptr                            Pointer to packet             */
8609 /*                                                                        */
8610 /*  OUTPUT                                                                */
8611 /*                                                                        */
8612 /*    status                                Completion status             */
8613 /*                                                                        */
8614 /*  CALLS                                                                 */
8615 /*                                                                        */
8616 /*    nx_tcp_socket_send                                                  */
8617 /*                                                                        */
8618 /*  CALLED BY                                                             */
8619 /*                                                                        */
8620 /*    Application Code                                                    */
8621 /*                                                                        */
8622 /*  RELEASE HISTORY                                                       */
8623 /*                                                                        */
8624 /*    DATE              NAME                      DESCRIPTION             */
8625 /*                                                                        */
8626 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8627 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8628 /*                                            resulting in version 6.1    */
8629 /*                                                                        */
8630 /**************************************************************************/
_nx_http_server_callback_packet_send(NX_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr)8631 UINT  _nx_http_server_callback_packet_send(NX_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr)
8632 {
8633 
8634     /* Send internal. */
8635     return nx_tcp_socket_send(&(server_ptr -> nx_http_server_socket), packet_ptr, NX_HTTP_SERVER_TIMEOUT_SEND);
8636 }
8637 
8638 
8639 /**************************************************************************/
8640 /*                                                                        */
8641 /*  FUNCTION                                               RELEASE        */
8642 /*                                                                        */
8643 /*    _nxe_http_server_gmt_callback_set                   PORTABLE C      */
8644 /*                                                           6.1          */
8645 /*  AUTHOR                                                                */
8646 /*                                                                        */
8647 /*    Yuxin Zhou, Microsoft Corporation                                   */
8648 /*                                                                        */
8649 /*  DESCRIPTION                                                           */
8650 /*                                                                        */
8651 /*    This function checks error for setting gmt callback function.       */
8652 /*                                                                        */
8653 /*  INPUT                                                                 */
8654 /*                                                                        */
8655 /*    server_ptr                            Pointer to HTTP server        */
8656 /*    gmt_get                               Pointer to application's      */
8657 /*                                            GMT time function           */
8658 /*                                                                        */
8659 /*  OUTPUT                                                                */
8660 /*                                                                        */
8661 /*    status                                Completion status             */
8662 /*                                                                        */
8663 /*  CALLS                                                                 */
8664 /*                                                                        */
8665 /*    _nx_http_server_gmt_callback_set                                    */
8666 /*                                                                        */
8667 /*  CALLED BY                                                             */
8668 /*                                                                        */
8669 /*    Application Code                                                    */
8670 /*                                                                        */
8671 /*  RELEASE HISTORY                                                       */
8672 /*                                                                        */
8673 /*    DATE              NAME                      DESCRIPTION             */
8674 /*                                                                        */
8675 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8676 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8677 /*                                            resulting in version 6.1    */
8678 /*                                                                        */
8679 /**************************************************************************/
_nxe_http_server_gmt_callback_set(NX_HTTP_SERVER * server_ptr,VOID (* gmt_get)(NX_HTTP_SERVER_DATE *))8680 UINT  _nxe_http_server_gmt_callback_set(NX_HTTP_SERVER *server_ptr, VOID (*gmt_get)(NX_HTTP_SERVER_DATE *))
8681 {
8682 
8683     /* Check for invalid input pointers.  */
8684     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) || (gmt_get == NX_NULL))
8685         return(NX_PTR_ERROR);
8686 
8687     /* Send internal. */
8688     return _nx_http_server_gmt_callback_set(server_ptr, gmt_get);
8689 }
8690 
8691 
8692 /**************************************************************************/
8693 /*                                                                        */
8694 /*  FUNCTION                                               RELEASE        */
8695 /*                                                                        */
8696 /*    _nx_http_server_gmt_callback_set                    PORTABLE C      */
8697 /*                                                           6.1          */
8698 /*  AUTHOR                                                                */
8699 /*                                                                        */
8700 /*    Yuxin Zhou, Microsoft Corporation                                   */
8701 /*                                                                        */
8702 /*  DESCRIPTION                                                           */
8703 /*                                                                        */
8704 /*    This function sets gmt callback function.                           */
8705 /*                                                                        */
8706 /*  INPUT                                                                 */
8707 /*                                                                        */
8708 /*    server_ptr                            Pointer to HTTP server        */
8709 /*    gmt_get                               Pointer to application's      */
8710 /*                                            GMT time function           */
8711 /*                                                                        */
8712 /*  OUTPUT                                                                */
8713 /*                                                                        */
8714 /*    status                                Completion status             */
8715 /*                                                                        */
8716 /*  CALLS                                                                 */
8717 /*                                                                        */
8718 /*                                                                        */
8719 /*  CALLED BY                                                             */
8720 /*                                                                        */
8721 /*    Application Code                                                    */
8722 /*                                                                        */
8723 /*  RELEASE HISTORY                                                       */
8724 /*                                                                        */
8725 /*    DATE              NAME                      DESCRIPTION             */
8726 /*                                                                        */
8727 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8728 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8729 /*                                            resulting in version 6.1    */
8730 /*                                                                        */
8731 /**************************************************************************/
_nx_http_server_gmt_callback_set(NX_HTTP_SERVER * server_ptr,VOID (* gmt_get)(NX_HTTP_SERVER_DATE *))8732 UINT  _nx_http_server_gmt_callback_set(NX_HTTP_SERVER *server_ptr, VOID (*gmt_get)(NX_HTTP_SERVER_DATE *))
8733 {
8734 
8735 TX_INTERRUPT_SAVE_AREA
8736 
8737     /* Lockout interrupts.  */
8738     TX_DISABLE
8739 
8740     /* Set the function pointer. */
8741     server_ptr -> nx_http_server_gmt_get = gmt_get;
8742 
8743     /* Restore interrupts.  */
8744     TX_RESTORE
8745 
8746     return NX_SUCCESS;
8747 }
8748 
8749 
8750 /**************************************************************************/
8751 /*                                                                        */
8752 /*  FUNCTION                                               RELEASE        */
8753 /*                                                                        */
8754 /*    _nxe_http_server_cache_info_callback_set            PORTABLE C      */
8755 /*                                                           6.1          */
8756 /*  AUTHOR                                                                */
8757 /*                                                                        */
8758 /*    Yuxin Zhou, Microsoft Corporation                                   */
8759 /*                                                                        */
8760 /*  DESCRIPTION                                                           */
8761 /*                                                                        */
8762 /*    This function checks error for setting cache info callback function.*/
8763 /*                                                                        */
8764 /*  INPUT                                                                 */
8765 /*                                                                        */
8766 /*    server_ptr                            Pointer to HTTP server        */
8767 /*    cache_info_get                        Pointer to application's      */
8768 /*                                            cache information function  */
8769 /*                                                                        */
8770 /*  OUTPUT                                                                */
8771 /*                                                                        */
8772 /*    status                                Completion status             */
8773 /*                                                                        */
8774 /*  CALLS                                                                 */
8775 /*                                                                        */
8776 /*    _nx_http_server_cache_info_callback_set                             */
8777 /*                                                                        */
8778 /*  CALLED BY                                                             */
8779 /*                                                                        */
8780 /*    Application Code                                                    */
8781 /*                                                                        */
8782 /*  RELEASE HISTORY                                                       */
8783 /*                                                                        */
8784 /*    DATE              NAME                      DESCRIPTION             */
8785 /*                                                                        */
8786 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8787 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8788 /*                                            resulting in version 6.1    */
8789 /*                                                                        */
8790 /**************************************************************************/
_nxe_http_server_cache_info_callback_set(NX_HTTP_SERVER * server_ptr,UINT (* cache_info_get)(CHAR *,UINT *,NX_HTTP_SERVER_DATE *))8791 UINT  _nxe_http_server_cache_info_callback_set(NX_HTTP_SERVER *server_ptr, UINT (*cache_info_get)(CHAR *, UINT *, NX_HTTP_SERVER_DATE *))
8792 {
8793 
8794     /* Check for invalid input pointers.  */
8795     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) || (cache_info_get == NX_NULL))
8796         return(NX_PTR_ERROR);
8797 
8798     /* Send internal. */
8799     return _nx_http_server_cache_info_callback_set(server_ptr, cache_info_get);
8800 }
8801 
8802 
8803 /**************************************************************************/
8804 /*                                                                        */
8805 /*  FUNCTION                                               RELEASE        */
8806 /*                                                                        */
8807 /*    _nx_http_server_cache_info_callback_set             PORTABLE C      */
8808 /*                                                           6.1          */
8809 /*  AUTHOR                                                                */
8810 /*                                                                        */
8811 /*    Yuxin Zhou, Microsoft Corporation                                   */
8812 /*                                                                        */
8813 /*  DESCRIPTION                                                           */
8814 /*                                                                        */
8815 /*    This function sets cache info callback function.                    */
8816 /*                                                                        */
8817 /*    Note: The string length of resource in cache_info_get is limited by */
8818 /*    NX_HTTP_MAX_RESOURCE.                                               */
8819 /*                                                                        */
8820 /*  INPUT                                                                 */
8821 /*                                                                        */
8822 /*    server_ptr                            Pointer to HTTP server        */
8823 /*    cache_info_get                        Pointer to application's      */
8824 /*                                            cache information function  */
8825 /*                                                                        */
8826 /*  OUTPUT                                                                */
8827 /*                                                                        */
8828 /*    status                                Completion status             */
8829 /*                                                                        */
8830 /*  CALLS                                                                 */
8831 /*                                                                        */
8832 /*                                                                        */
8833 /*  CALLED BY                                                             */
8834 /*                                                                        */
8835 /*    Application Code                                                    */
8836 /*                                                                        */
8837 /*  RELEASE HISTORY                                                       */
8838 /*                                                                        */
8839 /*    DATE              NAME                      DESCRIPTION             */
8840 /*                                                                        */
8841 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8842 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8843 /*                                            resulting in version 6.1    */
8844 /*                                                                        */
8845 /**************************************************************************/
_nx_http_server_cache_info_callback_set(NX_HTTP_SERVER * server_ptr,UINT (* cache_info_get)(CHAR *,UINT *,NX_HTTP_SERVER_DATE *))8846 UINT  _nx_http_server_cache_info_callback_set(NX_HTTP_SERVER *server_ptr, UINT (*cache_info_get)(CHAR *, UINT *, NX_HTTP_SERVER_DATE *))
8847 {
8848 
8849 TX_INTERRUPT_SAVE_AREA
8850 
8851     /* Lockout interrupts.  */
8852     TX_DISABLE
8853 
8854     /* Set the function pointer. */
8855     server_ptr -> nx_http_server_cache_info_get = cache_info_get;
8856 
8857     /* Restore interrupts.  */
8858     TX_RESTORE
8859 
8860     return NX_SUCCESS;
8861 }
8862 
8863 
8864 /**************************************************************************/
8865 /*                                                                        */
8866 /*  FUNCTION                                               RELEASE        */
8867 /*                                                                        */
8868 /*    _nx_http_server_date_to_string                      PORTABLE C      */
8869 /*                                                           6.1          */
8870 /*  AUTHOR                                                                */
8871 /*                                                                        */
8872 /*    Yuxin Zhou, Microsoft Corporation                                   */
8873 /*                                                                        */
8874 /*  DESCRIPTION                                                           */
8875 /*                                                                        */
8876 /*    This function converts from date to string.                         */
8877 /*                                                                        */
8878 /*  INPUT                                                                 */
8879 /*                                                                        */
8880 /*    date                                  Pointer to HTTP date          */
8881 /*    string                                Pointer to output buffer      */
8882 /*                                                                        */
8883 /*  OUTPUT                                                                */
8884 /*                                                                        */
8885 /*    status                                Completion status             */
8886 /*                                                                        */
8887 /*  CALLS                                                                 */
8888 /*                                                                        */
8889 /*    _nx_http_server_date_convert                                        */
8890 /*                                                                        */
8891 /*  CALLED BY                                                             */
8892 /*                                                                        */
8893 /*    _nx_http_server_get_process                                         */
8894 /*    _nx_http_server_generate_response_header                            */
8895 /*                                                                        */
8896 /*  RELEASE HISTORY                                                       */
8897 /*                                                                        */
8898 /*    DATE              NAME                      DESCRIPTION             */
8899 /*                                                                        */
8900 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8901 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8902 /*                                            resulting in version 6.1    */
8903 /*                                                                        */
8904 /**************************************************************************/
_nx_http_server_date_to_string(NX_HTTP_SERVER_DATE * date,CHAR * string)8905 UINT  _nx_http_server_date_to_string(NX_HTTP_SERVER_DATE *date, CHAR *string)
8906 {
8907 
8908 UINT index = 0;
8909 
8910     /* RDC1122-date. */
8911     /* Append weekday. */
8912     string[index++] = *(_nx_http_server_weekday[date -> nx_http_server_weekday]);
8913     string[index++] = *(_nx_http_server_weekday[date -> nx_http_server_weekday] + 1);
8914     string[index++] = *(_nx_http_server_weekday[date -> nx_http_server_weekday] + 2);
8915     string[index++] = ',';
8916     string[index++] = ' ';
8917 
8918     /* Convert and append day. */
8919     _nx_http_server_date_convert(date -> nx_http_server_day, 2, &string[index]);
8920     index += 2;
8921     string[index++] = ' ';
8922 
8923     /* Append month. */
8924     string[index++] = *(_nx_http_server_month[date -> nx_http_server_month]);
8925     string[index++] = *(_nx_http_server_month[date -> nx_http_server_month] + 1);
8926     string[index++] = *(_nx_http_server_month[date -> nx_http_server_month] + 2);
8927     string[index++] = ' ';
8928 
8929     /* Convert and append year. */
8930     _nx_http_server_date_convert(date -> nx_http_server_year, 4, &string[index]);
8931     index += 4;
8932     string[index++] = ' ';
8933 
8934     /* Convert and append hour. */
8935     _nx_http_server_date_convert(date -> nx_http_server_hour, 2, &string[index]);
8936     index += 2;
8937     string[index++] = ':';
8938 
8939     /* Convert and append minute. */
8940     _nx_http_server_date_convert(date -> nx_http_server_minute, 2, &string[index]);
8941     index += 2;
8942     string[index++] = ':';
8943 
8944     /* Convert and append second. */
8945     _nx_http_server_date_convert(date -> nx_http_server_second, 2, &string[index]);
8946     index += 2;
8947     string[index++] = ' ';
8948     string[index++] = 'G';
8949     string[index++] = 'M';
8950     string[index++] = 'T';
8951 
8952     return index;
8953 }
8954 
8955 
8956 /**************************************************************************/
8957 /*                                                                        */
8958 /*  FUNCTION                                               RELEASE        */
8959 /*                                                                        */
8960 /*    _nx_http_server_date_convert                        PORTABLE C      */
8961 /*                                                           6.1          */
8962 /*  AUTHOR                                                                */
8963 /*                                                                        */
8964 /*    Yuxin Zhou, Microsoft Corporation                                   */
8965 /*                                                                        */
8966 /*  DESCRIPTION                                                           */
8967 /*                                                                        */
8968 /*    This function converts a date from number to string.                */
8969 /*                                                                        */
8970 /*  INPUT                                                                 */
8971 /*                                                                        */
8972 /*    date                                  The number to convert         */
8973 /*    count                                 Digital count for string      */
8974 /*    string                                Pointer to output buffer      */
8975 /*                                                                        */
8976 /*  OUTPUT                                                                */
8977 /*                                                                        */
8978 /*    None                                                                */
8979 /*                                                                        */
8980 /*  CALLS                                                                 */
8981 /*                                                                        */
8982 /*                                                                        */
8983 /*  CALLED BY                                                             */
8984 /*                                                                        */
8985 /*    _nx_http_server_date_to_string                                      */
8986 /*                                                                        */
8987 /*  RELEASE HISTORY                                                       */
8988 /*                                                                        */
8989 /*    DATE              NAME                      DESCRIPTION             */
8990 /*                                                                        */
8991 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8992 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8993 /*                                            resulting in version 6.1    */
8994 /*                                                                        */
8995 /**************************************************************************/
_nx_http_server_date_convert(UINT date,UINT count,CHAR * string)8996 VOID  _nx_http_server_date_convert(UINT date, UINT count, CHAR *string)
8997 {
8998 
8999 UINT    digit;
9000 
9001     /* Initialize all 4 bytes to digit 0. */
9002     *((ULONG*)string) = 0x30303030;
9003     string[count] = 0;
9004 
9005     /* Loop to convert the number to ASCII.  */
9006     while(count > 0)
9007     {
9008         count--;
9009 
9010         /* Compute the next decimal digit.  */
9011         digit =  date % 10;
9012 
9013         /* Update the input date.  */
9014         date =  date / 10;
9015 
9016         /* Store the new digit in ASCII form.  */
9017         string[count] =  (CHAR) (digit + 0x30);
9018     }
9019 }
9020 
9021 
9022 /**************************************************************************/
9023 /*                                                                        */
9024 /*  FUNCTION                                               RELEASE        */
9025 /*                                                                        */
9026 /*    _nxe_http_server_mime_maps_additional_set           PORTABLE C      */
9027 /*                                                           6.1          */
9028 /*  AUTHOR                                                                */
9029 /*                                                                        */
9030 /*    Yuxin Zhou, Microsoft Corporation                                   */
9031 /*                                                                        */
9032 /*  DESCRIPTION                                                           */
9033 /*                                                                        */
9034 /*    This function checks error for setting additional MIME maps.        */
9035 /*                                                                        */
9036 /*  INPUT                                                                 */
9037 /*                                                                        */
9038 /*    server_ptr                            Pointer to HTTP server        */
9039 /*    mime_maps                             Pointer MIME map array        */
9040 /*    mime_maps_num                         Number of MIME map array      */
9041 /*                                                                        */
9042 /*  OUTPUT                                                                */
9043 /*                                                                        */
9044 /*    status                                Completion status             */
9045 /*                                                                        */
9046 /*  CALLS                                                                 */
9047 /*                                                                        */
9048 /*    _nx_http_server_mime_maps_additional_set                            */
9049 /*                                                                        */
9050 /*  CALLED BY                                                             */
9051 /*                                                                        */
9052 /*    Application Code                                                    */
9053 /*                                                                        */
9054 /*  RELEASE HISTORY                                                       */
9055 /*                                                                        */
9056 /*    DATE              NAME                      DESCRIPTION             */
9057 /*                                                                        */
9058 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9059 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9060 /*                                            resulting in version 6.1    */
9061 /*                                                                        */
9062 /**************************************************************************/
_nxe_http_server_mime_maps_additional_set(NX_HTTP_SERVER * server_ptr,NX_HTTP_SERVER_MIME_MAP * mime_maps,UINT mime_maps_num)9063 UINT  _nxe_http_server_mime_maps_additional_set(NX_HTTP_SERVER *server_ptr, NX_HTTP_SERVER_MIME_MAP *mime_maps, UINT mime_maps_num)
9064 {
9065 
9066     /* Check for invalid input pointers.  */
9067     if ((server_ptr == NX_NULL) || (server_ptr -> nx_http_server_id != NXD_HTTP_SERVER_ID) || (mime_maps == NX_NULL))
9068         return(NX_PTR_ERROR);
9069 
9070     /* Send internal. */
9071     return _nx_http_server_mime_maps_additional_set(server_ptr, mime_maps, mime_maps_num);
9072 }
9073 
9074 
9075 /**************************************************************************/
9076 /*                                                                        */
9077 /*  FUNCTION                                               RELEASE        */
9078 /*                                                                        */
9079 /*    _nx_http_server_mime_maps_additional_set            PORTABLE C      */
9080 /*                                                           6.1          */
9081 /*  AUTHOR                                                                */
9082 /*                                                                        */
9083 /*    Yuxin Zhou, Microsoft Corporation                                   */
9084 /*                                                                        */
9085 /*  DESCRIPTION                                                           */
9086 /*                                                                        */
9087 /*    This function sets additional MIME maps.                            */
9088 /*                                                                        */
9089 /*  INPUT                                                                 */
9090 /*                                                                        */
9091 /*    server_ptr                            Pointer to HTTP server        */
9092 /*    mime_maps                             Pointer MIME map array        */
9093 /*    mime_maps_num                         Number of MIME map array      */
9094 /*                                                                        */
9095 /*  OUTPUT                                                                */
9096 /*                                                                        */
9097 /*    status                                Completion status             */
9098 /*                                                                        */
9099 /*  CALLS                                                                 */
9100 /*                                                                        */
9101 /*                                                                        */
9102 /*  CALLED BY                                                             */
9103 /*                                                                        */
9104 /*    Application Code                                                    */
9105 /*                                                                        */
9106 /*  RELEASE HISTORY                                                       */
9107 /*                                                                        */
9108 /*    DATE              NAME                      DESCRIPTION             */
9109 /*                                                                        */
9110 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9111 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9112 /*                                            resulting in version 6.1    */
9113 /*                                                                        */
9114 /**************************************************************************/
_nx_http_server_mime_maps_additional_set(NX_HTTP_SERVER * server_ptr,NX_HTTP_SERVER_MIME_MAP * mime_maps,UINT mime_maps_num)9115 UINT  _nx_http_server_mime_maps_additional_set(NX_HTTP_SERVER *server_ptr, NX_HTTP_SERVER_MIME_MAP *mime_maps, UINT mime_maps_num)
9116 {
9117 
9118 TX_INTERRUPT_SAVE_AREA
9119 
9120     /* Lockout interrupts.  */
9121     TX_DISABLE
9122 
9123     /* Set the mime maps. */
9124     server_ptr -> nx_http_server_mime_maps_additional = mime_maps;
9125     server_ptr -> nx_http_server_mime_maps_additional_num = mime_maps_num;
9126 
9127     /* Restore interrupts.  */
9128     TX_RESTORE
9129 
9130     return NX_SUCCESS;
9131 }
9132 
9133 
9134 /**************************************************************************/
9135 /*                                                                        */
9136 /*  FUNCTION                                               RELEASE        */
9137 /*                                                                        */
9138 /*    _nxe_http_server_digest_authenticate_notify_set     PORTABLE C      */
9139 /*                                                           6.1          */
9140 /*  AUTHOR                                                                */
9141 /*                                                                        */
9142 /*    Yuxin Zhou, Microsoft Corporation                                   */
9143 /*                                                                        */
9144 /*  DESCRIPTION                                                           */
9145 /*                                                                        */
9146 /*    This function performs error checking for service to set digest     */
9147 /*    authenticate callback function.                                     */
9148 /*                                                                        */
9149 /*  INPUT                                                                 */
9150 /*                                                                        */
9151 /*    http_server_ptr                       Pointer to HTTP server        */
9152 /*    digest_authenticate_callback          Pointer to application's      */
9153 /*                                          digest authenticate callback  */
9154 /*                                          function                      */
9155 /*                                                                        */
9156 /*  OUTPUT                                                                */
9157 /*                                                                        */
9158 /*    status                                Completion status             */
9159 /*                                                                        */
9160 /*  CALLS                                                                 */
9161 /*                                                                        */
9162 /*    _nx_http_server_digest_authenticate_notify_set                      */
9163 /*                                                                        */
9164 /*  CALLED BY                                                             */
9165 /*                                                                        */
9166 /*    Application Code                                                    */
9167 /*                                                                        */
9168 /*  RELEASE HISTORY                                                       */
9169 /*                                                                        */
9170 /*    DATE              NAME                      DESCRIPTION             */
9171 /*                                                                        */
9172 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9173 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9174 /*                                            resulting in version 6.1    */
9175 /*                                                                        */
9176 /**************************************************************************/
_nxe_http_server_digest_authenticate_notify_set(NX_HTTP_SERVER * http_server_ptr,UINT (* digest_authenticate_callback)(NX_HTTP_SERVER * server_ptr,CHAR * name_ptr,CHAR * realm_ptr,CHAR * password_ptr,CHAR * method,CHAR * authorization_uri,CHAR * authorization_nc,CHAR * authorization_cnonce))9177 UINT _nxe_http_server_digest_authenticate_notify_set(NX_HTTP_SERVER *http_server_ptr,
9178                                                      UINT (*digest_authenticate_callback)(NX_HTTP_SERVER *server_ptr, CHAR *name_ptr,
9179                                                      CHAR *realm_ptr, CHAR *password_ptr, CHAR *method,
9180                                                      CHAR *authorization_uri, CHAR *authorization_nc,
9181                                                      CHAR *authorization_cnonce))
9182 {
9183 
9184     /* Check for invalid input pointers.  */
9185     if ((http_server_ptr == NX_NULL) || (digest_authenticate_callback == NX_NULL))
9186     {
9187         return(NX_PTR_ERROR);
9188     }
9189 
9190     return(_nx_http_server_digest_authenticate_notify_set(http_server_ptr, digest_authenticate_callback));
9191 }
9192 
9193 
9194 /**************************************************************************/
9195 /*                                                                        */
9196 /*  FUNCTION                                               RELEASE        */
9197 /*                                                                        */
9198 /*    _nx_http_server_digest_authenticate_notify_set      PORTABLE C      */
9199 /*                                                           6.1          */
9200 /*  AUTHOR                                                                */
9201 /*                                                                        */
9202 /*    Yuxin Zhou, Microsoft Corporation                                   */
9203 /*                                                                        */
9204 /*  DESCRIPTION                                                           */
9205 /*                                                                        */
9206 /*    This function sets digest authenticate callback function.           */
9207 /*                                                                        */
9208 /*    Note: The string length of realm_ptr, name_ptr, and password_ptr in */
9209 /*    digest_authenticate_callback is checked internally. The method,     */
9210 /*    authorization_uri, authorization_nc and authorization_cnonce in     */
9211 /*    digest_authenticate_callback are built internally.                  */
9212 /*                                                                        */
9213 /*  INPUT                                                                 */
9214 /*                                                                        */
9215 /*    http_server_ptr                       Pointer to HTTP server        */
9216 /*    digest_authenticate_callback          Pointer to application's      */
9217 /*                                          digest authenticate callback  */
9218 /*                                          function                      */
9219 /*                                                                        */
9220 /*  OUTPUT                                                                */
9221 /*                                                                        */
9222 /*    status                                Completion status             */
9223 /*                                                                        */
9224 /*  CALLS                                                                 */
9225 /*                                                                        */
9226 /*                                                                        */
9227 /*  CALLED BY                                                             */
9228 /*                                                                        */
9229 /*    Application Code                                                    */
9230 /*                                                                        */
9231 /*  RELEASE HISTORY                                                       */
9232 /*                                                                        */
9233 /*    DATE              NAME                      DESCRIPTION             */
9234 /*                                                                        */
9235 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9236 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9237 /*                                            resulting in version 6.1    */
9238 /*                                                                        */
9239 /**************************************************************************/
_nx_http_server_digest_authenticate_notify_set(NX_HTTP_SERVER * http_server_ptr,UINT (* digest_authenticate_callback)(NX_HTTP_SERVER * server_ptr,CHAR * name_ptr,CHAR * realm_ptr,CHAR * password_ptr,CHAR * method,CHAR * authorization_uri,CHAR * authorization_nc,CHAR * authorization_cnonce))9240 UINT _nx_http_server_digest_authenticate_notify_set(NX_HTTP_SERVER *http_server_ptr,
9241                                                     UINT (*digest_authenticate_callback)(NX_HTTP_SERVER *server_ptr, CHAR *name_ptr,
9242                                                     CHAR *realm_ptr, CHAR *password_ptr, CHAR *method,
9243                                                     CHAR *authorization_uri, CHAR *authorization_nc,
9244                                                     CHAR *authorization_cnonce))
9245 {
9246 
9247 #ifdef  NX_HTTP_DIGEST_ENABLE
9248     http_server_ptr -> nx_http_server_digest_authenticate_callback = digest_authenticate_callback;
9249 
9250     return(NX_SUCCESS);
9251 #else
9252     NX_PARAMETER_NOT_USED(http_server_ptr);
9253     NX_PARAMETER_NOT_USED(digest_authenticate_callback);
9254 
9255     return(NX_NOT_SUPPORTED);
9256 #endif
9257 }
9258 
9259 
9260 /**************************************************************************/
9261 /*                                                                        */
9262 /*  FUNCTION                                               RELEASE        */
9263 /*                                                                        */
9264 /*    _nxe_http_server_authentication_check_set           PORTABLE C      */
9265 /*                                                           6.1          */
9266 /*  AUTHOR                                                                */
9267 /*                                                                        */
9268 /*    Yuxin Zhou, Microsoft Corporation                                   */
9269 /*                                                                        */
9270 /*  DESCRIPTION                                                           */
9271 /*                                                                        */
9272 /*    This function checks errors for setting authentication checking     */
9273 /*    callback function.                                                  */
9274 /*                                                                        */
9275 /*                                                                        */
9276 /*  INPUT                                                                 */
9277 /*                                                                        */
9278 /*    http_server_ptr                       Pointer to HTTP server        */
9279 /*    authentication_check_extended         Pointer to application's      */
9280 /*                                            authentication checking     */
9281 /*                                                                        */
9282 /*  OUTPUT                                                                */
9283 /*                                                                        */
9284 /*    status                                Completion status             */
9285 /*                                                                        */
9286 /*  CALLS                                                                 */
9287 /*                                                                        */
9288 /*    _nx_http_server_authentication_check_set                            */
9289 /*                                                                        */
9290 /*  CALLED BY                                                             */
9291 /*                                                                        */
9292 /*    Application Code                                                    */
9293 /*                                                                        */
9294 /*  RELEASE HISTORY                                                       */
9295 /*                                                                        */
9296 /*    DATE              NAME                      DESCRIPTION             */
9297 /*                                                                        */
9298 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9299 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9300 /*                                            resulting in version 6.1    */
9301 /*                                                                        */
9302 /**************************************************************************/
_nxe_http_server_authentication_check_set(NX_HTTP_SERVER * http_server_ptr,UINT (* authentication_check_extended)(NX_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,UINT * name_length,CHAR ** password,UINT * password_length,CHAR ** realm,UINT * realm_length))9303 UINT  _nxe_http_server_authentication_check_set(NX_HTTP_SERVER *http_server_ptr,
9304                                                 UINT (*authentication_check_extended)(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, UINT *name_length, CHAR **password, UINT *password_length, CHAR **realm, UINT *realm_length))
9305 {
9306 UINT status;
9307 
9308     /* Check for invalid input pointers.  */
9309     if ((http_server_ptr == NX_NULL) || (authentication_check_extended == NX_NULL))
9310     {
9311         return(NX_PTR_ERROR);
9312     }
9313 
9314     /* Check for appropriate caller.  */
9315     NX_THREADS_ONLY_CALLER_CHECKING
9316 
9317     /* Call the actual authentication checking set function.  */
9318     status= _nx_http_server_authentication_check_set(http_server_ptr, authentication_check_extended);
9319 
9320     /* Return staus.  */
9321     return(status);
9322 }
9323 
9324 
9325 /**************************************************************************/
9326 /*                                                                        */
9327 /*  FUNCTION                                               RELEASE        */
9328 /*                                                                        */
9329 /*    _nx_http_server_authentication_check_set            PORTABLE C      */
9330 /*                                                           6.1          */
9331 /*  AUTHOR                                                                */
9332 /*                                                                        */
9333 /*    Yuxin Zhou, Microsoft Corporation                                   */
9334 /*                                                                        */
9335 /*  DESCRIPTION                                                           */
9336 /*                                                                        */
9337 /*    This function sets the callback function of authentication checking.*/
9338 /*                                                                        */
9339 /*    Note: The strings of name, password and realm must be               */
9340 /*    NULL-terminated and length of each string matches the length        */
9341 /*    specified in the argument list.                                     */
9342 /*                                                                        */
9343 /*                                                                        */
9344 /*  INPUT                                                                 */
9345 /*                                                                        */
9346 /*    http_server_ptr                       Pointer to HTTP server        */
9347 /*    authentication_check_extended         Pointer to application's      */
9348 /*                                            authentication checking     */
9349 /*                                                                        */
9350 /*  OUTPUT                                                                */
9351 /*                                                                        */
9352 /*    status                                Completion status             */
9353 /*                                                                        */
9354 /*  CALLS                                                                 */
9355 /*                                                                        */
9356 /*    None                                                                */
9357 /*                                                                        */
9358 /*  CALLED BY                                                             */
9359 /*                                                                        */
9360 /*    Application Code                                                    */
9361 /*                                                                        */
9362 /*  RELEASE HISTORY                                                       */
9363 /*                                                                        */
9364 /*    DATE              NAME                      DESCRIPTION             */
9365 /*                                                                        */
9366 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9367 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9368 /*                                            resulting in version 6.1    */
9369 /*                                                                        */
9370 /**************************************************************************/
_nx_http_server_authentication_check_set(NX_HTTP_SERVER * http_server_ptr,UINT (* authentication_check_extended)(NX_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,UINT * name_length,CHAR ** password,UINT * password_length,CHAR ** realm,UINT * realm_length))9371 UINT  _nx_http_server_authentication_check_set(NX_HTTP_SERVER *http_server_ptr,
9372                                                         UINT (*authentication_check_extended)(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, UINT *name_length, CHAR **password, UINT *password_length, CHAR **realm, UINT *realm_length))
9373 {
9374 
9375     /* Set the extended authentication checking function.  */
9376     http_server_ptr -> nx_http_server_authentication_check_extended = authentication_check_extended;
9377 
9378     /* Return success.  */
9379     return(NX_SUCCESS);
9380 }
9381 
9382