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