1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** NetX Web Component                                                    */
17 /**                                                                       */
18 /**   Hypertext Transfer Protocol (HTTP)                                  */
19 /**   Hypertext Transfer Protocol Secure (HTTPS using TLS)                */
20 /**                                                                       */
21 /**************************************************************************/
22 /**************************************************************************/
23 
24 #define NX_WEB_HTTP_SERVER_SOURCE_CODE
25 
26 
27 /* Force error checking to be disabled in this module */
28 
29 #ifndef NX_DISABLE_ERROR_CHECKING
30 #define NX_DISABLE_ERROR_CHECKING
31 #endif
32 
33 /* Include necessary system files.  */
34 
35 #include    "nx_api.h"
36 #include    "nx_ip.h"
37 #include    "nx_web_http_server.h"
38 
39 #include    "stdio.h"
40 #include    "string.h"
41 #ifdef NX_WEB_HTTP_DIGEST_ENABLE
42 #include   "nx_md5.h"
43 #endif
44 
45 #if defined(NX_WEB_HTTP_SERVER_OMIT_CONTENT_LENGTH) && !defined(NX_WEB_HTTP_KEEPALIVE_DISABLE)
46 #error "Content length needed when keepalive is enabled"
47 #endif /* NX_WEB_HTTP_SERVER_OMIT_CONTENT_LENGTH */
48 
49 #ifdef  NX_WEB_HTTP_DIGEST_ENABLE
50 
51 /* Use for mapping random nonces to printable characters.  */
52 static CHAR _nx_web_http_server_base64_array[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
53 #endif
54 
55 /* Define date strings. */
56 const CHAR _nx_web_http_server_weekday[][3] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
57 const CHAR _nx_web_http_server_month[][3] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
58 
59 /* Define basic MIME maps. */
60 static NX_WEB_HTTP_SERVER_MIME_MAP _nx_web_http_server_mime_maps[] =
61 {
62     {"html",     "text/html"},
63     {"htm",      "text/html"},
64     {"txt",      "text/plain"},
65     {"gif",      "image/gif"},
66     {"jpg",      "image/jpeg"},
67     {"ico",      "image/x-icon"},
68 };
69 
70 
71 /* Create two arrays to hold encoded and decoded username/password data. */
72 static CHAR  authorization_request[NX_WEB_HTTP_MAX_STRING + 1];
73 static CHAR  authorization_decoded[NX_WEB_HTTP_MAX_NAME + NX_WEB_HTTP_MAX_PASSWORD + 2];
74 
75 /* Bring in externs for caller checking code.  */
76 
77 NX_CALLER_CHECKING_EXTERNS
78 
79 
80 /**************************************************************************/
81 /*                                                                        */
82 /*  FUNCTION                                               RELEASE        */
83 /*                                                                        */
84 /*    _nxe_web_http_server_content_get                    PORTABLE C      */
85 /*                                                           6.1          */
86 /*  AUTHOR                                                                */
87 /*                                                                        */
88 /*    Yuxin Zhou, Microsoft Corporation                                   */
89 /*                                                                        */
90 /*  DESCRIPTION                                                           */
91 /*                                                                        */
92 /*    This function checks for errors in the HTTP content get call.       */
93 /*                                                                        */
94 /*                                                                        */
95 /*  INPUT                                                                 */
96 /*                                                                        */
97 /*    server_ptr                            Pointer to HTTP server        */
98 /*    packet_ptr                            Pointer to HTTP request packet*/
99 /*    byte_offset                           Byte offset into content      */
100 /*    destination_ptr                       Pointer to content destination*/
101 /*    destination_size                      Maximum size of destination   */
102 /*    actual_size                           Actual amount of content      */
103 /*                                                                        */
104 /*  OUTPUT                                                                */
105 /*                                                                        */
106 /*    status                                Completion status             */
107 /*                                                                        */
108 /*  CALLS                                                                 */
109 /*                                                                        */
110 /*    _nx_web_http_server_content_get       Actual server content get call*/
111 /*                                                                        */
112 /*  CALLED BY                                                             */
113 /*                                                                        */
114 /*    Application Code                                                    */
115 /*                                                                        */
116 /*  RELEASE HISTORY                                                       */
117 /*                                                                        */
118 /*    DATE              NAME                      DESCRIPTION             */
119 /*                                                                        */
120 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
121 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
122 /*                                            resulting in version 6.1    */
123 /*                                                                        */
124 /**************************************************************************/
_nxe_web_http_server_content_get(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,ULONG byte_offset,CHAR * destination_ptr,UINT destination_size,UINT * actual_size)125 UINT  _nxe_web_http_server_content_get(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, ULONG byte_offset, CHAR *destination_ptr, UINT destination_size, UINT *actual_size)
126 {
127 
128 UINT    status;
129 
130 
131     /* Check for invalid input pointers.  */
132     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
133         (packet_ptr == NX_NULL) || (destination_ptr == NX_NULL) || (actual_size == NX_NULL))
134         return(NX_PTR_ERROR);
135 
136     /* Check for appropriate caller.  */
137     NX_THREADS_ONLY_CALLER_CHECKING
138 
139     /* Call actual server content get function.  */
140     status =  _nx_web_http_server_content_get(server_ptr, packet_ptr, byte_offset, destination_ptr, destination_size, actual_size);
141 
142     /* Return completion status.  */
143     return(status);
144 }
145 
146 
147 /**************************************************************************/
148 /*                                                                        */
149 /*  FUNCTION                                               RELEASE        */
150 /*                                                                        */
151 /*    _nx_web_http_server_content_get                     PORTABLE C      */
152 /*                                                           6.1          */
153 /*  AUTHOR                                                                */
154 /*                                                                        */
155 /*    Yuxin Zhou, Microsoft Corporation                                   */
156 /*                                                                        */
157 /*  DESCRIPTION                                                           */
158 /*                                                                        */
159 /*    This function returns the user's specified portion of the HTTP      */
160 /*    content. Content is typically included in POST and PUT requests     */
161 /*    from the client. This routine is designed to be called from the     */
162 /*    application's request notify callback.                              */
163 /*                                                                        */
164 /*                                                                        */
165 /*  INPUT                                                                 */
166 /*                                                                        */
167 /*    server_ptr                            Pointer to HTTP server        */
168 /*    packet_ptr                            Pointer to HTTP request packet*/
169 /*    byte_offset                           Byte offset into content      */
170 /*    destination_ptr                       Pointer to content destination*/
171 /*    destination_size                      Maximum size of destination   */
172 /*    actual_size                           Actual amount of content      */
173 /*                                                                        */
174 /*  OUTPUT                                                                */
175 /*                                                                        */
176 /*    status                                Completion status             */
177 /*                                                                        */
178 /*  CALLS                                                                 */
179 /*                                                                        */
180 /*    _nx_web_http_server_content_get_extended                            */
181 /*                                          Get content data              */
182 /*                                                                        */
183 /*  CALLED BY                                                             */
184 /*                                                                        */
185 /*    Application Code                                                    */
186 /*                                                                        */
187 /*  RELEASE HISTORY                                                       */
188 /*                                                                        */
189 /*    DATE              NAME                      DESCRIPTION             */
190 /*                                                                        */
191 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
192 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
193 /*                                            resulting in version 6.1    */
194 /*                                                                        */
195 /**************************************************************************/
_nx_web_http_server_content_get(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,ULONG byte_offset,CHAR * destination_ptr,UINT destination_size,UINT * actual_size)196 UINT  _nx_web_http_server_content_get(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, ULONG byte_offset, CHAR *destination_ptr, UINT destination_size, UINT *actual_size)
197 {
198 UINT status;
199 
200     /* Get content data.  */
201     status = _nx_web_http_server_content_get_extended(server_ptr, packet_ptr, byte_offset, destination_ptr, destination_size, actual_size);
202 
203     return(status);
204 }
205 
206 
207 /**************************************************************************/
208 /*                                                                        */
209 /*  FUNCTION                                               RELEASE        */
210 /*                                                                        */
211 /*    _nxe_web_http_server_packet_content_find            PORTABLE C      */
212 /*                                                           6.1          */
213 /*  AUTHOR                                                                */
214 /*                                                                        */
215 /*    Yuxin Zhou, Microsoft Corporation                                   */
216 /*                                                                        */
217 /*  DESCRIPTION                                                           */
218 /*                                                                        */
219 /*    This function checks for errors in the HTTP packet content find     */
220 /*    call.                                                               */
221 /*                                                                        */
222 /*                                                                        */
223 /*  INPUT                                                                 */
224 /*                                                                        */
225 /*    server_ptr                            Pointer to HTTP server        */
226 /*    packet_ptr                            Pointer to pointer to the     */
227 /*                                            packet that contains the    */
228 /*                                            HTTP header                 */
229 /*    content_length                        Pointer to content length     */
230 /*                                                                        */
231 /*  OUTPUT                                                                */
232 /*                                                                        */
233 /*    status                                Completion status             */
234 /*                                                                        */
235 /*  CALLS                                                                 */
236 /*                                                                        */
237 /*    _nx_web_http_server_packet_content_find                             */
238 /*                                          Actual server packet content  */
239 /*                                            find call                   */
240 /*                                                                        */
241 /*  CALLED BY                                                             */
242 /*                                                                        */
243 /*    Application Code                                                    */
244 /*                                                                        */
245 /*  RELEASE HISTORY                                                       */
246 /*                                                                        */
247 /*    DATE              NAME                      DESCRIPTION             */
248 /*                                                                        */
249 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
250 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
251 /*                                            resulting in version 6.1    */
252 /*                                                                        */
253 /**************************************************************************/
_nxe_web_http_server_packet_content_find(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr,ULONG * content_length)254 UINT  _nxe_web_http_server_packet_content_find(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr, ULONG *content_length)
255 {
256 
257 
258     /* Check for invalid packet pointer.  */
259     if((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
260        (packet_ptr == NX_NULL) || (*packet_ptr == NX_NULL) || (content_length == NX_NULL))
261         return(NX_PTR_ERROR);
262 
263     /* Call actual server content length get function.  */
264     return(_nx_web_http_server_packet_content_find(server_ptr, packet_ptr, content_length));
265 
266 }
267 
268 /**************************************************************************/
269 /*                                                                        */
270 /*  FUNCTION                                               RELEASE        */
271 /*                                                                        */
272 /*    _nx_web_http_server_packet_content_find             PORTABLE C      */
273 /*                                                           6.1.7        */
274 /*  AUTHOR                                                                */
275 /*                                                                        */
276 /*    Yuxin Zhou, Microsoft Corporation                                   */
277 /*                                                                        */
278 /*  DESCRIPTION                                                           */
279 /*                                                                        */
280 /*    This function finds the content length specified in the HTTP        */
281 /*    header, and move the nx_packet_prepend_ptr to the beginning of      */
282 /*    the content.  If the beginning of the content is not in the packet, */
283 /*    this function attempts to read the HTTP server socket for the       */
284 /*    next packet.                                                        */
285 /*                                                                        */
286 /*                                                                        */
287 /*  INPUT                                                                 */
288 /*                                                                        */
289 /*    server_ptr                            Pointer to HTTP server        */
290 /*    packet_ptr                            Pointer to pointer to the     */
291 /*                                            packet that contains the    */
292 /*                                            HTTP header                 */
293 /*    content_length                        Pointer to content length     */
294 /*                                                                        */
295 /*  OUTPUT                                                                */
296 /*                                                                        */
297 /*    status                                Completion status             */
298 /*                                                                        */
299 /*  CALLS                                                                 */
300 /*                                                                        */
301 /*    _nx_web_http_server_content_length_get                              */
302 /*                                          Get content length            */
303 /*    _nx_web_http_server_packet_get        Receive another packet        */
304 /*    _nx_web_http_server_calculate_content_offset                        */
305 /*                                          Pickup content offset         */
306 /*    nx_packet_allocate                    Allocate a new packet         */
307 /*    nx_packet_release                     Release the packet            */
308 /*                                                                        */
309 /*  CALLED BY                                                             */
310 /*                                                                        */
311 /*    Application Code                                                    */
312 /*                                                                        */
313 /*  RELEASE HISTORY                                                       */
314 /*                                                                        */
315 /*    DATE              NAME                      DESCRIPTION             */
316 /*                                                                        */
317 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
318 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
319 /*                                            resulting in version 6.1    */
320 /*  06-02-2021     Yuxin Zhou               Modified comment(s),          */
321 /*                                            fixed compiler warnings,    */
322 /*                                            resulting in version 6.1.7  */
323 /*                                                                        */
324 /**************************************************************************/
_nx_web_http_server_packet_content_find(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr,ULONG * content_length)325 UINT  _nx_web_http_server_packet_content_find(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr, ULONG *content_length)
326 {
327 
328 ULONG       get_offset;
329 UINT        status;
330 ULONG       length = 0;
331 UINT        packet_chunked;
332 NX_PACKET  *header_packet_ptr;
333 NX_PACKET  *new_packet_ptr;
334 ULONG       temp_offset;
335 
336     /* Check if the packet is chunked.  */
337     packet_chunked = _nx_web_http_server_chunked_check(*packet_ptr);
338 
339     /* If the packet isn't chunked.  */
340     if (!packet_chunked)
341     {
342 
343         /* Get the content length header information. */
344         status = _nx_web_http_server_content_length_get(*packet_ptr, &length);
345 
346         if (status != NX_SUCCESS)
347         {
348             return(status);
349         }
350     }
351 
352     /* Get the content offset.  */
353     get_offset = (ULONG)_nx_web_http_server_calculate_content_offset(*packet_ptr);
354 
355     /* Check packet length.  */
356     if((*packet_ptr) -> nx_packet_length == get_offset)
357     {
358 
359         /* If the packet doesn't contain any content, need to receive a new packet.  */
360 
361         /* If the received request packet is chunked.  */
362         if (server_ptr -> nx_web_http_server_request_chunked)
363         {
364 
365             /* Initialize the request packet pointer and remaining size for processing chunked packet.  */
366             server_ptr -> nx_web_http_server_request_packet = NX_NULL;
367             server_ptr -> nx_web_http_server_chunked_request_remaining_size = 0;
368         }
369 
370         /* Make the receive call to obtain the next packet. */
371         status = _nx_web_http_server_packet_get(server_ptr, packet_ptr);
372 
373         if(status != NX_SUCCESS)
374         {
375             return(NX_WEB_HTTP_TIMEOUT);
376         }
377 
378     }
379     else
380     {
381 
382         /* Separate the HTTP header and content. Copy the content to a new packet.  */
383 
384         /* Remember the packet pointer and content offset.  */
385         header_packet_ptr = *packet_ptr;
386         temp_offset = get_offset;
387 
388 #ifndef NX_DISABLE_PACKET_CHAIN
389 
390         /* If the packet is chained, loop to find the end of the HTTP header.  */
391         while ((*packet_ptr) && (temp_offset > (ULONG)((*packet_ptr) -> nx_packet_append_ptr - (*packet_ptr) -> nx_packet_prepend_ptr)))
392         {
393             temp_offset -= (ULONG)((*packet_ptr) -> nx_packet_append_ptr - (*packet_ptr) -> nx_packet_prepend_ptr);
394             (*packet_ptr) = (*packet_ptr) -> nx_packet_next;
395         }
396 
397         /* Chack if packet is valid.  */
398         if ((*packet_ptr) == NX_NULL)
399         {
400             return(NX_WEB_HTTP_BAD_PACKET_LENGTH);
401         }
402 
403         /* If this packet contain no content, set next packet as the first packet of the content.  */
404         if (temp_offset == (ULONG)((*packet_ptr) -> nx_packet_append_ptr - (*packet_ptr) -> nx_packet_prepend_ptr))
405         {
406             new_packet_ptr = (*packet_ptr) -> nx_packet_next;
407         }
408         else
409         {
410 #endif
411 
412             /* Allocate a new packet to store content.  */
413             status = nx_packet_allocate(server_ptr -> nx_web_http_server_packet_pool_ptr,
414                                         &new_packet_ptr, 0, NX_WAIT_FOREVER);
415             if(status)
416             {
417                 return(status);
418             }
419 
420             /* Copy the content part to the new packet.  */
421             nx_packet_data_append(new_packet_ptr,
422                                   (*packet_ptr) -> nx_packet_prepend_ptr + temp_offset,
423                                   (ULONG)((*packet_ptr) -> nx_packet_append_ptr - (*packet_ptr) -> nx_packet_prepend_ptr) - temp_offset,
424                                   server_ptr -> nx_web_http_server_packet_pool_ptr,
425                                   NX_WAIT_FOREVER);
426 
427             /* Update the append pointer of the header part.  */
428             (*packet_ptr) -> nx_packet_append_ptr = (*packet_ptr) -> nx_packet_prepend_ptr + temp_offset;
429 
430 #ifndef NX_DISABLE_PACKET_CHAIN
431 
432             /* Set the next packet of the content packet.  */
433             new_packet_ptr -> nx_packet_next = (*packet_ptr) -> nx_packet_next;
434         }
435 
436         /* Set the last packet of the content and header packet.  */
437         new_packet_ptr -> nx_packet_last = header_packet_ptr -> nx_packet_last;
438         header_packet_ptr -> nx_packet_last = (*packet_ptr);
439         (*packet_ptr) -> nx_packet_next = NX_NULL;
440 #endif
441 
442         /* Update the length of the header and content packet.  */
443         new_packet_ptr -> nx_packet_length = header_packet_ptr -> nx_packet_length - get_offset;
444         header_packet_ptr -> nx_packet_length = get_offset;
445 
446         /* Return the content packet.  */
447         if (server_ptr -> nx_web_http_server_request_chunked)
448         {
449 
450             /* If the packet is chunked, set for processing chunked packet.  */
451             server_ptr -> nx_web_http_server_request_packet = new_packet_ptr;
452             server_ptr -> nx_web_http_server_chunked_request_remaining_size = new_packet_ptr -> nx_packet_length;
453 
454             /* Get the processed chunked packet. Set this packet as the returned packet.  */
455             status = _nx_web_http_server_packet_get(server_ptr, packet_ptr);
456             if (status)
457             {
458                 return(status);
459             }
460         }
461         else
462         {
463 
464             /* Set the returned packet.  */
465             *packet_ptr = new_packet_ptr;
466         }
467     }
468 
469     /* Determine if there is content in this HTTP request.  */
470     if(content_length)
471     {
472 
473         if (packet_chunked)
474         {
475 
476             /* If the packet is chunked, set content length as packet length.  */
477             *content_length = (*packet_ptr) -> nx_packet_length;
478         }
479         else
480         {
481 
482             /* Set the content length as the length in HTTP header.  */
483             *content_length =  length;
484         }
485     }
486 
487     return(NX_SUCCESS);
488 }
489 
490 
491 /**************************************************************************/
492 /*                                                                        */
493 /*  FUNCTION                                               RELEASE        */
494 /*                                                                        */
495 /*    _nxe_web_http_server_packet_get                     PORTABLE C      */
496 /*                                                           6.1          */
497 /*  AUTHOR                                                                */
498 /*                                                                        */
499 /*    Yuxin Zhou, Microsoft Corporation                                   */
500 /*                                                                        */
501 /*  DESCRIPTION                                                           */
502 /*                                                                        */
503 /*    This function checks for errors in the HTTP server packet get call. */
504 /*                                                                        */
505 /*                                                                        */
506 /*  INPUT                                                                 */
507 /*                                                                        */
508 /*    server_ptr                            Pointer to HTTP server        */
509 /*    packet_ptr                            Pointer to the packet to      */
510 /*                                            be returned.                */
511 /*                                                                        */
512 /*  OUTPUT                                                                */
513 /*                                                                        */
514 /*    status                                Completion status             */
515 /*                                                                        */
516 /*  CALLS                                                                 */
517 /*                                                                        */
518 /*    _nx_web_http_server_packet_get        Actual server packet get call */
519 /*                                                                        */
520 /*  CALLED BY                                                             */
521 /*                                                                        */
522 /*    Application Code                                                    */
523 /*                                                                        */
524 /*  RELEASE HISTORY                                                       */
525 /*                                                                        */
526 /*    DATE              NAME                      DESCRIPTION             */
527 /*                                                                        */
528 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
529 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
530 /*                                            resulting in version 6.1    */
531 /*                                                                        */
532 /**************************************************************************/
_nxe_web_http_server_packet_get(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr)533 UINT  _nxe_web_http_server_packet_get(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr)
534 {
535 
536 
537     /* Check for invalid packet pointer.  */
538     if((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
539        (packet_ptr == NX_NULL))
540         return(NX_PTR_ERROR);
541 
542     /* Call actual server packet get function.  */
543     return(_nx_web_http_server_packet_get(server_ptr, packet_ptr));
544 
545 }
546 
547 
548 /**************************************************************************/
549 /*                                                                        */
550 /*  FUNCTION                                               RELEASE        */
551 /*                                                                        */
552 /*    _nx_web_http_server_packet_get                      PORTABLE C      */
553 /*                                                           6.1          */
554 /*  AUTHOR                                                                */
555 /*                                                                        */
556 /*    Yuxin Zhou, Microsoft Corporation                                   */
557 /*                                                                        */
558 /*  DESCRIPTION                                                           */
559 /*                                                                        */
560 /*    This function obtains the next packet from the HTTP server socket.  */
561 /*                                                                        */
562 /*                                                                        */
563 /*  INPUT                                                                 */
564 /*                                                                        */
565 /*    server_ptr                            Pointer to HTTP server        */
566 /*    packet_ptr                            Pointer to the packet to      */
567 /*                                            be returned.                */
568 /*                                                                        */
569 /*  OUTPUT                                                                */
570 /*                                                                        */
571 /*    status                                Completion status             */
572 /*                                                                        */
573 /*  CALLS                                                                 */
574 /*                                                                        */
575 /*    _nx_web_http_server_request_chunked_get                             */
576 /*                                          Get chunked request packet    */
577 /*    _nx_web_http_server_receive           Receive another packet        */
578 /*    nx_packet_release                     Packet release                */
579 /*                                                                        */
580 /*  CALLED BY                                                             */
581 /*                                                                        */
582 /*    Application Code                                                    */
583 /*                                                                        */
584 /*  RELEASE HISTORY                                                       */
585 /*                                                                        */
586 /*    DATE              NAME                      DESCRIPTION             */
587 /*                                                                        */
588 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
589 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
590 /*                                            resulting in version 6.1    */
591 /*                                                                        */
592 /**************************************************************************/
_nx_web_http_server_packet_get(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr)593 UINT _nx_web_http_server_packet_get(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr)
594 {
595 NX_PACKET *new_packet_ptr;
596 UINT       status;
597 
598     if (server_ptr -> nx_web_http_server_request_chunked)
599     {
600 
601         /* If the request packet is chunked, remove the chunk header and get the packet which contain the chunk data.  */
602         status = _nx_web_http_server_request_chunked_get(server_ptr, &new_packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_RECEIVE);
603     }
604     else
605     {
606 
607         /* Receive another packet from client.  */
608         status = _nx_web_http_server_receive(server_ptr, &new_packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_RECEIVE);
609     }
610 
611     /* Check the return status.  */
612     if (status != NX_SUCCESS)
613     {
614 
615         if (server_ptr -> nx_web_http_server_request_chunked)
616         {
617 
618             /* Reset the chunked info.  */
619             nx_packet_release(server_ptr -> nx_web_http_server_request_packet);
620             server_ptr -> nx_web_http_server_request_packet = NX_NULL;
621             server_ptr -> nx_web_http_server_chunked_request_remaining_size = 0;
622             server_ptr -> nx_web_http_server_request_chunked = NX_FALSE;
623             return(status);
624         }
625 
626         /* Error, return to caller.  */
627         return(NX_WEB_HTTP_TIMEOUT);
628     }
629 
630     *packet_ptr = new_packet_ptr;
631 
632     return(NX_SUCCESS);
633 
634 }
635 
636 
637 /**************************************************************************/
638 /*                                                                        */
639 /*  FUNCTION                                               RELEASE        */
640 /*                                                                        */
641 /*    _nxe_web_http_server_content_get_extended           PORTABLE C      */
642 /*                                                           6.1          */
643 /*  AUTHOR                                                                */
644 /*                                                                        */
645 /*    Yuxin Zhou, Microsoft Corporation                                   */
646 /*                                                                        */
647 /*  DESCRIPTION                                                           */
648 /*                                                                        */
649 /*    This function checks for errors in the HTTP extended get content    */
650 /*    service.                                                            */
651 /*                                                                        */
652 /*                                                                        */
653 /*  INPUT                                                                 */
654 /*                                                                        */
655 /*    server_ptr                            Pointer to HTTP server        */
656 /*    packet_ptr                            Pointer to HTTP request packet*/
657 /*    byte_offset                           Byte offset into content      */
658 /*    destination_ptr                       Pointer to content destination*/
659 /*    destination_size                      Maximum size of destination   */
660 /*    actual_size                           Actual amount of content      */
661 /*                                                                        */
662 /*  OUTPUT                                                                */
663 /*                                                                        */
664 /*    status                                Completion status             */
665 /*                                                                        */
666 /*  CALLS                                                                 */
667 /*                                                                        */
668 /*    _nx_web_http_server_content_get_extended                            */
669 /*                                          Actual extended get content   */
670 /*                                              get service               */
671 /*                                                                        */
672 /*  CALLED BY                                                             */
673 /*                                                                        */
674 /*    Application Code                                                    */
675 /*                                                                        */
676 /*  RELEASE HISTORY                                                       */
677 /*                                                                        */
678 /*    DATE              NAME                      DESCRIPTION             */
679 /*                                                                        */
680 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
681 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
682 /*                                            resulting in version 6.1    */
683 /*                                                                        */
684 /**************************************************************************/
_nxe_web_http_server_content_get_extended(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,ULONG byte_offset,CHAR * destination_ptr,UINT destination_size,UINT * actual_size)685 UINT  _nxe_web_http_server_content_get_extended(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, ULONG byte_offset,
686                                             CHAR *destination_ptr, UINT destination_size, UINT *actual_size)
687 {
688 
689 UINT    status;
690 
691 
692     /* Check for invalid input pointers.  */
693     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
694         (packet_ptr == NX_NULL) || (destination_ptr == NX_NULL) || (actual_size == NX_NULL))
695         return(NX_PTR_ERROR);
696 
697     /* Check for appropriate caller.  */
698     NX_THREADS_ONLY_CALLER_CHECKING
699 
700     /* Call actual server content get function.  */
701     status =  _nx_web_http_server_content_get_extended(server_ptr, packet_ptr, byte_offset, destination_ptr, destination_size, actual_size);
702 
703     /* Return completion status.  */
704     return(status);
705 }
706 
707 
708 /**************************************************************************/
709 /*                                                                        */
710 /*  FUNCTION                                               RELEASE        */
711 /*                                                                        */
712 /*    _nx_web_http_server_content_get_extended            PORTABLE C      */
713 /*                                                           6.1          */
714 /*  AUTHOR                                                                */
715 /*                                                                        */
716 /*    Yuxin Zhou, Microsoft Corporation                                   */
717 /*                                                                        */
718 /*  DESCRIPTION                                                           */
719 /*                                                                        */
720 /*    This function returns the user's specified portion of the HTTP      */
721 /*    content. Content is typically included in POST and PUT requests     */
722 /*    from the client. This routine is designed to be called from the     */
723 /*    application's request notify callback.                              */
724 /*                                                                        */
725 /*  INPUT                                                                 */
726 /*                                                                        */
727 /*    server_ptr                            Pointer to HTTP server        */
728 /*    packet_ptr                            Pointer to HTTP request packet*/
729 /*    byte_offset                           Byte offset into content      */
730 /*    destination_ptr                       Pointer to content destination*/
731 /*    destination_size                      Maximum size of destination   */
732 /*    actual_size                           Actual amount of content      */
733 /*                                                                        */
734 /*  OUTPUT                                                                */
735 /*                                                                        */
736 /*    status                                Completion status             */
737 /*                                                                        */
738 /*  CALLS                                                                 */
739 /*                                                                        */
740 /*    _nx_web_http_server_chunked_check     Check if the packet is chunked*/
741 /*    _nx_web_http_server_packet_get        Receive another packet        */
742 /*    _nx_web_http_server_content_length_get                              */
743 /*                                          Get content length with error */
744 /*                                          status returned separately    */
745 /*                                          content length value.         */
746 /*    _nx_web_http_server_calculate_content_offset                        */
747 /*                                          Pickup content offset         */
748 /*    _nx_web_http_server_packet_content_find                             */
749 /*                                          Get the content packet        */
750 /*                                                                        */
751 /*  CALLED BY                                                             */
752 /*                                                                        */
753 /*    Application Code                                                    */
754 /*                                                                        */
755 /*  RELEASE HISTORY                                                       */
756 /*                                                                        */
757 /*    DATE              NAME                      DESCRIPTION             */
758 /*                                                                        */
759 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
760 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
761 /*                                            resulting in version 6.1    */
762 /*                                                                        */
763 /**************************************************************************/
_nx_web_http_server_content_get_extended(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,ULONG byte_offset,CHAR * destination_ptr,UINT destination_size,UINT * actual_size)764 UINT  _nx_web_http_server_content_get_extended(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, ULONG byte_offset,
765                                                CHAR *destination_ptr, UINT destination_size, UINT *actual_size)
766 {
767 
768 ULONG       content_length;
769 ULONG       offset;
770 UINT        status;
771 UINT        remaining_bytes;
772 NX_PACKET   *new_packet_ptr;
773 CHAR        *buffer_ptr;
774 #ifndef NX_DISABLE_PACKET_CHAIN
775 NX_PACKET   *header_packet_ptr = NX_NULL;
776 #endif
777 
778     /* Default the actual size to zero.  */
779     *actual_size =  0;
780 
781     if (_nx_web_http_server_chunked_check(packet_ptr) == NX_FALSE)
782     {
783 
784         /* Determine if there is content in this HTTP request.  */
785         status =  _nx_web_http_server_content_length_get(packet_ptr, &content_length);
786 
787         if (status != NX_SUCCESS)
788         {
789             return status;
790         }
791 
792         /* Make sure the content length is at least greater than the byte offset supplied.  */
793         if (content_length <= byte_offset)
794         {
795 
796             /* No more data in this buffer.  */
797             return(NX_WEB_HTTP_DATA_END);
798         }
799 
800         /* Determine if the destination size is greater than the content length.  */
801         if (destination_size > content_length)
802         {
803 
804             /* Yes, make the destination size equal to the content length.  */
805             destination_size = content_length;
806         }
807 
808         /* Add the byte offset with content offset.  */
809         byte_offset +=  ((ULONG) _nx_web_http_server_calculate_content_offset(packet_ptr));
810     }
811     else
812     {
813 #ifdef NX_DISABLE_PACKET_CHAIN
814 
815         NX_PARAMETER_NOT_USED(server_ptr);
816 
817         return NX_WEB_HTTP_ERROR;
818 #else
819 
820         /* If never processed the chunked packet, need to separate the HTTP header and content.  */
821         if (!server_ptr -> nx_web_http_server_expect_receive_bytes)
822         {
823 
824             /* Remember the header packet.  */
825             header_packet_ptr = packet_ptr;
826 
827             /* Separate the HTTP header and get the first content packet.  */
828             status = _nx_web_http_server_packet_content_find(server_ptr, &packet_ptr, NX_NULL);
829             if (status)
830             {
831                 return(status);
832             }
833         }
834         else
835         {
836 
837             /* If the HTTP header and content is already separated, process this packet as normal packet.  */
838             byte_offset +=  ((ULONG) _nx_web_http_server_calculate_content_offset(packet_ptr));
839         }
840 #endif
841     }
842 
843     /* Determine if we need to read one or more additional packets.  */
844     while (byte_offset >= packet_ptr -> nx_packet_length)
845     {
846 
847 #ifdef NX_DISABLE_PACKET_CHAIN
848         NX_PARAMETER_NOT_USED(server_ptr);
849 
850         return NX_WEB_HTTP_ERROR;
851 #else
852         /* Read another packet because the offset reaches past the current packet
853            length.  */
854         status = _nx_web_http_server_packet_get(server_ptr, &new_packet_ptr);
855 
856         /* Check the return status.  */
857         if (status != NX_SUCCESS)
858         {
859 
860             /* Error, return to caller.  */
861             return(NX_WEB_HTTP_TIMEOUT);
862         }
863 
864         /* Otherwise, we have a new packet to append to the head packet.  */
865 
866         /* Determine if the current packet is already chained.  */
867         if (packet_ptr -> nx_packet_next)
868         {
869 
870             /* Yes, link the current last packet to the new packet.  */
871             (packet_ptr -> nx_packet_last) -> nx_packet_next =  new_packet_ptr;
872         }
873         else
874         {
875 
876             /* Otherwise, this is our first chained packet.  Link to the head.  */
877             packet_ptr -> nx_packet_next =  new_packet_ptr;
878         }
879 
880         /* Is the new packet chained?  */
881         if (new_packet_ptr -> nx_packet_next)
882         {
883 
884             /* Yes, there is a last packet pointer.  Point to this from the head packet.  */
885             packet_ptr -> nx_packet_last =  new_packet_ptr -> nx_packet_last;
886         }
887         else
888         {
889 
890             /* No, there isn't a last packet pointer.  Point to new packet from the head packet.  */
891             packet_ptr -> nx_packet_last =  new_packet_ptr;
892         }
893 
894         /* Update the packet length.  */
895         packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length + new_packet_ptr -> nx_packet_length;
896 #endif /* NX_DISABLE_PACKET_CHAIN */
897     }
898 
899 #ifndef NX_DISABLE_PACKET_CHAIN
900     if (header_packet_ptr)
901     {
902 
903         /* Append the content packet to the header packet.  */
904         if (header_packet_ptr -> nx_packet_next)
905         {
906             (header_packet_ptr -> nx_packet_last) -> nx_packet_next =  packet_ptr;
907         }
908         else
909         {
910             header_packet_ptr -> nx_packet_next =  packet_ptr;
911         }
912 
913         /* Update the last packet.  */
914         if (packet_ptr -> nx_packet_next)
915         {
916             header_packet_ptr -> nx_packet_last =  packet_ptr -> nx_packet_last;
917         }
918         else
919         {
920             header_packet_ptr -> nx_packet_last =  packet_ptr;
921         }
922 
923         /* Update the packet length.  */
924         header_packet_ptr -> nx_packet_length =  header_packet_ptr -> nx_packet_length + packet_ptr -> nx_packet_length;
925     }
926 #endif
927 
928     /* Default the buffer pointer to NULL.  */
929     buffer_ptr =  NX_NULL;
930 
931     /* Now find the packet that contains the offset.  */
932     offset =  0;
933     new_packet_ptr =  packet_ptr;
934     do
935     {
936 
937         /* Determine if the get request falls into this packet.  */
938         if (byte_offset < (offset + (ULONG)(new_packet_ptr -> nx_packet_append_ptr - new_packet_ptr -> nx_packet_prepend_ptr)))
939         {
940 
941             /* Yes, the get offset is in this packet.  */
942 
943             /* Setup the starting byte pointer.  */
944             buffer_ptr =  ((CHAR *) new_packet_ptr -> nx_packet_prepend_ptr) + (byte_offset - offset);
945             break;
946         }
947 
948         /* Otherwise update the offset.  */
949         offset =  offset + (ULONG)(new_packet_ptr -> nx_packet_append_ptr - new_packet_ptr -> nx_packet_prepend_ptr);
950 
951 #ifdef NX_DISABLE_PACKET_CHAIN
952         new_packet_ptr =  NX_NULL;
953 #else
954         /* Move to next packet in the chain.  */
955         new_packet_ptr =  new_packet_ptr -> nx_packet_next;
956 #endif /* NX_DISABLE_PACKET_CHAIN */
957 
958     } while (new_packet_ptr);
959 
960     /* Determine if an error occurred in the search.  */
961     if ((buffer_ptr == (CHAR *) NX_NULL) || (new_packet_ptr == NX_NULL))
962         return(NX_WEB_HTTP_ERROR);
963 
964     /* Now determine if the maximum buffer size has to be adjusted.  */
965     if (destination_size > (UINT) (packet_ptr -> nx_packet_length - byte_offset))
966     {
967 
968         /* Adjust the destination size downward.  */
969         destination_size =  (UINT) (packet_ptr -> nx_packet_length - byte_offset);
970     }
971 
972     /* Initialize the remaining bytes.  */
973     remaining_bytes =  destination_size;
974 
975     /* Otherwise copy the bytes from the offset to the end of the packet pointer.  */
976     while (remaining_bytes--)
977     {
978 
979 #ifndef NX_DISABLE_PACKET_CHAIN
980 
981         /* If the packet is chained, copy the data in the chain.  */
982         if (buffer_ptr == (CHAR *)new_packet_ptr -> nx_packet_append_ptr)
983         {
984             new_packet_ptr = new_packet_ptr -> nx_packet_next;
985             buffer_ptr = (CHAR *)new_packet_ptr -> nx_packet_prepend_ptr;
986         }
987 #endif /* NX_DISABLE_PACKET_CHAIN */
988 
989         /* Copy a byte to the destination.  */
990         *destination_ptr++ =  *buffer_ptr++;
991     }
992 
993     /* Successful completion.  */
994     *actual_size =  destination_size;
995     return(NX_SUCCESS);
996 }
997 
998 
999 /**************************************************************************/
1000 /*                                                                        */
1001 /*  FUNCTION                                               RELEASE        */
1002 /*                                                                        */
1003 /*    _nxe_web_http_server_content_length_get             PORTABLE C      */
1004 /*                                                           6.1          */
1005 /*  AUTHOR                                                                */
1006 /*                                                                        */
1007 /*    Yuxin Zhou, Microsoft Corporation                                   */
1008 /*                                                                        */
1009 /*  DESCRIPTION                                                           */
1010 /*                                                                        */
1011 /*    This function checks for errors in the HTTP content length service. */
1012 /*                                                                        */
1013 /*                                                                        */
1014 /*  INPUT                                                                 */
1015 /*                                                                        */
1016 /*    packet_ptr                            Pointer to HTTP packet        */
1017 /*    content_length                        Pointer for returning content */
1018 /*                                             length value               */
1019 /*                                                                        */
1020 /*  OUTPUT                                                                */
1021 /*                                                                        */
1022 /*    status                                Completion status             */
1023 /*                                                                        */
1024 /*  CALLS                                                                 */
1025 /*                                                                        */
1026 /*    _nx_web_http_server_content_length_get                              */
1027 /*                                          Actual get content length call*/
1028 /*                                                                        */
1029 /*  CALLED BY                                                             */
1030 /*                                                                        */
1031 /*    Application Code                                                    */
1032 /*                                                                        */
1033 /*  RELEASE HISTORY                                                       */
1034 /*                                                                        */
1035 /*    DATE              NAME                      DESCRIPTION             */
1036 /*                                                                        */
1037 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1038 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1039 /*                                            resulting in version 6.1    */
1040 /*                                                                        */
1041 /**************************************************************************/
_nxe_web_http_server_content_length_get(NX_PACKET * packet_ptr,ULONG * content_length)1042 UINT  _nxe_web_http_server_content_length_get(NX_PACKET *packet_ptr, ULONG *content_length)
1043 {
1044 
1045 UINT    status;
1046 
1047 
1048     /* Check for invalid input pointers.  */
1049     if ((packet_ptr == NX_NULL) || (content_length == NX_NULL))
1050         return(NX_PTR_ERROR);
1051 
1052     /* Call actual server content length get function.  */
1053     status =  _nx_web_http_server_content_length_get(packet_ptr, content_length);
1054 
1055     /* Return completion status. */
1056     return status;
1057 }
1058 
1059 /**************************************************************************/
1060 /*                                                                        */
1061 /*  FUNCTION                                               RELEASE        */
1062 /*                                                                        */
1063 /*    _nx_web_http_server_content_length_get              PORTABLE C      */
1064 /*                                                           6.1          */
1065 /*  AUTHOR                                                                */
1066 /*                                                                        */
1067 /*    Yuxin Zhou, Microsoft Corporation                                   */
1068 /*                                                                        */
1069 /*  DESCRIPTION                                                           */
1070 /*                                                                        */
1071 /*    This function find a valid content length field and returns a       */
1072 /*    successful completion status (NX_SUCCESS) if so. Otherwise it       */
1073 /*    it returns an error status.  A valid content length value is        */
1074 /*    zero or more and matches the size of the message body.              */
1075 /*                                                                        */
1076 /*                                                                        */
1077 /*  INPUT                                                                 */
1078 /*                                                                        */
1079 /*    packet_ptr                            Pointer to HTTP request packet*/
1080 /*    content_length                        Pointer to a valid Content    */
1081 /*                                            Length value                */
1082 /*                                                                        */
1083 /*  OUTPUT                                                                */
1084 /*                                                                        */
1085 /*    NX_SUCCESS                            Content length extracted      */
1086 /*    status                                Invalid content length        */
1087 /*                                                                        */
1088 /*  CALLS                                                                 */
1089 /*                                                                        */
1090 /*    None                                                                */
1091 /*                                                                        */
1092 /*  CALLED BY                                                             */
1093 /*                                                                        */
1094 /*    Threads                                                             */
1095 /*                                                                        */
1096 /*  RELEASE HISTORY                                                       */
1097 /*                                                                        */
1098 /*    DATE              NAME                      DESCRIPTION             */
1099 /*                                                                        */
1100 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1101 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1102 /*                                            resulting in version 6.1    */
1103 /*                                                                        */
1104 /**************************************************************************/
_nx_web_http_server_content_length_get(NX_PACKET * packet_ptr,ULONG * length)1105 UINT  _nx_web_http_server_content_length_get(NX_PACKET *packet_ptr, ULONG *length)
1106 {
1107 
1108 CHAR    *buffer_ptr;
1109 
1110 
1111     /* Default the content length to no data.  */
1112     *length =  0;
1113 
1114     /* Setup pointer to buffer.  */
1115     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
1116 
1117     /* Find the "Content-length: " token first.  */
1118     while (((buffer_ptr+17) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
1119     {
1120 
1121         /* Check for the Content-length token.  */
1122         if (((*buffer_ptr ==      'c') || (*buffer_ptr ==      'C')) &&
1123             ((*(buffer_ptr+1) ==  'o') || (*(buffer_ptr+1) ==  'O')) &&
1124             ((*(buffer_ptr+2) ==  'n') || (*(buffer_ptr+2) ==  'N')) &&
1125             ((*(buffer_ptr+3) ==  't') || (*(buffer_ptr+3) ==  'T')) &&
1126             ((*(buffer_ptr+4) ==  'e') || (*(buffer_ptr+4) ==  'E')) &&
1127             ((*(buffer_ptr+5) ==  'n') || (*(buffer_ptr+5) ==  'N')) &&
1128             ((*(buffer_ptr+6) ==  't') || (*(buffer_ptr+6) ==  'T')) &&
1129             (*(buffer_ptr+7) ==  '-') &&
1130             ((*(buffer_ptr+8) ==  'l') || (*(buffer_ptr+8) ==  'L')) &&
1131             ((*(buffer_ptr+9) ==  'e') || (*(buffer_ptr+9) ==  'E')) &&
1132             ((*(buffer_ptr+10) == 'n') || (*(buffer_ptr+10) == 'N')) &&
1133             ((*(buffer_ptr+11) == 'g') || (*(buffer_ptr+11) == 'G')) &&
1134             ((*(buffer_ptr+12) == 't') || (*(buffer_ptr+12) == 'T')) &&
1135             ((*(buffer_ptr+13) == 'h') || (*(buffer_ptr+13) == 'H')) &&
1136             (*(buffer_ptr+14) == ':') &&
1137             (*(buffer_ptr+15) == ' '))
1138         {
1139 
1140             /* Move the pointer up to the length token.  */
1141             buffer_ptr =  buffer_ptr + 16;
1142             break;
1143         }
1144 
1145         /* Move the pointer up to the next character.  */
1146         buffer_ptr++;
1147     }
1148 
1149     /* Now convert the length into a numeric value.  */
1150     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr >= '0') && (*buffer_ptr <= '9'))
1151     {
1152 
1153         /* Update the content length.  */
1154         *length =  *length * 10;
1155         *length =  *length + (((UINT) (*buffer_ptr)) - 0x30);
1156 
1157         /* Move the buffer pointer forward.  */
1158         buffer_ptr++;
1159     }
1160 
1161      /* Determine if the content length was picked up properly.  */
1162      if ((buffer_ptr >= (CHAR *) packet_ptr -> nx_packet_append_ptr) ||
1163          ((*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13)))
1164      {
1165 
1166          /* Error, set the length to zero.  */
1167          return NX_WEB_HTTP_INCOMPLETE_PUT_ERROR;
1168      }
1169 
1170     /* Return successful completion status to the caller.  */
1171     return NX_SUCCESS;
1172 }
1173 
1174 
1175 /**************************************************************************/
1176 /*                                                                        */
1177 /*  FUNCTION                                               RELEASE        */
1178 /*                                                                        */
1179 /*    _nxe_web_http_server_create                         PORTABLE C      */
1180 /*                                                           6.1          */
1181 /*  AUTHOR                                                                */
1182 /*                                                                        */
1183 /*    Yuxin Zhou, Microsoft Corporation                                   */
1184 /*                                                                        */
1185 /*  DESCRIPTION                                                           */
1186 /*                                                                        */
1187 /*    This function checks for errors in the HTTP server create call.     */
1188 /*                                                                        */
1189 /*                                                                        */
1190 /*  INPUT                                                                 */
1191 /*                                                                        */
1192 /*    http_server_ptr                       Pointer to HTTP server        */
1193 /*    http_server_name                      Name of HTTP server           */
1194 /*    server_port                           Port to use for HTTP server   */
1195 /*    ip_ptr                                Pointer to IP instance        */
1196 /*    media_ptr                             Pointer to media structure    */
1197 /*    stack_ptr                             Server thread's stack pointer */
1198 /*    stack_size                            Server thread's stack size    */
1199 /*    pool_ptr                              Pointer to packet pool        */
1200 /*    authentication_check                  Pointer to application's      */
1201 /*                                            authentication checking     */
1202 /*    request_notify                        Pointer to application's      */
1203 /*                                            request notify service      */
1204 /*    http_server_size                      Size of HTTP server           */
1205 /*                                                                        */
1206 /*  OUTPUT                                                                */
1207 /*                                                                        */
1208 /*    status                                Completion status             */
1209 /*                                                                        */
1210 /*  CALLS                                                                 */
1211 /*                                                                        */
1212 /*    _nx_web_http_server_create            Actual server create call     */
1213 /*                                                                        */
1214 /*  CALLED BY                                                             */
1215 /*                                                                        */
1216 /*    Application Code                                                    */
1217 /*                                                                        */
1218 /*  RELEASE HISTORY                                                       */
1219 /*                                                                        */
1220 /*    DATE              NAME                      DESCRIPTION             */
1221 /*                                                                        */
1222 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1223 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1224 /*                                            resulting in version 6.1    */
1225 /*                                                                        */
1226 /**************************************************************************/
_nxe_web_http_server_create(NX_WEB_HTTP_SERVER * http_server_ptr,CHAR * http_server_name,NX_IP * ip_ptr,UINT server_port,FX_MEDIA * media_ptr,VOID * stack_ptr,ULONG stack_size,NX_PACKET_POOL * pool_ptr,UINT (* authentication_check)(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,CHAR ** password,CHAR ** realm),UINT (* request_notify)(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,NX_PACKET * packet_ptr),UINT http_server_size)1227 UINT  _nxe_web_http_server_create(NX_WEB_HTTP_SERVER *http_server_ptr, CHAR *http_server_name, NX_IP *ip_ptr, UINT server_port, FX_MEDIA *media_ptr, VOID *stack_ptr, ULONG stack_size, NX_PACKET_POOL *pool_ptr,
1228                                 UINT (*authentication_check)(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, CHAR **password, CHAR **realm),
1229                                 UINT (*request_notify)(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr), UINT http_server_size)
1230 {
1231 
1232 NX_PACKET   *packet_ptr;
1233 UINT        status;
1234 
1235 
1236     /* Check for invalid input pointers.  */
1237     if ((ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
1238         (http_server_ptr == NX_NULL) || (http_server_ptr -> nx_web_http_server_id == NX_WEB_HTTP_SERVER_ID) ||
1239         (stack_ptr == NX_NULL) || (pool_ptr == NX_NULL) ||
1240         (http_server_size != sizeof(NX_WEB_HTTP_SERVER)))
1241         return(NX_PTR_ERROR);
1242 
1243     /* Pickup a packet from the supplied packet pool.  */
1244     packet_ptr =  pool_ptr -> nx_packet_pool_available_list;
1245 
1246     /* Determine if the packet payload is equal to or greater than the maximum HTTP header supported.  */
1247     if (((packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_data_start) - NX_PHYSICAL_TRAILER)
1248                                                                                             < NX_WEB_HTTP_SERVER_MIN_PACKET_SIZE)
1249         return(NX_WEB_HTTP_POOL_ERROR);
1250 
1251     /* Call actual server create function.  */
1252     status =  _nx_web_http_server_create(http_server_ptr, http_server_name, ip_ptr, server_port, media_ptr, stack_ptr, stack_size, pool_ptr,
1253                             authentication_check, request_notify);
1254 
1255     /* Return completion status.  */
1256     return(status);
1257 }
1258 
1259 
1260 /**************************************************************************/
1261 /*                                                                        */
1262 /*  FUNCTION                                               RELEASE        */
1263 /*                                                                        */
1264 /*    _nx_web_http_server_create                          PORTABLE C      */
1265 /*                                                           6.1          */
1266 /*  AUTHOR                                                                */
1267 /*                                                                        */
1268 /*    Yuxin Zhou, Microsoft Corporation                                   */
1269 /*                                                                        */
1270 /*  DESCRIPTION                                                           */
1271 /*                                                                        */
1272 /*    This function creates a HTTP server on the specified IP. In doing   */
1273 /*    so this function creates an TCP socket for subsequent HTTP          */
1274 /*    transfers and a thread for the HTTP server.                         */
1275 /*                                                                        */
1276 /*    Note: The string resource in callback functions authentication_check*/
1277 /*    and request_notify is built by internal logic and always            */
1278 /*    NULL-terminated.                                                    */
1279 /*                                                                        */
1280 /*                                                                        */
1281 /*  INPUT                                                                 */
1282 /*                                                                        */
1283 /*    http_server_ptr                       Pointer to HTTP server        */
1284 /*    http_server_name                      Name of HTTP server           */
1285 /*    server_port                           Port for 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 /*                                                                        */
1296 /*  OUTPUT                                                                */
1297 /*                                                                        */
1298 /*    status                                Completion status             */
1299 /*                                                                        */
1300 /*  CALLS                                                                 */
1301 /*                                                                        */
1302 /*    nx_tcp_socket_create                  Create HTTP server socket     */
1303 /*    nx_tcp_socket_delete                  Delete the HTTP server socket */
1304 /*    tx_thread_create                      Create the HTTP server thread */
1305 /*                                                                        */
1306 /*  CALLED BY                                                             */
1307 /*                                                                        */
1308 /*    Application Code                                                    */
1309 /*                                                                        */
1310 /*  RELEASE HISTORY                                                       */
1311 /*                                                                        */
1312 /*    DATE              NAME                      DESCRIPTION             */
1313 /*                                                                        */
1314 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1315 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1316 /*                                            resulting in version 6.1    */
1317 /*                                                                        */
1318 /**************************************************************************/
_nx_web_http_server_create(NX_WEB_HTTP_SERVER * http_server_ptr,CHAR * http_server_name,NX_IP * ip_ptr,UINT server_port,FX_MEDIA * media_ptr,VOID * stack_ptr,ULONG stack_size,NX_PACKET_POOL * pool_ptr,UINT (* authentication_check)(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,CHAR ** password,CHAR ** realm),UINT (* request_notify)(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,NX_PACKET * packet_ptr))1319 UINT _nx_web_http_server_create(NX_WEB_HTTP_SERVER *http_server_ptr,
1320                                CHAR *http_server_name, NX_IP *ip_ptr,
1321                                UINT server_port, FX_MEDIA *media_ptr,
1322                                VOID *stack_ptr, ULONG stack_size,
1323                                NX_PACKET_POOL *pool_ptr,
1324                                UINT (*authentication_check)(NX_WEB_HTTP_SERVER *server_ptr,
1325                                                             UINT request_type, CHAR *resource,
1326                                                             CHAR **name, CHAR **password, CHAR **realm),
1327                               UINT (*request_notify)(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type,
1328                                                      CHAR *resource, NX_PACKET *packet_ptr))
1329 {
1330 
1331 UINT        status;
1332 
1333 
1334     /* Clear the HTTP server structure.  */
1335     memset((void *) http_server_ptr, 0, sizeof(NX_WEB_HTTP_SERVER));
1336 
1337     /* Create the Server's TCP socket.  */
1338     status = nx_tcpserver_create(ip_ptr, &http_server_ptr -> nx_web_http_server_tcpserver, http_server_name,
1339                                  NX_WEB_HTTP_TYPE_OF_SERVICE,  NX_WEB_HTTP_FRAGMENT_OPTION, NX_WEB_HTTP_TIME_TO_LIVE,
1340                                  NX_WEB_HTTP_SERVER_WINDOW_SIZE, NX_NULL,
1341                                  _nx_web_http_server_receive_data, _nx_web_http_server_connection_end,
1342                                  _nx_web_http_server_connection_timeout, NX_WEB_HTTP_SERVER_TIMEOUT / NX_IP_PERIODIC_RATE,
1343                                  stack_ptr, stack_size, http_server_ptr -> nx_web_http_server_session_buffer,
1344                                  NX_WEB_HTTP_SERVER_SESSION_BUFFER_SIZE, NX_WEB_HTTP_SERVER_PRIORITY, NX_WEB_HTTP_SERVER_TIMEOUT_ACCEPT);
1345 
1346     /* Determine if an error occurred.   */
1347     if (status != NX_SUCCESS)
1348     {
1349 
1350         /* Yes, return error code.  */
1351         return(status);
1352     }
1353 
1354     /* Store server ptr. */
1355     http_server_ptr -> nx_web_http_server_tcpserver.nx_tcpserver_reserved = (ULONG)http_server_ptr;
1356 
1357     /* Save the Server name.  */
1358     http_server_ptr -> nx_web_http_server_name =  http_server_name;
1359 
1360     /* Save the IP pointer address.  */
1361     http_server_ptr -> nx_web_http_server_ip_ptr =  ip_ptr;
1362 
1363     /* Save the packet pool pointer.  */
1364     http_server_ptr -> nx_web_http_server_packet_pool_ptr =  pool_ptr;
1365 
1366     /* Save the media pointer address.  */
1367     http_server_ptr -> nx_web_http_server_media_ptr =  media_ptr;
1368 
1369     /* Save the user-supplied routines, if specified.  */
1370     http_server_ptr -> nx_web_http_server_authentication_check =  authentication_check;
1371     http_server_ptr -> nx_web_http_server_request_notify =        request_notify;
1372 
1373     /* Set the server ID to indicate the HTTP server is ready.  */
1374     http_server_ptr -> nx_web_http_server_id =  NX_WEB_HTTP_SERVER_ID;
1375 
1376     /* Set the port to the default HTTP listening port (80). */
1377     http_server_ptr -> nx_web_http_server_listen_port = server_port;
1378 
1379     /* Return successful completion.  */
1380     return(NX_SUCCESS);
1381 }
1382 
1383 
1384 /**************************************************************************/
1385 /*                                                                        */
1386 /*  FUNCTION                                               RELEASE        */
1387 /*                                                                        */
1388 /*    _nxe_web_http_server_delete                         PORTABLE C      */
1389 /*                                                           6.1          */
1390 /*  AUTHOR                                                                */
1391 /*                                                                        */
1392 /*    Yuxin Zhou, Microsoft Corporation                                   */
1393 /*                                                                        */
1394 /*  DESCRIPTION                                                           */
1395 /*                                                                        */
1396 /*    This function checks for errors in the HTTP server delete call.     */
1397 /*                                                                        */
1398 /*                                                                        */
1399 /*  INPUT                                                                 */
1400 /*                                                                        */
1401 /*    http_server_ptr                       Pointer to HTTP server        */
1402 /*                                                                        */
1403 /*  OUTPUT                                                                */
1404 /*                                                                        */
1405 /*    status                                Completion status             */
1406 /*                                                                        */
1407 /*  CALLS                                                                 */
1408 /*                                                                        */
1409 /*    _nx_web_http_server_delete            Actual server delete call     */
1410 /*                                                                        */
1411 /*  CALLED BY                                                             */
1412 /*                                                                        */
1413 /*    Application Code                                                    */
1414 /*                                                                        */
1415 /*  RELEASE HISTORY                                                       */
1416 /*                                                                        */
1417 /*    DATE              NAME                      DESCRIPTION             */
1418 /*                                                                        */
1419 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1420 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1421 /*                                            resulting in version 6.1    */
1422 /*                                                                        */
1423 /**************************************************************************/
_nxe_web_http_server_delete(NX_WEB_HTTP_SERVER * http_server_ptr)1424 UINT  _nxe_web_http_server_delete(NX_WEB_HTTP_SERVER *http_server_ptr)
1425 {
1426 
1427 UINT    status;
1428 
1429 
1430     /* Check for invalid input pointers.  */
1431     if ((http_server_ptr == NX_NULL) || (http_server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID))
1432         return(NX_PTR_ERROR);
1433 
1434     /* Check for appropriate caller.  */
1435     NX_THREADS_ONLY_CALLER_CHECKING
1436 
1437     /* Call actual server delete function.  */
1438     status =  _nx_web_http_server_delete(http_server_ptr);
1439 
1440     /* Return completion status.  */
1441     return(status);
1442 }
1443 
1444 
1445 /**************************************************************************/
1446 /*                                                                        */
1447 /*  FUNCTION                                               RELEASE        */
1448 /*                                                                        */
1449 /*    _nx_web_http_server_delete                          PORTABLE C      */
1450 /*                                                           6.1          */
1451 /*  AUTHOR                                                                */
1452 /*                                                                        */
1453 /*    Yuxin Zhou, Microsoft Corporation                                   */
1454 /*                                                                        */
1455 /*  DESCRIPTION                                                           */
1456 /*                                                                        */
1457 /*    This function deletes a previously created HTTP server on the       */
1458 /*    specified IP.                                                       */
1459 /*                                                                        */
1460 /*                                                                        */
1461 /*  INPUT                                                                 */
1462 /*                                                                        */
1463 /*    http_server_ptr                       Pointer to HTTP server        */
1464 /*                                                                        */
1465 /*  OUTPUT                                                                */
1466 /*                                                                        */
1467 /*    status                                Completion status             */
1468 /*                                                                        */
1469 /*  CALLS                                                                 */
1470 /*                                                                        */
1471 /*    nx_tcp_socket_delete                  Delete the HTTP server socket */
1472 /*    nx_tcp_socket_disconnect              Disconnect HTTP server socket */
1473 /*    nx_tcp_socket_unaccept                Unaccept HTTP server connect  */
1474 /*    nx_tcp_socket_unlisten                Unlisten on the HTTP port     */
1475 /*    tx_thread_delete                      Delete the HTTP server thread */
1476 /*    tx_thread_suspend                     Suspend the HTTP server thread*/
1477 /*    tx_thread_terminate                   Terminate the HTTP server     */
1478 /*                                            thread                      */
1479 /*                                                                        */
1480 /*  CALLED BY                                                             */
1481 /*                                                                        */
1482 /*    Application Code                                                    */
1483 /*                                                                        */
1484 /*  RELEASE HISTORY                                                       */
1485 /*                                                                        */
1486 /*    DATE              NAME                      DESCRIPTION             */
1487 /*                                                                        */
1488 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1489 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1490 /*                                            resulting in version 6.1    */
1491 /*                                                                        */
1492 /**************************************************************************/
_nx_web_http_server_delete(NX_WEB_HTTP_SERVER * http_server_ptr)1493 UINT  _nx_web_http_server_delete(NX_WEB_HTTP_SERVER *http_server_ptr)
1494 {
1495 UINT status;
1496 NX_TCPSERVER *tcpserver_ptr = &(http_server_ptr -> nx_web_http_server_tcpserver);
1497 
1498 
1499 #ifdef NX_WEB_HTTPS_ENABLE
1500 UINT i;
1501 
1502     /* Stop TLS session if using HTTPS. */
1503     if(http_server_ptr -> nx_web_http_is_https_server)
1504     {
1505         for(i = 0; i < tcpserver_ptr -> nx_tcpserver_sessions_count; i++)
1506         {
1507             nx_secure_tls_session_end(&(tcpserver_ptr -> nx_tcpserver_sessions[i].nx_tcp_session_tls_session), NX_WAIT_FOREVER);
1508             nx_secure_tls_session_delete(&(tcpserver_ptr -> nx_tcpserver_sessions[i].nx_tcp_session_tls_session));
1509         }
1510     }
1511 
1512 #endif
1513 
1514     /* Delete the TCP server.  */
1515     status = nx_tcpserver_delete(tcpserver_ptr);
1516 
1517     /* Clear the server ID to indicate the HTTP server is no longer ready.  */
1518     http_server_ptr -> nx_web_http_server_id =  0;
1519 
1520     /* Return status.  */
1521     return(status);
1522 }
1523 
1524 
1525 /**************************************************************************/
1526 /*                                                                        */
1527 /*  FUNCTION                                               RELEASE        */
1528 /*                                                                        */
1529 /*    _nxe_web_http_server_param_get                      PORTABLE C      */
1530 /*                                                           6.1          */
1531 /*  AUTHOR                                                                */
1532 /*                                                                        */
1533 /*    Yuxin Zhou, Microsoft Corporation                                   */
1534 /*                                                                        */
1535 /*  DESCRIPTION                                                           */
1536 /*                                                                        */
1537 /*    This function checks for errors in the HTTP parameter get call.     */
1538 /*                                                                        */
1539 /*                                                                        */
1540 /*  INPUT                                                                 */
1541 /*                                                                        */
1542 /*    packet_ptr                            Pointer to HTTP request packet*/
1543 /*    param_number                          Parameter number (start at 0) */
1544 /*    param_ptr                             Pointer to destination        */
1545 /*    max_param_size                        Maximum size of destination   */
1546 /*                                                                        */
1547 /*  OUTPUT                                                                */
1548 /*                                                                        */
1549 /*    status                                Completion status             */
1550 /*                                                                        */
1551 /*  CALLS                                                                 */
1552 /*                                                                        */
1553 /*    _nx_web_http_server_param_get         Actual server parameter get   */
1554 /*                                            call                        */
1555 /*                                                                        */
1556 /*  CALLED BY                                                             */
1557 /*                                                                        */
1558 /*    Application Code                                                    */
1559 /*                                                                        */
1560 /*  RELEASE HISTORY                                                       */
1561 /*                                                                        */
1562 /*    DATE              NAME                      DESCRIPTION             */
1563 /*                                                                        */
1564 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1565 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1566 /*                                            resulting in version 6.1    */
1567 /*                                                                        */
1568 /**************************************************************************/
_nxe_web_http_server_param_get(NX_PACKET * packet_ptr,UINT param_number,CHAR * param_ptr,UINT * param_size,UINT max_param_size)1569 UINT  _nxe_web_http_server_param_get(NX_PACKET *packet_ptr, UINT param_number, CHAR *param_ptr, UINT *param_size, UINT max_param_size)
1570 {
1571 
1572 UINT    status;
1573 
1574 
1575     /* Check for invalid input pointers.  */
1576     if ((packet_ptr == NX_NULL) || (param_ptr == NX_NULL) || (param_size == NX_NULL))
1577         return(NX_PTR_ERROR);
1578 
1579     /* Check for appropriate caller.  */
1580     NX_THREADS_ONLY_CALLER_CHECKING
1581 
1582     /* Call actual server parameter get function.  */
1583     status =  _nx_web_http_server_param_get(packet_ptr, param_number, param_ptr, param_size, max_param_size);
1584 
1585     /* Return completion status.  */
1586     return(status);
1587 }
1588 
1589 
1590 /**************************************************************************/
1591 /*                                                                        */
1592 /*  FUNCTION                                               RELEASE        */
1593 /*                                                                        */
1594 /*    _nx_web_http_server_param_get                       PORTABLE C      */
1595 /*                                                           6.1          */
1596 /*  AUTHOR                                                                */
1597 /*                                                                        */
1598 /*    Yuxin Zhou, Microsoft Corporation                                   */
1599 /*                                                                        */
1600 /*  DESCRIPTION                                                           */
1601 /*                                                                        */
1602 /*    This function returns the requested parameter specified in the URL  */
1603 /*    requested by the client. If the specified parameter is not present, */
1604 /*    a not found error is returned to the caller.                        */
1605 /*                                                                        */
1606 /*                                                                        */
1607 /*  INPUT                                                                 */
1608 /*                                                                        */
1609 /*    packet_ptr                            Pointer to HTTP request packet*/
1610 /*    param_number                          Parameter number (start at 0) */
1611 /*    param_ptr                             Pointer to destination        */
1612 /*    max_param_size                        Maximum size of destination   */
1613 /*                                                                        */
1614 /*  OUTPUT                                                                */
1615 /*                                                                        */
1616 /*    status                                Completion status             */
1617 /*                                                                        */
1618 /*  CALLS                                                                 */
1619 /*                                                                        */
1620 /*    None                                                                */
1621 /*                                                                        */
1622 /*  CALLED BY                                                             */
1623 /*                                                                        */
1624 /*    Application Code                                                    */
1625 /*                                                                        */
1626 /*  RELEASE HISTORY                                                       */
1627 /*                                                                        */
1628 /*    DATE              NAME                      DESCRIPTION             */
1629 /*                                                                        */
1630 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1631 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1632 /*                                            resulting in version 6.1    */
1633 /*                                                                        */
1634 /**************************************************************************/
_nx_web_http_server_param_get(NX_PACKET * packet_ptr,UINT param_number,CHAR * param_ptr,UINT * param_size,UINT max_param_size)1635 UINT  _nx_web_http_server_param_get(NX_PACKET *packet_ptr, UINT param_number, CHAR *param_ptr, UINT *param_size, UINT max_param_size)
1636 {
1637 
1638 UINT    i;
1639 UINT    current_param;
1640 CHAR    *buffer_ptr;
1641 
1642 
1643     /* Set the destination string to NULL.  */
1644     param_ptr[0] =  (CHAR) NX_NULL;
1645     *param_size = 0;
1646 
1647     /* Set current parameter to 0.  */
1648     current_param =  0;
1649 
1650     /* Setup a pointer to the HTTP buffer.  */
1651     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
1652 
1653     /* Position to the start of the URL.  */
1654     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != '/'))
1655     {
1656 
1657         /* Move the buffer pointer.  */
1658         buffer_ptr++;
1659     }
1660 
1661     /* Not find URL.  */
1662     if (buffer_ptr >= (CHAR *) packet_ptr -> nx_packet_append_ptr)
1663     {
1664         return(NX_WEB_HTTP_NOT_FOUND);
1665     }
1666 
1667     /* Loop through the buffer to search for the specified parameter.  */
1668     do
1669     {
1670 
1671         /* Determine if the character is a semicolon, indicating a parameter
1672            is present.  */
1673         if (*buffer_ptr == ';')
1674         {
1675 
1676             /* Yes, a parameter is present.  */
1677 
1678             /* Move the buffer pointer forward.  */
1679             buffer_ptr++;
1680 
1681             /* Is this the parameter requested?  */
1682             if (current_param == param_number)
1683             {
1684 
1685 
1686                 /* Yes, we have found the parameter.  */
1687                 for (i = 0; i < max_param_size; i++)
1688                 {
1689 
1690                     /* Check if reach the end of the packet data.  */
1691                     if (buffer_ptr >= (CHAR *)packet_ptr -> nx_packet_append_ptr)
1692                     {
1693                         return(NX_WEB_HTTP_NOT_FOUND);
1694                     }
1695 
1696                     /* Check for end of parameter.  */
1697                     if ((*buffer_ptr == ';') || (*buffer_ptr == '?') ||
1698                         (*buffer_ptr == '&') || (*buffer_ptr == ' ') ||
1699                         (*buffer_ptr == (CHAR) 13))
1700                     {
1701 
1702                         /* Yes, we are finished and need to get out of the loop.  */
1703                         break;
1704                     }
1705 
1706                     /* Otherwise, store the character in the destination.  */
1707                     param_ptr[i] =  *buffer_ptr++;
1708                 }
1709 
1710                 /* NULL terminate the parameter.  */
1711                 if (i < max_param_size)
1712                 {
1713                     param_ptr[i] =  (CHAR) NX_NULL;
1714                 }
1715 
1716                 /* Return to caller.  */
1717                 if (param_ptr[i] == (CHAR) NX_NULL)
1718                 {
1719                     *param_size = i;
1720                     return(NX_SUCCESS);
1721                 }
1722                 else
1723                 {
1724                     return(NX_WEB_HTTP_IMPROPERLY_TERMINATED_PARAM);
1725                 }
1726             }
1727             else
1728             {
1729 
1730                 /* Increment the current parameter.  */
1731                 current_param++;
1732             }
1733         }
1734         else
1735         {
1736 
1737             /* Check for any other character that signals the end of the param list.  */
1738             if ((*buffer_ptr == '?') || (*buffer_ptr == ' ') || (*buffer_ptr == '&'))
1739                 break;
1740 
1741             /* Update the buffer pointer.  */
1742             buffer_ptr++;
1743         }
1744 
1745     } while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 13));
1746 
1747     /* Return a not found error.  */
1748     return(NX_WEB_HTTP_NOT_FOUND);
1749 }
1750 
1751 
1752 /**************************************************************************/
1753 /*                                                                        */
1754 /*  FUNCTION                                               RELEASE        */
1755 /*                                                                        */
1756 /*    _nxe_web_http_server_query_get                      PORTABLE C      */
1757 /*                                                           6.1          */
1758 /*  AUTHOR                                                                */
1759 /*                                                                        */
1760 /*    Yuxin Zhou, Microsoft Corporation                                   */
1761 /*                                                                        */
1762 /*  DESCRIPTION                                                           */
1763 /*                                                                        */
1764 /*    This function checks for errors in the HTTP query get call.         */
1765 /*                                                                        */
1766 /*                                                                        */
1767 /*  INPUT                                                                 */
1768 /*                                                                        */
1769 /*    packet_ptr                            Pointer to HTTP request packet*/
1770 /*    query_number                          Query number (start at 0)     */
1771 /*    query_ptr                             Pointer to destination        */
1772 /*    query_size                            Pointer to data size return   */
1773 /*    max_query_size                        Maximum size of destination   */
1774 /*                                                                        */
1775 /*  OUTPUT                                                                */
1776 /*                                                                        */
1777 /*    status                                Completion status             */
1778 /*                                                                        */
1779 /*  CALLS                                                                 */
1780 /*                                                                        */
1781 /*    _nx_web_http_server_query_get         Actual server query get       */
1782 /*                                            call                        */
1783 /*                                                                        */
1784 /*  CALLED BY                                                             */
1785 /*                                                                        */
1786 /*    Application Code                                                    */
1787 /*                                                                        */
1788 /*  RELEASE HISTORY                                                       */
1789 /*                                                                        */
1790 /*    DATE              NAME                      DESCRIPTION             */
1791 /*                                                                        */
1792 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1793 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1794 /*                                            resulting in version 6.1    */
1795 /*                                                                        */
1796 /**************************************************************************/
_nxe_web_http_server_query_get(NX_PACKET * packet_ptr,UINT query_number,CHAR * query_ptr,UINT * query_size,UINT max_query_size)1797 UINT  _nxe_web_http_server_query_get(NX_PACKET *packet_ptr, UINT query_number, CHAR *query_ptr, UINT *query_size, UINT max_query_size)
1798 {
1799 
1800 UINT    status;
1801 
1802 
1803     /* Check for invalid input pointers.  */
1804     if ((packet_ptr == NX_NULL) || (query_ptr == NX_NULL) || (query_size == NX_NULL))
1805         return(NX_PTR_ERROR);
1806 
1807     /* Check for appropriate caller.  */
1808     NX_THREADS_ONLY_CALLER_CHECKING
1809 
1810     /* Call actual server query get function.  */
1811     status =  _nx_web_http_server_query_get(packet_ptr, query_number, query_ptr, query_size, max_query_size);
1812 
1813     /* Return completion status.  */
1814     return(status);
1815 }
1816 
1817 
1818 /**************************************************************************/
1819 /*                                                                        */
1820 /*  FUNCTION                                               RELEASE        */
1821 /*                                                                        */
1822 /*    _nx_web_http_server_query_get                       PORTABLE C      */
1823 /*                                                           6.1          */
1824 /*  AUTHOR                                                                */
1825 /*                                                                        */
1826 /*    Yuxin Zhou, Microsoft Corporation                                   */
1827 /*                                                                        */
1828 /*  DESCRIPTION                                                           */
1829 /*                                                                        */
1830 /*    This function returns the requested query specified in the URL      */
1831 /*    requested by the client. If the specified query is not present,     */
1832 /*    a not found error is returned to the caller.                        */
1833 /*                                                                        */
1834 /*                                                                        */
1835 /*  INPUT                                                                 */
1836 /*                                                                        */
1837 /*    packet_ptr                            Pointer to HTTP request packet*/
1838 /*    query_number                          Query number (start at 0)     */
1839 /*    query_ptr                             Pointer to destination        */
1840 /*    query_size                            Pointer to data size return   */
1841 /*    max_query_size                        Maximum size of destination   */
1842 /*                                                                        */
1843 /*  OUTPUT                                                                */
1844 /*                                                                        */
1845 /*    status                                Completion status             */
1846 /*                                                                        */
1847 /*  CALLS                                                                 */
1848 /*                                                                        */
1849 /*    None                                                                */
1850 /*                                                                        */
1851 /*  CALLED BY                                                             */
1852 /*                                                                        */
1853 /*    Application Code                                                    */
1854 /*                                                                        */
1855 /*  RELEASE HISTORY                                                       */
1856 /*                                                                        */
1857 /*    DATE              NAME                      DESCRIPTION             */
1858 /*                                                                        */
1859 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1860 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1861 /*                                            resulting in version 6.1    */
1862 /*                                                                        */
1863 /**************************************************************************/
_nx_web_http_server_query_get(NX_PACKET * packet_ptr,UINT query_number,CHAR * query_ptr,UINT * query_size,UINT max_query_size)1864 UINT  _nx_web_http_server_query_get(NX_PACKET *packet_ptr, UINT query_number, CHAR *query_ptr, UINT *query_size, UINT max_query_size)
1865 {
1866 
1867 UINT    i;
1868 UINT    current_query;
1869 CHAR    *buffer_ptr;
1870 
1871 
1872     /* Set the destination string to NULL.  */
1873     query_ptr[0] =  (CHAR) NX_NULL;
1874     *query_size = 0;
1875 
1876     /* Set current query number to 0.  */
1877     current_query =  0;
1878 
1879     /* Setup a pointer to the HTTP buffer.  */
1880     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
1881 
1882     /* Position to the start of the URL.  */
1883     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != '/'))
1884     {
1885 
1886         /* Move the buffer pointer.  */
1887         buffer_ptr++;
1888     }
1889 
1890     /* Not find URL.  */
1891     if (buffer_ptr >= (CHAR *) packet_ptr -> nx_packet_append_ptr)
1892     {
1893         return(NX_WEB_HTTP_NOT_FOUND);
1894     }
1895 
1896     /* Loop through the buffer to search for the specified query instance.  */
1897     do
1898     {
1899 
1900         /* Determine if the character is a '?' or a '&', indicating a query
1901            is present.  */
1902         if (((*buffer_ptr == '?') && (current_query == 0)) ||
1903             ((*buffer_ptr == '&') && (current_query != 0)))
1904         {
1905 
1906             /* Yes, a query is present.  */
1907 
1908             /* Move the buffer pointer forward.  */
1909             buffer_ptr++;
1910 
1911             /* Is this the query requested?  */
1912             if (current_query == query_number)
1913             {
1914 
1915 
1916                 /* Yes, we have found the query.  */
1917                 for (i = 0; i < max_query_size; i++)
1918                 {
1919 
1920                     /* Check if reach the end of the packet data.  */
1921                     if (buffer_ptr >= (CHAR *)packet_ptr -> nx_packet_append_ptr)
1922                     {
1923                         return(NX_WEB_HTTP_NOT_FOUND);
1924                     }
1925 
1926                     /* Check for end of query.  */
1927                     if ((*buffer_ptr == ';') || (*buffer_ptr == '?') ||
1928                         (*buffer_ptr == '&') || (*buffer_ptr == ' ') ||
1929                         (*buffer_ptr == (CHAR) 13))
1930                     {
1931 
1932                         /* Yes, we are finished and need to get out of the loop.  */
1933                         break;
1934                     }
1935 
1936                     /* Otherwise, store the character in the destination.  */
1937                     query_ptr[i] =  *buffer_ptr++;
1938                 }
1939 
1940                 /* NULL terminate the query.  */
1941                 query_ptr[i] =  (CHAR) NX_NULL;
1942 
1943                 /* Return to caller.  */
1944                 if (i)
1945                 {
1946                     *query_size = i;
1947                     return(NX_SUCCESS);
1948                 }
1949                 else
1950                 {
1951                     return(NX_WEB_HTTP_NO_QUERY_PARSED);
1952                 }
1953             }
1954             else
1955             {
1956 
1957                 /* Increment the current query.  */
1958                 current_query++;
1959             }
1960         }
1961         else
1962         {
1963 
1964             /* Check for any other character that signals the end of the query list.  */
1965             if ((*buffer_ptr == '?') || (*buffer_ptr == ' ') || (*buffer_ptr == ';'))
1966                 break;
1967 
1968             /* Update the buffer pointer.  */
1969             buffer_ptr++;
1970         }
1971 
1972     } while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 13));
1973 
1974     /* Return a not found error.  */
1975     return(NX_WEB_HTTP_NOT_FOUND);
1976 }
1977 
1978 
1979 /**************************************************************************/
1980 /*                                                                        */
1981 /*  FUNCTION                                               RELEASE        */
1982 /*                                                                        */
1983 /*    _nxe_web_http_server_start                          PORTABLE C      */
1984 /*                                                           6.1          */
1985 /*  AUTHOR                                                                */
1986 /*                                                                        */
1987 /*    Yuxin Zhou, Microsoft Corporation                                   */
1988 /*                                                                        */
1989 /*  DESCRIPTION                                                           */
1990 /*                                                                        */
1991 /*    This function checks for errors in the HTTP server start call.      */
1992 /*                                                                        */
1993 /*                                                                        */
1994 /*  INPUT                                                                 */
1995 /*                                                                        */
1996 /*    http_server_ptr                       Pointer to HTTP server        */
1997 /*                                                                        */
1998 /*  OUTPUT                                                                */
1999 /*                                                                        */
2000 /*    status                                Completion status             */
2001 /*                                                                        */
2002 /*  CALLS                                                                 */
2003 /*                                                                        */
2004 /*    _nx_web_http_server_start             Actual server start call      */
2005 /*                                                                        */
2006 /*  CALLED BY                                                             */
2007 /*                                                                        */
2008 /*    Application Code                                                    */
2009 /*                                                                        */
2010 /*  RELEASE HISTORY                                                       */
2011 /*                                                                        */
2012 /*    DATE              NAME                      DESCRIPTION             */
2013 /*                                                                        */
2014 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2015 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2016 /*                                            resulting in version 6.1    */
2017 /*                                                                        */
2018 /**************************************************************************/
_nxe_web_http_server_start(NX_WEB_HTTP_SERVER * http_server_ptr)2019 UINT  _nxe_web_http_server_start(NX_WEB_HTTP_SERVER *http_server_ptr)
2020 {
2021 
2022 UINT    status;
2023 
2024 
2025     /* Check for invalid input pointers.  */
2026     if ((http_server_ptr == NX_NULL) || (http_server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID))
2027         return(NX_PTR_ERROR);
2028 
2029     /* Call actual server start function.  */
2030     status =  _nx_web_http_server_start(http_server_ptr);
2031 
2032     /* Return completion status.  */
2033     return(status);
2034 }
2035 
2036 
2037 /**************************************************************************/
2038 /*                                                                        */
2039 /*  FUNCTION                                               RELEASE        */
2040 /*                                                                        */
2041 /*    _nx_web_http_server_start                           PORTABLE C      */
2042 /*                                                           6.1          */
2043 /*  AUTHOR                                                                */
2044 /*                                                                        */
2045 /*    Yuxin Zhou, Microsoft Corporation                                   */
2046 /*                                                                        */
2047 /*  DESCRIPTION                                                           */
2048 /*                                                                        */
2049 /*    This function starts a previously created HTTP server on the        */
2050 /*    specified IP.                                                       */
2051 /*                                                                        */
2052 /*                                                                        */
2053 /*  INPUT                                                                 */
2054 /*                                                                        */
2055 /*    http_server_ptr                       Pointer to HTTP server        */
2056 /*                                                                        */
2057 /*  OUTPUT                                                                */
2058 /*                                                                        */
2059 /*    status                                Completion status             */
2060 /*                                                                        */
2061 /*  CALLS                                                                 */
2062 /*                                                                        */
2063 /*    nx_tcp_server_socket_listen           Start listening on HTTP port  */
2064 /*    tx_thread_resume                      Resume the HTTP server thread */
2065 /*                                                                        */
2066 /*  CALLED BY                                                             */
2067 /*                                                                        */
2068 /*    Application Code                                                    */
2069 /*                                                                        */
2070 /*  RELEASE HISTORY                                                       */
2071 /*                                                                        */
2072 /*    DATE              NAME                      DESCRIPTION             */
2073 /*                                                                        */
2074 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2075 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2076 /*                                            resulting in version 6.1    */
2077 /*                                                                        */
2078 /**************************************************************************/
_nx_web_http_server_start(NX_WEB_HTTP_SERVER * http_server_ptr)2079 UINT  _nx_web_http_server_start(NX_WEB_HTTP_SERVER *http_server_ptr)
2080 {
2081 
2082 UINT    status;
2083 UINT    port;
2084 
2085     port = http_server_ptr -> nx_web_http_server_listen_port;
2086 
2087     /* Start listening on the HTTP server port.  */
2088     status =  nx_tcpserver_start(&http_server_ptr -> nx_web_http_server_tcpserver, port, NX_WEB_HTTP_SERVER_MAX_PENDING);
2089 
2090     /* Determine if the listen was unsuccessful.  */
2091     if (status != NX_SUCCESS)
2092     {
2093         /* Just return an HTTP error.  */
2094         return(status);
2095     }
2096 
2097     /* Return successful completion.  */
2098     return(NX_SUCCESS);
2099 }
2100 
2101 #ifdef NX_WEB_HTTPS_ENABLE
2102 
2103 /**************************************************************************/
2104 /*                                                                        */
2105 /*  FUNCTION                                               RELEASE        */
2106 /*                                                                        */
2107 /*    _nxe_web_http_server_secure_configure               PORTABLE C      */
2108 /*                                                           6.1          */
2109 /*  AUTHOR                                                                */
2110 /*                                                                        */
2111 /*    Yuxin Zhou, Microsoft Corporation                                   */
2112 /*                                                                        */
2113 /*  DESCRIPTION                                                           */
2114 /*                                                                        */
2115 /*    This function checks for errors in the HTTPS configuration call.    */
2116 /*                                                                        */
2117 /*  INPUT                                                                 */
2118 /*                                                                        */
2119 /*    http_server_ptr                       Pointer to HTTP server        */
2120 /*    crypto_table                          TLS cryptographic routines    */
2121 /*    metadata_buffer                       Cryptographic metadata buffer */
2122 /*    metadata_size                         Size of metadata buffer       */
2123 /*    packet_buffer                         TLS packet buffer             */
2124 /*    packet_size                           Size of packet buffer         */
2125 /*    identity_certificate                  TLS server certificate        */
2126 /*    trusted_certificates                  TLS trusted certificates      */
2127 /*    trusted_certs_num                     Number of trusted certs       */
2128 /*    remote_certificates                   Remote certificates array     */
2129 /*    remote_certs_num                      Number of remote certificates */
2130 /*    remote_certificate_buffer             Buffer for remote certs       */
2131 /*    remote_cert_buffer_size               Size of remote cert buffer    */
2132 /*                                                                        */
2133 /*  OUTPUT                                                                */
2134 /*                                                                        */
2135 /*    status                                Completion status             */
2136 /*                                                                        */
2137 /*  CALLS                                                                 */
2138 /*                                                                        */
2139 /*    _nx_web_http_server_secure_configure Actual server configure call   */
2140 /*                                                                        */
2141 /*  CALLED BY                                                             */
2142 /*                                                                        */
2143 /*    Application Code                                                    */
2144 /*                                                                        */
2145 /*  RELEASE HISTORY                                                       */
2146 /*                                                                        */
2147 /*    DATE              NAME                      DESCRIPTION             */
2148 /*                                                                        */
2149 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2150 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2151 /*                                            resulting in version 6.1    */
2152 /*                                                                        */
2153 /**************************************************************************/
_nxe_web_http_server_secure_configure(NX_WEB_HTTP_SERVER * http_server_ptr,const NX_SECURE_TLS_CRYPTO * crypto_table,VOID * metadata_buffer,ULONG metadata_size,UCHAR * packet_buffer,UINT packet_buffer_size,NX_SECURE_X509_CERT * identity_certificate,NX_SECURE_X509_CERT * trusted_certificates[],UINT trusted_certs_num,NX_SECURE_X509_CERT * remote_certificates[],UINT remote_certs_num,UCHAR * remote_certificate_buffer,UINT remote_cert_buffer_size)2154 UINT  _nxe_web_http_server_secure_configure(NX_WEB_HTTP_SERVER *http_server_ptr, const NX_SECURE_TLS_CRYPTO *crypto_table,
2155                                             VOID *metadata_buffer, ULONG metadata_size,
2156                                             UCHAR* packet_buffer, UINT packet_buffer_size,
2157                                             NX_SECURE_X509_CERT *identity_certificate,
2158                                             NX_SECURE_X509_CERT *trusted_certificates[],
2159                                             UINT trusted_certs_num,
2160                                             NX_SECURE_X509_CERT *remote_certificates[],
2161                                             UINT remote_certs_num,
2162                                             UCHAR *remote_certificate_buffer,
2163                                             UINT remote_cert_buffer_size)
2164 {
2165 
2166 UINT    status;
2167 
2168 
2169     /* Check for invalid input pointers. Note that the remote certificates array and buffer
2170      * may be NX_NULL for the HTTPS server since remote certificates are optional for TLS Server.*/
2171     if ((http_server_ptr == NX_NULL) || (http_server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
2172          crypto_table == NX_NULL || metadata_buffer == NX_NULL || packet_buffer == NX_NULL ||
2173          identity_certificate == NX_NULL)
2174     {
2175         return(NX_PTR_ERROR);
2176     }
2177 
2178     /* Call actual server start function.  */
2179     status =  _nx_web_http_server_secure_configure(http_server_ptr, crypto_table, metadata_buffer, metadata_size,
2180                                                    packet_buffer, packet_buffer_size, identity_certificate,
2181                                                    trusted_certificates, trusted_certs_num,
2182                                                    remote_certificates, remote_certs_num, remote_certificate_buffer,
2183                                                    remote_cert_buffer_size);
2184 
2185     /* Return completion status.  */
2186     return(status);
2187 }
2188 
2189 
2190 /**************************************************************************/
2191 /*                                                                        */
2192 /*  FUNCTION                                               RELEASE        */
2193 /*                                                                        */
2194 /*    _nx_web_http_server_secure_configure                PORTABLE C      */
2195 /*                                                           6.1.11       */
2196 /*  AUTHOR                                                                */
2197 /*                                                                        */
2198 /*    Yuxin Zhou, Microsoft Corporation                                   */
2199 /*                                                                        */
2200 /*  DESCRIPTION                                                           */
2201 /*                                                                        */
2202 /*    This function configures a previously created NetX Web HTTP server  */
2203 /*    instance to use TLS for secure HTTPS communications. The parameters */
2204 /*    are used to configure all the possible TLS sessions with identical  */
2205 /*    state so that each incoming HTTPS client experiences consistent     */
2206 /*    behavior. The number of TLS sessions is controlled using the macro  */
2207 /*    NX_WEB_HTTP_SERVER_SESSION_MAX.                                     */
2208 /*                                                                        */
2209 /*    The cryptographic routine table (ciphersuite table) is shared       */
2210 /*    between all TLS sessions as it just contains function pointers.     */
2211 /*                                                                        */
2212 /*    The metadata buffer and packet reassembly buffer are divided        */
2213 /*    equally between all TLS sessions. If the buffer size is not evenly  */
2214 /*    divisible by the number of sessions the remainder will be unused.   */
2215 /*                                                                        */
2216 /*    The passed-in identity certificate is used by all sessions. During  */
2217 /*    TLS operation the server identity certificate is only read from so  */
2218 /*    copies are not needed for each session.                             */
2219 /*                                                                        */
2220 /*    The trusted certificates are added to the trusted store for each    */
2221 /*    TLS session in the server. This is used for client certificate      */
2222 /*    verification which is enabled if remote certificates are provided.  */
2223 /*                                                                        */
2224 /*    The remote certificate array and buffer is shared by default        */
2225 /*    between all TLS sessions. This does mean that some sessions may     */
2226 /*    block during certificate validation.                                */
2227 /*                                                                        */
2228 /*  INPUT                                                                 */
2229 /*                                                                        */
2230 /*    http_server_ptr                       Pointer to HTTP server        */
2231 /*    crypto_table                          TLS cryptographic routines    */
2232 /*    metadata_buffer                       Cryptographic metadata buffer */
2233 /*    metadata_size                         Size of metadata buffer       */
2234 /*    packet_buffer                         TLS packet buffer             */
2235 /*    packet_size                           Size of packet buffer         */
2236 /*    identity_certificate                  TLS server certificate        */
2237 /*    trusted_certificates                  TLS trusted certificates      */
2238 /*    trusted_certs_num                     Number of trusted certs       */
2239 /*    remote_certificates                   Remote certificates array     */
2240 /*    remote_certs_num                      Number of remote certificates */
2241 /*    remote_certificate_buffer             Buffer for remote certs       */
2242 /*    remote_cert_buffer_size               Size of remote cert buffer    */
2243 /*                                                                        */
2244 /*  OUTPUT                                                                */
2245 /*                                                                        */
2246 /*    status                                Completion status             */
2247 /*                                                                        */
2248 /*  CALLS                                                                 */
2249 /*                                                                        */
2250 /*    nx_tcpserver_tls_setup                Socket server TLS configure   */
2251 /*                                                                        */
2252 /*  CALLED BY                                                             */
2253 /*                                                                        */
2254 /*    Application Code                                                    */
2255 /*                                                                        */
2256 /*  RELEASE HISTORY                                                       */
2257 /*                                                                        */
2258 /*    DATE              NAME                      DESCRIPTION             */
2259 /*                                                                        */
2260 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2261 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2262 /*                                            resulting in version 6.1    */
2263 /*  04-25-2022     Yuxin Zhou               Modified comment(s),          */
2264 /*                                            resulting in version 6.1.11 */
2265 /*                                                                        */
2266 /**************************************************************************/
_nx_web_http_server_secure_configure(NX_WEB_HTTP_SERVER * http_server_ptr,const NX_SECURE_TLS_CRYPTO * crypto_table,VOID * metadata_buffer,ULONG metadata_size,UCHAR * packet_buffer,UINT packet_buffer_size,NX_SECURE_X509_CERT * identity_certificate,NX_SECURE_X509_CERT * trusted_certificates[],UINT trusted_certs_num,NX_SECURE_X509_CERT * remote_certificates[],UINT remote_certs_num,UCHAR * remote_certificate_buffer,UINT remote_cert_buffer_size)2267 UINT  _nx_web_http_server_secure_configure(NX_WEB_HTTP_SERVER *http_server_ptr, const NX_SECURE_TLS_CRYPTO *crypto_table,
2268                                             VOID *metadata_buffer, ULONG metadata_size,
2269                                             UCHAR* packet_buffer, UINT packet_buffer_size,
2270                                             NX_SECURE_X509_CERT *identity_certificate,
2271                                             NX_SECURE_X509_CERT *trusted_certificates[],
2272                                             UINT trusted_certs_num,
2273                                             NX_SECURE_X509_CERT *remote_certificates[],
2274                                             UINT remote_certs_num,
2275                                             UCHAR *remote_certificate_buffer,
2276                                             UINT remote_cert_buffer_size)
2277 {
2278 
2279 UINT    status;
2280 
2281     /* This is a secure HTTP server, so set HTTPS flag. */
2282     http_server_ptr -> nx_web_http_is_https_server = NX_TRUE;
2283 
2284     /* Configure TLS for the socket server. */
2285     status = nx_tcpserver_tls_setup(&http_server_ptr->nx_web_http_server_tcpserver,
2286                                     crypto_table, metadata_buffer, metadata_size,
2287                                     packet_buffer, packet_buffer_size, identity_certificate,
2288                                     trusted_certificates, trusted_certs_num,
2289                                     remote_certificates, remote_certs_num,
2290                                     remote_certificate_buffer,remote_cert_buffer_size);
2291 
2292     /* Return result of TLS setup. */
2293     return(status);
2294 }
2295 
2296 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
2297 /**************************************************************************/
2298 /*                                                                        */
2299 /*  FUNCTION                                               RELEASE        */
2300 /*                                                                        */
2301 /*    _nxe_web_http_server_secure_ecc_configure           PORTABLE C      */
2302 /*                                                           6.1.11       */
2303 /*  AUTHOR                                                                */
2304 /*                                                                        */
2305 /*    Yuxin Zhou, Microsoft Corporation                                   */
2306 /*                                                                        */
2307 /*  DESCRIPTION                                                           */
2308 /*                                                                        */
2309 /*    This function checks for errors in the HTTPS ECC configuration call.*/
2310 /*                                                                        */
2311 /*  INPUT                                                                 */
2312 /*                                                                        */
2313 /*    http_server_ptr                       Pointer to HTTP server        */
2314 /*    supported_groups                      List of supported groups      */
2315 /*    supported_group_count                 Number of supported groups    */
2316 /*    curves                                List of curve methods         */
2317 /*                                                                        */
2318 /*  OUTPUT                                                                */
2319 /*                                                                        */
2320 /*    status                                Completion status             */
2321 /*                                                                        */
2322 /*  CALLS                                                                 */
2323 /*                                                                        */
2324 /*    _nx_web_http_server_secure_ecc_configure                            */
2325 /*                                          Actual ECC configuration call */
2326 /*                                                                        */
2327 /*  CALLED BY                                                             */
2328 /*                                                                        */
2329 /*    Application Code                                                    */
2330 /*                                                                        */
2331 /*  RELEASE HISTORY                                                       */
2332 /*                                                                        */
2333 /*    DATE              NAME                      DESCRIPTION             */
2334 /*                                                                        */
2335 /*  04-25-2022     Yuxin Zhou               Initial Version 6.1.11        */
2336 /*                                                                        */
2337 /**************************************************************************/
_nxe_web_http_server_secure_ecc_configure(NX_WEB_HTTP_SERVER * http_server_ptr,const USHORT * supported_groups,USHORT supported_group_count,const NX_CRYPTO_METHOD ** curves)2338 UINT _nxe_web_http_server_secure_ecc_configure(NX_WEB_HTTP_SERVER *http_server_ptr,
2339                                                const USHORT *supported_groups, USHORT supported_group_count,
2340                                                const NX_CRYPTO_METHOD **curves)
2341 {
2342 UINT status;
2343 
2344     /* Check for invalid input pointers. */
2345     if ((http_server_ptr == NX_NULL) || (http_server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
2346         (supported_groups == NX_NULL) || (supported_group_count == 0) || (curves == NX_NULL))
2347     {
2348         return(NX_PTR_ERROR);
2349     }
2350 
2351     /* Call actual ECC configuration function.  */
2352     status = _nx_web_http_server_secure_ecc_configure(http_server_ptr, supported_groups, supported_group_count, curves);
2353     return(status);
2354 }
2355 
2356 /**************************************************************************/
2357 /*                                                                        */
2358 /*  FUNCTION                                               RELEASE        */
2359 /*                                                                        */
2360 /*    _nx_web_http_server_secure_ecc_configure            PORTABLE C      */
2361 /*                                                           6.1.11       */
2362 /*  AUTHOR                                                                */
2363 /*                                                                        */
2364 /*    Yuxin Zhou, Microsoft Corporation                                   */
2365 /*                                                                        */
2366 /*  DESCRIPTION                                                           */
2367 /*                                                                        */
2368 /*    This function configures supported curve lists for NetX Web HTTP    */
2369 /*    server instance using TLS.                                          */
2370 /*                                                                        */
2371 /*  INPUT                                                                 */
2372 /*                                                                        */
2373 /*    http_server_ptr                       Pointer to HTTP server        */
2374 /*    supported_groups                      List of supported groups      */
2375 /*    supported_group_count                 Number of supported groups    */
2376 /*    curves                                List of curve methods         */
2377 /*                                                                        */
2378 /*  OUTPUT                                                                */
2379 /*                                                                        */
2380 /*    status                                Completion status             */
2381 /*                                                                        */
2382 /*  CALLS                                                                 */
2383 /*                                                                        */
2384 /*    nx_tcpserver_tls_ecc_setup            Socket server ECC configure   */
2385 /*                                                                        */
2386 /*  CALLED BY                                                             */
2387 /*                                                                        */
2388 /*    Application Code                                                    */
2389 /*                                                                        */
2390 /*  RELEASE HISTORY                                                       */
2391 /*                                                                        */
2392 /*    DATE              NAME                      DESCRIPTION             */
2393 /*                                                                        */
2394 /*  04-25-2022     Yuxin Zhou               Initial Version 6.1.11        */
2395 /*                                                                        */
2396 /**************************************************************************/
_nx_web_http_server_secure_ecc_configure(NX_WEB_HTTP_SERVER * http_server_ptr,const USHORT * supported_groups,USHORT supported_group_count,const NX_CRYPTO_METHOD ** curves)2397 UINT _nx_web_http_server_secure_ecc_configure(NX_WEB_HTTP_SERVER *http_server_ptr,
2398                                               const USHORT *supported_groups, USHORT supported_group_count,
2399                                               const NX_CRYPTO_METHOD **curves)
2400 {
2401 UINT status;
2402 
2403     /* Configure TLS ECC for the socket server. */
2404     status = nx_tcpserver_tls_ecc_setup(&http_server_ptr -> nx_web_http_server_tcpserver,
2405                                         supported_groups, supported_group_count, curves);
2406     return(status);
2407 }
2408 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
2409 
2410 #endif /* NX_WEB_HTTPS_ENABLE */
2411 
2412 /**************************************************************************/
2413 /*                                                                        */
2414 /*  FUNCTION                                               RELEASE        */
2415 /*                                                                        */
2416 /*    _nxe_web_http_server_stop                           PORTABLE C      */
2417 /*                                                           6.1          */
2418 /*  AUTHOR                                                                */
2419 /*                                                                        */
2420 /*    Yuxin Zhou, Microsoft Corporation                                   */
2421 /*                                                                        */
2422 /*  DESCRIPTION                                                           */
2423 /*                                                                        */
2424 /*    This function checks for errors in the HTTP server stop call.       */
2425 /*                                                                        */
2426 /*                                                                        */
2427 /*  INPUT                                                                 */
2428 /*                                                                        */
2429 /*    http_server_ptr                       Pointer to HTTP server        */
2430 /*                                                                        */
2431 /*  OUTPUT                                                                */
2432 /*                                                                        */
2433 /*    status                                Completion status             */
2434 /*                                                                        */
2435 /*  CALLS                                                                 */
2436 /*                                                                        */
2437 /*    _nx_web_http_server_stop              Actual server stop call       */
2438 /*                                                                        */
2439 /*  CALLED BY                                                             */
2440 /*                                                                        */
2441 /*    Application Code                                                    */
2442 /*                                                                        */
2443 /*  RELEASE HISTORY                                                       */
2444 /*                                                                        */
2445 /*    DATE              NAME                      DESCRIPTION             */
2446 /*                                                                        */
2447 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2448 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2449 /*                                            resulting in version 6.1    */
2450 /*                                                                        */
2451 /**************************************************************************/
_nxe_web_http_server_stop(NX_WEB_HTTP_SERVER * http_server_ptr)2452 UINT  _nxe_web_http_server_stop(NX_WEB_HTTP_SERVER *http_server_ptr)
2453 {
2454 
2455 UINT    status;
2456 
2457 
2458     /* Check for invalid input pointers.  */
2459     if ((http_server_ptr == NX_NULL) || (http_server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID))
2460         return(NX_PTR_ERROR);
2461 
2462     /* Check for appropriate caller.  */
2463     NX_THREADS_ONLY_CALLER_CHECKING
2464 
2465     /* Call actual server stop function.  */
2466     status =  _nx_web_http_server_stop(http_server_ptr);
2467 
2468     /* Return completion status.  */
2469     return(status);
2470 }
2471 
2472 
2473 /**************************************************************************/
2474 /*                                                                        */
2475 /*  FUNCTION                                               RELEASE        */
2476 /*                                                                        */
2477 /*    _nx_web_http_server_stop                            PORTABLE C      */
2478 /*                                                           6.1          */
2479 /*  AUTHOR                                                                */
2480 /*                                                                        */
2481 /*    Yuxin Zhou, Microsoft Corporation                                   */
2482 /*                                                                        */
2483 /*  DESCRIPTION                                                           */
2484 /*                                                                        */
2485 /*    This function stops a previously started HTTP server on the         */
2486 /*    specified IP.                                                       */
2487 /*                                                                        */
2488 /*                                                                        */
2489 /*  INPUT                                                                 */
2490 /*                                                                        */
2491 /*    http_server_ptr                       Pointer to HTTP server        */
2492 /*                                                                        */
2493 /*  OUTPUT                                                                */
2494 /*                                                                        */
2495 /*    status                                Completion status             */
2496 /*                                                                        */
2497 /*  CALLS                                                                 */
2498 /*                                                                        */
2499 /*    nx_tcpserver_stop                     Suspend the HTTP server thread*/
2500 /*                                                                        */
2501 /*  CALLED BY                                                             */
2502 /*                                                                        */
2503 /*    Application Code                                                    */
2504 /*                                                                        */
2505 /*  RELEASE HISTORY                                                       */
2506 /*                                                                        */
2507 /*    DATE              NAME                      DESCRIPTION             */
2508 /*                                                                        */
2509 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2510 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2511 /*                                            resulting in version 6.1    */
2512 /*                                                                        */
2513 /**************************************************************************/
_nx_web_http_server_stop(NX_WEB_HTTP_SERVER * http_server_ptr)2514 UINT  _nx_web_http_server_stop(NX_WEB_HTTP_SERVER *http_server_ptr)
2515 {
2516 UINT status;
2517 NX_TCPSERVER *tcpserver_ptr = &(http_server_ptr -> nx_web_http_server_tcpserver);
2518 
2519 #ifdef NX_WEB_HTTPS_ENABLE
2520 UINT i;
2521 
2522     /* Stop TLS session if using HTTPS. */
2523     if(http_server_ptr -> nx_web_http_is_https_server)
2524     {
2525         for(i = 0; i < tcpserver_ptr -> nx_tcpserver_sessions_count; i++)
2526         {
2527             nx_secure_tls_session_end(&(tcpserver_ptr -> nx_tcpserver_sessions[i].nx_tcp_session_tls_session), NX_WAIT_FOREVER);
2528         }
2529     }
2530 #endif
2531 
2532     /* Suspend the HTTP server thread.  */
2533     status = nx_tcpserver_stop(tcpserver_ptr);
2534 
2535     /* Return status.  */
2536     return(status);
2537 }
2538 
2539 
2540 /**************************************************************************/
2541 /*                                                                        */
2542 /*  FUNCTION                                               RELEASE        */
2543 /*                                                                        */
2544 /*    _nxe_web_http_server_callback_data_send             PORTABLE C      */
2545 /*                                                           6.1          */
2546 /*  AUTHOR                                                                */
2547 /*                                                                        */
2548 /*    Yuxin Zhou, Microsoft Corporation                                   */
2549 /*                                                                        */
2550 /*  DESCRIPTION                                                           */
2551 /*                                                                        */
2552 /*    This function checks for errors in the data send call.              */
2553 /*                                                                        */
2554 /*                                                                        */
2555 /*  INPUT                                                                 */
2556 /*                                                                        */
2557 /*    http_server_ptr                       Pointer to HTTP server        */
2558 /*    data_ptr                              Pointer to data to send       */
2559 /*    data_length                           Length of data to send        */
2560 /*                                                                        */
2561 /*  OUTPUT                                                                */
2562 /*                                                                        */
2563 /*    status                                Completion status             */
2564 /*                                                                        */
2565 /*  CALLS                                                                 */
2566 /*                                                                        */
2567 /*    _nx_web_http_server_callback_data_send                              */
2568 /*                                          Actual function call          */
2569 /*                                                                        */
2570 /*  CALLED BY                                                             */
2571 /*                                                                        */
2572 /*    Application Code                                                    */
2573 /*                                                                        */
2574 /*  RELEASE HISTORY                                                       */
2575 /*                                                                        */
2576 /*    DATE              NAME                      DESCRIPTION             */
2577 /*                                                                        */
2578 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2579 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2580 /*                                            resulting in version 6.1    */
2581 /*                                                                        */
2582 /**************************************************************************/
_nxe_web_http_server_callback_data_send(NX_WEB_HTTP_SERVER * server_ptr,VOID * data_ptr,ULONG data_length)2583 UINT  _nxe_web_http_server_callback_data_send(NX_WEB_HTTP_SERVER *server_ptr, VOID *data_ptr, ULONG data_length)
2584 {
2585 UINT        status;
2586 
2587     /* Check pointers. */
2588     if(server_ptr == NX_NULL || data_ptr == NX_NULL || server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID)
2589     {
2590         return(NX_PTR_ERROR);
2591     }
2592 
2593     /* Actual function call. */
2594     status = _nx_web_http_server_callback_data_send(server_ptr, data_ptr, data_length);
2595 
2596     /* Return completion status.  */
2597     return(status);
2598 }
2599 
2600 
2601 /**************************************************************************/
2602 /*                                                                        */
2603 /*  FUNCTION                                               RELEASE        */
2604 /*                                                                        */
2605 /*    _nx_web_http_server_callback_data_send              PORTABLE C      */
2606 /*                                                           6.1          */
2607 /*  AUTHOR                                                                */
2608 /*                                                                        */
2609 /*    Yuxin Zhou, Microsoft Corporation                                   */
2610 /*                                                                        */
2611 /*  DESCRIPTION                                                           */
2612 /*                                                                        */
2613 /*    This function sends data to the client from the application         */
2614 /*    callback function. This is typically done to satisfy a GET or       */
2615 /*    POST request that is processed completely by the application        */
2616 /*    callback function.                                                  */
2617 /*                                                                        */
2618 /*                                                                        */
2619 /*  INPUT                                                                 */
2620 /*                                                                        */
2621 /*    http_server_ptr                       Pointer to HTTP server        */
2622 /*    data_ptr                              Pointer to data to send       */
2623 /*    data_length                           Length of data to send        */
2624 /*                                                                        */
2625 /*  OUTPUT                                                                */
2626 /*                                                                        */
2627 /*    status                                Completion status             */
2628 /*                                                                        */
2629 /*  CALLS                                                                 */
2630 /*                                                                        */
2631 /*    _nx_web_http_server_response_packet_allocate                        */
2632 /*                                          Allocate a resonse packet     */
2633 /*    nx_packet_data_append                 Append data to packet         */
2634 /*    nx_tcp_socket_send                    Send TCP data                 */
2635 /*                                                                        */
2636 /*  CALLED BY                                                             */
2637 /*                                                                        */
2638 /*    Application Code                                                    */
2639 /*                                                                        */
2640 /*  RELEASE HISTORY                                                       */
2641 /*                                                                        */
2642 /*    DATE              NAME                      DESCRIPTION             */
2643 /*                                                                        */
2644 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2645 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2646 /*                                            resulting in version 6.1    */
2647 /*                                                                        */
2648 /**************************************************************************/
_nx_web_http_server_callback_data_send(NX_WEB_HTTP_SERVER * server_ptr,VOID * data_ptr,ULONG data_length)2649 UINT  _nx_web_http_server_callback_data_send(NX_WEB_HTTP_SERVER *server_ptr, VOID *data_ptr, ULONG data_length)
2650 {
2651 
2652 NX_PACKET   *new_packet_ptr;
2653 UINT        status;
2654 
2655 
2656     /* Allocate a new packet for data.  */
2657     status =  _nx_web_http_server_response_packet_allocate(server_ptr, &new_packet_ptr, NX_WAIT_FOREVER);
2658 
2659     /* Determine if an error is present.  */
2660     if (status != NX_SUCCESS)
2661     {
2662 
2663         /* Indicate an allocation error occurred.  */
2664         server_ptr -> nx_web_http_server_allocation_errors++;
2665 
2666         /* Error, return to caller.  */
2667         return(NX_WEB_HTTP_ERROR);
2668     }
2669 
2670     /* Now append the data to the packet.  */
2671     status =  nx_packet_data_append(new_packet_ptr, data_ptr, data_length,
2672                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
2673 
2674     /* Determine if an error is present.  */
2675     if (status != NX_SUCCESS)
2676     {
2677 
2678         /* Indicate an allocation error occurred.  */
2679         server_ptr -> nx_web_http_server_allocation_errors++;
2680 
2681         /* Release the initial packet.  */
2682         nx_packet_release(new_packet_ptr);
2683 
2684         /* Error, return to caller.  */
2685         return(status);
2686     }
2687 
2688     /* Send the data back to the client.  */
2689     status = _nx_web_http_server_send(server_ptr, new_packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_SEND);
2690 
2691     /* Determine if this is successful.  */
2692     if (status != NX_SUCCESS)
2693     {
2694         /* Release the packet.  */
2695         nx_packet_release(new_packet_ptr);
2696     }
2697 
2698     /* Return completion status.  */
2699     return(status);
2700 }
2701 
2702 
2703 /**************************************************************************/
2704 /*                                                                        */
2705 /*  FUNCTION                                               RELEASE        */
2706 /*                                                                        */
2707 /*    _nxe_web_http_server_callback_response_send         PORTABLE C      */
2708 /*                                                           6.1          */
2709 /*  AUTHOR                                                                */
2710 /*                                                                        */
2711 /*    Yuxin Zhou, Microsoft Corporation                                   */
2712 /*                                                                        */
2713 /*  DESCRIPTION                                                           */
2714 /*                                                                        */
2715 /*    This function checks for errors in the response send call.          */
2716 /*                                                                        */
2717 /*                                                                        */
2718 /*  INPUT                                                                 */
2719 /*                                                                        */
2720 /*    http_server_ptr                       Pointer to HTTP server        */
2721 /*    status_code                           Status-code and reason-phrase */
2722 /*    information                           Pointer to HTTP info string   */
2723 /*    additional_information                Pointer to additional HTTP    */
2724 /*                                            information                 */
2725 /*                                                                        */
2726 /*  OUTPUT                                                                */
2727 /*                                                                        */
2728 /*    status                                Completion status             */
2729 /*                                                                        */
2730 /*  CALLS                                                                 */
2731 /*                                                                        */
2732 /*    _nxe_web_http_server_callback_response_send                         */
2733 /*                                          Actual function call          */
2734 /*                                                                        */
2735 /*  CALLED BY                                                             */
2736 /*                                                                        */
2737 /*    Application Code                                                    */
2738 /*                                                                        */
2739 /*  RELEASE HISTORY                                                       */
2740 /*                                                                        */
2741 /*    DATE              NAME                      DESCRIPTION             */
2742 /*                                                                        */
2743 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2744 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2745 /*                                            resulting in version 6.1    */
2746 /*                                                                        */
2747 /**************************************************************************/
_nxe_web_http_server_callback_response_send(NX_WEB_HTTP_SERVER * server_ptr,CHAR * status_code,CHAR * information,CHAR * additional_info)2748 UINT  _nxe_web_http_server_callback_response_send(NX_WEB_HTTP_SERVER *server_ptr, CHAR *status_code, CHAR *information, CHAR *additional_info)
2749 {
2750 UINT status;
2751 
2752     if(server_ptr == NX_NULL || status_code == NX_NULL)
2753     {
2754         return(NX_PTR_ERROR);
2755     }
2756 
2757     /* Check for appropriate caller.  */
2758     NX_THREADS_ONLY_CALLER_CHECKING
2759 
2760     /* Actual function call.  */
2761     status = _nx_web_http_server_callback_response_send(server_ptr, status_code, information, additional_info);
2762 
2763     /* Return successful completion.  */
2764     return(status);
2765 }
2766 
2767 
2768 /**************************************************************************/
2769 /*                                                                        */
2770 /*  FUNCTION                                               RELEASE        */
2771 /*                                                                        */
2772 /*    _nx_web_http_server_callback_response_send          PORTABLE C      */
2773 /*                                                           6.1          */
2774 /*  AUTHOR                                                                */
2775 /*                                                                        */
2776 /*    Yuxin Zhou, Microsoft Corporation                                   */
2777 /*                                                                        */
2778 /*  DESCRIPTION                                                           */
2779 /*                                                                        */
2780 /*    This function sends the completion response to the client from the  */
2781 /*    application callback function. This is typically done to satisfy a  */
2782 /*    GET or POST request that is processed completely by the application */
2783 /*    callback function.                                                  */
2784 /*                                                                        */
2785 /*                                                                        */
2786 /*  INPUT                                                                 */
2787 /*                                                                        */
2788 /*    http_server_ptr                       Pointer to HTTP server        */
2789 /*    status_code                           Status-code and reason-phrase */
2790 /*    information                           Pointer to HTTP info string   */
2791 /*    additional_information                Pointer to additional HTTP    */
2792 /*                                            information                 */
2793 /*                                                                        */
2794 /*  OUTPUT                                                                */
2795 /*                                                                        */
2796 /*    status                                Completion status             */
2797 /*                                                                        */
2798 /*  CALLS                                                                 */
2799 /*                                                                        */
2800 /*    _nx_web_http_server_response_send     Send HTTP response            */
2801 /*    _nx_utility_string_length_check       Check string length           */
2802 /*                                                                        */
2803 /*  CALLED BY                                                             */
2804 /*                                                                        */
2805 /*    Application Code                                                    */
2806 /*                                                                        */
2807 /*  RELEASE HISTORY                                                       */
2808 /*                                                                        */
2809 /*    DATE              NAME                      DESCRIPTION             */
2810 /*                                                                        */
2811 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2812 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2813 /*                                            resulting in version 6.1    */
2814 /*                                                                        */
2815 /**************************************************************************/
_nx_web_http_server_callback_response_send(NX_WEB_HTTP_SERVER * server_ptr,CHAR * status_code,CHAR * information,CHAR * additional_info)2816 UINT  _nx_web_http_server_callback_response_send(NX_WEB_HTTP_SERVER *server_ptr, CHAR *status_code, CHAR *information, CHAR *additional_info)
2817 {
2818 
2819 UINT status_code_length = 0;
2820 UINT information_length = 0;
2821 UINT additional_info_length = 0;
2822 UINT status;
2823 
2824 
2825     /* Check length of header, information and additional information.  */
2826     if (_nx_utility_string_length_check(status_code, &status_code_length, NX_MAX_STRING_LENGTH) ||
2827         (information && _nx_utility_string_length_check(information, &information_length, NX_MAX_STRING_LENGTH)) ||
2828         (additional_info && _nx_utility_string_length_check(additional_info, &additional_info_length, NX_MAX_STRING_LENGTH)))
2829     {
2830         return(NX_WEB_HTTP_ERROR);
2831     }
2832 
2833     /* Call the internal HTTP response send function.  */
2834     status = _nx_web_http_server_response_send(server_ptr, status_code, status_code_length, information,
2835                                                information_length, additional_info, additional_info_length);
2836 
2837     /* Return status.  */
2838     return(status);
2839 }
2840 
2841 /**************************************************************************/
2842 /*                                                                        */
2843 /*  FUNCTION                                               RELEASE        */
2844 /*                                                                        */
2845 /*    _nxe_web_http_server_callback_response_send_extended                */
2846 /*                                                        PORTABLE C      */
2847 /*                                                           6.1          */
2848 /*  AUTHOR                                                                */
2849 /*                                                                        */
2850 /*    Yuxin Zhou, Microsoft Corporation                                   */
2851 /*                                                                        */
2852 /*  DESCRIPTION                                                           */
2853 /*                                                                        */
2854 /*    This function checks for errors in the response send call.          */
2855 /*                                                                        */
2856 /*                                                                        */
2857 /*  INPUT                                                                 */
2858 /*                                                                        */
2859 /*    http_server_ptr                       Pointer to HTTP server        */
2860 /*    status_code                           Status-code and reason-phrase */
2861 /*    status_code_length                    Length of status-code         */
2862 /*    information                           Pointer to HTTP info string   */
2863 /*    information_length                    Length of information         */
2864 /*    additional_information                Pointer to additional HTTP    */
2865 /*                                            information                 */
2866 /*    additional_information_length         Length of additional          */
2867 /*                                            information                 */
2868 /*                                                                        */
2869 /*  OUTPUT                                                                */
2870 /*                                                                        */
2871 /*    status                                Completion status             */
2872 /*                                                                        */
2873 /*  CALLS                                                                 */
2874 /*                                                                        */
2875 /*    _nxe_web_http_server_callback_response_send_extended                */
2876 /*                                          Actual function call          */
2877 /*                                                                        */
2878 /*  CALLED BY                                                             */
2879 /*                                                                        */
2880 /*    Application Code                                                    */
2881 /*                                                                        */
2882 /*  RELEASE HISTORY                                                       */
2883 /*                                                                        */
2884 /*    DATE              NAME                      DESCRIPTION             */
2885 /*                                                                        */
2886 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2887 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2888 /*                                            resulting in version 6.1    */
2889 /*                                                                        */
2890 /**************************************************************************/
_nxe_web_http_server_callback_response_send_extended(NX_WEB_HTTP_SERVER * server_ptr,CHAR * status_code,UINT status_code_length,CHAR * information,UINT information_length,CHAR * additional_info,UINT additional_information_length)2891 UINT _nxe_web_http_server_callback_response_send_extended(NX_WEB_HTTP_SERVER *server_ptr, CHAR *status_code,
2892                                                           UINT status_code_length, CHAR *information,
2893                                                           UINT information_length, CHAR *additional_info,
2894                                                           UINT additional_information_length)
2895 {
2896 UINT status;
2897 
2898     if(server_ptr == NX_NULL || status_code == NX_NULL)
2899     {
2900         return(NX_PTR_ERROR);
2901     }
2902 
2903     /* Check for appropriate caller.  */
2904     NX_THREADS_ONLY_CALLER_CHECKING
2905 
2906     /* Actual function call.  */
2907     status = _nx_web_http_server_callback_response_send_extended(server_ptr, status_code, status_code_length,
2908                                                                  information, information_length,
2909                                                                  additional_info, additional_information_length);
2910 
2911     /* Return successful completion.  */
2912     return(status);
2913 }
2914 
2915 
2916 /**************************************************************************/
2917 /*                                                                        */
2918 /*  FUNCTION                                               RELEASE        */
2919 /*                                                                        */
2920 /*    _nx_web_http_server_callback_response_send_extended PORTABLE C      */
2921 /*                                                           6.1          */
2922 /*  AUTHOR                                                                */
2923 /*                                                                        */
2924 /*    Yuxin Zhou, Microsoft Corporation                                   */
2925 /*                                                                        */
2926 /*  DESCRIPTION                                                           */
2927 /*                                                                        */
2928 /*    This function sends the completion response to the client from the  */
2929 /*    application callback function. This is typically done to satisfy a  */
2930 /*    GET or POST request that is processed completely by the application */
2931 /*    callback function.                                                  */
2932 /*                                                                        */
2933 /*    Note: The strings of status_code, information and                   */
2934 /*    additional_information must be NULL-terminated and length of each   */
2935 /*    string matches the length specified in the argument list.           */
2936 /*                                                                        */
2937 /*                                                                        */
2938 /*  INPUT                                                                 */
2939 /*                                                                        */
2940 /*    http_server_ptr                       Pointer to HTTP server        */
2941 /*    status_code                           Status-code and reason-phrase */
2942 /*    status_code_length                    Length of status-code         */
2943 /*    information                           Pointer to HTTP info string   */
2944 /*    information_length                    Length of information         */
2945 /*    additional_information                Pointer to additional HTTP    */
2946 /*                                            information                 */
2947 /*    additional_information_length         Length of additional          */
2948 /*                                            information                 */
2949 /*                                                                        */
2950 /*  OUTPUT                                                                */
2951 /*                                                                        */
2952 /*    status                                Completion status             */
2953 /*                                                                        */
2954 /*  CALLS                                                                 */
2955 /*                                                                        */
2956 /*    _nx_web_http_server_response_send     Send HTTP response            */
2957 /*    _nx_utility_string_length_check       Check string length           */
2958 /*                                                                        */
2959 /*  CALLED BY                                                             */
2960 /*                                                                        */
2961 /*    Application Code                                                    */
2962 /*                                                                        */
2963 /*  RELEASE HISTORY                                                       */
2964 /*                                                                        */
2965 /*    DATE              NAME                      DESCRIPTION             */
2966 /*                                                                        */
2967 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2968 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2969 /*                                            resulting in version 6.1    */
2970 /*                                                                        */
2971 /**************************************************************************/
_nx_web_http_server_callback_response_send_extended(NX_WEB_HTTP_SERVER * server_ptr,CHAR * status_code,UINT status_code_length,CHAR * information,UINT information_length,CHAR * additional_info,UINT additional_info_length)2972 UINT _nx_web_http_server_callback_response_send_extended(NX_WEB_HTTP_SERVER *server_ptr, CHAR *status_code,
2973                                                          UINT status_code_length, CHAR *information,
2974                                                          UINT information_length, CHAR *additional_info,
2975                                                          UINT additional_info_length)
2976 {
2977 UINT temp_status_code_length = 0;
2978 UINT temp_information_length = 0;
2979 UINT temp_additional_info_length = 0;
2980 
2981     /* Check length of status_code, information and additional information.  */
2982     if (_nx_utility_string_length_check(status_code, &temp_status_code_length, NX_MAX_STRING_LENGTH) ||
2983         (information && _nx_utility_string_length_check(information, &temp_information_length, NX_MAX_STRING_LENGTH)) ||
2984         (additional_info && _nx_utility_string_length_check(additional_info, &temp_additional_info_length, NX_MAX_STRING_LENGTH)))
2985     {
2986         return(NX_WEB_HTTP_ERROR);
2987     }
2988 
2989     /* Validate string length.  */
2990     if ((temp_status_code_length != status_code_length) ||
2991         (information && (temp_information_length != information_length)) ||
2992         (additional_info && (temp_additional_info_length != additional_info_length)))
2993     {
2994         return(NX_WEB_HTTP_ERROR);
2995     }
2996 
2997     /* Call the internal HTTP response send function.  */
2998     return(_nx_web_http_server_response_send(server_ptr, status_code, status_code_length, information,
2999                                              information_length, additional_info, additional_info_length));
3000 }
3001 
3002 /**************************************************************************/
3003 /*                                                                        */
3004 /*  FUNCTION                                               RELEASE        */
3005 /*                                                                        */
3006 /*    _nx_web_http_server_connection_end                  PORTABLE C      */
3007 /*                                                           6.1          */
3008 /*  AUTHOR                                                                */
3009 /*                                                                        */
3010 /*    Yuxin Zhou, Microsoft Corporation                                   */
3011 /*                                                                        */
3012 /*  DESCRIPTION                                                           */
3013 /*                                                                        */
3014 /*    This function is an internal callback used by the TCP server when a */
3015 /*    TCP connection is ready to close.                                   */
3016 /*                                                                        */
3017 /*                                                                        */
3018 /*  INPUT                                                                 */
3019 /*                                                                        */
3020 /*    tcpserver_ptr                         Pointer to TCP server         */
3021 /*    session_ptr                           Pointer to TCP session        */
3022 /*                                                                        */
3023 /*  OUTPUT                                                                */
3024 /*                                                                        */
3025 /*    None                                                                */
3026 /*                                                                        */
3027 /*  CALLS                                                                 */
3028 /*                                                                        */
3029 /*    _nx_web_http_server_connection_disconnect                           */
3030 /*                                          Disconnect TCP or TLS         */
3031 /*                                                                        */
3032 /*  CALLED BY                                                             */
3033 /*                                                                        */
3034 /*    NetX Duo                                                            */
3035 /*                                                                        */
3036 /*  RELEASE HISTORY                                                       */
3037 /*                                                                        */
3038 /*    DATE              NAME                      DESCRIPTION             */
3039 /*                                                                        */
3040 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3041 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3042 /*                                            resulting in version 6.1    */
3043 /*                                                                        */
3044 /**************************************************************************/
_nx_web_http_server_connection_end(NX_TCPSERVER * tcpserver_ptr,NX_TCP_SESSION * session_ptr)3045 VOID        _nx_web_http_server_connection_end(NX_TCPSERVER *tcpserver_ptr, NX_TCP_SESSION *session_ptr)
3046 {
3047 NX_WEB_HTTP_SERVER *server_ptr;
3048 
3049 
3050     /* Get the HTTP server pointer.  */
3051     server_ptr =  (NX_WEB_HTTP_SERVER *) tcpserver_ptr -> nx_tcpserver_reserved;
3052 
3053     /* Disconnect the TCP server (and end TLS if used). */
3054     _nx_web_http_server_connection_disconnect(server_ptr, session_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_DISCONNECT);
3055 }
3056 
3057 
3058 /**************************************************************************/
3059 /*                                                                        */
3060 /*  FUNCTION                                               RELEASE        */
3061 /*                                                                        */
3062 /*    _nx_web_http_server_connection_timeout              PORTABLE C      */
3063 /*                                                           6.1          */
3064 /*  AUTHOR                                                                */
3065 /*                                                                        */
3066 /*    Yuxin Zhou, Microsoft Corporation                                   */
3067 /*                                                                        */
3068 /*  DESCRIPTION                                                           */
3069 /*                                                                        */
3070 /*    This function is an internal callback used by the TCP server when a */
3071 /*    TCP connection times out.                                           */
3072 /*                                                                        */
3073 /*                                                                        */
3074 /*  INPUT                                                                 */
3075 /*                                                                        */
3076 /*    tcpserver_ptr                         Pointer to TCP server         */
3077 /*    session_ptr                           Pointer to TCP session        */
3078 /*                                                                        */
3079 /*  OUTPUT                                                                */
3080 /*                                                                        */
3081 /*    None                                                                */
3082 /*                                                                        */
3083 /*  CALLS                                                                 */
3084 /*                                                                        */
3085 /*    _nx_web_http_server_connection_disconnect                           */
3086 /*                                          Disconnect TCP or TLS         */
3087 /*                                                                        */
3088 /*  CALLED BY                                                             */
3089 /*                                                                        */
3090 /*    NetX Duo                                                            */
3091 /*                                                                        */
3092 /*  RELEASE HISTORY                                                       */
3093 /*                                                                        */
3094 /*    DATE              NAME                      DESCRIPTION             */
3095 /*                                                                        */
3096 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3097 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3098 /*                                            resulting in version 6.1    */
3099 /*                                                                        */
3100 /**************************************************************************/
_nx_web_http_server_connection_timeout(NX_TCPSERVER * tcpserver_ptr,NX_TCP_SESSION * session_ptr)3101 VOID        _nx_web_http_server_connection_timeout(NX_TCPSERVER *tcpserver_ptr, NX_TCP_SESSION *session_ptr)
3102 {
3103 NX_WEB_HTTP_SERVER *server_ptr;
3104 
3105 
3106     /* Get the HTTP server pointer.  */
3107     server_ptr =  (NX_WEB_HTTP_SERVER *) tcpserver_ptr -> nx_tcpserver_reserved;
3108 
3109     /* Disconnect the TCP server (and end TLS if used). */
3110     _nx_web_http_server_connection_disconnect(server_ptr, session_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_DISCONNECT);
3111 }
3112 
3113 
3114 /**************************************************************************/
3115 /*                                                                        */
3116 /*  FUNCTION                                               RELEASE        */
3117 /*                                                                        */
3118 /*    _nx_web_http_server_receive_data                    PORTABLE C      */
3119 /*                                                           6.1          */
3120 /*  AUTHOR                                                                */
3121 /*                                                                        */
3122 /*    Yuxin Zhou, Microsoft Corporation                                   */
3123 /*                                                                        */
3124 /*  DESCRIPTION                                                           */
3125 /*                                                                        */
3126 /*    This function is the callback function executed whenever a client   */
3127 /*    connection appears on the HTTP Server port.  It is responsible for  */
3128 /*    waking up the HTTP Server thread.                                   */
3129 /*                                                                        */
3130 /*                                                                        */
3131 /*  INPUT                                                                 */
3132 /*                                                                        */
3133 /*    socket_ptr                            Pointer to HTTP Server socket */
3134 /*    port                                  HTTP Server port              */
3135 /*                                                                        */
3136 /*  OUTPUT                                                                */
3137 /*                                                                        */
3138 /*    None                                                                */
3139 /*                                                                        */
3140 /*  CALLS                                                                 */
3141 /*                                                                        */
3142 /*    _nx_web_http_server_get_client_request                              */
3143 /*                                          Get request from client       */
3144 /*    _nx_web_http_server_connection_disconnect                           */
3145 /*                                          Disconnect connection         */
3146 /*    _nx_web_http_server_get_client_keepalive                            */
3147 /*                                          Get keepalive flag            */
3148 /*    _nx_web_http_server_chunked_check     Check if the packet is chunked*/
3149 /*    _nx_web_http_server_get_process       Process GET request           */
3150 /*    _nx_web_http_server_put_process       Process PUT request           */
3151 /*    _nx_web_http_server_delete_process    Process DELETE request        */
3152 /*    _nx_web_http_server_response_packet_allocate                        */
3153 /*                                          Allocate a response packet    */
3154 /*                                                                        */
3155 /*  CALLED BY                                                             */
3156 /*                                                                        */
3157 /*    NetX                                                                */
3158 /*                                                                        */
3159 /*  RELEASE HISTORY                                                       */
3160 /*                                                                        */
3161 /*    DATE              NAME                      DESCRIPTION             */
3162 /*                                                                        */
3163 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3164 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3165 /*                                            resulting in version 6.1    */
3166 /*                                                                        */
3167 /**************************************************************************/
_nx_web_http_server_receive_data(NX_TCPSERVER * tcpserver_ptr,NX_TCP_SESSION * session_ptr)3168 VOID  _nx_web_http_server_receive_data(NX_TCPSERVER *tcpserver_ptr, NX_TCP_SESSION *session_ptr)
3169 {
3170 
3171 NX_WEB_HTTP_SERVER      *server_ptr;
3172 NX_PACKET               *packet_ptr;
3173 UCHAR                   *buffer_ptr;
3174 UINT                    status;
3175 NX_PACKET               *response_pkt;
3176 
3177 
3178     /* Set the HTTP server pointer.  */
3179     server_ptr =  (NX_WEB_HTTP_SERVER *) tcpserver_ptr -> nx_tcpserver_reserved;
3180 
3181     /* Store the current session. */
3182     server_ptr -> nx_web_http_server_current_session_ptr = session_ptr;
3183 
3184     /* Get the complete HTTP client request.  */
3185     status =  _nx_web_http_server_get_client_request(server_ptr, &packet_ptr);
3186 
3187     /* Check if the HTTP request is valid.  */
3188     if (status == NX_SUCCESS)
3189     {
3190         if (packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr < 7)
3191         {
3192             nx_packet_release(packet_ptr);
3193             status = NX_WEB_HTTP_ERROR;
3194         }
3195     }
3196 
3197     /* Determine if it was successful.  */
3198     if (status != NX_SUCCESS)
3199     {
3200 
3201         if(status != NX_NO_PACKET)
3202         {
3203 
3204             /* Increment the number of invalid HTTP requests.  */
3205             server_ptr -> nx_web_http_server_invalid_http_headers++;
3206         }
3207 
3208         /* Disconnect from the current connection.  */
3209         _nx_web_http_server_connection_disconnect(server_ptr, session_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_DISCONNECT);
3210 
3211         /* Return.  */
3212         return;
3213     }
3214 
3215 #ifndef NX_WEB_HTTP_KEEPALIVE_DISABLE
3216     /* Check whether keepalive is necessary. */
3217     _nx_web_http_server_get_client_keepalive(server_ptr, packet_ptr);
3218 #endif /* NX_WEB_HTTP_KEEPALIVE_DISABLE */
3219 
3220     /* Check if the packet is chunked.  */
3221     server_ptr -> nx_web_http_server_request_chunked = (UCHAR)_nx_web_http_server_chunked_check(packet_ptr);
3222     server_ptr -> nx_web_http_server_expect_receive_bytes = 0;
3223     server_ptr -> nx_web_http_server_actual_bytes_received = 0;
3224 
3225     /* Otherwise, we have received an HTTP client request successfully.  */
3226 
3227     /* Setup a pointer to packet buffer area.  */
3228     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
3229 
3230     /* Determine what type of request is present.  */
3231 
3232     /* Check for a GET request.  */
3233     if ((buffer_ptr[0] == 'G') && (buffer_ptr[1] == 'E') && (buffer_ptr[2] == 'T') && (buffer_ptr[3] == ' '))
3234     {
3235 
3236         /* We have a HTTP GET request to get a resource from this HTTP Server.  */
3237         server_ptr -> nx_web_http_server_request_type = NX_WEB_HTTP_SERVER_GET_REQUEST;
3238 
3239         /* Increment the number of GET requests.  */
3240         server_ptr -> nx_web_http_server_get_requests++;
3241 
3242         /* Process the GET request.  */
3243         _nx_web_http_server_get_process(server_ptr, NX_WEB_HTTP_SERVER_GET_REQUEST, packet_ptr);
3244     }
3245 
3246     /* Check for a PUT request.  */
3247     else if ((buffer_ptr[0] == 'P') && (buffer_ptr[1] == 'U') && (buffer_ptr[2] == 'T') && (buffer_ptr[3] == ' '))
3248     {
3249 
3250         /* We have a HTTP PUT request to store a resource on this HTTP Server.  */
3251         server_ptr -> nx_web_http_server_request_type = NX_WEB_HTTP_SERVER_PUT_REQUEST;
3252 
3253         /* Increment the number of PUT requests.  */
3254         server_ptr -> nx_web_http_server_put_requests++;
3255 
3256         /* Process the PUT request.  */
3257         _nx_web_http_server_put_process(server_ptr, packet_ptr);
3258     }
3259 
3260     /* Check for a DELETE request.  */
3261     else if ((buffer_ptr[0] == 'D') && (buffer_ptr[1] == 'E') && (buffer_ptr[2] == 'L') && (buffer_ptr[3] == 'E') &&
3262              (buffer_ptr[4] == 'T') && (buffer_ptr[5] == 'E') && (buffer_ptr[6] == ' '))
3263     {
3264 
3265         /* We have a HTTP DELETE request to delete a resource from this HTTP Server.  */
3266         server_ptr -> nx_web_http_server_request_type = NX_WEB_HTTP_SERVER_DELETE_REQUEST;
3267 
3268         /* Increment the number of DELETE requests.  */
3269         server_ptr -> nx_web_http_server_delete_requests++;
3270 
3271         /* Process the Delete request.  */
3272         _nx_web_http_server_delete_process(server_ptr, packet_ptr);
3273     }
3274 
3275     /* Check for a POST request.  */
3276     else if ((buffer_ptr[0] == 'P') && (buffer_ptr[1] == 'O') && (buffer_ptr[2] == 'S') &&
3277              (buffer_ptr[3] == 'T') && (buffer_ptr[4] == ' '))
3278     {
3279 
3280         /* We have a HTTP POST request to send data to this HTTP Server for processing.  Note that the POST
3281            request is nearly identical to the GET request, except the parameter/query data is found in the
3282            content rather than as part of the URL (resource). */
3283         server_ptr -> nx_web_http_server_request_type = NX_WEB_HTTP_SERVER_POST_REQUEST;
3284 
3285         /* Increment the number of POST requests.  */
3286         server_ptr -> nx_web_http_server_post_requests++;
3287 
3288 #ifdef NX_WEB_HTTP_MULTIPART_ENABLE
3289 
3290         /* Reset last received multipart packet. */
3291         server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_last_packet = NX_NULL;
3292 #endif /* NX_WEB_HTTP_MULTIPART_ENABLE */
3293 
3294         /* Process the POST request.  */
3295         _nx_web_http_server_get_process(server_ptr, NX_WEB_HTTP_SERVER_POST_REQUEST, packet_ptr);
3296 
3297 #ifdef NX_WEB_HTTP_MULTIPART_ENABLE
3298         /* Restore the packet to release. */
3299         if (server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_last_packet)
3300             packet_ptr = server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_last_packet;
3301 #endif /* NX_WEB_HTTP_MULTIPART_ENABLE */
3302     }
3303 
3304     /* Check for a HEAD request.  */
3305     else if ((buffer_ptr[0] == 'H') && (buffer_ptr[1] == 'E') && (buffer_ptr[2] == 'A') &&
3306              (buffer_ptr[3] == 'D') && (buffer_ptr[4] == ' '))
3307     {
3308 
3309         /* We have a HTTP HEAD request to get a resource header from this HTTP Server.  Note that the HEAD
3310            request is nearly identical to the GET request, except the requested content is not returned to
3311            the client.  */
3312         server_ptr -> nx_web_http_server_request_type = NX_WEB_HTTP_SERVER_HEAD_REQUEST;
3313 
3314         /* Increment the number of HEAD requests.  */
3315         server_ptr -> nx_web_http_server_head_requests++;
3316 
3317         /* Process the HEAD request.  */
3318         _nx_web_http_server_get_process(server_ptr, NX_WEB_HTTP_SERVER_HEAD_REQUEST, packet_ptr);
3319     }
3320 
3321     /* Unhandled request.  */
3322     else
3323     {
3324 
3325         /* We have an unhandled HTTP request.  */
3326         server_ptr -> nx_web_http_server_request_type = NX_WEB_HTTP_SERVER_UNKNOWN_REQUEST;
3327 
3328         /* Send response back to HTTP Client.  */
3329         _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_NOT_IMPLEMENTED,
3330                                           sizeof(NX_WEB_HTTP_STATUS_NOT_IMPLEMENTED) - 1,
3331                                           "NetX HTTP Request Not Implemented",
3332                                           sizeof("NetX HTTP Request Not Implemented") - 1, NX_NULL, 0);
3333 
3334         /* Increment the number of unhandled requests.  */
3335         server_ptr -> nx_web_http_server_unknown_requests++;
3336     }
3337 
3338     /* Release the packet.  */
3339     nx_packet_release(packet_ptr);
3340 
3341     /* Release the unprocessed packet.  */
3342     if (server_ptr -> nx_web_http_server_request_packet)
3343     {
3344         nx_packet_release(server_ptr -> nx_web_http_server_request_packet);
3345         server_ptr -> nx_web_http_server_request_packet = NX_NULL;
3346     }
3347 
3348     /* If there are no more data to send, append the last chunk.  */
3349     if (server_ptr -> nx_web_http_server_response_chunked)
3350     {
3351 
3352         /* Allocate a packet to send the chunk end.  */
3353         status = _nx_web_http_server_response_packet_allocate(server_ptr, &response_pkt, NX_WAIT_FOREVER);
3354         if (status)
3355         {
3356 
3357             /* Disconnect from the current connection.  */
3358             _nx_web_http_server_connection_disconnect(server_ptr, session_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_DISCONNECT);
3359             return;
3360         }
3361 
3362         nx_packet_data_append(response_pkt, "0\r\n\r\n", 5, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
3363 
3364         /* Send internal. */
3365         status = _nx_web_http_server_send(server_ptr, response_pkt, NX_WEB_HTTP_SERVER_TIMEOUT_SEND);
3366         if (status)
3367         {
3368 
3369             /* Disconnect from the current connection.  */
3370             _nx_web_http_server_connection_disconnect(server_ptr, session_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_DISCONNECT);
3371 
3372             nx_packet_release(response_pkt);
3373             return;
3374         }
3375 
3376         server_ptr -> nx_web_http_server_response_chunked = NX_FALSE;
3377     }
3378 
3379 #ifndef NX_WEB_HTTP_KEEPALIVE_DISABLE
3380     if(server_ptr -> nx_web_http_server_keepalive == NX_FALSE)
3381     {
3382 #endif
3383         /* Disconnect from the current connection.  */
3384         _nx_web_http_server_connection_disconnect(server_ptr, session_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_DISCONNECT);
3385 
3386 #ifndef NX_WEB_HTTP_KEEPALIVE_DISABLE
3387     }
3388 #endif
3389 
3390     return;
3391 }
3392 
3393 
3394 /**************************************************************************/
3395 /*                                                                        */
3396 /*  FUNCTION                                               RELEASE        */
3397 /*                                                                        */
3398 /*    _nx_web_http_server_get_client_request              PORTABLE C      */
3399 /*                                                           6.1          */
3400 /*  AUTHOR                                                                */
3401 /*                                                                        */
3402 /*    Yuxin Zhou, Microsoft Corporation                                   */
3403 /*                                                                        */
3404 /*  DESCRIPTION                                                           */
3405 /*                                                                        */
3406 /*    This function retrieves the complete HTTP client request in a single*/
3407 /*    packet.  Doing this makes the other parsing and searching           */
3408 /*    routines simple.                                                    */
3409 /*                                                                        */
3410 /*                                                                        */
3411 /*  INPUT                                                                 */
3412 /*                                                                        */
3413 /*    server_ptr                            HTTP Server pointer           */
3414 /*    packet_ptr                            Destination for request       */
3415 /*                                            packet pointer              */
3416 /*                                                                        */
3417 /*  OUTPUT                                                                */
3418 /*                                                                        */
3419 /*    status                                Completion status             */
3420 /*                                                                        */
3421 /*  CALLS                                                                 */
3422 /*                                                                        */
3423 /*    nx_packet_copy                        Copy packet                   */
3424 /*    nx_packet_data_append                 Move data into packet         */
3425 /*    nx_packet_release                     Release packet                */
3426 /*    nx_tcp_socket_receive                 Receive an HTTP request packet*/
3427 /*                                                                        */
3428 /*  CALLED BY                                                             */
3429 /*    _nx_web_http_server_receive_data                                    */
3430 /*                                                                        */
3431 /*  RELEASE HISTORY                                                       */
3432 /*                                                                        */
3433 /*    DATE              NAME                      DESCRIPTION             */
3434 /*                                                                        */
3435 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3436 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3437 /*                                            resulting in version 6.1    */
3438 /*                                                                        */
3439 /**************************************************************************/
_nx_web_http_server_get_client_request(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr)3440 UINT  _nx_web_http_server_get_client_request(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr)
3441 {
3442 
3443 NX_PACKET   *head_packet_ptr;
3444 NX_PACKET   *new_packet_ptr;
3445 CHAR        *buffer_ptr;
3446 UINT        status;
3447 NX_PACKET   *work_ptr;
3448 UINT        crlf_found = 0;
3449 NX_PACKET   *tmp_ptr;
3450 
3451 
3452     /* Default the return packet pointer to NULL.  */
3453     *packet_ptr =  NX_NULL;
3454 
3455     /* Wait for a request on the HTTP TCP well known port 80, or if encryption is enabled 443.  */
3456     status = _nx_web_http_server_receive(server_ptr, &head_packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_RECEIVE);
3457 
3458     /* At this point, the server has a connection with an HTTP Client  */
3459 
3460     /* Check the return status.  */
3461     if (status != NX_SUCCESS)
3462     {
3463 
3464         /* Return an error condition.  */
3465         return(status);
3466     }
3467 
3468     /* Setup pointer to start of buffer.  */
3469     buffer_ptr =  (CHAR *) head_packet_ptr -> nx_packet_prepend_ptr;
3470 
3471     /* Determine if the packet is an HTTP request.  */
3472     if ((buffer_ptr[0] != 'G') && (buffer_ptr[0] != 'g') && (buffer_ptr[0] != 'P') && (buffer_ptr[0] != 'p') &&
3473         (buffer_ptr[0] != 'D') && (buffer_ptr[0] != 'd') && (buffer_ptr[0] != 'H') && (buffer_ptr[0] != 'h') &&
3474         (buffer_ptr[0] != 'T') && (buffer_ptr[0] != 't'))
3475     {
3476 
3477         /* Invalid first packet for HTTP request.  */
3478 
3479         /* Release the packet.  */
3480         nx_packet_release(head_packet_ptr);
3481 
3482         /* Return an error.  */
3483         return(NX_WEB_HTTP_ERROR);
3484     }
3485 
3486     crlf_found = 0;
3487     work_ptr = head_packet_ptr;
3488 
3489     /* Build a pointer to the buffer area.  */
3490     buffer_ptr =  (CHAR *) work_ptr -> nx_packet_prepend_ptr;
3491 
3492     do
3493     {
3494 
3495         /* See if there is a blank line present in the buffer.  */
3496         /* Search the buffer for a cr/lf pair.  */
3497         while (buffer_ptr < (CHAR *) work_ptr -> nx_packet_append_ptr)
3498         {
3499             if (!(crlf_found & 1) && (*buffer_ptr == (CHAR)13))
3500             {
3501 
3502                 /* Found CR. */
3503                 crlf_found++;
3504             }
3505             else if((crlf_found & 1) && (*buffer_ptr == (CHAR)10))
3506             {
3507 
3508                 /* Found LF. */
3509                 crlf_found++;
3510             }
3511             else
3512             {
3513 
3514                 /* Reset the CRLF marker. */
3515                 crlf_found = 0;
3516             }
3517 
3518             if (crlf_found == 4)
3519             {
3520 
3521                 /* Yes, we have found the end of the HTTP request header.  */
3522 
3523                 /* Set the return packet pointer.  */
3524                 *packet_ptr =  head_packet_ptr;
3525 
3526                 /* Return a successful completion.  */
3527                 return(NX_SUCCESS);
3528             }
3529 
3530             /* Move the buffer pointer up.  */
3531             buffer_ptr++;
3532         }
3533 
3534         /* Determine if the packet has already overflowed into another packet.  */
3535 
3536 #ifndef NX_DISABLE_PACKET_CHAIN
3537 
3538         if (work_ptr -> nx_packet_next != NX_NULL)
3539         {
3540             /* Get the next packet in the chain. */
3541             work_ptr  = work_ptr -> nx_packet_next;
3542             buffer_ptr =  (CHAR *) work_ptr -> nx_packet_prepend_ptr;
3543         }
3544         else
3545 
3546 #endif
3547         {
3548             /* Receive another packet from the HTTP server port.  */
3549             status = _nx_web_http_server_receive(server_ptr, &new_packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_RECEIVE);
3550 
3551             /* Check the return status.  */
3552             if (status != NX_SUCCESS)
3553             {
3554 
3555                 /* Release the current head packet.  */
3556                 nx_packet_release(head_packet_ptr);
3557 
3558                 /* Return an error condition.  */
3559                 return(status);
3560             }
3561 
3562             /* Successfully received another packet.  Its contents now need to be placed in the head packet.  */
3563             tmp_ptr = new_packet_ptr;
3564 #ifndef NX_DISABLE_PACKET_CHAIN
3565             while (tmp_ptr)
3566             {
3567 #endif /* NX_DISABLE_PACKET_CHAIN */
3568 
3569                 /* Copy the contents of the current packet into the head packet.  */
3570                 status =  nx_packet_data_append(head_packet_ptr, (VOID *) tmp_ptr -> nx_packet_prepend_ptr,
3571                                                 (ULONG)(tmp_ptr -> nx_packet_append_ptr - tmp_ptr -> nx_packet_prepend_ptr),
3572                                                 server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WEB_HTTP_SERVER_TIMEOUT);
3573 
3574                 /* Determine if an error occurred.  */
3575                 if (status != NX_SUCCESS)
3576                 {
3577 
3578                     /* Yes, an error is present.  */
3579 
3580                     /* Release both packets.  */
3581                     nx_packet_release(head_packet_ptr);
3582                     nx_packet_release(new_packet_ptr);
3583 
3584                     /* Return an error condition.  */
3585                     return(status);
3586                 }
3587 
3588 #ifndef NX_DISABLE_PACKET_CHAIN
3589                 tmp_ptr = tmp_ptr -> nx_packet_next;
3590             }
3591 #endif /* NX_DISABLE_PACKET_CHAIN */
3592 
3593             /* Release the new packet. */
3594             nx_packet_release(new_packet_ptr);
3595         }
3596 
3597     } while (status == NX_SUCCESS);
3598 
3599     /* Release the packet.  */
3600     nx_packet_release(head_packet_ptr);
3601 
3602     return NX_WEB_HTTP_ERROR;
3603 }
3604 
3605 
3606 /**************************************************************************/
3607 /*                                                                        */
3608 /*  FUNCTION                                               RELEASE        */
3609 /*                                                                        */
3610 /*    _nx_web_http_server_get_process                     PORTABLE C      */
3611 /*                                                           6.1          */
3612 /*  AUTHOR                                                                */
3613 /*                                                                        */
3614 /*    Yuxin Zhou, Microsoft Corporation                                   */
3615 /*                                                                        */
3616 /*  DESCRIPTION                                                           */
3617 /*                                                                        */
3618 /*    This function processes the GET, POST, and HEAD HTTP client         */
3619 /*    requests.                                                           */
3620 /*                                                                        */
3621 /*                                                                        */
3622 /*  INPUT                                                                 */
3623 /*                                                                        */
3624 /*    server_ptr                            HTTP Server pointer           */
3625 /*    request_type                          Type of request (GET, POST,   */
3626 /*                                            or HEAD)                    */
3627 /*    packet_ptr                            Request packet pointer        */
3628 /*                                                                        */
3629 /*  OUTPUT                                                                */
3630 /*                                                                        */
3631 /*    None                                                                */
3632 /*                                                                        */
3633 /*  CALLS                                                                 */
3634 /*                                                                        */
3635 /*    _nx_web_http_server_basic_authenticate                              */
3636 /*                                          Process basic authentication  */
3637 /*    _nx_web_http_server_digest_authenticate                             */
3638 /*                                          Process digest authentication */
3639 /*    _nx_web_http_server_calculate_content_offset                        */
3640 /*                                          Retrieve content offset       */
3641 /*    _nx_web_http_server_content_length_get                              */
3642 /*                                          Retrieve content length       */
3643 /*    _nx_web_http_server_response_send     Send response back to client  */
3644 /*    _nx_web_http_server_retrieve_resource Retrieve resource from request*/
3645 /*    _nx_web_http_server_type_get_extended Derive file type              */
3646 /*    _nx_web_http_server_packet_get        Receive another packet        */
3647 /*    _nx_web_http_server_field_value_get   Get field value               */
3648 /*    nx_tcp_socket_transmit_configure      Configure the server socket   */
3649 /*    fx_directory_information_get          Get length of resource file   */
3650 /*    fx_file_close                         Close resource file           */
3651 /*    fx_file_open                          Open resource file            */
3652 /*    fx_file_read                          Read data from resource file  */
3653 /*    _nx_web_http_server_reponse_packet_allocate                         */
3654 /*                                          Allocate a response packet    */
3655 /*    nx_packet_release                     Release packet                */
3656 /*    _nx_utility_string_length_check       Check string length           */
3657 /*                                                                        */
3658 /*  CALLED BY                                                             */
3659 /*                                                                        */
3660 /*    _nx_web_http_server_receive_data      HTTP receive processing       */
3661 /*                                                                        */
3662 /*  RELEASE HISTORY                                                       */
3663 /*                                                                        */
3664 /*    DATE              NAME                      DESCRIPTION             */
3665 /*                                                                        */
3666 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3667 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3668 /*                                            resulting in version 6.1    */
3669 /*                                                                        */
3670 /**************************************************************************/
_nx_web_http_server_get_process(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,NX_PACKET * packet_ptr)3671 VOID  _nx_web_http_server_get_process(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, NX_PACKET *packet_ptr)
3672 {
3673 
3674 ULONG       length = 0;
3675 UINT        file_type_length;
3676 UINT        status;
3677 NX_PACKET   *new_packet_ptr;
3678 CHAR        *name_ptr;
3679 CHAR        *password_ptr;
3680 CHAR        *realm_ptr;
3681 ULONG       temp;
3682 CHAR        temp_string[30];
3683 UINT        auth_request_present = NX_FALSE;
3684 NX_TCP_SOCKET *socket_ptr = &server_ptr -> nx_web_http_server_current_session_ptr -> nx_tcp_session_socket;
3685 UINT        offset = 0;
3686 UINT        resource_length;
3687 UINT        name_length = 0;
3688 UINT        password_length = 0;
3689 UINT        realm_length = 0;
3690 UINT        temp_name_length = 0;
3691 UINT        temp_password_length = 0;
3692 UINT        temp_realm_length = 0;
3693 
3694 
3695     /* Pickup the URL (resource) from the request.  */
3696     status =  _nx_web_http_server_retrieve_resource(server_ptr, packet_ptr, server_ptr -> nx_web_http_server_request_resource, NX_WEB_HTTP_MAX_RESOURCE + 1);
3697 
3698     /* Determine if the resource was extracted successfully.  */
3699     if (status != NX_SUCCESS)
3700     {
3701 
3702         /* Send response back to HTTP Client.  */
3703         _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_BAD_REQUEST,
3704                                           sizeof(NX_WEB_HTTP_STATUS_BAD_REQUEST) - 1,
3705                                           "NetX HTTP URL Bad", sizeof("NetX HTTP URL Bad") - 1, NX_NULL, 0);
3706 
3707         /* Error, return to caller.  */
3708         return;
3709     }
3710 
3711     /* Determine if a POST is present.  */
3712     if (request_type == NX_WEB_HTTP_SERVER_POST_REQUEST)
3713     {
3714 
3715         if (!server_ptr -> nx_web_http_server_request_chunked)
3716         {
3717 
3718             /* It is. Check for a valid content-length field. */
3719             status = _nx_web_http_server_content_length_get(packet_ptr, &length);
3720 
3721             /* Check for errors.  */
3722             if ( status != NX_SUCCESS)
3723             {
3724 
3725                 /* Send response back to HTTP Client.  */
3726                 _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_BAD_REQUEST,
3727                                                   sizeof(NX_WEB_HTTP_STATUS_BAD_REQUEST) - 1,
3728                                                   "NetX HTTP Invalid Content Length",
3729                                                   sizeof("NetX HTTP Invalid Content Length") - 1, NX_NULL, 0);
3730 
3731                 /* Error, return to caller.  */
3732                 return;
3733             }
3734         }
3735 
3736         /* Check for an invalid content offset .  */
3737         offset = _nx_web_http_server_calculate_content_offset(packet_ptr);
3738         if (offset == 0)
3739         {
3740 
3741             /* Send response back to HTTP Client.  */
3742             _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_BAD_REQUEST,
3743                                               sizeof(NX_WEB_HTTP_STATUS_BAD_REQUEST) - 1,
3744                                               "NetX HTTP Invalid Content Offset",
3745                                               sizeof("NetX HTTP Invalid Content Offset") - 1, NX_NULL, 0);
3746 
3747             /* Error, return to caller.  */
3748             return;
3749         }
3750 
3751 #ifdef  NX_WEB_HTTP_MULTIPART_ENABLE
3752         /* Cleanup the multipart field. */
3753         memset(&server_ptr -> nx_web_http_server_multipart, 0, sizeof(NX_WEB_HTTP_SERVER_MULTIPART));
3754 #endif /* NX_WEB_HTTP_MULTIPART_ENABLE */
3755     }
3756 
3757     /* Determine if the application has specified an authentication function for this server.  */
3758     if (server_ptr -> nx_web_http_server_authentication_check ||
3759         server_ptr -> nx_web_http_server_authentication_check_extended)
3760     {
3761 
3762         /* Determine if authentication is required for the specified resource.  */
3763         if (server_ptr -> nx_web_http_server_authentication_check_extended)
3764         {
3765             status =  (server_ptr -> nx_web_http_server_authentication_check_extended)(server_ptr, request_type, server_ptr -> nx_web_http_server_request_resource,
3766                                                                                        &name_ptr, &name_length, &password_ptr, &password_length, &realm_ptr, &realm_length);
3767         }
3768         else
3769         {
3770             status =  (server_ptr -> nx_web_http_server_authentication_check)(server_ptr, request_type, server_ptr -> nx_web_http_server_request_resource,
3771                                                                             &name_ptr, &password_ptr, &realm_ptr);
3772         }
3773 
3774         if ((status == NX_WEB_HTTP_BASIC_AUTHENTICATE) ||
3775             (status == NX_WEB_HTTP_DIGEST_AUTHENTICATE))
3776         {
3777 
3778             /* Check name, password and realm string.  */
3779             if (_nx_utility_string_length_check(name_ptr, &temp_name_length, NX_WEB_HTTP_MAX_NAME) ||
3780                 _nx_utility_string_length_check(password_ptr, &temp_password_length, NX_WEB_HTTP_MAX_PASSWORD) ||
3781                 _nx_utility_string_length_check(realm_ptr, &temp_realm_length, NX_MAX_STRING_LENGTH))
3782             {
3783 
3784                 /* Error, return to caller.  */
3785                 return;
3786             }
3787 
3788             /* Validate string length. */
3789             if (server_ptr -> nx_web_http_server_authentication_check_extended &&
3790                 ((realm_length != temp_realm_length) ||
3791                  (name_length != temp_name_length) ||
3792                  (password_length != temp_password_length)))
3793             {
3794                 return;
3795             }
3796         }
3797 
3798         /* Determine what kind - if any - authentication is requested for this resource.  */
3799         if (status == NX_WEB_HTTP_BASIC_AUTHENTICATE)
3800         {
3801 
3802             /* Process basic authentication request.  */
3803             status =  _nx_web_http_server_basic_authenticate(server_ptr, packet_ptr, name_ptr, password_ptr, realm_ptr, &auth_request_present);
3804         }
3805 #ifdef  NX_WEB_HTTP_DIGEST_ENABLE
3806         else if (status == NX_WEB_HTTP_DIGEST_AUTHENTICATE)
3807         {
3808 
3809             /* Process digest authentication request.  */
3810             status =  _nx_web_http_server_digest_authenticate(server_ptr, packet_ptr, name_ptr, password_ptr, realm_ptr, &auth_request_present);
3811         }
3812 #endif
3813 
3814         /* Determine if the authentication failed.  */
3815         if ((status != NX_WEB_HTTP_DONT_AUTHENTICATE) && (status != NX_SUCCESS))
3816         {
3817 
3818             /*  Yes it did. Inform the HTTP server application about the failed authentication. */
3819             if (server_ptr -> nx_web_http_server_invalid_username_password_callback && auth_request_present)
3820             {
3821             NXD_ADDRESS client_nxd_address;
3822             ULONG       client_port;
3823 
3824                 /* Get the IP address of the client:  */
3825                 status =   nxd_tcp_socket_peer_info_get(socket_ptr, &client_nxd_address , &client_port);
3826 
3827                 if (status == NX_SUCCESS)
3828                 {
3829                     /* Send this information to the host application. */
3830                     (server_ptr -> nx_web_http_server_invalid_username_password_callback)(server_ptr -> nx_web_http_server_request_resource, &client_nxd_address, request_type);
3831                 }
3832             }
3833 
3834             return;
3835         }
3836     }
3837 
3838     /* Check whether a full response is necessary. */
3839     if((server_ptr -> nx_web_http_server_cache_info_get) &&
3840        (server_ptr -> nx_web_http_server_request_type == NX_WEB_HTTP_SERVER_GET_REQUEST))
3841     {
3842 
3843         /* Searching for "If-Modified-Since" header. */
3844         if(_nx_web_http_server_field_value_get(packet_ptr, (UCHAR *)"if-modified-since", 17, (UCHAR *)temp_string, sizeof(temp_string)) == NX_SUCCESS)
3845         {
3846         UINT max_age;
3847         NX_WEB_HTTP_SERVER_DATE date;
3848         CHAR date_string[30];
3849 
3850             /* Get last modified date of this resource. */
3851             if(server_ptr -> nx_web_http_server_cache_info_get(server_ptr -> nx_web_http_server_request_resource, &max_age, &date) == NX_TRUE)
3852             {
3853 
3854                 /* Convert date to string, the return length is always 29. */
3855                 temp = _nx_web_http_server_date_to_string(&date, date_string);
3856                 date_string[temp] = 0;
3857 
3858                 /* Check the last modified date with if-modified-since. */
3859                 if(memcmp(temp_string, date_string, temp + 1) == 0)
3860                 {
3861 
3862                     /* Send not modified.  */
3863                     _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_NOT_MODIFIED,
3864                                                       sizeof(NX_WEB_HTTP_STATUS_NOT_MODIFIED) - 1,
3865                                                       NX_NULL, 0, NX_NULL, 0);
3866 
3867                     /* Return to caller.  */
3868                     return;
3869                 }
3870             }
3871         }
3872     }
3873 
3874     /* Setup the server socket with a specific packet transmit retry logic.  */
3875     nx_tcp_socket_transmit_configure(socket_ptr,
3876                                     NX_WEB_HTTP_SERVER_TRANSMIT_QUEUE_DEPTH,
3877                                     NX_WEB_HTTP_SERVER_RETRY_SECONDS*NX_IP_PERIODIC_RATE,
3878                                     NX_WEB_HTTP_SERVER_RETRY_MAX,
3879                                     NX_WEB_HTTP_SERVER_RETRY_SHIFT);
3880 
3881     /* At this point, either there isn't any required authentication for this resource or the authentication is
3882        complete.  */
3883 
3884     /* If the HTTP server receives an empty POST request (no message body, content length = 0, it is the
3885        responsibility of the request notify callback to send a response (if any) to the HTTP Client.
3886        The HTTP server will process the request no further. */
3887 
3888     /* Determine if a user supplied get function has been specified.  */
3889     if (server_ptr -> nx_web_http_server_request_notify)
3890     {
3891 
3892         /* Call the user supplied function to notify the user of the get request.  */
3893         status =  (server_ptr -> nx_web_http_server_request_notify)(server_ptr, request_type, server_ptr -> nx_web_http_server_request_resource, packet_ptr);
3894 
3895 #ifdef  NX_WEB_HTTP_MULTIPART_ENABLE
3896         /* Release the packet that is not processed by callback function. */
3897         if(server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_next_packet)
3898             nx_packet_release(server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_next_packet);
3899 #endif /* NX_WEB_HTTP_MULTIPART_ENABLE */
3900 
3901         /* Determine if the user supplied routine is requesting the get should be aborted.  */
3902         if (status != NX_SUCCESS)
3903         {
3904 
3905             /* Determine if the user callback routine successfully completed the request processing.  */
3906             if (status == NX_WEB_HTTP_CALLBACK_COMPLETED)
3907             {
3908 
3909                 /* User callback routine already sent success response back to HTTP Client.  */
3910                 return;
3911             }
3912 
3913             /* Send response back to HTTP Client.  */
3914             _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
3915                                               sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
3916                                               "NetX HTTP Request Aborted",
3917                                               sizeof("NetX HTTP Request Aborted") - 1, NX_NULL, 0);
3918 
3919             /* Yes, error was detected. Abort the remainder of the get processing.  */
3920             return;
3921         }
3922     }
3923 
3924     /* If it's POST request, process the message body.  */
3925     if (request_type == NX_WEB_HTTP_SERVER_POST_REQUEST)
3926     {
3927 
3928         /* Was there a message body in the request? */
3929         if (server_ptr -> nx_web_http_server_request_chunked)
3930         {
3931 
3932             /* Find the first chunk of the content.  */
3933             status = _nx_web_http_server_packet_content_find(server_ptr, &packet_ptr, NX_NULL);
3934             if (status)
3935             {
3936 
3937                 /* No. Regardless if a reply was sent via the request notify callback, we are done with this packet. */
3938                 return;
3939             }
3940 
3941             nx_packet_release(packet_ptr);
3942         }
3943         else
3944         {
3945             if (length == 0)
3946             {
3947 
3948                 /* No. Regardless if a reply was sent via the request notify callback, we are done with this packet. */
3949                 return;
3950             }
3951 
3952             length -= (ULONG)(packet_ptr -> nx_packet_length - offset);
3953         }
3954 
3955         /* If necessary, receive more packets from the TCP socket.  */
3956         while (length || server_ptr -> nx_web_http_server_request_chunked)
3957         {
3958 
3959             /* Wait for more packets.  */
3960             status = _nx_web_http_server_packet_get(server_ptr, &new_packet_ptr);
3961 
3962             /* Check the return status.  */
3963             if (status != NX_SUCCESS)
3964             {
3965 
3966                 if (status == NX_WEB_HTTP_GET_DONE)
3967                 {
3968                     break;
3969                 }
3970 
3971                 /* Send response back to HTTP Client.  */
3972                 _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
3973                                                   sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
3974                                                   "NetX HTTP Receive Timeout",
3975                                                   sizeof("NetX HTTP Receive Timeout") - 1, NX_NULL, 0);
3976 
3977                 /* Error, return to caller.  */
3978                 return;
3979             }
3980 
3981             /* Update the length.  */
3982             if (!server_ptr -> nx_web_http_server_request_chunked)
3983             {
3984                 length -= new_packet_ptr -> nx_packet_length;
3985             }
3986 
3987             nx_packet_release(new_packet_ptr);
3988         }
3989     }
3990 
3991 
3992     /* Get the length of request resource.  */
3993     if (_nx_utility_string_length_check(server_ptr -> nx_web_http_server_request_resource,  &resource_length,
3994                                         sizeof(server_ptr -> nx_web_http_server_request_resource) - 1))
3995     {
3996         return;
3997     }
3998 
3999     /* Open the specified file for reading.  */
4000     status =  fx_file_open(server_ptr -> nx_web_http_server_media_ptr, &(server_ptr -> nx_web_http_server_file), server_ptr -> nx_web_http_server_request_resource, FX_OPEN_FOR_READ);
4001 
4002     /* Check for error condition.  */
4003     if (status != NX_SUCCESS)
4004     {
4005 
4006         /* Send response back to HTTP Client.  */
4007         _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_NOT_FOUND,
4008                                           sizeof(NX_WEB_HTTP_STATUS_NOT_FOUND) - 1,
4009                                           "NetX HTTP Server unable to find file: ",
4010                                           sizeof("NetX HTTP Server unable to find file: ") - 1,
4011                                           server_ptr -> nx_web_http_server_request_resource,
4012                                           resource_length);
4013 
4014         /* Error, return to caller.  */
4015         return;
4016     }
4017 
4018     /* Calculate the size of the file.  */
4019     length =  0;
4020     fx_directory_information_get(server_ptr -> nx_web_http_server_media_ptr, server_ptr -> nx_web_http_server_request_resource, FX_NULL,
4021                             &length, FX_NULL, FX_NULL, FX_NULL, FX_NULL, FX_NULL, FX_NULL);
4022 
4023     /* Derive the file type. We use whatever value is returned since if there is no
4024        match this function will return a default value.  */
4025     _nx_web_http_server_type_get_extended(server_ptr, server_ptr -> nx_web_http_server_request_resource, resource_length, temp_string, sizeof(temp_string), &file_type_length);
4026 
4027     temp = file_type_length;
4028     temp_string[temp] = 0;
4029 
4030     /* Now build a response header.  */
4031     status = _nx_web_http_server_generate_response_header(server_ptr, &new_packet_ptr, NX_WEB_HTTP_STATUS_OK,
4032                                                           sizeof(NX_WEB_HTTP_STATUS_OK) - 1, length, temp_string,
4033                                                           file_type_length, NX_NULL, 0);
4034     if(status)
4035     {
4036 
4037         /* Send response back to HTTP Client.  */
4038         _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
4039                                           sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
4040                                           "NetX HTTP Request Aborted",
4041                                           sizeof("NetX HTTP Request Aborted") - 1, NX_NULL, 0);
4042 
4043         /* Close the file.  */
4044         fx_file_close(&(server_ptr -> nx_web_http_server_file));
4045 
4046         /* Error, return to caller.  */
4047         return;
4048     }
4049 
4050     /* Check to see if only a response is required.  */
4051     if ((!length) || (request_type == NX_WEB_HTTP_SERVER_HEAD_REQUEST))
4052     {
4053 
4054         /* Yes, only a response is required... send it!  */
4055         status = _nx_web_http_server_send(server_ptr, new_packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_SEND);
4056 
4057         /* Determine if this is successful.  */
4058         if (status != NX_SUCCESS)
4059         {
4060 
4061             /* Release the packet.  */
4062             nx_packet_release(new_packet_ptr);
4063 
4064             /* Force zero length.  */
4065             length = 0;
4066         }
4067     }
4068 
4069     /* Get length of packet */
4070     temp = new_packet_ptr -> nx_packet_length;
4071 
4072     /* Now, loop to send the data contents.  If the request type is "HEAD", skip this loop to output the
4073        file contents.  */
4074     while ((length) && (request_type != NX_WEB_HTTP_SERVER_HEAD_REQUEST))
4075     {
4076 
4077         /* Determine if we need to allocate a new packet for data.  */
4078         if (!temp)
4079         {
4080 
4081             /* Yes, allocate a new packet.  */
4082             status =  _nx_web_http_server_response_packet_allocate(server_ptr, &new_packet_ptr, NX_WAIT_FOREVER);
4083 
4084             /* Determine if an error is present.  */
4085             if (status != NX_SUCCESS)
4086             {
4087 
4088                 /* Indicate an allocation error occurred.  */
4089                 server_ptr -> nx_web_http_server_allocation_errors++;
4090 
4091                 /* Error, return to caller.  */
4092                 break;
4093             }
4094         }
4095 
4096         /* Calculate the maximum length.  */
4097         temp =  ((ULONG) (new_packet_ptr -> nx_packet_data_end - new_packet_ptr -> nx_packet_append_ptr)) - NX_PHYSICAL_TRAILER;
4098 
4099         /* Determine if this exceeds the MSS of the peer.  */
4100         if (temp > socket_ptr -> nx_tcp_socket_connect_mss)
4101         {
4102 
4103             /* Yes, reduce the maximum size to the mss size.  */
4104             temp =  socket_ptr -> nx_tcp_socket_connect_mss;
4105         }
4106 
4107         /* Read data from the file.  */
4108         status =  fx_file_read(&(server_ptr -> nx_web_http_server_file), new_packet_ptr -> nx_packet_append_ptr,
4109                                         temp, &temp);
4110 
4111         /* Check for an error.  */
4112         if (status != NX_SUCCESS)
4113         {
4114 
4115             /* Release the packet.  */
4116             nx_packet_release(new_packet_ptr);
4117 
4118             /* Error, return.  */
4119             break;
4120         }
4121 
4122         /* Update the packet information with the data read.  */
4123         new_packet_ptr -> nx_packet_length =  new_packet_ptr -> nx_packet_length + temp;
4124         new_packet_ptr -> nx_packet_append_ptr =  new_packet_ptr -> nx_packet_append_ptr + temp;
4125 
4126         /* Send the packet out.  */
4127         status =  _nx_web_http_server_send(server_ptr, new_packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_SEND);
4128 
4129         /* Check for success.  */
4130         if (status != NX_SUCCESS)
4131         {
4132 
4133             /* Release the packet.  */
4134             nx_packet_release(new_packet_ptr);
4135 
4136             /* Return to caller.  */
4137             break;
4138         }
4139 
4140         /* Increment the bytes sent count.  */
4141         server_ptr -> nx_web_http_server_total_bytes_sent =  server_ptr -> nx_web_http_server_total_bytes_sent + temp;
4142 
4143         /* Adjust the file length based on what we have sent.  */
4144         length =  length - temp;
4145 
4146         /* Indicate new packet needed */
4147         temp = 0;
4148     }
4149 
4150     /* Close the file.  */
4151     fx_file_close(&(server_ptr -> nx_web_http_server_file));
4152 }
4153 
4154 
4155 /**************************************************************************/
4156 /*                                                                        */
4157 /*  FUNCTION                                               RELEASE        */
4158 /*                                                                        */
4159 /*    _nx_web_http_server_put_process                     PORTABLE C      */
4160 /*                                                           6.1          */
4161 /*  AUTHOR                                                                */
4162 /*                                                                        */
4163 /*    Yuxin Zhou, Microsoft Corporation                                   */
4164 /*                                                                        */
4165 /*  DESCRIPTION                                                           */
4166 /*                                                                        */
4167 /*    This function processes the PUT HTTP client requests.               */
4168 /*                                                                        */
4169 /*                                                                        */
4170 /*  INPUT                                                                 */
4171 /*                                                                        */
4172 /*    server_ptr                            HTTP Server pointer           */
4173 /*    packet_ptr                            Request packet pointer        */
4174 /*                                                                        */
4175 /*  OUTPUT                                                                */
4176 /*                                                                        */
4177 /*    None                                                                */
4178 /*                                                                        */
4179 /*  CALLS                                                                 */
4180 /*                                                                        */
4181 /*    _nx_web_http_server_basic_authenticate                              */
4182 /*                                          Process basic authentication  */
4183 /*    _nx_web_http_server_digest_authenticate                             */
4184 /*                                          Process digest authentication */
4185 /*    _nx_web_http_server_calculate_content_offset                        */
4186 /*                                          Retrieve content offset       */
4187 /*    _nx_web_http_server_content_length_get                              */
4188 /*                                          Retrieve content length       */
4189 /*    _nx_web_http_server_response_send     Send response back to client  */
4190 /*    _nx_web_http_server_retrieve_resource Retrieve resource from request*/
4191 /*    _nx_web_http_server_packet_get        Receive another packet        */
4192 /*    fx_file_close                         Close resource file           */
4193 /*    fx_file_create                        Create resource file          */
4194 /*    fx_file_open                          Open resource file            */
4195 /*    fx_file_write                         Write data to resource file   */
4196 /*    nx_packet_release                     Release packet                */
4197 /*    _nx_utility_string_length_check       Check string length           */
4198 /*                                                                        */
4199 /*  CALLED BY                                                             */
4200 /*                                                                        */
4201 /*    _nx_web_http_server_content_get       Content get processing        */
4202 /*    _nx_web_http_server_get_process       GET request processing        */
4203 /*    _nx_web_http_server_put_process       PUT request processing        */
4204 /*                                                                        */
4205 /*  RELEASE HISTORY                                                       */
4206 /*                                                                        */
4207 /*    DATE              NAME                      DESCRIPTION             */
4208 /*                                                                        */
4209 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4210 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4211 /*                                            resulting in version 6.1    */
4212 /*                                                                        */
4213 /**************************************************************************/
_nx_web_http_server_put_process(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr)4214 VOID  _nx_web_http_server_put_process(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr)
4215 {
4216 
4217 UINT        status;
4218 ULONG       length = 0;
4219 UINT        offset;
4220 CHAR        *name_ptr;
4221 CHAR        *password_ptr;
4222 CHAR        *realm_ptr;
4223 NX_PACKET   *data_packet_ptr;
4224 NX_PACKET   *next_packet_ptr;
4225 UINT        auth_request_present = NX_FALSE;
4226 NX_TCP_SOCKET *socket_ptr = &server_ptr -> nx_web_http_server_current_session_ptr -> nx_tcp_session_socket;
4227 UINT        name_length = 0;
4228 UINT        password_length = 0;
4229 UINT        realm_length = 0;
4230 UINT        temp_name_length = 0;
4231 UINT        temp_password_length = 0;
4232 UINT        temp_realm_length = 0;
4233 
4234 
4235     /* Pickup the URL (resource) from the request.  */
4236     status =  _nx_web_http_server_retrieve_resource(server_ptr, packet_ptr, server_ptr -> nx_web_http_server_request_resource, NX_WEB_HTTP_MAX_RESOURCE + 1);
4237 
4238     /* Determine if the resource was extracted successfully.  */
4239     if (status != NX_SUCCESS)
4240     {
4241 
4242         /* Send response back to HTTP Client.  */
4243         _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_BAD_REQUEST,
4244                                           sizeof(NX_WEB_HTTP_STATUS_BAD_REQUEST) - 1,
4245                                           "NetX HTTP URL Bad",
4246                                           sizeof("NetX HTTP URL Bad") - 1, NX_NULL, 0);
4247 
4248         /* Error, return to caller.  */
4249         return;
4250     }
4251 
4252     if (!server_ptr -> nx_web_http_server_request_chunked)
4253     {
4254 
4255         /* Calculate the content length from the request.  */
4256         status =  _nx_web_http_server_content_length_get(packet_ptr, &length);
4257 
4258         /* Determine if the content length is valid.  */
4259         if (status != NX_SUCCESS)
4260         {
4261 
4262             /* Send response back to HTTP Client.  */
4263             _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_BAD_REQUEST,
4264                                               sizeof(NX_WEB_HTTP_STATUS_BAD_REQUEST) - 1,
4265                                               "NetX HTTP Invalid Content Length",
4266                                               sizeof("NetX HTTP Invalid Content Length") - 1, NX_NULL, 0);
4267 
4268             /* Error, return to caller.  */
4269             return;
4270         }
4271     }
4272 
4273     /* Calculate the offset to the content (the two Cr LF tokens) in the request.  */
4274     offset =  _nx_web_http_server_calculate_content_offset(packet_ptr);
4275 
4276     /* Determine if the offset to the content is valid.  */
4277     if (offset == 0)
4278     {
4279 
4280         /* Send response back to HTTP Client.  */
4281         _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_BAD_REQUEST,
4282                                           sizeof(NX_WEB_HTTP_STATUS_BAD_REQUEST) - 1,
4283                                           "NetX HTTP Invalid Content Offset",
4284                                           sizeof("NetX HTTP Invalid Content Offset") - 1, NX_NULL, 0);
4285 
4286         /* Error, return to caller.  */
4287         return;
4288     }
4289 
4290     /* Determine if the application has specified an authentication function for this server.  */
4291     if (server_ptr -> nx_web_http_server_authentication_check ||
4292         server_ptr -> nx_web_http_server_authentication_check_extended)
4293     {
4294 
4295         /* Determine if authentication is required for the specified resource.  */
4296         if (server_ptr -> nx_web_http_server_authentication_check_extended)
4297         {
4298             status =  (server_ptr -> nx_web_http_server_authentication_check_extended)(server_ptr, NX_WEB_HTTP_SERVER_PUT_REQUEST, server_ptr -> nx_web_http_server_request_resource,
4299                                                                                        &name_ptr, &name_length, &password_ptr, &password_length, &realm_ptr, &realm_length);
4300         }
4301         else
4302         {
4303             status =  (server_ptr -> nx_web_http_server_authentication_check)(server_ptr, NX_WEB_HTTP_SERVER_PUT_REQUEST, server_ptr -> nx_web_http_server_request_resource,
4304                                                                             &name_ptr, &password_ptr, &realm_ptr);
4305         }
4306 
4307         if ((status == NX_WEB_HTTP_BASIC_AUTHENTICATE) ||
4308             (status == NX_WEB_HTTP_DIGEST_AUTHENTICATE))
4309         {
4310 
4311             /* Check name, password and realm string.  */
4312             if (_nx_utility_string_length_check(name_ptr, &temp_name_length, NX_WEB_HTTP_MAX_NAME) ||
4313                 _nx_utility_string_length_check(password_ptr, &temp_password_length, NX_WEB_HTTP_MAX_PASSWORD) ||
4314                 _nx_utility_string_length_check(realm_ptr, &temp_realm_length, NX_MAX_STRING_LENGTH))
4315             {
4316 
4317                 /* Error, return to caller.  */
4318                 return;
4319             }
4320 
4321             /* Validate string length. */
4322             if (server_ptr -> nx_web_http_server_authentication_check_extended &&
4323                 ((realm_length != temp_realm_length) ||
4324                  (name_length != temp_name_length) ||
4325                  (password_length != temp_password_length)))
4326             {
4327                 return;
4328             }
4329         }
4330 
4331         /* Determine what kind - if any - authentication is requested for this resource.  */
4332         if (status == NX_WEB_HTTP_BASIC_AUTHENTICATE)
4333         {
4334 
4335             /* Process basic authentication request.  */
4336             status =  _nx_web_http_server_basic_authenticate(server_ptr, packet_ptr, name_ptr, password_ptr, realm_ptr, &auth_request_present);
4337         }
4338 #ifdef  NX_WEB_HTTP_DIGEST_ENABLE
4339         else if (status == NX_WEB_HTTP_DIGEST_AUTHENTICATE)
4340         {
4341 
4342             /* Process digest authentication request.  */
4343             status =  _nx_web_http_server_digest_authenticate(server_ptr, packet_ptr, name_ptr, password_ptr, realm_ptr, &auth_request_present);
4344         }
4345 #endif
4346 
4347         /* Determine if the authentication is currently in progress.  */
4348         if ((status != NX_WEB_HTTP_DONT_AUTHENTICATE) && (status != NX_SUCCESS))
4349         {
4350 
4351             /* Yes, authentication is in progress.  The HTTP 401 has already been sent.  */
4352             if (server_ptr -> nx_web_http_server_invalid_username_password_callback && auth_request_present)
4353             {
4354             NXD_ADDRESS client_nxd_address;
4355             ULONG       client_port;
4356 
4357                 /* Get the IP address of the client:  */
4358                 status =   nxd_tcp_socket_peer_info_get(socket_ptr, &client_nxd_address , &client_port);
4359 
4360                 if (status == NX_SUCCESS)
4361                 {
4362                     /* Send this information to the host application. */
4363                     (server_ptr -> nx_web_http_server_invalid_username_password_callback)(server_ptr -> nx_web_http_server_request_resource, &client_nxd_address, NX_WEB_HTTP_SERVER_PUT_REQUEST);
4364                 }
4365             }
4366 
4367             return;
4368         }
4369     }
4370 
4371     /* At this point, either there isn't any required authentication for this resource or the authentication is
4372        complete.  */
4373 
4374     /* If the request is empty (content-length = 0) the request notify callback is where a response is generated
4375        to return to the Client.  NetX HTTP Server will not process an empty request further. */
4376 
4377     /* Determine if a user supplied get function has been specified.  */
4378     if (server_ptr -> nx_web_http_server_request_notify)
4379     {
4380 
4381         /* Call the user supplied function to notify the user of the put request.  */
4382         status =  (server_ptr -> nx_web_http_server_request_notify)(server_ptr, NX_WEB_HTTP_SERVER_PUT_REQUEST, server_ptr -> nx_web_http_server_request_resource, packet_ptr);
4383 
4384         /* Determine if the user supplied routine is requesting the put should be aborted.  */
4385         if (status != NX_SUCCESS)
4386         {
4387 
4388             /* Determine if the user callback routine successfully completed the request processing.  */
4389             if (status == NX_WEB_HTTP_CALLBACK_COMPLETED)
4390             {
4391 
4392                 /* Send success response back to HTTP Client.  */
4393                 _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_OK,
4394                                                   sizeof(NX_WEB_HTTP_STATUS_OK) - 1, NX_NULL, 0, NX_NULL, 0);
4395                 return;
4396             }
4397 
4398             /* No, an error was detected. Abort the remainder of the get processing.  */
4399             _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
4400                                               sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
4401                                               "NetX HTTP Request Aborted",
4402                                               sizeof("NetX HTTP Request Aborted") - 1, NX_NULL, 0);
4403             return;
4404         }
4405     }
4406 
4407     /* Was there a message body in the request? */
4408     if (server_ptr -> nx_web_http_server_request_chunked)
4409     {
4410 
4411         /* Find the first chunk of the content.  */
4412         status = _nx_web_http_server_packet_content_find(server_ptr, &packet_ptr, NX_NULL);
4413         if (status)
4414         {
4415 
4416             /* No. Regardless if a reply was sent via the request notify callback, we are done with this packet. */
4417             return;
4418         }
4419 
4420         offset = 0;
4421         length = packet_ptr -> nx_packet_length;
4422     }
4423     else if (length == 0)
4424     {
4425 
4426         /* No. Regardless if a reply was sent via the request notify callback, we are done with this packet. */
4427         return;
4428     }
4429 
4430     /* Otherwise, everything is okay...  complete the request.  */
4431 
4432     /* Create the specified file.  */
4433     status = fx_file_create(server_ptr -> nx_web_http_server_media_ptr, server_ptr -> nx_web_http_server_request_resource);
4434 
4435 
4436     if (status != NX_SUCCESS)
4437     {
4438 
4439         /* Send response back to HTTP Client.  */
4440         _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
4441                                           sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
4442                                           "NetX HTTP File Create Failed",
4443                                           sizeof("NetX HTTP File Create Failed") - 1, NX_NULL, 0);
4444 
4445         /* Release first chunked packet.  */
4446         if (server_ptr -> nx_web_http_server_request_chunked)
4447         {
4448             nx_packet_release(packet_ptr);
4449         }
4450 
4451         /* Error, return to caller.  */
4452         return;
4453     }
4454 
4455     /* Open the specified file for writing.  */
4456     status =  fx_file_open(server_ptr -> nx_web_http_server_media_ptr, &(server_ptr -> nx_web_http_server_file), server_ptr -> nx_web_http_server_request_resource, FX_OPEN_FOR_WRITE);
4457 
4458     /* Check for error condition.  */
4459     if (status != NX_SUCCESS)
4460     {
4461 
4462         /* Send response back to HTTP Client.  */
4463         _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
4464                                           sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
4465                                           "NetX HTTP File Open Failed",
4466                                           sizeof("NetX HTTP File Open Failed") - 1, NX_NULL, 0);
4467 
4468         /* Release first chunked packet.  */
4469         if (server_ptr -> nx_web_http_server_request_chunked)
4470         {
4471             nx_packet_release(packet_ptr);
4472         }
4473 
4474         /* Error, return to caller.  */
4475         return;
4476     }
4477 
4478     /* Determine if there is any content in the first packet.  */
4479     if ((UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) > offset)
4480     {
4481 
4482         /* Write the content found in this packet.  */
4483         status =  fx_file_write(&(server_ptr -> nx_web_http_server_file), (packet_ptr -> nx_packet_prepend_ptr + offset),
4484                                 ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) - offset));
4485 
4486         /* Check the status.  */
4487         if (status != NX_SUCCESS)
4488         {
4489 
4490             /* Send response back to HTTP Client.  */
4491             _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
4492                                               sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
4493                                               "NetX HTTP File Write Failed",
4494                                               sizeof("NetX HTTP File Write Failed") - 1, NX_NULL, 0);
4495 
4496             /* Release first chunked packet.  */
4497             if (server_ptr -> nx_web_http_server_request_chunked)
4498             {
4499                 nx_packet_release(packet_ptr);
4500             }
4501 
4502             /* Error, return to caller.  */
4503             return;
4504         }
4505 
4506         /* Update the length.  */
4507         length =  length - ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) - offset);
4508 
4509         /* Increment the bytes received count.  */
4510         server_ptr -> nx_web_http_server_total_bytes_received =  server_ptr -> nx_web_http_server_total_bytes_received +
4511                                                              ((ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) - offset);
4512     }
4513 
4514 #ifndef NX_DISABLE_PACKET_CHAIN
4515     /* Loop to write chained packets out to the file.  */
4516     next_packet_ptr =  packet_ptr -> nx_packet_next;
4517     while ((length) && (next_packet_ptr))
4518     {
4519 
4520         /* Write the content of the next packet.  */
4521         status =  fx_file_write(&(server_ptr -> nx_web_http_server_file), next_packet_ptr -> nx_packet_prepend_ptr,
4522                                 (ULONG)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr));
4523 
4524         /* Check the status.  */
4525         if (status != NX_SUCCESS)
4526         {
4527 
4528             /* Send response back to HTTP Client.  */
4529             _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
4530                                               sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
4531                                               "NetX HTTP File Write Failed",
4532                                               sizeof("NetX HTTP File Write Failed") - 1, NX_NULL, 0);
4533 
4534             /* Release first chunked packet.  */
4535             if (server_ptr -> nx_web_http_server_request_chunked)
4536             {
4537                 nx_packet_release(packet_ptr);
4538             }
4539 
4540             /* Error, return to caller.  */
4541             return;
4542         }
4543 
4544         /* Update the length.  */
4545         length =  length - (ULONG)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr);
4546 
4547         /* Increment the bytes received count.  */
4548         server_ptr -> nx_web_http_server_total_bytes_received =  server_ptr -> nx_web_http_server_total_bytes_received +
4549                                         (ULONG)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr);
4550 
4551         /* Move to the next pointer.  */
4552         next_packet_ptr =  next_packet_ptr -> nx_packet_next;
4553     }
4554 #endif /* NX_DISABLE_PACKET_CHAIN */
4555 
4556     /* Release first chunked packet.  */
4557     if (server_ptr -> nx_web_http_server_request_chunked)
4558     {
4559         nx_packet_release(packet_ptr);
4560     }
4561 
4562     /* If necessary, receive more packets from the TCP socket to complete the write request.  */
4563     while (length || server_ptr -> nx_web_http_server_request_chunked)
4564     {
4565 
4566         /* Wait for a request.  */
4567         status = _nx_web_http_server_packet_get(server_ptr, &data_packet_ptr);
4568 
4569         /* Check the return status.  */
4570         if (status != NX_SUCCESS)
4571         {
4572 
4573             if (status == NX_WEB_HTTP_GET_DONE)
4574             {
4575                 break;
4576             }
4577 
4578             /* Send response back to HTTP Client.  */
4579             _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
4580                                               sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
4581                                               "NetX HTTP Receive Timeout",
4582                                               sizeof("NetX HTTP Receive Timeout") - 1, NX_NULL, 0);
4583 
4584             /* Error, return to caller.  */
4585             return;
4586         }
4587 
4588         if (server_ptr -> nx_web_http_server_request_chunked)
4589         {
4590             length = data_packet_ptr -> nx_packet_length;
4591         }
4592 
4593         /* Loop to write the packet chain out to the file.  */
4594         next_packet_ptr =  data_packet_ptr;
4595         do
4596         {
4597 
4598             /* Write the content of this packet.  */
4599             status =  fx_file_write(&(server_ptr -> nx_web_http_server_file), next_packet_ptr -> nx_packet_prepend_ptr,
4600                                                (ULONG)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr));
4601 
4602             /* Check the status.  */
4603             if (status != NX_SUCCESS)
4604             {
4605 
4606                 /* Send response back to HTTP Client.  */
4607                 _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
4608                                                   sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
4609                                                   "NetX HTTP File Write Failed",
4610                                                   sizeof("NetX HTTP File Write Failed") - 1, NX_NULL, 0);
4611 
4612                 /* Release the previous data packet.  */
4613                 nx_packet_release(data_packet_ptr);
4614 
4615                 /* Error, return to caller.  */
4616                 return;
4617             }
4618 
4619             /* Update the length.  */
4620             length =  length - (UINT)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr);
4621 
4622             /* Increment the bytes received count.  */
4623             server_ptr -> nx_web_http_server_total_bytes_received =  server_ptr -> nx_web_http_server_total_bytes_received +
4624                                         (ULONG)(next_packet_ptr -> nx_packet_append_ptr - next_packet_ptr -> nx_packet_prepend_ptr);
4625 
4626 #ifdef NX_DISABLE_PACKET_CHAIN
4627             next_packet_ptr =  NX_NULL;
4628 #else
4629             /* Move to the next pointer.  */
4630             next_packet_ptr =  next_packet_ptr -> nx_packet_next;
4631 #endif /* NX_DISABLE_PACKET_CHAIN */
4632 
4633         } while ((length) && (next_packet_ptr));
4634 
4635         /* Release the previous data packet.  */
4636         nx_packet_release(data_packet_ptr);
4637     }
4638 
4639     /* Success, at this point close the file and prepare a successful response for the client.  */
4640     fx_file_close(&(server_ptr -> nx_web_http_server_file));
4641 
4642 
4643     /* Now build a response header.  */
4644     status = _nx_web_http_server_generate_response_header(server_ptr, &data_packet_ptr, NX_WEB_HTTP_STATUS_OK,
4645                                                           sizeof(NX_WEB_HTTP_STATUS_OK) - 1, 0,
4646                                                           NX_NULL, 0, NX_NULL, 0);
4647     if (status == NX_SUCCESS)
4648     {
4649 
4650         /* Send the response back to the client.  */
4651         status = _nx_web_http_server_send(server_ptr, data_packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_SEND);
4652 
4653         /* Check for an error.  */
4654         if (status != NX_SUCCESS)
4655         {
4656 
4657             /* Just release the packet.  */
4658             nx_packet_release(data_packet_ptr);
4659         }
4660     }
4661 
4662 }
4663 
4664 
4665 /**************************************************************************/
4666 /*                                                                        */
4667 /*  FUNCTION                                               RELEASE        */
4668 /*                                                                        */
4669 /*    _nx_web_http_server_delete_process                  PORTABLE C      */
4670 /*                                                           6.1          */
4671 /*  AUTHOR                                                                */
4672 /*                                                                        */
4673 /*    Yuxin Zhou, Microsoft Corporation                                   */
4674 /*                                                                        */
4675 /*  DESCRIPTION                                                           */
4676 /*                                                                        */
4677 /*    This function processes the DELETE HTTP client requests.            */
4678 /*                                                                        */
4679 /*  INPUT                                                                 */
4680 /*                                                                        */
4681 /*    server_ptr                            HTTP Server pointer           */
4682 /*    packet_ptr                            Request packet pointer        */
4683 /*                                                                        */
4684 /*  OUTPUT                                                                */
4685 /*                                                                        */
4686 /*    None                                                                */
4687 /*                                                                        */
4688 /*  CALLS                                                                 */
4689 /*                                                                        */
4690 /*    _nx_web_http_server_basic_authenticate                              */
4691 /*                                          Process basic authentication  */
4692 /*    _nx_web_http_server_digest_authenticate                             */
4693 /*                                          Process digest authentication */
4694 /*    _nx_web_http_server_response_send     Send response back to client  */
4695 /*    _nx_web_http_server_retrieve_resource Retrieve resource from request*/
4696 /*    fx_file_delete                        Delete resource file          */
4697 /*    nx_packet_release                     Release packet                */
4698 /*    _nx_web_http_server_send              Send packet to client         */
4699 /*    _nx_utility_string_length_check       Check string length           */
4700 /*                                                                        */
4701 /*  CALLED BY                                                             */
4702 /*                                                                        */
4703 /*    _nx_web_http_server_receive_data      HTTP Server receive processing*/
4704 /*                                                                        */
4705 /*  RELEASE HISTORY                                                       */
4706 /*                                                                        */
4707 /*    DATE              NAME                      DESCRIPTION             */
4708 /*                                                                        */
4709 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4710 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4711 /*                                            resulting in version 6.1    */
4712 /*                                                                        */
4713 /**************************************************************************/
_nx_web_http_server_delete_process(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr)4714 VOID  _nx_web_http_server_delete_process(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr)
4715 {
4716 
4717 UINT        status;
4718 CHAR        *name_ptr;
4719 CHAR        *password_ptr;
4720 CHAR        *realm_ptr;
4721 NX_PACKET   *response_ptr;
4722 UINT        auth_request_present = NX_FALSE;
4723 NX_TCP_SOCKET *socket_ptr = &server_ptr -> nx_web_http_server_current_session_ptr -> nx_tcp_session_socket;
4724 UINT        name_length = 0;
4725 UINT        password_length = 0;
4726 UINT        realm_length = 0;
4727 UINT        temp_name_length = 0;
4728 UINT        temp_password_length = 0;
4729 UINT        temp_realm_length = 0;
4730 
4731 
4732     /* Pickup the URL (resource) from the request.  */
4733     status =  _nx_web_http_server_retrieve_resource(server_ptr, packet_ptr, server_ptr -> nx_web_http_server_request_resource, NX_WEB_HTTP_MAX_RESOURCE + 1);
4734 
4735     /* Determine if the resource was extracted successfully.  */
4736     if (status != NX_SUCCESS)
4737     {
4738 
4739         /* Send response back to HTTP Client.  */
4740         _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_BAD_REQUEST,
4741                                           sizeof(NX_WEB_HTTP_STATUS_BAD_REQUEST) - 1,
4742                                           "NetX HTTP URL Bad",
4743                                           sizeof("NetX HTTP URL Bad") - 1, NX_NULL, 0);
4744 
4745         /* Error, return to caller.  */
4746         return;
4747     }
4748 
4749     /* Determine if the application has specified an authentication function for this server.  */
4750     if (server_ptr -> nx_web_http_server_authentication_check ||
4751         server_ptr -> nx_web_http_server_authentication_check_extended)
4752     {
4753 
4754         /* Determine if authentication is required for the specified resource.  */
4755         if (server_ptr -> nx_web_http_server_authentication_check_extended)
4756         {
4757             status =  (server_ptr -> nx_web_http_server_authentication_check_extended)(server_ptr, NX_WEB_HTTP_SERVER_DELETE_REQUEST, server_ptr -> nx_web_http_server_request_resource,
4758                                                                                        &name_ptr, &name_length, &password_ptr, &password_length, &realm_ptr, &realm_length);
4759         }
4760         else
4761         {
4762             status =  (server_ptr -> nx_web_http_server_authentication_check)(server_ptr, NX_WEB_HTTP_SERVER_DELETE_REQUEST, server_ptr -> nx_web_http_server_request_resource,
4763                                                                             &name_ptr, &password_ptr, &realm_ptr);
4764         }
4765 
4766         if ((status == NX_WEB_HTTP_BASIC_AUTHENTICATE) ||
4767             (status == NX_WEB_HTTP_DIGEST_AUTHENTICATE))
4768         {
4769 
4770             /* Check name, password and realm string.  */
4771             if (_nx_utility_string_length_check(name_ptr, &temp_name_length, NX_WEB_HTTP_MAX_NAME) ||
4772                 _nx_utility_string_length_check(password_ptr, &temp_password_length, NX_WEB_HTTP_MAX_PASSWORD) ||
4773                 _nx_utility_string_length_check(realm_ptr, &temp_realm_length, NX_MAX_STRING_LENGTH))
4774             {
4775 
4776                 /* Error, return to caller.  */
4777                 return;
4778             }
4779 
4780             /* Validate string length. */
4781             if (server_ptr -> nx_web_http_server_authentication_check_extended &&
4782                 ((realm_length != temp_realm_length) ||
4783                  (name_length != temp_name_length) ||
4784                  (password_length != temp_password_length)))
4785             {
4786                 return;
4787             }
4788         }
4789 
4790         /* Determine what kind - if any - authentication is requested for this resource.  */
4791         if (status == NX_WEB_HTTP_BASIC_AUTHENTICATE)
4792         {
4793 
4794             /* Process basic authentication request.  */
4795             status =  _nx_web_http_server_basic_authenticate(server_ptr, packet_ptr, name_ptr, password_ptr, realm_ptr, &auth_request_present);
4796         }
4797 #ifdef  NX_WEB_HTTP_DIGEST_ENABLE
4798         else if (status == NX_WEB_HTTP_DIGEST_AUTHENTICATE)
4799         {
4800 
4801             /* Process digest authentication request.  */
4802             status =  _nx_web_http_server_digest_authenticate(server_ptr, packet_ptr, name_ptr, password_ptr, realm_ptr, &auth_request_present);
4803         }
4804 #endif
4805 
4806         /* Determine if the authentication is currently in progress.  */
4807         if ((status != NX_WEB_HTTP_DONT_AUTHENTICATE) && (status != NX_SUCCESS))
4808         {
4809 
4810             /* Yes, authentication is in progress.  The HTTP 401 has already been sent.  */
4811             if (server_ptr -> nx_web_http_server_invalid_username_password_callback && auth_request_present)
4812             {
4813             NXD_ADDRESS client_nxd_address;
4814             ULONG       client_port;
4815 
4816                 /* Get the IP address of the client:  */
4817                 status =   nxd_tcp_socket_peer_info_get(socket_ptr, &client_nxd_address , &client_port);
4818 
4819                 if (status == NX_SUCCESS)
4820                 {
4821                     /* Send this information to the host application. */
4822                     (server_ptr -> nx_web_http_server_invalid_username_password_callback)(server_ptr -> nx_web_http_server_request_resource, &client_nxd_address, NX_WEB_HTTP_SERVER_DELETE_REQUEST);
4823                 }
4824             }
4825 
4826             return;
4827         }
4828     }
4829 
4830     /* Determine if a user supplied notify function has been specified.  */
4831     if (server_ptr -> nx_web_http_server_request_notify)
4832     {
4833 
4834         /* Call the user supplied function to notify the user of the delete request.  */
4835         status =  (server_ptr -> nx_web_http_server_request_notify)(server_ptr, NX_WEB_HTTP_SERVER_DELETE_REQUEST, server_ptr -> nx_web_http_server_request_resource, packet_ptr);
4836 
4837         /* Determine if the user supplied routine is requesting the delete should be aborted.  */
4838         if (status != NX_SUCCESS)
4839         {
4840 
4841             /* Determine if the user callback routine successfully completed the request processing.  */
4842             if (status == NX_WEB_HTTP_CALLBACK_COMPLETED)
4843             {
4844 
4845                 /* Send success response back to HTTP Client.  */
4846                 _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_OK,
4847                                                   sizeof(NX_WEB_HTTP_STATUS_OK) - 1, NX_NULL, 0, NX_NULL, 0);
4848                 return;
4849             }
4850 
4851             /* Send response back to HTTP Client.  */
4852             _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
4853                                               sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
4854                                               "NetX HTTP Request Aborted",
4855                                               sizeof("NetX HTTP Request Aborted") - 1, NX_NULL, 0);
4856 
4857             /* Yes, error was detected. Abort the remainder of the delete processing.  */
4858             return;
4859         }
4860     }
4861 
4862     /* Otherwise, everything is okay...  complete the request.  */
4863 
4864     /* Delete the specified file.  */
4865     status =  fx_file_delete(server_ptr -> nx_web_http_server_media_ptr, server_ptr -> nx_web_http_server_request_resource);
4866 
4867     /* Check for error condition.  */
4868     if (status != NX_SUCCESS)
4869     {
4870 
4871         /* Send response back to HTTP Client.  */
4872         _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR,
4873                                           sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
4874                                           "NetX HTTP File Delete Failed",
4875                                           sizeof("NetX HTTP File Delete Failed") - 1, NX_NULL, 0);
4876 
4877         /* Error, return to caller.  */
4878         return;
4879     }
4880 
4881     /* Now build a response header.  */
4882     status = _nx_web_http_server_generate_response_header(server_ptr, &response_ptr, NX_WEB_HTTP_STATUS_OK,
4883                                                           sizeof(NX_WEB_HTTP_STATUS_OK) - 1, 0, NX_NULL, 0, NX_NULL, 0);
4884     if (status == NX_SUCCESS)
4885     {
4886 
4887         /* Send the response back to the client.  */
4888         status = _nx_web_http_server_send(server_ptr, response_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_SEND);
4889 
4890         /* Check for an error.  */
4891         if (status != NX_SUCCESS)
4892         {
4893 
4894             /* Just release the packet.  */
4895             nx_packet_release(response_ptr);
4896         }
4897     }
4898 }
4899 
4900 
4901 /**************************************************************************/
4902 /*                                                                        */
4903 /*  FUNCTION                                               RELEASE        */
4904 /*                                                                        */
4905 /*    _nxe_web_http_server_invalid_userpassword_notify_set                */
4906 /*                                                        PORTABLE C      */
4907 /*                                                           6.1          */
4908 /*  AUTHOR                                                                */
4909 /*                                                                        */
4910 /*    Yuxin Zhou, Microsoft Corporation                                   */
4911 /*                                                                        */
4912 /*  DESCRIPTION                                                           */
4913 /*                                                                        */
4914 /*    This function performs error checking for service to set invalid    */
4915 /*    username password callback function.                                */
4916 /*                                                                        */
4917 /*  INPUT                                                                 */
4918 /*                                                                        */
4919 /*    http_server_ptr                       Pointer to HTTP server        */
4920 /*    invalid_username_password_callback    Pointer to application's      */
4921 /*                                          invalid username password     */
4922 /*                                          callback function             */
4923 /*                                                                        */
4924 /*  OUTPUT                                                                */
4925 /*                                                                        */
4926 /*    status                                Completion status             */
4927 /*                                                                        */
4928 /*  CALLED BY                                                             */
4929 /*                                                                        */
4930 /*    Application Code                                                    */
4931 /*                                                                        */
4932 /*  RELEASE HISTORY                                                       */
4933 /*                                                                        */
4934 /*    DATE              NAME                      DESCRIPTION             */
4935 /*                                                                        */
4936 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4937 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4938 /*                                            resulting in version 6.1    */
4939 /*                                                                        */
4940 /**************************************************************************/
_nxe_web_http_server_invalid_userpassword_notify_set(NX_WEB_HTTP_SERVER * http_server_ptr,UINT (* invalid_username_password_callback)(CHAR * resource,NXD_ADDRESS * client_nxd_address,UINT request_type))4941 UINT _nxe_web_http_server_invalid_userpassword_notify_set(NX_WEB_HTTP_SERVER *http_server_ptr,
4942                                                     UINT (*invalid_username_password_callback)(CHAR *resource, NXD_ADDRESS *client_nxd_address, UINT request_type))
4943 {
4944 
4945 UINT status;
4946 
4947 
4948     if ((http_server_ptr == NX_NULL) || (invalid_username_password_callback == NX_NULL))
4949     {
4950         return NX_PTR_ERROR;
4951     }
4952 
4953     status = _nx_web_http_server_invalid_userpassword_notify_set(http_server_ptr, invalid_username_password_callback);
4954 
4955     return status;
4956 }
4957 
4958 
4959 /**************************************************************************/
4960 /*                                                                        */
4961 /*  FUNCTION                                               RELEASE        */
4962 /*                                                                        */
4963 /*    _nx_web_http_server_invalid_userpassword_notify_set PORTABLE C      */
4964 /*                                                           6.1          */
4965 /*  AUTHOR                                                                */
4966 /*                                                                        */
4967 /*    Yuxin Zhou, Microsoft Corporation                                   */
4968 /*                                                                        */
4969 /*  DESCRIPTION                                                           */
4970 /*                                                                        */
4971 /*    This function sets invalid username password callback function      */
4972 /*                                                                        */
4973 /*    Note: The string resource in callback function                      */
4974 /*    invalid_username_password_callback is built by internal logic and   */
4975 /*    always NULL-terminated.                                             */
4976 /*                                                                        */
4977 /*                                                                        */
4978 /*  INPUT                                                                 */
4979 /*                                                                        */
4980 /*    http_server_ptr                       Pointer to HTTP server        */
4981 /*    invalid_username_password_callback    Pointer to application's      */
4982 /*                                          invalid username password     */
4983 /*                                          callback function             */
4984 /*                                                                        */
4985 /*  OUTPUT                                                                */
4986 /*                                                                        */
4987 /*    status                                Completion status             */
4988 /*                                                                        */
4989 /*  CALLED BY                                                             */
4990 /*                                                                        */
4991 /*    Application Code                                                    */
4992 /*                                                                        */
4993 /*  RELEASE HISTORY                                                       */
4994 /*                                                                        */
4995 /*    DATE              NAME                      DESCRIPTION             */
4996 /*                                                                        */
4997 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4998 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4999 /*                                            resulting in version 6.1    */
5000 /*                                                                        */
5001 /**************************************************************************/
_nx_web_http_server_invalid_userpassword_notify_set(NX_WEB_HTTP_SERVER * http_server_ptr,UINT (* invalid_username_password_callback)(CHAR * resource,NXD_ADDRESS * client_nxd_address,UINT request_type))5002 UINT _nx_web_http_server_invalid_userpassword_notify_set(NX_WEB_HTTP_SERVER *http_server_ptr,
5003                                                          UINT (*invalid_username_password_callback)(CHAR *resource, NXD_ADDRESS *client_nxd_address, UINT request_type))
5004 {
5005 
5006     http_server_ptr -> nx_web_http_server_invalid_username_password_callback = invalid_username_password_callback;
5007 
5008     return NX_SUCCESS;
5009 }
5010 
5011 
5012 /**************************************************************************/
5013 /*                                                                        */
5014 /*  FUNCTION                                               RELEASE        */
5015 /*                                                                        */
5016 /*    _nx_web_http_server_response_send                   PORTABLE C      */
5017 /*                                                           6.1          */
5018 /*  AUTHOR                                                                */
5019 /*                                                                        */
5020 /*    Yuxin Zhou, Microsoft Corporation                                   */
5021 /*                                                                        */
5022 /*  DESCRIPTION                                                           */
5023 /*                                                                        */
5024 /*    This function sends the specified Server response to the requesting */
5025 /*    HTTP client.                                                        */
5026 /*                                                                        */
5027 /*                                                                        */
5028 /*  INPUT                                                                 */
5029 /*                                                                        */
5030 /*    server_ptr                            HTTP Server pointer           */
5031 /*    status_code                           Status-code and reason-phrase */
5032 /*    status_code_length                    Length of status-code         */
5033 /*    information                           Pointer to HTTP info string   */
5034 /*    information_length                    Length of information         */
5035 /*    additional_information                Pointer to additional HTTP    */
5036 /*                                            information                 */
5037 /*    additional_information_length         Length of additional          */
5038 /*                                            information                 */
5039 /*                                                                        */
5040 /*  OUTPUT                                                                */
5041 /*                                                                        */
5042 /*    status                                Completion status             */
5043 /*                                                                        */
5044 /*  CALLS                                                                 */
5045 /*                                                                        */
5046 /*    _nx_web_http_server_generate_response_header                        */
5047 /*                                          Generate response header      */
5048 /*    nx_packet_data_append                 Append information to response*/
5049 /*    nx_packet_release                     Release packet                */
5050 /*    _nx_web_http_server_send              Send HTTP Server response     */
5051 /*                                                                        */
5052 /*  CALLED BY                                                             */
5053 /*                                                                        */
5054 /*    _nx_web_http_server_receive               HTTP receive processing   */
5055 /*    _nx_web_http_server_get_process           Process GET request       */
5056 /*    _nx_web_http_server_put_process           Process PUT request       */
5057 /*    _nx_web_http_server_delete_process        Process DELETE request    */
5058 /*                                                                        */
5059 /*  RELEASE HISTORY                                                       */
5060 /*                                                                        */
5061 /*    DATE              NAME                      DESCRIPTION             */
5062 /*                                                                        */
5063 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5064 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5065 /*                                            resulting in version 6.1    */
5066 /*                                                                        */
5067 /**************************************************************************/
_nx_web_http_server_response_send(NX_WEB_HTTP_SERVER * server_ptr,CHAR * status_code,UINT status_code_length,CHAR * information,UINT information_length,CHAR * additional_information,UINT additional_information_length)5068 UINT  _nx_web_http_server_response_send(NX_WEB_HTTP_SERVER *server_ptr, CHAR *status_code,
5069                                         UINT status_code_length, CHAR *information,
5070                                         UINT information_length, CHAR *additional_information,
5071                                         UINT additional_information_length)
5072 {
5073 
5074 UINT        status;
5075 UINT        length;
5076 NX_PACKET   *packet_ptr;
5077 
5078     /* Determine if there is additional information.  */
5079     if(information)
5080     {
5081 
5082         /* Calculate the size of the information field.  */
5083         length = information_length;
5084 
5085         /* Determine if there is additional information.  */
5086         if (additional_information)
5087         {
5088 
5089             /* Update the length with it as well.  */
5090             length = length + additional_information_length;
5091         }
5092     }
5093     else
5094         length = 0;
5095 
5096     /* Generate response header. */
5097     status = _nx_web_http_server_generate_response_header(server_ptr, &packet_ptr, status_code,
5098                                                           status_code_length, length, NX_NULL, 0, NX_NULL, 0);
5099 
5100     /* Determine if an error occurred.  */
5101     if (status != NX_SUCCESS)
5102     {
5103 
5104         /* Just return.  */
5105         return(status);
5106     }
5107 
5108     /* Determine if there is additional information.  */
5109     if (information)
5110     {
5111 
5112         /* Place the first informational field.  */
5113         status = nx_packet_data_append(packet_ptr, information, information_length,
5114                                        server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5115 
5116         /* If there is additional information, place it in the buffer as well.  */
5117         if (additional_information)
5118         {
5119 
5120             /* Now, place the additional informational field.  */
5121             status += nx_packet_data_append(packet_ptr, additional_information, additional_information_length,
5122                                             server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5123         }
5124     }
5125 
5126     /* Check for an error.  */
5127     if (status != NX_SUCCESS)
5128     {
5129 
5130         /* Just release the packet and return.  */
5131         nx_packet_release(packet_ptr);
5132         return(status);
5133     }
5134 
5135     /* Send the response back to the client.  */
5136     status = _nx_web_http_server_send(server_ptr, packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_SEND);
5137 
5138     /* Check for an error.  */
5139     if (status != NX_SUCCESS)
5140     {
5141 
5142         /* Just release the packet.  */
5143         nx_packet_release(packet_ptr);
5144     }
5145 
5146     return(status);
5147 }
5148 
5149 
5150 /**************************************************************************/
5151 /*                                                                        */
5152 /*  FUNCTION                                               RELEASE        */
5153 /*                                                                        */
5154 /*    _nx_web_http_server_basic_authenticate              PORTABLE C      */
5155 /*                                                           6.2.0        */
5156 /*  AUTHOR                                                                */
5157 /*                                                                        */
5158 /*    Yuxin Zhou, Microsoft Corporation                                   */
5159 /*                                                                        */
5160 /*  DESCRIPTION                                                           */
5161 /*                                                                        */
5162 /*    This function checks for basic (name & password) authentication.    */
5163 /*    If found and correct, it returns a success.  Otherwise, it returns  */
5164 /*    an authentication request to the requesting client.                 */
5165 /*                                                                        */
5166 /*                                                                        */
5167 /*  INPUT                                                                 */
5168 /*                                                                        */
5169 /*    server_ptr                            HTTP Server pointer           */
5170 /*    packet_ptr                            Request packet pointer        */
5171 /*    name_ptr                              Pointer to name string        */
5172 /*    password_ptr                          Pointer to password string    */
5173 /*    realm_ptr                             Pointer to realm string       */
5174 /*    auth_request_present                  Indicate if authentication    */
5175 /*                                                  must be performed     */
5176 /*                                                                        */
5177 /*  OUTPUT                                                                */
5178 /*                                                                        */
5179 /*    status                                Completion status             */
5180 /*                                                                        */
5181 /*  CALLS                                                                 */
5182 /*                                                                        */
5183 /*   _nx_web_http_server_retrieve_basic_authorization                     */
5184 /*                                          Pickup authorization          */
5185 /*   _nx_web_http_base64_decode             Decode authorization          */
5186 /*    _nx_web_http_server_response_packet_allocate                        */
5187 /*                                          Allocate a response packet    */
5188 /*    nx_packet_data_append                 Append information to response*/
5189 /*    nx_packet_release                     Release packet                */
5190 /*    _nx_web_http_server_send              Send HTTP Server response     */
5191 /*    _nx_utility_string_length_check       Check string length           */
5192 /*                                                                        */
5193 /*  CALLED BY                                                             */
5194 /*                                                                        */
5195 /*    _nx_web_http_server_get_process       Process GET request           */
5196 /*    _nx_web_http_server_put_process       Process PUT request           */
5197 /*    _nx_web_http_server_delete_process    Process DELETE request        */
5198 /*                                                                        */
5199 /*  RELEASE HISTORY                                                       */
5200 /*                                                                        */
5201 /*    DATE              NAME                      DESCRIPTION             */
5202 /*                                                                        */
5203 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5204 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5205 /*                                            resulting in version 6.1    */
5206 /*  04-02-2021     Yuxin Zhou               Modified comment(s), and      */
5207 /*                                            improved the logic of       */
5208 /*                                            parsing base64,             */
5209 /*                                            resulting in version 6.1.6  */
5210 /*  10-31-2022     Yuxin Zhou               Modified comment(s), fixed    */
5211 /*                                            the issue of processing     */
5212 /*                                            empty password,             */
5213 /*                                            resulting in version 6.2.0  */
5214 /*                                                                        */
5215 /**************************************************************************/
_nx_web_http_server_basic_authenticate(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,CHAR * name_ptr,CHAR * password_ptr,CHAR * realm_ptr,UINT * auth_request_present)5216 UINT  _nx_web_http_server_basic_authenticate(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, CHAR *name_ptr, CHAR *password_ptr, CHAR *realm_ptr, UINT *auth_request_present)
5217 {
5218 
5219 UINT        i, j;
5220 UINT        status, status1;
5221 CHAR        quote[2] = {0x22, 0};
5222 CHAR        crlf[2] = {13,10};
5223 UINT        match;
5224 UINT        realm_length;
5225 UINT        length;
5226 UINT        authorization_decoded_size;
5227 
5228     /* Default to no authentication request detected. */
5229     *auth_request_present = NX_FALSE;
5230 
5231     /* Default the status to authenticate.  */
5232     status =  NX_WEB_HTTP_BASIC_AUTHENTICATE;
5233 
5234     memset(&authorization_request[0], 0, sizeof(authorization_request));
5235 
5236     memset(&authorization_decoded[0], 0, sizeof(authorization_decoded));
5237 
5238     /* Is the authorization request present?  */
5239     length = _nx_web_http_server_retrieve_basic_authorization(packet_ptr, authorization_request);
5240     if (length)
5241     {
5242 
5243         /* Yes, an authorization request is present.  */
5244         *auth_request_present = NX_TRUE;
5245 
5246         /* Convert the request from Base64 representation to ASCII.  */
5247         _nx_utility_base64_decode((UCHAR *)authorization_request, length, (UCHAR *)authorization_decoded, sizeof(authorization_decoded), &authorization_decoded_size);
5248 
5249         /* See if it is valid.  */
5250 
5251         /* Compare the name.  */
5252         i =  0;
5253         match = NX_TRUE;
5254         while (name_ptr[i] && (i < authorization_decoded_size))
5255         {
5256 
5257             /* Is there a mismatch?  */
5258             if (name_ptr[i] != authorization_decoded[i])
5259             {
5260 
5261                 /* Name mismatch. Continue to avoid timing attack. */
5262                 match = NX_FALSE;
5263             }
5264 
5265             /* Move to next character.  */
5266             i++;
5267         }
5268 
5269         /* Determine if everything matches.  */
5270         if (match && (i < authorization_decoded_size) && (authorization_decoded[i] == ':'))
5271         {
5272 
5273             /* Move the authorization index past the semicolon.  */
5274             i++;
5275 
5276             /* Now compare the passwords.  */
5277             j =  0;
5278             match = NX_TRUE;
5279             while (password_ptr[j] && (i < authorization_decoded_size))
5280             {
5281 
5282                 /* Is there a mismatch?  */
5283                 if (password_ptr[j] != authorization_decoded[i])
5284                 {
5285 
5286                     /* Password mismatch. Continue to avoid timing attack. */
5287                     match = NX_FALSE;
5288                 }
5289 
5290                 /* Move to next character.  */
5291                 i++;
5292                 j++;
5293             }
5294 
5295             /* Determine if we have a match.  */
5296             if (match && (i == authorization_decoded_size) &&
5297                 (authorization_decoded[i] == (CHAR) NX_NULL) &&
5298                 (password_ptr[j] == (CHAR) NX_NULL))
5299             {
5300 
5301                 /* Yes, we have successful authorization!!  */
5302                 status =  NX_SUCCESS;
5303             }
5304         }
5305     }
5306 
5307     /* Determine if we need to send back an unauthorized request.  */
5308     if (status == NX_WEB_HTTP_BASIC_AUTHENTICATE)
5309     {
5310 
5311         /* We need authorization so build the HTTP 401 Unauthorized message to send to the server.  */
5312 
5313         if (_nx_utility_string_length_check(realm_ptr, &realm_length, NX_MAX_STRING_LENGTH))
5314         {
5315             return(NX_WEB_HTTP_ERROR);
5316         }
5317 
5318         /* Allocate a packet for sending the response back.  */
5319         status1 =  _nx_web_http_server_response_packet_allocate(server_ptr, &packet_ptr, NX_WAIT_FOREVER);
5320 
5321         /* Determine if an error occurred in the packet allocation.  */
5322         if (status1 != NX_SUCCESS)
5323         {
5324 
5325             /* Indicate an allocation error occurred.  */
5326             server_ptr -> nx_web_http_server_allocation_errors++;
5327 
5328             /* Just return.  */
5329             return(status1);
5330         }
5331 
5332         /* Insert the response header.  */
5333         nx_packet_data_append(packet_ptr, NX_WEB_HTTP_VERSION, sizeof(NX_WEB_HTTP_VERSION) - 1,
5334                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5335         nx_packet_data_append(packet_ptr, " ", 1, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5336         nx_packet_data_append(packet_ptr, NX_WEB_HTTP_STATUS_UNAUTHORIZED, sizeof(NX_WEB_HTTP_STATUS_UNAUTHORIZED) - 1,
5337                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5338 
5339         /* Place the <cr,lf> into the buffer.  */
5340         nx_packet_data_append(packet_ptr, crlf, 2,
5341                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5342 
5343         /* Insert the type of authentication requested.  */
5344         nx_packet_data_append(packet_ptr, "WWW-Authenticate: Basic realm=", 30,
5345                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5346 
5347         /* Insert the double quote.  */
5348         nx_packet_data_append(packet_ptr, quote, 1,
5349                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5350 
5351         /* Place the realm string into the buffer.  */
5352         nx_packet_data_append(packet_ptr, realm_ptr, realm_length,
5353                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5354 
5355         /* Insert the double quote.  */
5356         nx_packet_data_append(packet_ptr, quote, 1,
5357                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5358 
5359         /* Place the <cr,lf> into the buffer.  */
5360         nx_packet_data_append(packet_ptr, crlf, 2,
5361                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5362 
5363         /* Place another <cr,lf> into the buffer to signal end of FULL HTTP response.  */
5364         nx_packet_data_append(packet_ptr, crlf, 2,
5365                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
5366 
5367         /* Send the response back to the client.  */
5368         status1 = _nx_web_http_server_send(server_ptr, packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_SEND);
5369 
5370         /* Check for an error.  */
5371         if (status1)
5372         {
5373 
5374             /* Return the internal NetX error. */
5375             status = status1;
5376 
5377             /* Just release the packet.  */
5378             nx_packet_release(packet_ptr);
5379         }
5380     }
5381 
5382     /* Return the result of the authentication request.  */
5383     return(status);
5384 }
5385 
5386 
5387 /**************************************************************************/
5388 /*                                                                        */
5389 /*  FUNCTION                                               RELEASE        */
5390 /*                                                                        */
5391 /*    _nx_web_http_server_retrieve_basic_authorization    PORTABLE C      */
5392 /*                                                           6.1.10       */
5393 /*  AUTHOR                                                                */
5394 /*                                                                        */
5395 /*    Yuxin Zhou, Microsoft Corporation                                   */
5396 /*                                                                        */
5397 /*  DESCRIPTION                                                           */
5398 /*                                                                        */
5399 /*    This function retrieves basic authentication information from the   */
5400 /*    HTTP request packet.                                                */
5401 /*                                                                        */
5402 /*                                                                        */
5403 /*  INPUT                                                                 */
5404 /*                                                                        */
5405 /*    packet_ptr                            Request packet pointer        */
5406 /*    authorization_request_ptr             Pointer to destination for    */
5407 /*                                            authorization string        */
5408 /*                                                                        */
5409 /*  OUTPUT                                                                */
5410 /*                                                                        */
5411 /*    status                                Completion status             */
5412 /*                                                                        */
5413 /*  CALLS                                                                 */
5414 /*                                                                        */
5415 /*   None                                                                 */
5416 /*                                                                        */
5417 /*  CALLED BY                                                             */
5418 /*                                                                        */
5419 /*    _nx_web_http_server_basic_authenticate                              */
5420 /*                                          Basic authenticate processing */
5421 /*                                                                        */
5422 /*  RELEASE HISTORY                                                       */
5423 /*                                                                        */
5424 /*    DATE              NAME                      DESCRIPTION             */
5425 /*                                                                        */
5426 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5427 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5428 /*                                            resulting in version 6.1    */
5429 /*  01-31-2022     Yuxin Zhou               Modified comment(s),  fixed   */
5430 /*                                            the HTTP Server state issue */
5431 /*                                            with basic authorization,   */
5432 /*                                            resulting in version 6.1.10 */
5433 /*                                                                        */
5434 /**************************************************************************/
_nx_web_http_server_retrieve_basic_authorization(NX_PACKET * packet_ptr,CHAR * authorization_request_ptr)5435 UINT  _nx_web_http_server_retrieve_basic_authorization(NX_PACKET *packet_ptr, CHAR *authorization_request_ptr)
5436 {
5437 
5438 UINT    length;
5439 UINT    found;
5440 CHAR    *buffer_ptr;
5441 
5442 
5443     /* Set the found flag to false.  */
5444     found =  NX_FALSE;
5445 
5446     /* Default the authorization request to zero.  */
5447     length =  0;
5448 
5449     /* Set the authorization request string to NULL.  */
5450     authorization_request_ptr[0] =  NX_NULL;
5451 
5452     /* Setup pointer to buffer.  */
5453     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
5454 
5455 
5456     /* Find the "Authorization: " token first.  */
5457     while (((buffer_ptr+15) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
5458     {
5459 
5460         /* Check for the Authorization: token.  */
5461         if (((*buffer_ptr ==      'a') || (*buffer_ptr ==      'A')) &&
5462             ((*(buffer_ptr+1) ==  'u') || (*(buffer_ptr+1) ==  'U')) &&
5463             ((*(buffer_ptr+2) ==  't') || (*(buffer_ptr+2) ==  'T')) &&
5464             ((*(buffer_ptr+3) ==  'h') || (*(buffer_ptr+3) ==  'H')) &&
5465             ((*(buffer_ptr+4) ==  'o') || (*(buffer_ptr+4) ==  'O')) &&
5466             ((*(buffer_ptr+5) ==  'r') || (*(buffer_ptr+5) ==  'R')) &&
5467             ((*(buffer_ptr+6) ==  'i') || (*(buffer_ptr+6) ==  'I')) &&
5468             ((*(buffer_ptr+7) ==  'z') || (*(buffer_ptr+7) ==  'Z')) &&
5469             ((*(buffer_ptr+8) ==  'a') || (*(buffer_ptr+8) ==  'A')) &&
5470             ((*(buffer_ptr+9) ==  't') || (*(buffer_ptr+9) ==  'T')) &&
5471             ((*(buffer_ptr+10) == 'i') || (*(buffer_ptr+10) == 'I')) &&
5472             ((*(buffer_ptr+11) == 'o') || (*(buffer_ptr+11) == 'O')) &&
5473             ((*(buffer_ptr+12) == 'n') || (*(buffer_ptr+12) == 'N')) &&
5474             (*(buffer_ptr+13) == ':') &&
5475             (*(buffer_ptr+14) == ' '))
5476         {
5477 
5478             /* Move the pointer up to the length token.  */
5479             buffer_ptr =  buffer_ptr + 15;
5480 
5481             /* Set the found flag.  */
5482             found =  NX_TRUE;
5483             break;
5484         }
5485 
5486         /* Move the pointer up to the next character.  */
5487         buffer_ptr++;
5488     }
5489 
5490     /* Determine if the first token was found.  */
5491     if (!found)
5492     {
5493 
5494         /* No, authorization is not present.  Return a zero length.  */
5495         return(length);
5496     }
5497 
5498     /* Set the found flag back to false.  */
5499     found =  NX_FALSE;
5500 
5501     /* Now remove any extra blanks.  */
5502     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
5503     {
5504 
5505         /* Move the pointer up one character.  */
5506         buffer_ptr++;
5507     }
5508 
5509     /* Now check for the "Basic " token.  */
5510     while (((buffer_ptr+6) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
5511     {
5512 
5513         /* Check for the Basic token.  */
5514         if (((*buffer_ptr ==      'b') || (*buffer_ptr ==      'B')) &&
5515             ((*(buffer_ptr+1) ==  'a') || (*(buffer_ptr+1) ==  'A')) &&
5516             ((*(buffer_ptr+2) ==  's') || (*(buffer_ptr+2) ==  'S')) &&
5517             ((*(buffer_ptr+3) ==  'i') || (*(buffer_ptr+3) ==  'I')) &&
5518             ((*(buffer_ptr+4) ==  'c') || (*(buffer_ptr+4) ==  'C')) &&
5519             (*(buffer_ptr+5) == ' '))
5520         {
5521 
5522             /* Move the pointer up to the actual authorization string.  */
5523             buffer_ptr =  buffer_ptr + 6;
5524 
5525             /* Set the found flag.  */
5526             found =  NX_TRUE;
5527             break;
5528         }
5529 
5530         /* Move the pointer up to the next character.  */
5531         buffer_ptr++;
5532     }
5533 
5534     /* Determine if the first token was found.  */
5535     if (!found)
5536     {
5537 
5538         /* No, authorization is not present.  Return a zero length.  */
5539         return(length);
5540     }
5541 
5542     /* Now remove any extra blanks.  */
5543     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
5544     {
5545 
5546         /* Move the pointer up one character.  */
5547         buffer_ptr++;
5548     }
5549 
5550     /* Now pickup the authorization string.  */
5551     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13) && (length < NX_WEB_HTTP_MAX_STRING))
5552     {
5553 
5554         /* Copy a character of the authorization string into the destination.  */
5555         authorization_request_ptr[length] =  *buffer_ptr++;
5556         length++;
5557     }
5558 
5559     /* Return the length to the caller.  */
5560     return(length);
5561 }
5562 
5563 
5564 /**************************************************************************/
5565 /*                                                                        */
5566 /*  FUNCTION                                               RELEASE        */
5567 /*                                                                        */
5568 /*    _nx_web_http_server_retrieve_resource               PORTABLE C      */
5569 /*                                                           6.1          */
5570 /*  AUTHOR                                                                */
5571 /*                                                                        */
5572 /*    Yuxin Zhou, Microsoft Corporation                                   */
5573 /*                                                                        */
5574 /*  DESCRIPTION                                                           */
5575 /*                                                                        */
5576 /*    This function retrieves the resource (URL) portion of the request   */
5577 /*    and places it in the destination.                                   */
5578 /*                                                                        */
5579 /*                                                                        */
5580 /*  INPUT                                                                 */
5581 /*                                                                        */
5582 /*    server_ptr                            HTTP Server pointer           */
5583 /*    packet_ptr                            Request packet pointer        */
5584 /*    destination                           Destination for resource      */
5585 /*    max_size                              Maximum size of destination   */
5586 /*                                                                        */
5587 /*  OUTPUT                                                                */
5588 /*                                                                        */
5589 /*    Status                                Completion status             */
5590 /*                                                                        */
5591 /*  CALLS                                                                 */
5592 /*                                                                        */
5593 /*    None                                                                */
5594 /*                                                                        */
5595 /*  CALLED BY                                                             */
5596 /*                                                                        */
5597 /*    _nx_web_http_server_get_process       Process GET request           */
5598 /*    _nx_web_http_server_put_process       Process PUT request           */
5599 /*    _nx_web_http_server_delete_process    Process DELETE request        */
5600 /*                                                                        */
5601 /*  RELEASE HISTORY                                                       */
5602 /*                                                                        */
5603 /*    DATE              NAME                      DESCRIPTION             */
5604 /*                                                                        */
5605 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5606 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5607 /*                                            resulting in version 6.1    */
5608 /*                                                                        */
5609 /**************************************************************************/
_nx_web_http_server_retrieve_resource(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,CHAR * destination,UINT max_size)5610 UINT  _nx_web_http_server_retrieve_resource(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, CHAR *destination, UINT max_size)
5611 {
5612 
5613 UINT    i;
5614 CHAR    *buffer_ptr;
5615 
5616 #ifndef NX_WEB_HTTPS_ENABLE
5617     NX_PARAMETER_NOT_USED(server_ptr);
5618 #endif /* NX_WEB_HTTPS_ENABLE */
5619 
5620     /* Set the destination to NULL.  */
5621     destination[0] =  (CHAR) 0;
5622 
5623     /* Setup pointer to buffer.  */
5624     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
5625 
5626     /* Find the first space which is the start position of URI. */
5627     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != ' '))
5628     {
5629 
5630         /* Move the pointer up to the next character.  */
5631         buffer_ptr++;
5632     }
5633 
5634     /* Check for an error condition.  */
5635     if (*buffer_ptr != ' ')
5636         return(NX_WEB_HTTP_ERROR);
5637 
5638     buffer_ptr++;
5639 
5640 #ifdef NX_WEB_HTTPS_ENABLE
5641 
5642     if (server_ptr -> nx_web_http_is_https_server)
5643     {
5644         if ((buffer_ptr + 8 < (CHAR *)packet_ptr->nx_packet_append_ptr) && (*buffer_ptr != '/'))
5645         {
5646 
5647             /* Check whether it is an absoluteURI*/
5648             if (((*buffer_ptr == 'h') || (*buffer_ptr == 'H')) &&
5649                 ((*(buffer_ptr + 1) == 't') || (*(buffer_ptr + 1) == 'T')) &&
5650                 ((*(buffer_ptr + 2) == 't') || (*(buffer_ptr + 2) == 'T')) &&
5651                 ((*(buffer_ptr + 3) == 'p') || (*(buffer_ptr + 3) == 'P')) &&
5652                 ((*(buffer_ptr + 4) == 's') || (*(buffer_ptr + 4) == 'S')) &&
5653                 (*(buffer_ptr + 5) == ':') &&
5654                 (*(buffer_ptr + 6) == '/') &&
5655                 (*(buffer_ptr + 7) == '/'))
5656             {
5657 
5658                 /* Yes it is. Find the absolute path. */
5659                 buffer_ptr += 8;
5660 
5661                 /* Find the first slash character.  The first slash marks the beginning of the URL.  */
5662                 while ((buffer_ptr < (CHAR *)packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR)0) && (*buffer_ptr != '/'))
5663                 {
5664 
5665                     /* Move the pointer up to the next character.  */
5666                     buffer_ptr++;
5667                 }
5668             }
5669         }
5670 
5671     }
5672     else
5673 #endif
5674     {
5675         if ((buffer_ptr + 7 < (CHAR *)packet_ptr->nx_packet_append_ptr) && (*buffer_ptr != '/'))
5676         {
5677 
5678             /* Check whether it is an absoluteURI*/
5679             if (((*buffer_ptr == 'h') || (*buffer_ptr == 'H')) &&
5680                 ((*(buffer_ptr + 1) == 't') || (*(buffer_ptr + 1) == 'T')) &&
5681                 ((*(buffer_ptr + 2) == 't') || (*(buffer_ptr + 2) == 'T')) &&
5682                 ((*(buffer_ptr + 3) == 'p') || (*(buffer_ptr + 3) == 'P')) &&
5683                 (*(buffer_ptr + 4) == ':') &&
5684                 (*(buffer_ptr + 5) == '/') &&
5685                 (*(buffer_ptr + 6) == '/'))
5686             {
5687 
5688                 /* Yes it is. Find the absolute path. */
5689                 buffer_ptr += 7;
5690 
5691                 /* Find the first slash character.  The first slash marks the beginning of the URL.  */
5692                 while ((buffer_ptr < (CHAR *)packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR)0) && (*buffer_ptr != '/'))
5693                 {
5694 
5695                     /* Move the pointer up to the next character.  */
5696                     buffer_ptr++;
5697                 }
5698             }
5699         }
5700     }
5701 
5702     /* Check for an error condition.  */
5703     if ((buffer_ptr >= (CHAR *) packet_ptr -> nx_packet_append_ptr) || (*buffer_ptr != '/'))
5704         return(NX_WEB_HTTP_ERROR);
5705 
5706     /* Copy the rest of the resource to the destination.  Space, semicolon, and question mark characters signal the
5707        end of the resource.  */
5708     i =  0;
5709     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != ' ') && (*buffer_ptr != ';') && (*buffer_ptr != '?') && (i < (max_size-1)))
5710     {
5711 
5712         /* Check escape characters. */
5713         if(*buffer_ptr == '%')
5714         {
5715 
5716             /* It is an escape character. */
5717             if((buffer_ptr + 2) < (CHAR *)packet_ptr -> nx_packet_append_ptr)
5718             {
5719 
5720                 /* Convert the HEX number. */
5721                 buffer_ptr++;
5722                 if((*buffer_ptr >= '0') && (*buffer_ptr <= '9'))
5723                     destination[i] = (CHAR)(*buffer_ptr - '0');
5724                 else if((*buffer_ptr >= 'a') && (*buffer_ptr <= 'f'))
5725                     destination[i] = (CHAR)(*buffer_ptr - 'a' + 10);
5726                 else if((*buffer_ptr >= 'A') && (*buffer_ptr <= 'F'))
5727                     destination[i] = (CHAR)(*buffer_ptr - 'A' + 10);
5728                 else
5729                 {
5730 
5731                     /* Error picking up the resource.  */
5732                     destination[0] =  (CHAR) 0;
5733                     return(NX_WEB_HTTP_ERROR);
5734                 }
5735                 destination[i] = (CHAR)(destination[i] << 4);
5736 
5737                 /* Convert the HEX number. */
5738                 buffer_ptr++;
5739                 if((*buffer_ptr >= '0') && (*buffer_ptr <= '9'))
5740                     destination[i] = (CHAR)(destination[i] + (*buffer_ptr - '0'));
5741                 else if((*buffer_ptr >= 'a') && (*buffer_ptr <= 'f'))
5742                     destination[i] = (CHAR)(destination[i] + (*buffer_ptr - 'a' + 10));
5743                 else if((*buffer_ptr >= 'A') && (*buffer_ptr <= 'F'))
5744                     destination[i] = (CHAR)(destination[i] + (*buffer_ptr - 'A' + 10));
5745                 else
5746                 {
5747 
5748                     /* Error picking up the resource.  */
5749                     destination[0] =  (CHAR) 0;
5750                     return(NX_WEB_HTTP_ERROR);
5751                 }
5752 
5753                 /* Move to the next byte. */
5754                 i++;
5755                 buffer_ptr++;
5756             }
5757             else
5758             {
5759 
5760                 /* Error picking up the resource.  */
5761                 destination[0] =  (CHAR) 0;
5762                 return(NX_WEB_HTTP_ERROR);
5763             }
5764         }
5765         else
5766         {
5767 
5768             /* Copy the URL name into the destination.  */
5769             destination[i++] =  *buffer_ptr++;
5770         }
5771     }
5772 
5773     /* Determine if the resource was retrieved.  */
5774     if ((destination[0] == (CHAR) 0) || (buffer_ptr >= (CHAR *)packet_ptr -> nx_packet_append_ptr) || ((*buffer_ptr != ' ') && (*buffer_ptr != '?') && (*buffer_ptr != ';')))
5775     {
5776 
5777         /* Error picking up the resource.  */
5778         destination[0] =  (CHAR) 0;
5779         return(NX_WEB_HTTP_ERROR);
5780     }
5781 
5782     /* Everything is okay, place a NULL at the end of the resource.  */
5783     destination[i] =  (CHAR) 0;
5784 
5785     /* Return success.  */
5786     return(NX_SUCCESS);
5787 }
5788 
5789 
5790 /**************************************************************************/
5791 /*                                                                        */
5792 /*  FUNCTION                                               RELEASE        */
5793 /*                                                                        */
5794 /*    _nx_web_http_server_calculate_content_offset        PORTABLE C      */
5795 /*                                                           6.1          */
5796 /*  AUTHOR                                                                */
5797 /*                                                                        */
5798 /*    Yuxin Zhou, Microsoft Corporation                                   */
5799 /*                                                                        */
5800 /*  DESCRIPTION                                                           */
5801 /*                                                                        */
5802 /*    This function calculates the byte offset to the start of the        */
5803 /*    HTTP request content area.  This area immediately follows the HTTP  */
5804 /*    request header (which ends with a blank line).                      */
5805 /*                                                                        */
5806 /*                                                                        */
5807 /*  INPUT                                                                 */
5808 /*                                                                        */
5809 /*    packet_ptr                            Pointer to request packet     */
5810 /*                                                                        */
5811 /*  OUTPUT                                                                */
5812 /*                                                                        */
5813 /*    Byte Offset                           (0 implies no content)        */
5814 /*                                                                        */
5815 /*  CALLS                                                                 */
5816 /*                                                                        */
5817 /*    None                                                                */
5818 /*                                                                        */
5819 /*  CALLED BY                                                             */
5820 /*                                                                        */
5821 /*    _nx_web_http_server_content_get       Application content get       */
5822 /*    _nx_web_http_server_get_process       Process GET request           */
5823 /*    _nx_web_http_server_put_process       Process PUT request           */
5824 /*                                                                        */
5825 /*  RELEASE HISTORY                                                       */
5826 /*                                                                        */
5827 /*    DATE              NAME                      DESCRIPTION             */
5828 /*                                                                        */
5829 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5830 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5831 /*                                            resulting in version 6.1    */
5832 /*                                                                        */
5833 /**************************************************************************/
_nx_web_http_server_calculate_content_offset(NX_PACKET * packet_ptr)5834 UINT  _nx_web_http_server_calculate_content_offset(NX_PACKET *packet_ptr)
5835 {
5836 
5837 UINT       offset;
5838 CHAR      *buffer_ptr;
5839 UINT       crlf_found = 0;
5840 
5841 
5842     /* Default the content offset to zero.  */
5843     offset =  0;
5844 
5845     /* Find the "cr,lf,cr,lf" token.  */
5846 #ifndef NX_DISABLE_PACKET_CHAIN
5847     while(packet_ptr)
5848     {
5849 #endif
5850 
5851         /* Setup pointer to buffer.  */
5852         buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
5853 
5854         while(buffer_ptr < (CHAR *)packet_ptr -> nx_packet_append_ptr)
5855         {
5856             if (!(crlf_found & 1) && (*buffer_ptr == (CHAR)13))
5857             {
5858 
5859                 /* Found CR.  */
5860                 crlf_found++;
5861             }
5862             else if ((crlf_found & 1) && (*buffer_ptr == (CHAR)10))
5863             {
5864 
5865                 /* Found LF.  */
5866                 crlf_found++;
5867             }
5868             else
5869             {
5870 
5871                 /* Reset the CRLF marker.  */
5872                 crlf_found = 0;
5873             }
5874 
5875             offset++;
5876             buffer_ptr++;
5877 
5878             if (crlf_found == 4)
5879             {
5880 
5881                 /* Return the offset to the caller.  */
5882                 return(offset);
5883             }
5884         }
5885 
5886 #ifndef NX_DISABLE_PACKET_CHAIN
5887         packet_ptr = packet_ptr -> nx_packet_next;
5888     }
5889 #endif
5890 
5891     /* Not found the "cr,lf,cr,lf".  */
5892     return(0);
5893 }
5894 
5895 
5896 /**************************************************************************/
5897 /*                                                                        */
5898 /*  FUNCTION                                               RELEASE        */
5899 /*                                                                        */
5900 /*    _nxe_web_http_server_type_get                       PORTABLE C      */
5901 /*                                                           6.1          */
5902 /*  AUTHOR                                                                */
5903 /*                                                                        */
5904 /*    Yuxin Zhou, Microsoft Corporation                                   */
5905 /*                                                                        */
5906 /*  DESCRIPTION                                                           */
5907 /*                                                                        */
5908 /*    This function checks error for deriving the type of the resource.   */
5909 /*                                                                        */
5910 /*  INPUT                                                                 */
5911 /*                                                                        */
5912 /*    server_ptr                            HTTP Server pointer           */
5913 /*    name                                  Name string                   */
5914 /*    http_type_string                      Destination HTTP type string  */
5915 /*    string_size                           Return HTTP type string size  */
5916 /*                                                                        */
5917 /*  OUTPUT                                                                */
5918 /*                                                                        */
5919 /*    Size                                  Number of bytes in string     */
5920 /*                                                                        */
5921 /*  CALLS                                                                 */
5922 /*                                                                        */
5923 /*    _nx_web_http_server_type_get                                        */
5924 /*                                                                        */
5925 /*  CALLED BY                                                             */
5926 /*                                                                        */
5927 /*    Application Code                                                    */
5928 /*                                                                        */
5929 /*  RELEASE HISTORY                                                       */
5930 /*                                                                        */
5931 /*    DATE              NAME                      DESCRIPTION             */
5932 /*                                                                        */
5933 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5934 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5935 /*                                            resulting in version 6.1    */
5936 /*                                                                        */
5937 /**************************************************************************/
_nxe_web_http_server_type_get(NX_WEB_HTTP_SERVER * server_ptr,CHAR * name,CHAR * http_type_string,UINT * string_size)5938 UINT  _nxe_web_http_server_type_get(NX_WEB_HTTP_SERVER *server_ptr, CHAR *name, CHAR *http_type_string, UINT *string_size)
5939 {
5940 UINT status;
5941 
5942 
5943     /* Check for invalid input pointers.  */
5944     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
5945         (name == NX_NULL)       || (http_type_string == NX_NULL) || (string_size == NX_NULL))
5946     {
5947         return(NX_PTR_ERROR);
5948     }
5949 
5950     status = _nx_web_http_server_type_get(server_ptr, name, http_type_string, string_size);
5951 
5952     return(status);
5953 }
5954 
5955 
5956 /**************************************************************************/
5957 /*                                                                        */
5958 /*  FUNCTION                                               RELEASE        */
5959 /*                                                                        */
5960 /*    _nx_web_http_server_type_get                        PORTABLE C      */
5961 /*                                                           6.1          */
5962 /*  AUTHOR                                                                */
5963 /*                                                                        */
5964 /*    Yuxin Zhou, Microsoft Corporation                                   */
5965 /*                                                                        */
5966 /*  DESCRIPTION                                                           */
5967 /*                                                                        */
5968 /*    This function derives the type of the resource.                     */
5969 /*                                                                        */
5970 /*  INPUT                                                                 */
5971 /*                                                                        */
5972 /*    server_ptr                            HTTP Server pointer           */
5973 /*    name                                  Name string                   */
5974 /*    http_type_string                      Destination HTTP type string  */
5975 /*    string_size                           Return HTTP type string size  */
5976 /*                                                                        */
5977 /*  OUTPUT                                                                */
5978 /*                                                                        */
5979 /*    Size                                  Number of bytes in string     */
5980 /*                                                                        */
5981 /*  CALLS                                                                 */
5982 /*                                                                        */
5983 /*    _nx_web_http_server_memicmp                                         */
5984 /*    _nx_utility_string_length_check                                     */
5985 /*                                                                        */
5986 /*  CALLED BY                                                             */
5987 /*                                                                        */
5988 /*    _nx_web_http_server_type_get_extended Get MIME type                 */
5989 /*                                                                        */
5990 /*  RELEASE HISTORY                                                       */
5991 /*                                                                        */
5992 /*    DATE              NAME                      DESCRIPTION             */
5993 /*                                                                        */
5994 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5995 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5996 /*                                            resulting in version 6.1    */
5997 /*                                                                        */
5998 /**************************************************************************/
_nx_web_http_server_type_get(NX_WEB_HTTP_SERVER * server_ptr,CHAR * name,CHAR * http_type_string,UINT * string_size)5999 UINT  _nx_web_http_server_type_get(NX_WEB_HTTP_SERVER *server_ptr, CHAR *name, CHAR *http_type_string, UINT *string_size)
6000 {
6001 UINT    temp_name_length;
6002 
6003     /* Check name length.  */
6004     if (_nx_utility_string_length_check(name, &temp_name_length, NX_MAX_STRING_LENGTH))
6005     {
6006         return(NX_WEB_HTTP_ERROR);
6007     }
6008 
6009     /* Call actual service type get function. */
6010     return(_nx_web_http_server_type_get_extended(server_ptr, name, temp_name_length,
6011                                                  http_type_string, NX_MAX_STRING_LENGTH + 1,
6012                                                  string_size));
6013 }
6014 
6015 
6016 /**************************************************************************/
6017 /*                                                                        */
6018 /*  FUNCTION                                               RELEASE        */
6019 /*                                                                        */
6020 /*    _nxe_web_http_server_type_get_extended              PORTABLE C      */
6021 /*                                                           6.1          */
6022 /*  AUTHOR                                                                */
6023 /*                                                                        */
6024 /*    Yuxin Zhou, Microsoft Corporation                                   */
6025 /*                                                                        */
6026 /*  DESCRIPTION                                                           */
6027 /*                                                                        */
6028 /*    This function checks error for deriving the type of the resource.   */
6029 /*                                                                        */
6030 /*  INPUT                                                                 */
6031 /*                                                                        */
6032 /*    server_ptr                            HTTP Server pointer           */
6033 /*    name                                  Name string                   */
6034 /*    name_length                           Length of name string         */
6035 /*    http_type_string                      Destination HTTP type string  */
6036 /*    http_type_string_max_size             Size of the destination string*/
6037 /*    string_size                           Return HTTP type string size  */
6038 /*                                                                        */
6039 /*  OUTPUT                                                                */
6040 /*                                                                        */
6041 /*    Status                                Web HTTP status code          */
6042 /*                                                                        */
6043 /*  CALLS                                                                 */
6044 /*                                                                        */
6045 /*    _nx_web_http_server_type_get_extended Get MIME type                 */
6046 /*                                                                        */
6047 /*  CALLED BY                                                             */
6048 /*                                                                        */
6049 /*    Application Code                                                    */
6050 /*                                                                        */
6051 /*  RELEASE HISTORY                                                       */
6052 /*                                                                        */
6053 /*    DATE              NAME                      DESCRIPTION             */
6054 /*                                                                        */
6055 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6056 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6057 /*                                            resulting in version 6.1    */
6058 /*                                                                        */
6059 /**************************************************************************/
_nxe_web_http_server_type_get_extended(NX_WEB_HTTP_SERVER * server_ptr,CHAR * name,UINT name_length,CHAR * http_type_string,UINT http_type_string_max_size,UINT * string_size)6060 UINT  _nxe_web_http_server_type_get_extended(NX_WEB_HTTP_SERVER *server_ptr, CHAR *name, UINT name_length,
6061                                              CHAR *http_type_string, UINT http_type_string_max_size,
6062                                              UINT *string_size)
6063 {
6064 UINT status;
6065 
6066 
6067     /* Check for invalid input pointers.  */
6068     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
6069         (name == NX_NULL)       || (http_type_string == NX_NULL) || (string_size == NX_NULL))
6070     {
6071         return(NX_PTR_ERROR);
6072     }
6073 
6074     /* Check for appropriate caller.  */
6075     NX_THREADS_ONLY_CALLER_CHECKING
6076 
6077     status = _nx_web_http_server_type_get_extended(server_ptr, name, name_length, http_type_string,
6078                                                    http_type_string_max_size, string_size);
6079 
6080     return(status);
6081 }
6082 
6083 
6084 /**************************************************************************/
6085 /*                                                                        */
6086 /*  FUNCTION                                               RELEASE        */
6087 /*                                                                        */
6088 /*    _nx_web_http_server_type_get_extended               PORTABLE C      */
6089 /*                                                           6.1          */
6090 /*  AUTHOR                                                                */
6091 /*                                                                        */
6092 /*    Yuxin Zhou, Microsoft Corporation                                   */
6093 /*                                                                        */
6094 /*  DESCRIPTION                                                           */
6095 /*                                                                        */
6096 /*    This function derives the type of the resource.                     */
6097 /*                                                                        */
6098 /*    Note: The string of name must be NULL-terminated and length of each */
6099 /*    string matches the length specified in the argument list.           */
6100 /*                                                                        */
6101 /*  INPUT                                                                 */
6102 /*                                                                        */
6103 /*    server_ptr                            HTTP Server pointer           */
6104 /*    name                                  Name string                   */
6105 /*    name_length                           Length of name string         */
6106 /*    http_type_string                      Destination HTTP type string  */
6107 /*    http_type_string_max_size             Size of the destination string*/
6108 /*    string_size                           Return HTTP type string size  */
6109 /*                                                                        */
6110 /*  OUTPUT                                                                */
6111 /*                                                                        */
6112 /*    Status                                Web HTTP status code          */
6113 /*                                                                        */
6114 /*  CALLS                                                                 */
6115 /*                                                                        */
6116 /*    _nx_web_http_server_memicmp           Compare ignore case           */
6117 /*    _nx_utility_string_length_check       String length check           */
6118 /*    memcpy                                Copy memory data              */
6119 /*                                                                        */
6120 /*  CALLED BY                                                             */
6121 /*                                                                        */
6122 /*    _nx_web_http_server_get_process       Process GET request           */
6123 /*    Application Code                                                    */
6124 /*                                                                        */
6125 /*  RELEASE HISTORY                                                       */
6126 /*                                                                        */
6127 /*    DATE              NAME                      DESCRIPTION             */
6128 /*                                                                        */
6129 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6130 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
6131 /*                                            verified memcpy use cases,  */
6132 /*                                            resulting in version 6.1    */
6133 /*                                                                        */
6134 /**************************************************************************/
_nx_web_http_server_type_get_extended(NX_WEB_HTTP_SERVER * server_ptr,CHAR * name,UINT name_length,CHAR * http_type_string,UINT http_type_string_max_size,UINT * string_size)6135 UINT  _nx_web_http_server_type_get_extended(NX_WEB_HTTP_SERVER *server_ptr, CHAR *name, UINT name_length,
6136                                             CHAR *http_type_string, UINT http_type_string_max_size,
6137                                             UINT *string_size)
6138 {
6139 
6140 UINT    i;
6141 CHAR   *ch;
6142 UINT    ext_length;
6143 UINT    map_ext_length;
6144 UINT    map_type_length;
6145 UINT    temp_name_length;
6146 
6147     /* Check name length.  */
6148     if (_nx_utility_string_length_check(name, &temp_name_length, name_length))
6149     {
6150         return(NX_WEB_HTTP_ERROR);
6151     }
6152 
6153     /* Validate string length. */
6154     if (name_length != temp_name_length)
6155     {
6156         return(NX_WEB_HTTP_ERROR);
6157     }
6158 
6159     /* First find the end of the string.  */
6160     ch = name + name_length;
6161 
6162     /* Now look backwards to find the last period that signals the
6163        file extension.  */
6164     ext_length = 0;
6165     while ((ch >= name) && (*ch != '.') &&(*ch != '/'))
6166     {
6167         ch--;
6168         ext_length++;
6169     }
6170 
6171     if(*ch != '.')
6172     {
6173 
6174         /* No extension is found. Return the default mime type. */
6175         if(http_type_string_max_size < (sizeof(NX_WEB_HTTP_SERVER_DEFAULT_MIME)))
6176         {
6177             /* NX_HTTP_SERVER_DEFAULT_MIME does not fit into
6178                the caller-supplied http_type_string. */
6179             return (NX_WEB_HTTP_ERROR);
6180         }
6181 
6182 
6183         /* No extension is found. Return the default mime type. */
6184         memcpy(http_type_string, NX_WEB_HTTP_SERVER_DEFAULT_MIME, sizeof(NX_WEB_HTTP_SERVER_DEFAULT_MIME)); /* Use case of memcpy is verified. */
6185         *string_size = sizeof(NX_WEB_HTTP_SERVER_DEFAULT_MIME) - 1;
6186         return(NX_WEB_HTTP_EXTENSION_MIME_DEFAULT);
6187     }
6188 
6189     /* Position forward again, past the period.  */
6190     ch++;
6191     ext_length--;
6192 
6193     /* Now see what HTTP file type to return.  */
6194     /* Search user defined MIME maps first. */
6195     if(server_ptr -> nx_web_http_server_mime_maps_additional &&
6196        (server_ptr -> nx_web_http_server_mime_maps_additional_num > 0))
6197     {
6198         for(i = 0; i < server_ptr -> nx_web_http_server_mime_maps_additional_num; i++)
6199         {
6200 
6201             /* Check map extension and type length.  */
6202             if (_nx_utility_string_length_check(server_ptr -> nx_web_http_server_mime_maps_additional[i].nx_web_http_server_mime_map_extension,
6203                                                 &map_ext_length, ext_length) ||
6204                 _nx_utility_string_length_check(server_ptr -> nx_web_http_server_mime_maps_additional[i].nx_web_http_server_mime_map_type,
6205                                                 &map_type_length, http_type_string_max_size - 1))
6206             {
6207                 continue;
6208             }
6209 
6210             if(_nx_web_http_server_memicmp((UCHAR *)ch, ext_length,
6211                                            (UCHAR *)server_ptr -> nx_web_http_server_mime_maps_additional[i].nx_web_http_server_mime_map_extension,
6212                                            map_ext_length) == NX_SUCCESS)
6213             {
6214 
6215                 /* Find the extension. Return the mapped MIME type. */
6216                 memcpy(http_type_string, server_ptr -> nx_web_http_server_mime_maps_additional[i].nx_web_http_server_mime_map_type, map_type_length + 1); /* Use case of memcpy is verified. */
6217                 *string_size = map_type_length;
6218                 return(NX_SUCCESS);
6219             }
6220         }
6221     }
6222 
6223     /* Search default MIME maps. */
6224     for(i = 0; i < sizeof(_nx_web_http_server_mime_maps) / sizeof(NX_WEB_HTTP_SERVER_MIME_MAP); i++)
6225     {
6226 
6227         /* Check map extension and type length.  */
6228         if (_nx_utility_string_length_check(_nx_web_http_server_mime_maps[i].nx_web_http_server_mime_map_extension,
6229                                             &map_ext_length, ext_length) ||
6230             _nx_utility_string_length_check(_nx_web_http_server_mime_maps[i].nx_web_http_server_mime_map_type,
6231                                             &map_type_length, http_type_string_max_size - 1))
6232         {
6233             continue;
6234         }
6235 
6236         if(_nx_web_http_server_memicmp((UCHAR *)ch, ext_length,
6237                                    (UCHAR *)_nx_web_http_server_mime_maps[i].nx_web_http_server_mime_map_extension,
6238                                    map_ext_length) == NX_SUCCESS)
6239         {
6240 
6241             /* Find the extension. Return the mapped MIME type. */
6242             memcpy(http_type_string, _nx_web_http_server_mime_maps[i].nx_web_http_server_mime_map_type, map_type_length + 1); /* Use case of memcpy is verified. */
6243             *string_size = map_type_length;
6244             return(NX_SUCCESS);
6245         }
6246     }
6247 
6248     /* No extension matches. Return the default mime type. */
6249 
6250     if(http_type_string_max_size < (sizeof(NX_WEB_HTTP_SERVER_DEFAULT_MIME)))
6251     {
6252         /* NX_HTTP_SERVER_DEFAULT_MIME does not fit into
6253            the caller-supplied http_type_string. */
6254         return (NX_WEB_HTTP_ERROR);
6255     }
6256 
6257     memcpy(http_type_string, NX_WEB_HTTP_SERVER_DEFAULT_MIME, sizeof(NX_WEB_HTTP_SERVER_DEFAULT_MIME)); /* Use case of memcpy is verified. */
6258     *string_size = sizeof(NX_WEB_HTTP_SERVER_DEFAULT_MIME) - 1;
6259     return(NX_WEB_HTTP_EXTENSION_MIME_DEFAULT);
6260 }
6261 
6262 
6263 #ifdef NX_WEB_HTTP_DIGEST_ENABLE
6264 
6265 /**************************************************************************/
6266 /*                                                                        */
6267 /*  FUNCTION                                               RELEASE        */
6268 /*                                                                        */
6269 /*    _nx_web_http_server_nonce_allocate                  PORTABLE C      */
6270 /*                                                           6.2.0        */
6271 /*  AUTHOR                                                                */
6272 /*                                                                        */
6273 /*    Yuxin Zhou, Microsoft Corporation                                   */
6274 /*                                                                        */
6275 /*  DESCRIPTION                                                           */
6276 /*                                                                        */
6277 /*    This function allocate a new nonce for digest authentication.       */
6278 /*                                                                        */
6279 /*  INPUT                                                                 */
6280 /*                                                                        */
6281 /*    server_ptr                            HTTP Server pointer           */
6282 /*    nonce_ptr                             Allocated nonce pointer       */
6283 /*                                                                        */
6284 /*  OUTPUT                                                                */
6285 /*                                                                        */
6286 /*    None                                                                */
6287 /*                                                                        */
6288 /*  CALLS                                                                 */
6289 /*                                                                        */
6290 /*    tx_time_get                           Get system time               */
6291 /*                                                                        */
6292 /*  CALLED BY                                                             */
6293 /*                                                                        */
6294 /*    _nx_web_http_server_digest_authenticate                             */
6295 /*                                          Digest authentication         */
6296 /*                                                                        */
6297 /*  RELEASE HISTORY                                                       */
6298 /*                                                                        */
6299 /*    DATE              NAME                      DESCRIPTION             */
6300 /*                                                                        */
6301 /*  10-31-2022     Yuxin Zhou               Initial Version 6.2.0         */
6302 /*                                                                        */
6303 /**************************************************************************/
_nx_web_http_server_nonce_allocate(NX_WEB_HTTP_SERVER * server_ptr,NX_WEB_HTTP_SERVER_NONCE ** nonce_ptr)6304 UINT _nx_web_http_server_nonce_allocate(NX_WEB_HTTP_SERVER *server_ptr, NX_WEB_HTTP_SERVER_NONCE **nonce_ptr)
6305 {
6306 UINT i;
6307 UCHAR random_value;
6308 NX_WEB_HTTP_SERVER_NONCE *nonces_list = server_ptr -> nx_web_http_server_nonces;
6309 
6310 
6311     /* Search if there is free entry for new nonce.  */
6312     for (i = 0; i < NX_WEB_HTTP_SERVER_NONCE_MAX; i++)
6313     {
6314         if (nonces_list[i].nonce_state == NX_WEB_HTTP_SERVER_NONCE_INVALID)
6315         {
6316             *nonce_ptr = &(nonces_list[i]);
6317             break;
6318         }
6319     }
6320 
6321     if (i == NX_WEB_HTTP_SERVER_NONCE_MAX)
6322     {
6323 
6324         /* If no free entry, check the timeout of allocated nonces.  */
6325         for (i = 0; i < NX_WEB_HTTP_SERVER_NONCE_MAX; i++)
6326         {
6327             if (nonces_list[i].nonce_state == NX_WEB_HTTP_SERVER_NONCE_VALID)
6328             {
6329                 if (tx_time_get() > nonces_list[i].nonce_timestamp + NX_WEB_HTTP_SERVER_NONCE_TIMEOUT)
6330                 {
6331 
6332                     /* If this nonce is timed out, free up this entry for new nonce.  */
6333                     *nonce_ptr = &(nonces_list[i]);
6334                     break;
6335                 }
6336             }
6337         }
6338 
6339         /* If no entry can be allocated, return error.  */
6340         if (i == NX_WEB_HTTP_SERVER_NONCE_MAX)
6341         {
6342             return(NX_NOT_FOUND);
6343         }
6344     }
6345 
6346     /* Generate new nonce for digest authentication. */
6347     for (i = 0; i < NX_WEB_HTTP_SERVER_NONCE_SIZE; i++)
6348     {
6349         random_value = (UCHAR)NX_RAND() % (sizeof(_nx_web_http_server_base64_array) - 1);
6350         (*nonce_ptr) -> nonce_buffer[i] = (UCHAR)_nx_web_http_server_base64_array[random_value];
6351     }
6352 
6353     /* Reset the timestamp and state for the new nonce.  */
6354     (*nonce_ptr) -> nonce_timestamp = tx_time_get();
6355     (*nonce_ptr) -> nonce_state = NX_WEB_HTTP_SERVER_NONCE_VALID;
6356 
6357     return(NX_SUCCESS);
6358 }
6359 
6360 /**************************************************************************/
6361 /*                                                                        */
6362 /*  FUNCTION                                               RELEASE        */
6363 /*                                                                        */
6364 /*    _nx_web_http_server_digest_authenticate             PORTABLE C      */
6365 /*                                                           6.2.0        */
6366 /*  AUTHOR                                                                */
6367 /*                                                                        */
6368 /*    Yuxin Zhou, Microsoft Corporation                                   */
6369 /*                                                                        */
6370 /*  DESCRIPTION                                                           */
6371 /*                                                                        */
6372 /*    This function checks for digest (MD5 only) authentication.          */
6373 /*    If the digest is correct, it returns a success.  Otherwise, it      */
6374 /*    returns an authentication request to the requesting client.         */
6375 /*                                                                        */
6376 /*                                                                        */
6377 /*  INPUT                                                                 */
6378 /*                                                                        */
6379 /*    server_ptr                            HTTP Server pointer           */
6380 /*    packet_ptr                            Request packet pointer        */
6381 /*    name_ptr                              Pointer to name string        */
6382 /*    password_ptr                          Pointer to password string    */
6383 /*    realm_ptr                             Pointer to realm string       */
6384 /*    auth_request_present                  Indicate if authentication    */
6385 /*                                            must be performed           */
6386 /*                                                                        */
6387 /*  OUTPUT                                                                */
6388 /*                                                                        */
6389 /*    status                                Completion status             */
6390 /*                                                                        */
6391 /*  CALLS                                                                 */
6392 /*                                                                        */
6393 /*   _nx_web_http_server_retrieve_digest_authorization                    */
6394 /*                                          Pickup authorization          */
6395 /*   _nx_web_http_server_digest_response_calculate                        */
6396 /*                                          Calculate the digest          */
6397 /*    _nx_web_http_server_response_packet_allocate                        */
6398 /*                                          Allocate a response packet    */
6399 /*    nx_packet_data_append                 Append information to response*/
6400 /*    nx_packet_release                     Release packet                */
6401 /*    _nx_web_http_server_send              Send HTTP Server response     */
6402 /*    _nx_utility_string_length_check       Check string length           */
6403 /*                                                                        */
6404 /*  CALLED BY                                                             */
6405 /*                                                                        */
6406 /*    _nx_web_http_server_get_process       Process GET request           */
6407 /*    _nx_web_http_server_put_process       Process PUT request           */
6408 /*    _nx_web_http_server_delete_process    Process DELETE request        */
6409 /*                                                                        */
6410 /*  RELEASE HISTORY                                                       */
6411 /*                                                                        */
6412 /*    DATE              NAME                      DESCRIPTION             */
6413 /*                                                                        */
6414 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6415 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6416 /*                                            resulting in version 6.1    */
6417 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
6418 /*                                            supported random nonce,     */
6419 /*                                            resulting in version 6.2.0  */
6420 /*                                                                        */
6421 /**************************************************************************/
_nx_web_http_server_digest_authenticate(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,CHAR * name_ptr,CHAR * password_ptr,CHAR * realm_ptr,UINT * auth_request_present)6422 UINT  _nx_web_http_server_digest_authenticate(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, CHAR *name_ptr, CHAR *password_ptr, CHAR *realm_ptr, UINT *auth_request_present)
6423 {
6424 
6425 CHAR        authorization_response[NX_WEB_HTTP_MAX_ASCII_MD5 + 1];
6426 CHAR        calculated_response[NX_WEB_HTTP_MAX_ASCII_MD5 + 1];
6427 CHAR        authorization_uri[NX_WEB_HTTP_MAX_RESOURCE + 1];
6428 CHAR        method[8];
6429 CHAR        quote[2] = {0x22, 0};
6430 CHAR        *buffer_ptr;
6431 UINT        i;
6432 UINT        status, status1, callback_status;
6433 CHAR        crlf[2] = {13,10};
6434 CHAR        authorization_nc[NX_WEB_HTTP_MAX_RESOURCE + 1];
6435 CHAR        authorization_cnonce[NX_WEB_HTTP_MAX_RESOURCE + 1];
6436 UINT        realm_length;
6437 NX_WEB_HTTP_SERVER_NONCE *nonce_ptr = NX_NULL;
6438 
6439     /* Default to no authentication request detected. */
6440     *auth_request_present =  NX_FALSE;
6441 
6442     /* Default the status to authenticate.  */
6443     status =  NX_WEB_HTTP_DIGEST_AUTHENTICATE;
6444 
6445     /* Is the authorization request present?  */
6446     if (_nx_web_http_server_retrieve_digest_authorization(server_ptr, packet_ptr, authorization_response, authorization_uri, authorization_nc, authorization_cnonce, &nonce_ptr))
6447     {
6448 
6449         /* Yes, an authorization request is present.  */
6450         *auth_request_present =  NX_TRUE;
6451 
6452         /* Pickup method from the packet.  */
6453         buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
6454         i = 0;
6455         while (((buffer_ptr + i) < (CHAR *)packet_ptr -> nx_packet_append_ptr) && (buffer_ptr[i] != ' ') && (i < (sizeof(method) - 1)))
6456         {
6457 
6458             /* Copy bytes of method. */
6459             method[i] =  buffer_ptr[i];
6460             i++;
6461         }
6462 
6463         /* Null terminate method.  */
6464         method[i] =  (CHAR) NX_NULL;
6465 
6466         /* If the digest authenticate callback function is set, invoke the callback function. */
6467         if(server_ptr -> nx_web_http_server_digest_authenticate_callback)
6468         {
6469             callback_status = (server_ptr -> nx_web_http_server_digest_authenticate_callback)(server_ptr, name_ptr, realm_ptr, password_ptr, method, authorization_uri, authorization_nc, authorization_cnonce);
6470         }
6471         else
6472         {
6473 
6474             /* If the digest authenticate callback is not set, assume it is success, for backward
6475                compatibility reasons. */
6476             callback_status = NX_SUCCESS;
6477         }
6478 
6479         /* Calculate what the MD5 should be.  */
6480         _nx_web_http_server_digest_response_calculate(server_ptr, name_ptr, realm_ptr, password_ptr, (CHAR *)(nonce_ptr -> nonce_buffer), method, authorization_uri, authorization_nc, authorization_cnonce, calculated_response);
6481 
6482         /* Determine if the calculated response is the same as the received response.  */
6483         i =  0;
6484         status = NX_SUCCESS;
6485         while (i < NX_WEB_HTTP_MAX_ASCII_MD5 + 1)
6486         {
6487             /* Is there a mismatch?  */
6488             if (calculated_response[i] != authorization_response[i])
6489             {
6490 
6491                 /* Authorization mismatch. Continue to avoid timing attack. */
6492                 status = NX_WEB_HTTP_DIGEST_AUTHENTICATE;
6493             }
6494 
6495             /* Otherwise, look at next character.  */
6496             i++;
6497         }
6498 
6499         /* If the response is authenticated, mark the nonce as accepted.  */
6500         if (status == NX_SUCCESS)
6501         {
6502 
6503             /* If another session uses the same nonce, don't accept it.  */
6504             if (nonce_ptr -> nonce_state == NX_WEB_HTTP_SERVER_NONCE_ACCEPTED)
6505             {
6506                 if (nonce_ptr -> nonce_session_ptr != server_ptr -> nx_web_http_server_current_session_ptr)
6507                 {
6508                     status = NX_WEB_HTTP_DIGEST_AUTHENTICATE;
6509                 }
6510             }
6511             else
6512             {
6513 
6514                 /* Update nonce state and set the session pointer for mapping in disconnection.  */
6515                 nonce_ptr -> nonce_state = NX_WEB_HTTP_SERVER_NONCE_ACCEPTED;
6516                 nonce_ptr -> nonce_session_ptr = server_ptr -> nx_web_http_server_current_session_ptr;
6517             }
6518         }
6519         else
6520         {
6521             nonce_ptr -> nonce_state = NX_WEB_HTTP_SERVER_NONCE_INVALID;
6522         }
6523 
6524         /* If digest authenticate callback function returns non-success value, the request is
6525            considered unauthenticated. */
6526         if(callback_status != NX_SUCCESS)
6527             status = NX_WEB_HTTP_DIGEST_AUTHENTICATE;
6528     }
6529 
6530     /* Determine if we need to send back an unauthorized request.  */
6531     if (status == NX_WEB_HTTP_DIGEST_AUTHENTICATE)
6532     {
6533 
6534         /* Allocate a new nonce for digest authentication.  */
6535         status1 = _nx_web_http_server_nonce_allocate(server_ptr, &nonce_ptr);
6536 
6537         /* Determine if an error occurred in the packet allocation.  */
6538         if (status1)
6539         {
6540 
6541             /* Send response back to HTTP Client.  */
6542             _nx_web_http_server_response_send(server_ptr, NX_WEB_HTTP_STATUS_INTERNAL_ERROR, sizeof(NX_WEB_HTTP_STATUS_INTERNAL_ERROR) - 1,
6543                                               "NetX HTTP Server Internal Error", sizeof("NetX HTTP Server Internal Error") - 1, NX_NULL, 0);
6544 
6545             /* Indicate an allocation error occurred.  */
6546             server_ptr -> nx_web_http_server_allocation_errors++;
6547 
6548             /* Return the internal NetX error.  */
6549             return(status1);
6550         }
6551 
6552         /* We need authorization so build the HTTP 401 Unauthorized message to send to the server.  */
6553 
6554         /* Check string length.  */
6555         if (_nx_utility_string_length_check(realm_ptr, &realm_length, NX_MAX_STRING_LENGTH))
6556         {
6557             return(NX_WEB_HTTP_ERROR);
6558         }
6559 
6560         /* Allocate a packet for sending the response back.  */
6561         status1 =  _nx_web_http_server_response_packet_allocate(server_ptr, &packet_ptr, NX_WAIT_FOREVER);
6562 
6563         /* Determine if an error occurred in the packet allocation.  */
6564         if (status1 != NX_SUCCESS)
6565         {
6566 
6567             /* Indicate an allocation error occurred.  */
6568             server_ptr -> nx_web_http_server_allocation_errors++;
6569 
6570             /* Return the internal NetX error.  */
6571             return(status1);
6572         }
6573 
6574         /* Insert the response header.  */
6575         nx_packet_data_append(packet_ptr, NX_WEB_HTTP_VERSION, sizeof(NX_WEB_HTTP_VERSION) - 1,
6576                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6577         nx_packet_data_append(packet_ptr, " ", 1, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6578         nx_packet_data_append(packet_ptr, NX_WEB_HTTP_STATUS_UNAUTHORIZED, sizeof(NX_WEB_HTTP_STATUS_UNAUTHORIZED) - 1,
6579                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6580 
6581         /* Place the <cr,lf> into the buffer.  */
6582         nx_packet_data_append(packet_ptr, crlf, 2,
6583                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6584 
6585         /* Insert the type of authentication requested.  */
6586         nx_packet_data_append(packet_ptr, "WWW-Authenticate: Digest realm=", 31,
6587                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6588 
6589         /* Insert the double quote.  */
6590         nx_packet_data_append(packet_ptr, quote, 1,
6591                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6592 
6593         /* Place the realm string into the buffer.  */
6594         nx_packet_data_append(packet_ptr, realm_ptr, realm_length,
6595                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6596 
6597         /* Insert the double quote.  */
6598         nx_packet_data_append(packet_ptr, quote, 1,
6599                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6600 
6601         /* Place a comma into the buffer.  */
6602         nx_packet_data_append(packet_ptr, ",", 1,
6603                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6604 
6605         /* Insert the algorithm into the buffer.  */
6606         nx_packet_data_append(packet_ptr, " algorithm=", 11,
6607                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6608 
6609         /* Insert the double quote.  */
6610         nx_packet_data_append(packet_ptr, quote, 1,
6611                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6612 
6613         /* Insert the md5 tag into the buffer.  */
6614         nx_packet_data_append(packet_ptr, "md5", 3,
6615                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6616 
6617         /* Insert the double quote.  */
6618         nx_packet_data_append(packet_ptr, quote, 1,
6619                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6620 
6621         /* Place a comma into the buffer.  */
6622         nx_packet_data_append(packet_ptr, ",", 1,
6623                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6624 
6625         /* Insert the nonce into the buffer.  */
6626         nx_packet_data_append(packet_ptr, " nonce=", 7,
6627                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6628 
6629         /* Insert the double quote.  */
6630         nx_packet_data_append(packet_ptr, quote, 1,
6631                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6632 
6633         /* Place the nonce string into the buffer.  */
6634         nx_packet_data_append(packet_ptr, nonce_ptr -> nonce_buffer, NX_WEB_HTTP_SERVER_NONCE_SIZE,
6635                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6636 
6637         /* Insert the double quote.  */
6638         nx_packet_data_append(packet_ptr, quote, 1,
6639                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6640 
6641         /* Place the qop="auth" parameter string into the buffer.  */
6642         nx_packet_data_append(packet_ptr, ", qop=\"auth\"", 12,
6643                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6644 
6645         /* Place the <cr,lf> into the buffer.  */
6646         nx_packet_data_append(packet_ptr, crlf, 2,
6647                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6648 
6649         /* Set Content-Length as 0.  */
6650         nx_packet_data_append(packet_ptr, "Content-Length: 0", 17,
6651                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6652 
6653         /* Place the <cr,lf> into the buffer.  */
6654         nx_packet_data_append(packet_ptr, crlf, 2,
6655                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6656 
6657         /* Place another <cr,lf> into the buffer to signal end of FULL HTTP response.  */
6658         nx_packet_data_append(packet_ptr, crlf, 2,
6659                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
6660 
6661         /* Send the response back to the client.  */
6662         status1 = _nx_web_http_server_send(server_ptr, packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_SEND);
6663 
6664         /* Check for an error.  */
6665         if (status1)
6666         {
6667 
6668             /* Set the internal NetX error as the status return. */
6669             status = status1;
6670 
6671             /* Just release the packet.  */
6672             nx_packet_release(packet_ptr);
6673         }
6674     }
6675 
6676     /* Return the result of the authentication request.  */
6677     return(status);
6678 }
6679 
6680 
6681 /**************************************************************************/
6682 /*                                                                        */
6683 /*  FUNCTION                                               RELEASE        */
6684 /*                                                                        */
6685 /*    _nx_web_http_server_digest_response_calculate       PORTABLE C      */
6686 /*                                                           6.2.0        */
6687 /*  AUTHOR                                                                */
6688 /*                                                                        */
6689 /*    Yuxin Zhou, Microsoft Corporation                                   */
6690 /*                                                                        */
6691 /*  DESCRIPTION                                                           */
6692 /*                                                                        */
6693 /*    This function computes the MD5 digest based on the supplied input   */
6694 /*    parameters.                                                         */
6695 /*                                                                        */
6696 /*  INPUT                                                                 */
6697 /*                                                                        */
6698 /*    server_ptr                            HTTP Server pointer           */
6699 /*    username                              Username string               */
6700 /*    realm                                 Realm string                  */
6701 /*    password                              Password string               */
6702 /*    nonce                                 Authentication nonce string   */
6703 /*    method                                Request method string         */
6704 /*    uri                                   Resource request string       */
6705 /*    nc                                    Nonce count string            */
6706 /*    cnonce                                Client nonce string           */
6707 /*    result                                Computed digest string        */
6708 /*                                                                        */
6709 /*  OUTPUT                                                                */
6710 /*                                                                        */
6711 /*    None                                                                */
6712 /*                                                                        */
6713 /*  CALLS                                                                 */
6714 /*                                                                        */
6715 /*   _nx_web_http_server_hex_ascii_convert  Convert hex to ASCII          */
6716 /*   _nx_md5_initialize                     Initialize MD5 algorithm      */
6717 /*   _nx_md5_update                         Update MD5 digest             */
6718 /*   _nx_md5_digest_calculate               Complete the MD5 algorithm    */
6719 /*    _nx_utility_string_length_check       Check string length           */
6720 /*                                                                        */
6721 /*  CALLED BY                                                             */
6722 /*                                                                        */
6723 /*    _nx_web_http_server_digest_authenticate                             */
6724 /*                                          Digest authentication         */
6725 /*                                                                        */
6726 /*  RELEASE HISTORY                                                       */
6727 /*                                                                        */
6728 /*    DATE              NAME                      DESCRIPTION             */
6729 /*                                                                        */
6730 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6731 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6732 /*                                            resulting in version 6.1    */
6733 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
6734 /*                                            supported random nonce,     */
6735 /*                                            resulting in version 6.2.0  */
6736 /*                                                                        */
6737 /**************************************************************************/
_nx_web_http_server_digest_response_calculate(NX_WEB_HTTP_SERVER * server_ptr,CHAR * username,CHAR * realm,CHAR * password,CHAR * nonce,CHAR * method,CHAR * uri,CHAR * nc,CHAR * cnonce,CHAR * result)6738 VOID  _nx_web_http_server_digest_response_calculate(NX_WEB_HTTP_SERVER *server_ptr, CHAR *username, CHAR *realm, CHAR *password, CHAR *nonce, CHAR *method, CHAR *uri, CHAR *nc, CHAR *cnonce, CHAR *result)
6739 {
6740 
6741 CHAR    md5_binary[NX_WEB_HTTP_MAX_BINARY_MD5];
6742 CHAR    ha1_string[NX_WEB_HTTP_MAX_ASCII_MD5 + 1];
6743 CHAR    ha2_string[NX_WEB_HTTP_MAX_ASCII_MD5 + 1];
6744 UINT    username_length;
6745 UINT    password_length;
6746 UINT    realm_length;
6747 UINT    method_length;
6748 UINT    uri_length;
6749 UINT    nc_length;
6750 UINT    cnonce_length;
6751 
6752     /* Check string length.  */
6753     if (_nx_utility_string_length_check(username, &username_length, NX_WEB_HTTP_MAX_NAME) ||
6754         _nx_utility_string_length_check(password, &password_length, NX_WEB_HTTP_MAX_PASSWORD) ||
6755         _nx_utility_string_length_check(realm, &realm_length, NX_MAX_STRING_LENGTH) ||
6756         _nx_utility_string_length_check(method, &method_length, 7) ||
6757         _nx_utility_string_length_check(uri, &uri_length, NX_WEB_HTTP_MAX_RESOURCE) ||
6758         _nx_utility_string_length_check(nc, &nc_length, NX_WEB_HTTP_MAX_RESOURCE) ||
6759         _nx_utility_string_length_check(cnonce, &cnonce_length, NX_WEB_HTTP_MAX_RESOURCE))
6760     {
6761         return;
6762     }
6763 
6764 
6765     /* Calculate the H(A1) portion of the digest.  */
6766     _nx_md5_initialize(&(server_ptr -> nx_web_http_server_md5data));
6767     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) username, username_length);
6768     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) ":", 1);
6769     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) realm, realm_length);
6770     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) ":", 1);
6771     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) password, password_length);
6772     _nx_md5_digest_calculate(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) md5_binary);
6773 
6774     /* Convert this H(A1) portion to ASCII Hex representation.  */
6775     _nx_web_http_server_hex_ascii_convert(md5_binary, NX_WEB_HTTP_MAX_BINARY_MD5, ha1_string);
6776 
6777     /* Make the H(A2) portion of the digest.  */
6778     _nx_md5_initialize(&(server_ptr -> nx_web_http_server_md5data));
6779     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) method, method_length);
6780     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) ":", 1);
6781     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) uri, uri_length);
6782     _nx_md5_digest_calculate(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) md5_binary);
6783 
6784     /* Convert this H(A2) portion to ASCII Hex representation.  */
6785     _nx_web_http_server_hex_ascii_convert(md5_binary, NX_WEB_HTTP_MAX_BINARY_MD5, ha2_string);
6786 
6787     /* Now make the final MD5 digest.  */
6788     _nx_md5_initialize(&(server_ptr -> nx_web_http_server_md5data));
6789     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) ha1_string, sizeof(ha1_string) - 1);
6790     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) ":", 1);
6791     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) nonce, NX_WEB_HTTP_SERVER_NONCE_SIZE);
6792 
6793     /* Start of Internet Explorer bug work-around.  */
6794     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) ":", 1);
6795     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) nc, nc_length);
6796     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) ":", 1);
6797     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) cnonce, cnonce_length);
6798     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) ":auth", 5);
6799     /* End of Internet Explorer bug work-around.  */
6800 
6801     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) ":", 1);
6802     _nx_md5_update(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) ha2_string, sizeof(ha2_string) - 1);
6803     _nx_md5_digest_calculate(&(server_ptr -> nx_web_http_server_md5data), (unsigned char *) md5_binary);
6804 
6805     /* Finally, convert the response back to an ASCII string and place in
6806        the destination.  */
6807     _nx_web_http_server_hex_ascii_convert(md5_binary, NX_WEB_HTTP_MAX_BINARY_MD5, result);
6808 }
6809 
6810 
6811 /**************************************************************************/
6812 /*                                                                        */
6813 /*  FUNCTION                                               RELEASE        */
6814 /*                                                                        */
6815 /*    _nx_web_http_server_retrieve_digest_authorization   PORTABLE C      */
6816 /*                                                           6.2.0        */
6817 /*  AUTHOR                                                                */
6818 /*                                                                        */
6819 /*    Yuxin Zhou, Microsoft Corporation                                   */
6820 /*                                                                        */
6821 /*  DESCRIPTION                                                           */
6822 /*                                                                        */
6823 /*    This function retrieves the MD5 digest parameters from the          */
6824 /*    supplied request packet.                                            */
6825 /*                                                                        */
6826 /*  INPUT                                                                 */
6827 /*                                                                        */
6828 /*    server_ptr                            HTTP Server pointer           */
6829 /*    packet_ptr                            Request packet pointer        */
6830 /*    response                              Digest response pointer       */
6831 /*    uri                                   URI from response pointer     */
6832 /*    nc                                    Nonce count string            */
6833 /*    cnonce                                Client nonce string           */
6834 /*    nonce_ptr                             Server nonce pointer          */
6835 /*                                                                        */
6836 /*  OUTPUT                                                                */
6837 /*                                                                        */
6838 /*    length                                Length of response (should be */
6839 /*                                            32). A value of 0 indicates */
6840 /*                                            an error is present         */
6841 /*                                                                        */
6842 /*  CALLS                                                                 */
6843 /*                                                                        */
6844 /*    None                                                                */
6845 /*                                                                        */
6846 /*  CALLED BY                                                             */
6847 /*                                                                        */
6848 /*    _nx_web_http_server_digest_authenticate                             */
6849 /*                                          Digest authentication         */
6850 /*                                                                        */
6851 /*  RELEASE HISTORY                                                       */
6852 /*                                                                        */
6853 /*    DATE              NAME                      DESCRIPTION             */
6854 /*                                                                        */
6855 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6856 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6857 /*                                            resulting in version 6.1    */
6858 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
6859 /*                                            supported random nonce,     */
6860 /*                                            resulting in version 6.2.0  */
6861 /*                                                                        */
6862 /**************************************************************************/
_nx_web_http_server_retrieve_digest_authorization(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,CHAR * response,CHAR * uri,CHAR * nc,CHAR * cnonce,NX_WEB_HTTP_SERVER_NONCE ** nonce_ptr)6863 UINT  _nx_web_http_server_retrieve_digest_authorization(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, CHAR *response, CHAR *uri, CHAR *nc, CHAR *cnonce, NX_WEB_HTTP_SERVER_NONCE **nonce_ptr)
6864 {
6865 
6866 UINT    length;
6867 UINT    found;
6868 CHAR    *buffer_ptr;
6869 CHAR    *saved_buffer_ptr;
6870 UCHAR   *nonce_buffer;
6871 UINT    i;
6872 
6873 
6874     /* Set the found flag to false.  */
6875     found =  NX_FALSE;
6876 
6877     /* Default the authorization request to zero.  */
6878     length =  0;
6879 
6880     /* Set the response and uri strings to NULL.  */
6881     response[0] =  NX_NULL;
6882     uri[0] =       NX_NULL;
6883 
6884     /* Internet Explorer bug work-around.  */
6885     nc[0] =        NX_NULL;
6886     cnonce[0] =    NX_NULL;
6887 
6888     /* Setup pointer to buffer.  */
6889     buffer_ptr =  (CHAR *) packet_ptr -> nx_packet_prepend_ptr;
6890 
6891     /* Find the "Authorization: " token first.  */
6892     while (((buffer_ptr+15) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
6893     {
6894 
6895         /* Check for the Authorization: token.  */
6896         if (((*buffer_ptr ==      'a') || (*buffer_ptr ==      'A')) &&
6897             ((*(buffer_ptr+1) ==  'u') || (*(buffer_ptr+1) ==  'U')) &&
6898             ((*(buffer_ptr+2) ==  't') || (*(buffer_ptr+2) ==  'T')) &&
6899             ((*(buffer_ptr+3) ==  'h') || (*(buffer_ptr+3) ==  'H')) &&
6900             ((*(buffer_ptr+4) ==  'o') || (*(buffer_ptr+4) ==  'O')) &&
6901             ((*(buffer_ptr+5) ==  'r') || (*(buffer_ptr+5) ==  'R')) &&
6902             ((*(buffer_ptr+6) ==  'i') || (*(buffer_ptr+6) ==  'I')) &&
6903             ((*(buffer_ptr+7) ==  'z') || (*(buffer_ptr+7) ==  'Z')) &&
6904             ((*(buffer_ptr+8) ==  'a') || (*(buffer_ptr+8) ==  'A')) &&
6905             ((*(buffer_ptr+9) ==  't') || (*(buffer_ptr+9) ==  'T')) &&
6906             ((*(buffer_ptr+10) == 'i') || (*(buffer_ptr+10) == 'I')) &&
6907             ((*(buffer_ptr+11) == 'o') || (*(buffer_ptr+11) == 'O')) &&
6908             ((*(buffer_ptr+12) == 'n') || (*(buffer_ptr+12) == 'N')) &&
6909             (*(buffer_ptr+13) == ':') &&
6910             (*(buffer_ptr+14) == ' '))
6911         {
6912 
6913             /* Move the pointer up to the length token.  */
6914             buffer_ptr =  buffer_ptr + 15;
6915 
6916             /* Set the found flag.  */
6917             found =  NX_TRUE;
6918             break;
6919         }
6920 
6921         /* Move the pointer up to the next character.  */
6922         buffer_ptr++;
6923     }
6924 
6925     /* Determine if the first token was found.  */
6926     if (!found)
6927     {
6928 
6929         /* No, authorization is not present.  Return a zero length.  */
6930         return(length);
6931     }
6932 
6933     /* Set the found flag back to false.  */
6934     found =  NX_FALSE;
6935 
6936     /* Now remove any extra blanks.  */
6937     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
6938     {
6939 
6940         /* Move the pointer up one character.  */
6941         buffer_ptr++;
6942     }
6943 
6944     /* Now check for the "Digest " token.  */
6945     while (((buffer_ptr+7) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
6946     {
6947 
6948         /* Check for the Digest token.  */
6949         if (((*buffer_ptr ==      'd') || (*buffer_ptr ==      'D')) &&
6950             ((*(buffer_ptr+1) ==  'i') || (*(buffer_ptr+1) ==  'I')) &&
6951             ((*(buffer_ptr+2) ==  'g') || (*(buffer_ptr+2) ==  'G')) &&
6952             ((*(buffer_ptr+3) ==  'e') || (*(buffer_ptr+3) ==  'E')) &&
6953             ((*(buffer_ptr+4) ==  's') || (*(buffer_ptr+4) ==  'S')) &&
6954             ((*(buffer_ptr+5) ==  't') || (*(buffer_ptr+5) ==  'T')) &&
6955             (*(buffer_ptr+6) == ' '))
6956         {
6957 
6958             /* Move the pointer up to the actual authorization string.  */
6959             buffer_ptr =  buffer_ptr + 7;
6960 
6961             /* Set the found flag.  */
6962             found =  NX_TRUE;
6963             break;
6964         }
6965 
6966         /* Move the pointer up to the next character.  */
6967         buffer_ptr++;
6968     }
6969 
6970     /* Determine if the second token was found.  */
6971     if (!found)
6972     {
6973 
6974         /* No, digest is not present.  Return a zero length.  */
6975         return(length);
6976     }
6977 
6978     /* Now remove any extra blanks.  */
6979     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' '))
6980     {
6981 
6982         /* Move the pointer up one character.  */
6983         buffer_ptr++;
6984     }
6985 
6986     /* Start of Internet Explorer bug work-around (Parses nc and cnonce parameters).  */
6987 
6988     /* Save current buffer pointer, so each parameter search always starts from here.  */
6989     saved_buffer_ptr =  buffer_ptr;
6990 
6991     while (((buffer_ptr + 6) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
6992     {
6993 
6994         /* Check for the uri token.  */
6995         if (((*(buffer_ptr) ==  'n') || (*(buffer_ptr) ==  'N')) &&
6996             ((*(buffer_ptr+1) ==  'o') || (*(buffer_ptr+1) ==  'O')) &&
6997             ((*(buffer_ptr+2) ==  'n') || (*(buffer_ptr+2) ==  'N')) &&
6998             ((*(buffer_ptr+3) ==  'c') || (*(buffer_ptr+3) ==  'C')) &&
6999             ((*(buffer_ptr+4) ==  'e') || (*(buffer_ptr+4) ==  'E')) &&
7000             (*(buffer_ptr+5) == '='))
7001         {
7002 
7003             /* Move the pointer up to the actual nonce string.  */
7004             buffer_ptr =  buffer_ptr + 6;
7005             found = NX_TRUE;
7006 
7007             break;
7008         }
7009 
7010         /* Move the pointer up to the next character.  */
7011         buffer_ptr++;
7012     }
7013 
7014     /* Check if nonce is found.  */
7015     if (!found)
7016     {
7017         return(0);
7018     }
7019 
7020     /* Now remove any extra blanks and quotes.  */
7021     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
7022     {
7023 
7024         /* Move the pointer up one character.  */
7025         buffer_ptr++;
7026     }
7027 
7028     /* Now pickup the nonce string.  */
7029     length =  0;
7030     nonce_buffer = (UCHAR *)buffer_ptr;
7031     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13))
7032     {
7033 
7034         /* Determine if the ending quote is present.  */
7035         if (*buffer_ptr == (CHAR) 0x22)
7036         {
7037             break;
7038         }
7039 
7040         /* Increase the length.  */
7041         length++;
7042         buffer_ptr++;
7043     }
7044 
7045     /* Check the nonce size.  */
7046     if (length != NX_WEB_HTTP_SERVER_NONCE_SIZE)
7047     {
7048         return(0);
7049     }
7050 
7051     /* Check if the nonce is valid.  */
7052     for (i = 0; i < NX_WEB_HTTP_SERVER_NONCE_MAX; i++)
7053     {
7054         if ((server_ptr -> nx_web_http_server_nonces[i].nonce_state != NX_WEB_HTTP_SERVER_NONCE_INVALID) &&
7055             (memcmp(server_ptr -> nx_web_http_server_nonces[i].nonce_buffer, nonce_buffer, NX_WEB_HTTP_SERVER_NONCE_SIZE) == 0)) /* Use case of memcmp is verified. */
7056         {
7057             *nonce_ptr = &(server_ptr -> nx_web_http_server_nonces[i]);
7058             break;
7059         }
7060     }
7061 
7062     /* If the nonca is invalid, just return.  */
7063     if (i == NX_WEB_HTTP_SERVER_NONCE_MAX)
7064     {
7065         return(0);
7066     }
7067 
7068     /* Get saved buffer pointer.  */
7069     buffer_ptr =  saved_buffer_ptr;
7070 
7071     /* Now look for the nc in the digest response.  */
7072     while (((buffer_ptr+3) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
7073     {
7074 
7075         /* Check for the nc token.  */
7076         if (((*buffer_ptr ==      'n') || (*buffer_ptr ==      'N')) &&
7077             ((*(buffer_ptr+1) ==  'c') || (*(buffer_ptr+1) ==  'C')) &&
7078             (*(buffer_ptr+2) == '='))
7079         {
7080 
7081             /* Move the pointer up to the actual authorization string.  */
7082             buffer_ptr =  buffer_ptr + 3;
7083 
7084             break;
7085         }
7086 
7087         /* Move the pointer up to the next character.  */
7088         buffer_ptr++;
7089     }
7090 
7091     /* Now remove any extra blanks and quotes (should be no starting quote).  */
7092     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
7093     {
7094 
7095         /* Move the pointer up one character.  */
7096         buffer_ptr++;
7097     }
7098 
7099     /* Now pickup the nc string (should be 8 hex characters; should not be quoted).  */
7100     length =  0;
7101     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13) && (length < NX_WEB_HTTP_MAX_RESOURCE))
7102     {
7103 
7104         /* Determine if the ending quote or comma is present (should be no ending quote).  */
7105         if ((*buffer_ptr == (CHAR) 0x22) || (*buffer_ptr == ','))
7106         {
7107 
7108             break;
7109         }
7110 
7111         /* Copy a character of the authorization string into the destination.  */
7112         nc[length++] =  *buffer_ptr++;
7113     }
7114 
7115     /* Null terminate the NC.  */
7116     nc[length] =  (CHAR) NX_NULL;
7117 
7118 
7119     /* Get saved buffer pointer.  */
7120     buffer_ptr =  saved_buffer_ptr;
7121 
7122     /* Now look for the cnonce in the digest response.  */
7123     while (((buffer_ptr+7) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
7124     {
7125 
7126         /* Check for the uri token.  */
7127         if (((*buffer_ptr ==      'c') || (*buffer_ptr ==      'C')) &&
7128             ((*(buffer_ptr+1) ==  'n') || (*(buffer_ptr+1) ==  'N')) &&
7129             ((*(buffer_ptr+2) ==  'o') || (*(buffer_ptr+2) ==  'O')) &&
7130             ((*(buffer_ptr+3) ==  'n') || (*(buffer_ptr+3) ==  'N')) &&
7131             ((*(buffer_ptr+4) ==  'c') || (*(buffer_ptr+4) ==  'C')) &&
7132             ((*(buffer_ptr+5) ==  'e') || (*(buffer_ptr+5) ==  'E')) &&
7133             (*(buffer_ptr+6) == '='))
7134         {
7135 
7136             /* Move the pointer up to the actual authorization string.  */
7137             buffer_ptr =  buffer_ptr + 7;
7138 
7139             break;
7140         }
7141 
7142         /* Move the pointer up to the next character.  */
7143         buffer_ptr++;
7144     }
7145 
7146     /* Now remove any extra blanks and quotes.  */
7147     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
7148     {
7149 
7150         /* Move the pointer up one character.  */
7151         buffer_ptr++;
7152     }
7153 
7154     /* Now pickup the cnonce string.  */
7155     length =  0;
7156     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13) && (length < NX_WEB_HTTP_MAX_RESOURCE))
7157     {
7158 
7159         /* Determine if the ending quote is present.  */
7160         if (*buffer_ptr == (CHAR) 0x22)
7161         {
7162 
7163             break;
7164         }
7165 
7166         /* Copy a character of the authorization string into the destination.  */
7167         cnonce[length++] =  *buffer_ptr++;
7168     }
7169 
7170     /* Null terminate the CNONCE.  */
7171     cnonce[length] =  (CHAR) NX_NULL;
7172 
7173     /* End of Internet Explorer bug work-around.  */
7174 
7175     /* Get saved buffer pointer.  */
7176     buffer_ptr =  saved_buffer_ptr;
7177 
7178     /* Now look for the uri in the digest response.  */
7179     while (((buffer_ptr+4) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
7180     {
7181 
7182         /* Check for the uri token.  */
7183         if (((*buffer_ptr ==      'u') || (*buffer_ptr ==      'U')) &&
7184             ((*(buffer_ptr+1) ==  'r') || (*(buffer_ptr+1) ==  'R')) &&
7185             ((*(buffer_ptr+2) ==  'i') || (*(buffer_ptr+2) ==  'I')) &&
7186             (*(buffer_ptr+3) == '='))
7187         {
7188 
7189             /* Move the pointer up to the actual authorization string.  */
7190             buffer_ptr =  buffer_ptr + 4;
7191 
7192             break;
7193         }
7194 
7195         /* Move the pointer up to the next character.  */
7196         buffer_ptr++;
7197     }
7198 
7199     /* Now remove any extra blanks and quotes.  */
7200     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
7201     {
7202 
7203         /* Move the pointer up one character.  */
7204         buffer_ptr++;
7205     }
7206 
7207     /* Now pickup the uri string.  */
7208     length =  0;
7209     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0) && (*buffer_ptr != ' ') && (*buffer_ptr != (CHAR) 13) && (length < NX_WEB_HTTP_MAX_RESOURCE))
7210     {
7211 
7212         /* Determine if the ending quote is present.  */
7213         if (*buffer_ptr == (CHAR) 0x22)
7214         {
7215 
7216             break;
7217         }
7218 
7219         /* Copy a character of the authorization string into the destination.  */
7220         uri[length++] =  *buffer_ptr++;
7221     }
7222 
7223     /* Null terminate the URI.  */
7224     uri[length] =  (CHAR) NX_NULL;
7225 
7226     /* Get saved buffer pointer.  */
7227     buffer_ptr =  saved_buffer_ptr;
7228 
7229     /* Now look for the digest response.  */
7230     while (((buffer_ptr+9) < (CHAR *) packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != (CHAR) 0))
7231     {
7232 
7233         /* Check for the uri token.  */
7234         if (((*buffer_ptr ==      'r') || (*buffer_ptr ==      'R')) &&
7235             ((*(buffer_ptr+1) ==  'e') || (*(buffer_ptr+1) ==  'E')) &&
7236             ((*(buffer_ptr+2) ==  's') || (*(buffer_ptr+2) ==  'S')) &&
7237             ((*(buffer_ptr+3) ==  'p') || (*(buffer_ptr+3) ==  'P')) &&
7238             ((*(buffer_ptr+4) ==  'o') || (*(buffer_ptr+4) ==  'O')) &&
7239             ((*(buffer_ptr+5) ==  'n') || (*(buffer_ptr+5) ==  'N')) &&
7240             ((*(buffer_ptr+6) ==  's') || (*(buffer_ptr+6) ==  'S')) &&
7241             ((*(buffer_ptr+7) ==  'e') || (*(buffer_ptr+7) ==  'E')) &&
7242             (*(buffer_ptr+8) == '='))
7243         {
7244 
7245             /* Move the pointer up to the actual authorization string.  */
7246             buffer_ptr =  buffer_ptr + 9;
7247 
7248             break;
7249         }
7250 
7251         /* Move the pointer up to the next character.  */
7252         buffer_ptr++;
7253     }
7254 
7255     /* Now remove any extra blanks and leading quote.  */
7256     while ((buffer_ptr < (CHAR *) packet_ptr -> nx_packet_append_ptr) && ((*buffer_ptr == ' ') || (*buffer_ptr == (CHAR) 0x22)))
7257     {
7258 
7259         /* Move the pointer up one character.  */
7260         buffer_ptr++;
7261     }
7262 
7263     /* Finally, pickup the response.  */
7264     length =  0;
7265     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_WEB_HTTP_MAX_ASCII_MD5))
7266     {
7267 
7268         /* Determine if the ending quote is present.  */
7269         if (*buffer_ptr == (CHAR) 0x22)
7270         {
7271 
7272             break;
7273         }
7274 
7275         /* Copy a character of the response string into the destination.  */
7276         response[length++] =  *buffer_ptr++;
7277     }
7278 
7279     /* Null terminate response.  */
7280     response[length] =  (CHAR) NX_NULL;
7281 
7282     /* Check for an error.  */
7283     if ((length != 32) || (buffer_ptr >= (CHAR *) packet_ptr -> nx_packet_append_ptr) || (*buffer_ptr != (CHAR) 0x22))
7284     {
7285 
7286         /* Error, clear the length and the response string.  */
7287         length =  0;
7288         response[0] =  (CHAR) NX_NULL;
7289     }
7290 
7291     /* Return the length to the caller.  */
7292     return(length);
7293 }
7294 
7295 
7296 /**************************************************************************/
7297 /*                                                                        */
7298 /*  FUNCTION                                               RELEASE        */
7299 /*                                                                        */
7300 /*    _nx_web_http_server_hex_ascii_convert               PORTABLE C      */
7301 /*                                                           6.1          */
7302 /*  AUTHOR                                                                */
7303 /*                                                                        */
7304 /*    Yuxin Zhou, Microsoft Corporation                                   */
7305 /*                                                                        */
7306 /*  DESCRIPTION                                                           */
7307 /*                                                                        */
7308 /*    This function converts hexadecimal characters into an ASCII string. */
7309 /*                                                                        */
7310 /*  INPUT                                                                 */
7311 /*                                                                        */
7312 /*    source                                Source hex string             */
7313 /*    source_length                         Length of source string       */
7314 /*    destination                           Pointer to destination string */
7315 /*                                                                        */
7316 /*  OUTPUT                                                                */
7317 /*                                                                        */
7318 /*    None                                                                */
7319 /*                                                                        */
7320 /*  CALLS                                                                 */
7321 /*                                                                        */
7322 /*    None                                                                */
7323 /*                                                                        */
7324 /*  CALLED BY                                                             */
7325 /*                                                                        */
7326 /*    _nx_web_http_server_digest_response_calculate                       */
7327 /*                                              Digest authentication     */
7328 /*                                                                        */
7329 /*  RELEASE HISTORY                                                       */
7330 /*                                                                        */
7331 /*    DATE              NAME                      DESCRIPTION             */
7332 /*                                                                        */
7333 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7334 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7335 /*                                            resulting in version 6.1    */
7336 /*                                                                        */
7337 /**************************************************************************/
_nx_web_http_server_hex_ascii_convert(CHAR * source,UINT source_length,CHAR * destination)7338 VOID  _nx_web_http_server_hex_ascii_convert(CHAR *source, UINT source_length, CHAR *destination)
7339 {
7340 
7341 UINT    i,j;
7342 CHAR    digit;
7343 
7344 
7345     /* Setup destination index.  */
7346     j =  0;
7347 
7348     /* Loop to process the entire source string.  */
7349     for (i = 0; i < source_length; i++)
7350     {
7351 
7352         /* Pickup the first nibble.  */
7353         digit =  (source[i] >> 4) & 0xF;
7354 
7355         /* Convert to ASCII and store.  */
7356         if (digit <= 9)
7357             destination[j++] =  (CHAR)(digit + '0');
7358         else
7359             destination[j++] =  (CHAR)(digit + 'a' - 10);
7360 
7361         /* Pickup the second nibble.  */
7362         digit =  source[i] & 0xF;
7363 
7364         /* Convert to ASCII and store.  */
7365         if (digit <= 9)
7366             destination[j++] =  (CHAR)(digit + '0');
7367         else
7368             destination[j++] =  (CHAR)(digit + 'a' - 10);
7369     }
7370 
7371     /* Finally, place a NULL in the destination string.  */
7372     destination[j] =  (CHAR) NX_NULL;
7373 }
7374 #endif
7375 
7376 
7377 /**************************************************************************/
7378 /*                                                                        */
7379 /*  FUNCTION                                               RELEASE        */
7380 /*                                                                        */
7381 /*    _nxe_web_http_server_get_entity_header              PORTABLE C      */
7382 /*                                                           6.1          */
7383 /*  AUTHOR                                                                */
7384 /*                                                                        */
7385 /*    Yuxin Zhou, Microsoft Corporation                                   */
7386 /*                                                                        */
7387 /*  DESCRIPTION                                                           */
7388 /*                                                                        */
7389 /*    This function checks error for getting the entity header.           */
7390 /*                                                                        */
7391 /*  INPUT                                                                 */
7392 /*                                                                        */
7393 /*    server_ptr                            Pointer to HTTP server        */
7394 /*    packet_pptr                           Pointer to packet             */
7395 /*    entity_header_buffer                  Buffer to get entity header   */
7396 /*    buffer_size                           Size of buffer                */
7397 /*                                                                        */
7398 /*  OUTPUT                                                                */
7399 /*                                                                        */
7400 /*    status                                Completion status             */
7401 /*                                                                        */
7402 /*  CALLS                                                                 */
7403 /*                                                                        */
7404 /*    _nx_web_http_server_get_entity_header                               */
7405 /*                                                                        */
7406 /*  CALLED BY                                                             */
7407 /*                                                                        */
7408 /*    Application Code                                                    */
7409 /*                                                                        */
7410 /*  RELEASE HISTORY                                                       */
7411 /*                                                                        */
7412 /*    DATE              NAME                      DESCRIPTION             */
7413 /*                                                                        */
7414 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7415 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7416 /*                                            resulting in version 6.1    */
7417 /*                                                                        */
7418 /**************************************************************************/
_nxe_web_http_server_get_entity_header(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,UCHAR * entity_header_buffer,ULONG buffer_size)7419 UINT  _nxe_web_http_server_get_entity_header(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, UCHAR *entity_header_buffer, ULONG buffer_size)
7420 {
7421 
7422 #ifdef  NX_WEB_HTTP_MULTIPART_ENABLE
7423     /* Check for invalid input pointers.  */
7424     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
7425         (packet_pptr == NX_NULL) || (entity_header_buffer == NX_NULL))
7426         return NX_PTR_ERROR;
7427 
7428     /* Check for appropriate caller.  */
7429     NX_THREADS_ONLY_CALLER_CHECKING
7430 
7431     return _nx_web_http_server_get_entity_header(server_ptr, packet_pptr, entity_header_buffer, buffer_size);
7432 #else
7433     NX_PARAMETER_NOT_USED(server_ptr);
7434     NX_PARAMETER_NOT_USED(packet_pptr);
7435     NX_PARAMETER_NOT_USED(entity_header_buffer);
7436     NX_PARAMETER_NOT_USED(buffer_size);
7437 
7438     return NX_WEB_HTTP_ERROR;
7439 #endif /* NX_WEB_HTTP_MULTIPART_ENABLE */
7440 }
7441 
7442 
7443 /**************************************************************************/
7444 /*                                                                        */
7445 /*  FUNCTION                                               RELEASE        */
7446 /*                                                                        */
7447 /*    _nx_web_http_server_get_entity_header               PORTABLE C      */
7448 /*                                                           6.1.11       */
7449 /*  AUTHOR                                                                */
7450 /*                                                                        */
7451 /*    Yuxin Zhou, Microsoft Corporation                                   */
7452 /*                                                                        */
7453 /*  DESCRIPTION                                                           */
7454 /*                                                                        */
7455 /*    This function gets the entity header and skip header.               */
7456 /*                                                                        */
7457 /*  INPUT                                                                 */
7458 /*                                                                        */
7459 /*    server_ptr                            Pointer to HTTP server        */
7460 /*    packet_pptr                           Pointer to packet             */
7461 /*    entity_header_buffer                  Buffer to get entity header   */
7462 /*    buffer_size                           Size of buffer                */
7463 /*                                                                        */
7464 /*  OUTPUT                                                                */
7465 /*                                                                        */
7466 /*    status                                Completion status             */
7467 /*                                                                        */
7468 /*  CALLS                                                                 */
7469 /*                                                                        */
7470 /*    _nx_web_http_server_field_value_get                                 */
7471 /*    _nx_web_http_server_memicmp                                         */
7472 /*    _nx_web_http_server_boundary_find                                   */
7473 /*    nx_packet_release                                                   */
7474 /*    nx_tcp_socket_receive                                               */
7475 /*    _nx_utility_string_length_check                                     */
7476 /*    memmove                                                             */
7477 /*                                                                        */
7478 /*  CALLED BY                                                             */
7479 /*                                                                        */
7480 /*    Application Code                                                    */
7481 /*                                                                        */
7482 /*  RELEASE HISTORY                                                       */
7483 /*                                                                        */
7484 /*    DATE              NAME                      DESCRIPTION             */
7485 /*                                                                        */
7486 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7487 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
7488 /*                                            fixed write underflow,      */
7489 /*                                            resulting in version 6.1    */
7490 /*  04-25-2022     Yuxin Zhou               Modified comment(s), and      */
7491 /*                                            verified memmove use cases, */
7492 /*                                            resulting in version 6.1.11 */
7493 /*                                                                        */
7494 /**************************************************************************/
_nx_web_http_server_get_entity_header(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,UCHAR * entity_header_buffer,ULONG buffer_size)7495 UINT  _nx_web_http_server_get_entity_header(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, UCHAR *entity_header_buffer, ULONG buffer_size)
7496 {
7497 
7498 #ifdef  NX_WEB_HTTP_MULTIPART_ENABLE
7499 NX_WEB_HTTP_SERVER_MULTIPART   *multipart_ptr;
7500 UINT                        status;
7501 UINT                        offset;
7502 NX_PACKET                  *available_packet;
7503 UINT                        crlf_match_count = 0;
7504 UINT                        end_boundary_count = 2;
7505 UINT                        skip_count = 2;
7506 UCHAR                      *ch;
7507 UINT                        index;
7508 
7509     /* Get multipart context. */
7510     multipart_ptr = &server_ptr -> nx_web_http_server_multipart;
7511 
7512     /* Is the multipart context initialized? */
7513     if(multipart_ptr -> nx_web_http_server_multipart_boundary[0] == 0)
7514     {
7515     ULONG   field_length;
7516     UINT    quotation_index;
7517     UINT    i;
7518 
7519         /* No, it is not initialized. */
7520 
7521         /* Get content type. */
7522         status = _nx_web_http_server_field_value_get(*packet_pptr, (UCHAR *)"content-type", 12,
7523                                                  multipart_ptr -> nx_web_http_server_multipart_boundary, NX_WEB_HTTP_MAX_HEADER_FIELD + 1);
7524         if(status)
7525             return status;
7526 
7527         /* Is the content type "multipart"? */
7528         /* Check the length. The length of "multipart/" is 10. */
7529         if (_nx_utility_string_length_check((CHAR *)multipart_ptr -> nx_web_http_server_multipart_boundary, (UINT *)&field_length, NX_WEB_HTTP_MAX_HEADER_FIELD))
7530             return NX_WEB_HTTP_ERROR;
7531         if(field_length < 10)
7532             return NX_WEB_HTTP_NOT_FOUND;
7533 
7534         /* Check the data. */
7535         if(_nx_web_http_server_memicmp(multipart_ptr -> nx_web_http_server_multipart_boundary, 10,
7536                                    (UCHAR *)"multipart/", 10) != NX_SUCCESS)
7537             return NX_WEB_HTTP_NOT_FOUND;
7538 
7539         /* Find the boundary. The length of "boundary=" is 9. */
7540         index = 0;
7541         while((index + 9) < field_length)
7542         {
7543             if(_nx_web_http_server_memicmp(&multipart_ptr -> nx_web_http_server_multipart_boundary[index], 9,
7544                                        (UCHAR *)"boundary=", 9) == NX_SUCCESS)
7545             {
7546 
7547                 break;
7548             }
7549 
7550             /* Move the pointer up to the next character.  */
7551             index++;
7552         }
7553 
7554         /* Move the pointer up to the boundary value. */
7555         index += 9;
7556 
7557         /* Is boundary string found? */
7558         if((field_length - index) <= 1)
7559         {
7560 
7561             /* Boundary not found or no boundary value. */
7562             return NX_WEB_HTTP_NOT_FOUND;
7563         }
7564 
7565         /* Boundary is started with "CRLF--". */
7566         multipart_ptr -> nx_web_http_server_multipart_boundary[0] = 13;
7567         multipart_ptr -> nx_web_http_server_multipart_boundary[1] = 10;
7568         multipart_ptr -> nx_web_http_server_multipart_boundary[2] = '-';
7569         multipart_ptr -> nx_web_http_server_multipart_boundary[3] = '-';
7570 
7571         /* Remove quotation. */
7572         if(multipart_ptr -> nx_web_http_server_multipart_boundary[index] == '"')
7573         {
7574 
7575             /* Find the right quotation. */
7576             index++;
7577             for(quotation_index = field_length; quotation_index > index; quotation_index--)
7578             {
7579                 if(multipart_ptr -> nx_web_http_server_multipart_boundary[quotation_index] == '"')
7580                     break;
7581             }
7582 
7583             /* Is the right quotation found? */
7584             if(quotation_index > index)
7585                 multipart_ptr -> nx_web_http_server_multipart_boundary[quotation_index] = 0;
7586             else
7587             {
7588 
7589                 /* Boundary not valid. */
7590                 return NX_WEB_HTTP_NOT_FOUND;
7591             }
7592 
7593             /* Leave boundary string only. */
7594             memmove(&multipart_ptr -> nx_web_http_server_multipart_boundary[4],
7595                     &multipart_ptr -> nx_web_http_server_multipart_boundary[index],
7596                     quotation_index - index + 1); /* Use case of memmove is verified.  */
7597         }
7598         else
7599         {
7600 
7601             /* Directly copy boundary string to the head field. */
7602             i = 4;
7603             index -= 4;
7604             do
7605             {
7606                 multipart_ptr -> nx_web_http_server_multipart_boundary[i] = multipart_ptr -> nx_web_http_server_multipart_boundary[index + i];
7607                 i++;
7608             }while((multipart_ptr -> nx_web_http_server_multipart_boundary[i - 1] != 0) &&
7609                    (multipart_ptr -> nx_web_http_server_multipart_boundary[i - 1] != ' '));
7610 
7611             /* Set the terminal character. */
7612             multipart_ptr -> nx_web_http_server_multipart_boundary[i - 1] = 0;
7613         }
7614     }
7615 
7616     /* If the received request is chunked.  */
7617     if (server_ptr -> nx_web_http_server_request_chunked)
7618     {
7619 
7620         /* If never processed the chunked packet, need to separate the HTTP header and content.  */
7621         if (!server_ptr -> nx_web_http_server_expect_receive_bytes)
7622         {
7623 
7624             available_packet = *packet_pptr;
7625 
7626             /* Separate the HTTP header and get the first content packet.  */
7627             status = _nx_web_http_server_packet_content_find(server_ptr, &available_packet, NX_NULL);
7628             if (status)
7629             {
7630                 return(status);
7631             }
7632 
7633             /* Append '\r\n' to the start of the packet.  */
7634             available_packet -> nx_packet_prepend_ptr -= 2;
7635             available_packet -> nx_packet_prepend_ptr[0] = 13;
7636             available_packet -> nx_packet_prepend_ptr[1] = 10;
7637 
7638             /* Update packet length.  */
7639             available_packet -> nx_packet_length += 2;
7640 
7641             /* Store the packet. */
7642             nx_packet_release(*packet_pptr);
7643             *packet_pptr = available_packet;
7644             server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_last_packet = available_packet;
7645 
7646             /* Reset the offset. */
7647             multipart_ptr -> nx_web_http_server_multipart_available_offset = 0;
7648         }
7649     }
7650 
7651     /* Find the boundary. */
7652     while(multipart_ptr -> nx_web_http_server_multipart_boundary_find == NX_FALSE)
7653     {
7654         if(_nx_web_http_server_boundary_find(server_ptr, packet_pptr) != NX_SUCCESS)
7655             break;
7656     }
7657 
7658     /* Whether the boundary is found? */
7659     if(multipart_ptr -> nx_web_http_server_multipart_boundary_find == NX_FALSE)
7660         return NX_WEB_HTTP_NOT_FOUND;
7661 
7662     /* Update the packet and offset. */
7663     _nx_web_http_server_boundary_find(server_ptr, packet_pptr);
7664 
7665     /* Get offset of available data in the packet.  */
7666     offset = multipart_ptr -> nx_web_http_server_multipart_available_offset;
7667 
7668     /* Skip data that are not header. */
7669     available_packet = *packet_pptr;
7670 
7671     if(offset >= available_packet -> nx_packet_length)
7672     {
7673 
7674         /* Release the packet that has been processed. */
7675         nx_packet_release(*packet_pptr);
7676 
7677         /* All data has been processed. Get a new packet. */
7678         if(_nx_web_http_server_packet_get(server_ptr, &available_packet) != NX_SUCCESS)
7679         {
7680 
7681             /* Error, return to caller.  */
7682             return(NX_WEB_HTTP_TIMEOUT);
7683         }
7684 
7685         /* Store the packet. */
7686         *packet_pptr = available_packet;
7687         server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_last_packet = available_packet;
7688     }
7689 #ifndef NX_DISABLE_PACKET_CHAIN
7690     else
7691     {
7692         while((UINT)(available_packet -> nx_packet_append_ptr - available_packet -> nx_packet_prepend_ptr) <= offset)
7693         {
7694             offset -= (UINT)(available_packet -> nx_packet_append_ptr - available_packet -> nx_packet_prepend_ptr);
7695 
7696             /* Get next packet. */
7697             available_packet = available_packet -> nx_packet_next;
7698         }
7699     }
7700 #endif /* NX_DISABLE_PACKET_CHAIN */
7701 
7702     /* Get entity header. */
7703     ch = available_packet -> nx_packet_prepend_ptr + offset;
7704     index = 0;
7705     while((entity_header_buffer == NX_NULL) || (index < buffer_size))
7706     {
7707 
7708         /* Calculate valid CRLF. */
7709         if((*ch == 13) && ((crlf_match_count & 1) == 0))
7710             crlf_match_count++;
7711         else if((*ch == 10) && ((crlf_match_count & 1) == 1))
7712             crlf_match_count++;
7713         else if(*ch == '-')
7714         {
7715 
7716             /* Check whether the last boundary is found. */
7717             if(end_boundary_count < 3)
7718                 end_boundary_count--;
7719 
7720             if(end_boundary_count == 0)
7721                 break;
7722         }
7723         else
7724         {
7725             end_boundary_count = 0xFF;
7726             crlf_match_count = 0;
7727         }
7728 
7729         /* Copy data to buffer. */
7730         if(skip_count >0)
7731             skip_count--;
7732         else
7733         {
7734             if(entity_header_buffer)
7735                 entity_header_buffer[index] = *ch;
7736             index++;
7737         }
7738         multipart_ptr -> nx_web_http_server_multipart_available_offset++;
7739 
7740         /* Check whether two CRLFs are found. */
7741         if(crlf_match_count == 4)
7742             break;
7743 
7744         /* Get next character. */
7745         if((ch + 1) >= available_packet -> nx_packet_append_ptr)
7746         {
7747 
7748             /* ch points to the end of this packet. */
7749 #ifndef NX_DISABLE_PACKET_CHAIN
7750             if(available_packet -> nx_packet_next)
7751             {
7752 
7753                 /* Copy data from next packet. */
7754                 available_packet = available_packet -> nx_packet_next;
7755             }
7756             else
7757 #endif /* NX_DISABLE_PACKET_CHAIN */
7758             {
7759 
7760                 /* Release the packet that has been processed. */
7761                 nx_packet_release(*packet_pptr);
7762 
7763                 /* Get a new packet and copy data from it. */
7764                 status = _nx_web_http_server_packet_get(server_ptr, &available_packet);
7765 
7766                 /* Check the return status.  */
7767                 if (status != NX_SUCCESS)
7768                 {
7769 
7770                     /* Error, return to caller.  */
7771                     return(NX_WEB_HTTP_TIMEOUT);
7772                 }
7773 
7774                 /* Store the packet. */
7775                 *packet_pptr = available_packet;
7776                 server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_last_packet = available_packet;
7777 
7778                 /* Reset the offset. */
7779                 multipart_ptr -> nx_web_http_server_multipart_available_offset = 0;
7780             }
7781 
7782             ch = available_packet -> nx_packet_prepend_ptr;
7783         }
7784         else
7785             ch++;
7786 
7787     }
7788 
7789     /* Check whether two CRLFs are found. */
7790     if(crlf_match_count == 4)
7791     {
7792 
7793         /* Set terminal 0. */
7794         if(entity_header_buffer)
7795         {
7796             if (index >= 4)
7797             {
7798                 entity_header_buffer[index - 4] = 0;
7799             }
7800             else
7801             {
7802                 entity_header_buffer[0] = 0;
7803             }
7804         }
7805         return NX_SUCCESS;
7806     }
7807     else
7808         return NX_WEB_HTTP_NOT_FOUND;
7809 #else
7810     NX_PARAMETER_NOT_USED(server_ptr);
7811     NX_PARAMETER_NOT_USED(packet_pptr);
7812     NX_PARAMETER_NOT_USED(entity_header_buffer);
7813     NX_PARAMETER_NOT_USED(buffer_size);
7814 
7815     return NX_WEB_HTTP_ERROR;
7816 #endif /* NX_WEB_HTTP_MULTIPART_ENABLE */
7817 }
7818 
7819 
7820 /**************************************************************************/
7821 /*                                                                        */
7822 /*  FUNCTION                                               RELEASE        */
7823 /*                                                                        */
7824 /*    _nxe_web_http_server_get_entity_content             PORTABLE C      */
7825 /*                                                           6.1          */
7826 /*  AUTHOR                                                                */
7827 /*                                                                        */
7828 /*    Yuxin Zhou, Microsoft Corporation                                   */
7829 /*                                                                        */
7830 /*  DESCRIPTION                                                           */
7831 /*                                                                        */
7832 /*    This function checks error for getting the entity content.          */
7833 /*                                                                        */
7834 /*  INPUT                                                                 */
7835 /*                                                                        */
7836 /*    server_ptr                            Pointer to HTTP server        */
7837 /*    packet_pptr                           Pointer to packet             */
7838 /*    available_offset                      Return the offset             */
7839 /*    available_length                      Return the length             */
7840 /*                                                                        */
7841 /*  OUTPUT                                                                */
7842 /*                                                                        */
7843 /*    status                                Completion status             */
7844 /*                                                                        */
7845 /*  CALLS                                                                 */
7846 /*                                                                        */
7847 /*    _nx_web_http_server_get_entity_content                              */
7848 /*                                                                        */
7849 /*  CALLED BY                                                             */
7850 /*                                                                        */
7851 /*    Application Code                                                    */
7852 /*                                                                        */
7853 /*  RELEASE HISTORY                                                       */
7854 /*                                                                        */
7855 /*    DATE              NAME                      DESCRIPTION             */
7856 /*                                                                        */
7857 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7858 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7859 /*                                            resulting in version 6.1    */
7860 /*                                                                        */
7861 /**************************************************************************/
_nxe_web_http_server_get_entity_content(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,ULONG * available_offset,ULONG * available_length)7862 UINT  _nxe_web_http_server_get_entity_content(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, ULONG *available_offset, ULONG *available_length)
7863 {
7864 
7865 #ifdef  NX_WEB_HTTP_MULTIPART_ENABLE
7866     /* Check for invalid input pointers.  */
7867     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
7868         (packet_pptr == NX_NULL) || (available_offset == NX_NULL) || (available_length == NX_NULL))
7869         return(NX_PTR_ERROR);
7870 
7871     /* Check whether boundary is found. */
7872     if(server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_boundary[0] == 0)
7873         return(NX_WEB_HTTP_ERROR);
7874 
7875     return _nx_web_http_server_get_entity_content(server_ptr, packet_pptr, available_offset, available_length);
7876 #else
7877     NX_PARAMETER_NOT_USED(server_ptr);
7878     NX_PARAMETER_NOT_USED(packet_pptr);
7879     NX_PARAMETER_NOT_USED(available_offset);
7880     NX_PARAMETER_NOT_USED(available_length);
7881 
7882     return NX_WEB_HTTP_ERROR;
7883 #endif /* NX_WEB_HTTP_MULTIPART_ENABLE */
7884 }
7885 
7886 
7887 /**************************************************************************/
7888 /*                                                                        */
7889 /*  FUNCTION                                               RELEASE        */
7890 /*                                                                        */
7891 /*    _nx_web_http_server_get_entity_content              PORTABLE C      */
7892 /*                                                           6.1          */
7893 /*  AUTHOR                                                                */
7894 /*                                                                        */
7895 /*    Yuxin Zhou, Microsoft Corporation                                   */
7896 /*                                                                        */
7897 /*  DESCRIPTION                                                           */
7898 /*                                                                        */
7899 /*    This function gets the entity content.                              */
7900 /*                                                                        */
7901 /*  INPUT                                                                 */
7902 /*                                                                        */
7903 /*    server_ptr                            Pointer to HTTP server        */
7904 /*    packet_pptr                           Pointer to packet             */
7905 /*    available_offset                      Return the offset             */
7906 /*    available_length                      Return the length             */
7907 /*                                                                        */
7908 /*  OUTPUT                                                                */
7909 /*                                                                        */
7910 /*    status                                Completion status             */
7911 /*                                                                        */
7912 /*  CALLS                                                                 */
7913 /*                                                                        */
7914 /*    _nx_web_http_server_boundary_find                                   */
7915 /*                                                                        */
7916 /*  CALLED BY                                                             */
7917 /*                                                                        */
7918 /*    Application Code                                                    */
7919 /*                                                                        */
7920 /*  RELEASE HISTORY                                                       */
7921 /*                                                                        */
7922 /*    DATE              NAME                      DESCRIPTION             */
7923 /*                                                                        */
7924 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7925 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7926 /*                                            resulting in version 6.1    */
7927 /*                                                                        */
7928 /**************************************************************************/
_nx_web_http_server_get_entity_content(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,ULONG * available_offset,ULONG * available_length)7929 UINT  _nx_web_http_server_get_entity_content(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, ULONG *available_offset, ULONG *available_length)
7930 {
7931 
7932 #ifdef  NX_WEB_HTTP_MULTIPART_ENABLE
7933 UINT    status;
7934 
7935     /* Whether the boundary is found? */
7936     if(server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_boundary_find == NX_TRUE)
7937         return NX_WEB_HTTP_BOUNDARY_ALREADY_FOUND;
7938 
7939     status = _nx_web_http_server_boundary_find(server_ptr, packet_pptr);
7940     if(status)
7941         return status;
7942 
7943     /* Set the offset and length. */
7944     *available_offset = server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_available_offset;
7945     *available_length = server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_available_length;
7946 
7947     return NX_SUCCESS;
7948 #else
7949     NX_PARAMETER_NOT_USED(server_ptr);
7950     NX_PARAMETER_NOT_USED(packet_pptr);
7951     NX_PARAMETER_NOT_USED(available_offset);
7952     NX_PARAMETER_NOT_USED(available_length);
7953 
7954     return NX_WEB_HTTP_ERROR;
7955 #endif /* NX_WEB_HTTP_MULTIPART_ENABLE */
7956 }
7957 
7958 
7959 #ifdef  NX_WEB_HTTP_MULTIPART_ENABLE
7960 /**************************************************************************/
7961 /*                                                                        */
7962 /*  FUNCTION                                               RELEASE        */
7963 /*                                                                        */
7964 /*    _nx_web_http_server_boundary_find                   PORTABLE C      */
7965 /*                                                           6.1          */
7966 /*  AUTHOR                                                                */
7967 /*                                                                        */
7968 /*    Yuxin Zhou, Microsoft Corporation                                   */
7969 /*                                                                        */
7970 /*  DESCRIPTION                                                           */
7971 /*                                                                        */
7972 /*    This function finds boundary in packet even if it is chained.       */
7973 /*                                                                        */
7974 /*  INPUT                                                                 */
7975 /*                                                                        */
7976 /*    server_ptr                            Pointer to HTTP server        */
7977 /*    packet_pptr                           Pointer to packet             */
7978 /*                                                                        */
7979 /*  OUTPUT                                                                */
7980 /*                                                                        */
7981 /*    status                                Completion status             */
7982 /*                                                                        */
7983 /*  CALLS                                                                 */
7984 /*                                                                        */
7985 /*    nx_packet_release                                                   */
7986 /*    nx_tcp_socket_receive                                               */
7987 /*    _nx_web_http_server_match_string                                    */
7988 /*    _nx_utility_string_length_check                                     */
7989 /*                                                                        */
7990 /*  CALLED BY                                                             */
7991 /*                                                                        */
7992 /*    _nx_web_http_server_get_entity_header                               */
7993 /*    _nx_web_http_server_get_entity_content                              */
7994 /*                                                                        */
7995 /*  RELEASE HISTORY                                                       */
7996 /*                                                                        */
7997 /*    DATE              NAME                      DESCRIPTION             */
7998 /*                                                                        */
7999 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8000 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8001 /*                                            resulting in version 6.1    */
8002 /*                                                                        */
8003 /**************************************************************************/
_nx_web_http_server_boundary_find(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr)8004 UINT  _nx_web_http_server_boundary_find(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr)
8005 {
8006 
8007 NX_WEB_HTTP_SERVER_MULTIPART   *multipart_ptr;
8008 NX_PACKET                  *available_packet;
8009 UINT                        offset;
8010 ULONG                       match_count = 0;
8011 UCHAR                      *match_end_ptr;
8012 UINT                        boundary_length;
8013 
8014     /* Get multipart context. */
8015     multipart_ptr = &server_ptr -> nx_web_http_server_multipart;
8016 
8017     /* Is boundary already found? */
8018     if(multipart_ptr -> nx_web_http_server_multipart_boundary_find == NX_TRUE)
8019     {
8020 
8021         /* Yes. Update the packet and offset. */
8022         if(multipart_ptr -> nx_web_http_server_multipart_next_packet != NX_NULL)
8023         {
8024             nx_packet_release(*packet_pptr);
8025             *packet_pptr = multipart_ptr -> nx_web_http_server_multipart_next_packet;
8026             server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_last_packet = multipart_ptr -> nx_web_http_server_multipart_next_packet;
8027         }
8028 
8029         multipart_ptr -> nx_web_http_server_multipart_available_offset = multipart_ptr -> nx_web_http_server_multipart_next_available_offset;
8030 
8031         /* Reset next packet and available offset. */
8032         multipart_ptr -> nx_web_http_server_multipart_next_packet = NX_NULL;
8033         multipart_ptr -> nx_web_http_server_multipart_next_available_offset = 0;
8034 
8035         /* Reset boundary find. */
8036         multipart_ptr -> nx_web_http_server_multipart_boundary_find = NX_FALSE;
8037 
8038         return NX_SUCCESS;
8039     }
8040 
8041     /* Is the boundary in the next packet? */
8042     if(multipart_ptr -> nx_web_http_server_multipart_next_packet)
8043     {
8044 
8045         /* Yes, we're done with this packet. */
8046         nx_packet_release(*packet_pptr);
8047 
8048         /* Update the packet and multipart offset. */
8049         *packet_pptr = multipart_ptr -> nx_web_http_server_multipart_next_packet;
8050         server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_last_packet = multipart_ptr -> nx_web_http_server_multipart_next_packet;
8051         multipart_ptr -> nx_web_http_server_multipart_available_offset = 0;
8052     }
8053     else if(multipart_ptr -> nx_web_http_server_multipart_next_available_offset)
8054     {
8055 
8056         /* Find boundary in this packet. */
8057         /* Update the offset. */
8058         multipart_ptr -> nx_web_http_server_multipart_available_offset = multipart_ptr -> nx_web_http_server_multipart_next_available_offset;
8059     }
8060     else
8061     {
8062 
8063         /* Find boundary from this packet. */
8064         /* Initialize the offset. */
8065         multipart_ptr -> nx_web_http_server_multipart_next_available_offset = multipart_ptr -> nx_web_http_server_multipart_available_offset;
8066     }
8067 
8068     /* Reset next packet. */
8069     multipart_ptr -> nx_web_http_server_multipart_next_packet = NX_NULL;
8070 
8071     /* Reset boundary find. */
8072     multipart_ptr -> nx_web_http_server_multipart_boundary_find = NX_FALSE;
8073 
8074 
8075     /* Get offset of available data in the packet.  */
8076     offset = multipart_ptr -> nx_web_http_server_multipart_available_offset;
8077 
8078     /* Skip data that are not header. */
8079     available_packet = *packet_pptr;
8080 
8081     if(offset >= available_packet -> nx_packet_length)
8082     {
8083 
8084         /* Release the packet that has been processed. */
8085         nx_packet_release(*packet_pptr);
8086 
8087         /* All data has been processed. Get a new packet. */
8088         if(_nx_web_http_server_packet_get(server_ptr, &available_packet) != NX_SUCCESS)
8089         {
8090 
8091             /* Error, return to caller.  */
8092             return(NX_WEB_HTTP_TIMEOUT);
8093         }
8094 
8095         /* Store the packet. */
8096         *packet_pptr = available_packet;
8097         server_ptr -> nx_web_http_server_multipart.nx_web_http_server_multipart_last_packet = available_packet;
8098 
8099         /* Reset the offset. */
8100         multipart_ptr -> nx_web_http_server_multipart_available_offset = 0;
8101         multipart_ptr -> nx_web_http_server_multipart_next_available_offset = 0;
8102         offset = 0;
8103     }
8104     else
8105     {
8106 #ifndef NX_DISABLE_PACKET_CHAIN
8107         while((UINT)(available_packet -> nx_packet_append_ptr - available_packet -> nx_packet_prepend_ptr) <= offset)
8108         {
8109             offset -= (UINT)(available_packet -> nx_packet_append_ptr - available_packet -> nx_packet_prepend_ptr);
8110 
8111             /* Get next packet. */
8112             available_packet = available_packet -> nx_packet_next;
8113         }
8114 #endif /* NX_DISABLE_PACKET_CHAIN */
8115     }
8116 
8117     /* Check boundary length.  */
8118     if (_nx_utility_string_length_check((CHAR *)multipart_ptr -> nx_web_http_server_multipart_boundary, &boundary_length, NX_WEB_HTTP_MAX_HEADER_FIELD))
8119     {
8120         return(NX_WEB_HTTP_ERROR);
8121     }
8122 
8123     /* Look for the boundary string in the (next) packet. */
8124     while(_nx_web_http_server_match_string(available_packet -> nx_packet_prepend_ptr + offset,
8125                                        available_packet -> nx_packet_append_ptr,
8126                                        multipart_ptr -> nx_web_http_server_multipart_boundary,
8127                                        boundary_length,
8128                                        &match_count, &match_end_ptr) != NX_SUCCESS)
8129     {
8130 
8131         /* Match string in the next packet. */
8132 #ifndef NX_DISABLE_PACKET_CHAIN
8133         if(available_packet -> nx_packet_next)
8134         {
8135             multipart_ptr -> nx_web_http_server_multipart_next_available_offset += (UINT)((UINT)(available_packet -> nx_packet_append_ptr - available_packet -> nx_packet_prepend_ptr) - offset);
8136             available_packet = available_packet -> nx_packet_next;
8137             offset = 0;
8138         }
8139         else
8140 #endif /* NX_DISABLE_PACKET_CHAIN */
8141             break;
8142     }
8143 
8144     /* Is boundary matched? */
8145     if(match_end_ptr)
8146     {
8147 
8148         /* Yes. Found a match. */
8149         multipart_ptr -> nx_web_http_server_multipart_next_available_offset += (UINT)((UINT)(match_end_ptr - available_packet -> nx_packet_prepend_ptr) - offset);
8150         multipart_ptr -> nx_web_http_server_multipart_available_length = multipart_ptr -> nx_web_http_server_multipart_next_available_offset - multipart_ptr -> nx_web_http_server_multipart_available_offset - match_count;
8151         multipart_ptr -> nx_web_http_server_multipart_boundary_find = NX_TRUE;
8152 
8153     }
8154     else if(match_count)
8155     {
8156 
8157         /* Set the available length to all remaining data. */
8158         multipart_ptr -> nx_web_http_server_multipart_available_length = (*packet_pptr) -> nx_packet_length - multipart_ptr -> nx_web_http_server_multipart_available_offset;
8159 
8160         /* Partial match. Get another packet. */
8161         if(_nx_web_http_server_packet_get(server_ptr, &available_packet) != NX_SUCCESS)
8162         {
8163 
8164             /* Error, return to caller.  */
8165             return(NX_WEB_HTTP_TIMEOUT);
8166         }
8167 
8168         /* Match the boundary again. */
8169         if(_nx_web_http_server_match_string(available_packet -> nx_packet_prepend_ptr,
8170                                         available_packet -> nx_packet_append_ptr,
8171                                         multipart_ptr -> nx_web_http_server_multipart_boundary,
8172                                         boundary_length,
8173                                         &match_count, &match_end_ptr) == NX_SUCCESS)
8174         {
8175 
8176             /* Yes. Find a match. */
8177             if((ULONG)(match_end_ptr - available_packet -> nx_packet_prepend_ptr) < match_count)
8178             {
8179 
8180                 /* The boundary is between two packets. */
8181                 multipart_ptr -> nx_web_http_server_multipart_next_available_offset = (UINT)(match_end_ptr - available_packet -> nx_packet_prepend_ptr);
8182                 multipart_ptr -> nx_web_http_server_multipart_available_length -= boundary_length - multipart_ptr -> nx_web_http_server_multipart_next_available_offset;
8183                 multipart_ptr -> nx_web_http_server_multipart_boundary_find = NX_TRUE;
8184             }
8185             else
8186             {
8187 
8188                 /* The boundary is in the next packet. */
8189                 multipart_ptr -> nx_web_http_server_multipart_next_available_offset = 0;
8190             }
8191         }
8192         else
8193         {
8194 
8195             /* The boundary is not found. */
8196             multipart_ptr -> nx_web_http_server_multipart_next_available_offset = 0;
8197         }
8198 
8199         /* Store the packet. */
8200         multipart_ptr -> nx_web_http_server_multipart_next_packet = available_packet;
8201 
8202     }
8203     else
8204     {
8205 
8206         /* Set the available length to all remaining data. */
8207         multipart_ptr -> nx_web_http_server_multipart_available_length = (*packet_pptr) -> nx_packet_length - multipart_ptr -> nx_web_http_server_multipart_available_offset;
8208         multipart_ptr -> nx_web_http_server_multipart_next_available_offset = (*packet_pptr) -> nx_packet_length;
8209     }
8210 
8211     return NX_SUCCESS;
8212 }
8213 #endif /* NX_WEB_HTTP_MULTIPART_ENABLE */
8214 
8215 
8216 /**************************************************************************/
8217 /*                                                                        */
8218 /*  FUNCTION                                               RELEASE        */
8219 /*                                                                        */
8220 /*    _nx_web_http_server_match_string                    PORTABLE C      */
8221 /*                                                           6.1          */
8222 /*  AUTHOR                                                                */
8223 /*                                                                        */
8224 /*    Yuxin Zhou, Microsoft Corporation                                   */
8225 /*                                                                        */
8226 /*  DESCRIPTION                                                           */
8227 /*                                                                        */
8228 /*    This function compares a target string in specified memory area.    */
8229 /*                                                                        */
8230 /*  INPUT                                                                 */
8231 /*                                                                        */
8232 /*    src_start                             Pointer to start of source    */
8233 /*    src_end                               Pointer to end of source      */
8234 /*    target                                Pointer to target             */
8235 /*    target_length                         Length to target              */
8236 /*    match_count                           Return the match count        */
8237 /*    match_end_ptr                         Return the end match position */
8238 /*                                                                        */
8239 /*  OUTPUT                                                                */
8240 /*                                                                        */
8241 /*    status                                Completion status             */
8242 /*                                                                        */
8243 /*  CALLS                                                                 */
8244 /*                                                                        */
8245 /*    memcmp                                Compare memory data           */
8246 /*                                                                        */
8247 /*  CALLED BY                                                             */
8248 /*                                                                        */
8249 /*    _nx_web_http_server_boundary_find                                   */
8250 /*                                                                        */
8251 /*  RELEASE HISTORY                                                       */
8252 /*                                                                        */
8253 /*    DATE              NAME                      DESCRIPTION             */
8254 /*                                                                        */
8255 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8256 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8257 /*                                            resulting in version 6.1    */
8258 /*                                                                        */
8259 /**************************************************************************/
_nx_web_http_server_match_string(UCHAR * src_start,UCHAR * src_end,UCHAR * target,ULONG target_length,ULONG * match_count,UCHAR ** match_end_ptr)8260 UINT  _nx_web_http_server_match_string(UCHAR *src_start, UCHAR *src_end, UCHAR *target, ULONG target_length, ULONG *match_count, UCHAR **match_end_ptr)
8261 {
8262 
8263 UCHAR  *ch;
8264 ULONG   pre_match = *match_count;
8265 ULONG   remain_match;
8266 
8267     /* Initialize. */
8268     *match_end_ptr = NX_NULL;
8269 
8270     /* Process part match. */
8271     while(pre_match)
8272     {
8273 
8274         /* Compare pre-match. */
8275         if(memcmp(target, target + (*match_count - pre_match), pre_match) == 0)
8276         {
8277 
8278             /* Calculate the remain match. */
8279             remain_match = target_length - pre_match;
8280 
8281             /* The pre-match is the same. */
8282             if((ULONG)(src_end - src_start) < remain_match)
8283                 remain_match = (ULONG)(src_end - src_start);
8284 
8285             if(memcmp(target + pre_match, src_start, remain_match) == 0)
8286             {
8287 
8288                 /* Remain part matches. */
8289                 *match_count = pre_match + remain_match;
8290 
8291                 if(*match_count < target_length)
8292                 {
8293 
8294                     /* Part match. */
8295                     return NX_WEB_HTTP_NOT_FOUND;
8296                 }
8297 
8298                 /* Full match. */
8299                 *match_end_ptr = src_start + remain_match;
8300                 return NX_SUCCESS;
8301             }
8302         }
8303 
8304         pre_match--;
8305     }
8306 
8307     ch = src_start;
8308 
8309     /* Perform full match. */
8310     *match_count = target_length;
8311     while(ch + *match_count <= src_end)
8312     {
8313         if(memcmp(ch, target, *match_count) == 0)
8314         {
8315 
8316             /* Find a match. */
8317             *match_end_ptr = ch + *match_count;
8318             return NX_SUCCESS;
8319         }
8320 
8321         ch++;
8322     }
8323 
8324     /* Perform part match. */
8325     for(*match_count = target_length - 1; *match_count > 0; *match_count = *match_count - 1)
8326     {
8327         if(ch + *match_count <= src_end)
8328         {
8329             if(memcmp(ch, target, *match_count) == 0)
8330             {
8331 
8332                 /* Find a match. */
8333                 return NX_WEB_HTTP_NOT_FOUND;
8334             }
8335 
8336             ch++;
8337         }
8338     }
8339 
8340     return NX_WEB_HTTP_NOT_FOUND;
8341 }
8342 
8343 
8344 /**************************************************************************/
8345 /*                                                                        */
8346 /*  FUNCTION                                               RELEASE        */
8347 /*                                                                        */
8348 /*    _nx_web_http_server_field_value_get                 PORTABLE C      */
8349 /*                                                           6.1          */
8350 /*  AUTHOR                                                                */
8351 /*                                                                        */
8352 /*    Yuxin Zhou, Microsoft Corporation                                   */
8353 /*                                                                        */
8354 /*  DESCRIPTION                                                           */
8355 /*                                                                        */
8356 /*    This function gets field value by field name from HTTP header.      */
8357 /*                                                                        */
8358 /*  INPUT                                                                 */
8359 /*                                                                        */
8360 /*    packet_ptr                            Pointer to packet             */
8361 /*    field_name                            Name of field in header       */
8362 /*    name_length                           Length of name field          */
8363 /*    field_value                           Return of field value         */
8364 /*    field_value_size                      Size of field value           */
8365 /*                                                                        */
8366 /*  OUTPUT                                                                */
8367 /*                                                                        */
8368 /*    status                                Completion status             */
8369 /*                                                                        */
8370 /*  CALLS                                                                 */
8371 /*                                                                        */
8372 /*    _nx_web_http_server_memicmp           Compare ignore case           */
8373 /*                                                                        */
8374 /*  CALLED BY                                                             */
8375 /*                                                                        */
8376 /*    _nx_web_http_server_get_process                                     */
8377 /*    _nx_web_http_server_get_entity_header                               */
8378 /*                                                                        */
8379 /*  RELEASE HISTORY                                                       */
8380 /*                                                                        */
8381 /*    DATE              NAME                      DESCRIPTION             */
8382 /*                                                                        */
8383 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8384 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8385 /*                                            resulting in version 6.1    */
8386 /*                                                                        */
8387 /**************************************************************************/
_nx_web_http_server_field_value_get(NX_PACKET * packet_ptr,UCHAR * field_name,ULONG name_length,UCHAR * field_value,ULONG field_value_size)8388 UINT  _nx_web_http_server_field_value_get(NX_PACKET *packet_ptr, UCHAR *field_name, ULONG name_length, UCHAR *field_value, ULONG field_value_size)
8389 {
8390 
8391 UCHAR  *ch;
8392 UINT    index;
8393 
8394 
8395     /* Initialize. */
8396     ch = packet_ptr -> nx_packet_prepend_ptr;
8397 
8398     /* Loop to find field name. */
8399     while(ch + name_length < packet_ptr -> nx_packet_append_ptr)
8400     {
8401         if(_nx_web_http_server_memicmp(ch, name_length, field_name, name_length) == NX_SUCCESS)
8402         {
8403 
8404             /* Field name found. */
8405             break;
8406         }
8407 
8408         /* Move the pointer up to the next character.  */
8409         ch++;
8410     }
8411 
8412     /* Skip field name and ':'. */
8413     ch += name_length + 1;
8414 
8415     /* Is field name found? */
8416     if(ch >= packet_ptr -> nx_packet_append_ptr)
8417         return NX_WEB_HTTP_NOT_FOUND;
8418 
8419     /* Skip white spaces. */
8420     while(*ch == ' ')
8421     {
8422         if(ch >= packet_ptr -> nx_packet_append_ptr)
8423             return NX_WEB_HTTP_NOT_FOUND;
8424 
8425         /* Get next character. */
8426         ch++;
8427     }
8428 
8429     /* Copy field value. */
8430     index = 0;
8431     while(index < field_value_size)
8432     {
8433 
8434         /* Whether the end of line CRLF is not found? */
8435         if(ch + 2 > packet_ptr -> nx_packet_append_ptr)
8436             return NX_WEB_HTTP_NOT_FOUND;
8437 
8438         /* Compare CRLF. */
8439         if((*ch == 13) && (*(ch + 1) == 10))
8440             break;
8441 
8442         /* Copy data. */
8443         field_value[index++] = *ch++;
8444     }
8445 
8446     /* Buffer overflow? */
8447     if(index == field_value_size)
8448         return NX_WEB_HTTP_NOT_FOUND;
8449 
8450     /* Trim white spaces. */
8451     while((index > 0) && (field_value[index - 1] == ' '))
8452         index--;
8453 
8454     /* Append terminal 0. */
8455     field_value[index] = 0;
8456 
8457 
8458     return NX_SUCCESS;
8459 }
8460 
8461 
8462 /**************************************************************************/
8463 /*                                                                        */
8464 /*  FUNCTION                                               RELEASE        */
8465 /*                                                                        */
8466 /*    _nx_web_http_server_memicmp                         PORTABLE C      */
8467 /*                                                           6.1          */
8468 /*  AUTHOR                                                                */
8469 /*                                                                        */
8470 /*    Yuxin Zhou, Microsoft Corporation                                   */
8471 /*                                                                        */
8472 /*  DESCRIPTION                                                           */
8473 /*                                                                        */
8474 /*    This function compares two pieces of memory case insensitive.       */
8475 /*                                                                        */
8476 /*  INPUT                                                                 */
8477 /*                                                                        */
8478 /*    src                                   Pointer to source             */
8479 /*    src_length                            Length of source              */
8480 /*    dest                                  Pointer to destination        */
8481 /*    dest_length                           Length of destination         */
8482 /*                                                                        */
8483 /*  OUTPUT                                                                */
8484 /*                                                                        */
8485 /*    status                                Completion status             */
8486 /*                                                                        */
8487 /*  CALLS                                                                 */
8488 /*                                                                        */
8489 /*                                                                        */
8490 /*  CALLED BY                                                             */
8491 /*                                                                        */
8492 /*    _nx_web_http_server_get_entity_header                               */
8493 /*    _nx_web_http_server_field_value_get                                 */
8494 /*                                                                        */
8495 /*  RELEASE HISTORY                                                       */
8496 /*                                                                        */
8497 /*    DATE              NAME                      DESCRIPTION             */
8498 /*                                                                        */
8499 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8500 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8501 /*                                            resulting in version 6.1    */
8502 /*                                                                        */
8503 /**************************************************************************/
_nx_web_http_server_memicmp(UCHAR * src,ULONG src_length,UCHAR * dest,ULONG dest_length)8504 UINT  _nx_web_http_server_memicmp(UCHAR *src, ULONG src_length, UCHAR *dest, ULONG dest_length)
8505 {
8506 UCHAR   ch;
8507 
8508     /* Compare the length. */
8509     if(src_length != dest_length)
8510         return NX_WEB_HTTP_FAILED;
8511 
8512     while(src_length)
8513     {
8514 
8515         /* Is src lowercase? */
8516         if((*src >= 'a') && (*src <= 'z'))
8517             ch = (UCHAR)(*src - 'a' + 'A');
8518 
8519         /* Is src uppercase? */
8520         else if((*src >= 'A') && (*src <= 'Z'))
8521             ch = (UCHAR)(*src - 'A' + 'a');
8522         else
8523             ch = *src;
8524 
8525         /* Compare case insensitive. */
8526         if((*src != *dest) && (ch != *dest))
8527             return NX_WEB_HTTP_FAILED;
8528 
8529         /* Pickup next character. */
8530         src_length--;
8531         src++;
8532         dest++;
8533     }
8534 
8535     return NX_SUCCESS;
8536 }
8537 
8538 
8539 /**************************************************************************/
8540 /*                                                                        */
8541 /*  FUNCTION                                               RELEASE        */
8542 /*                                                                        */
8543 /*    _nx_web_http_server_generate_response_header        PORTABLE C      */
8544 /*                                                           6.1.8        */
8545 /*  AUTHOR                                                                */
8546 /*                                                                        */
8547 /*    Yuxin Zhou, Microsoft Corporation                                   */
8548 /*                                                                        */
8549 /*  DESCRIPTION                                                           */
8550 /*                                                                        */
8551 /*    This function generates HTTP response header.                       */
8552 /*                                                                        */
8553 /*  INPUT                                                                 */
8554 /*                                                                        */
8555 /*    server_ptr                            Pointer to HTTP server        */
8556 /*    packet_pptr                           Pointer to packet             */
8557 /*    status_code                           Status-code and reason-phrase */
8558 /*    status_code_length                    Length of status-code         */
8559 /*    content_length                        Length of content             */
8560 /*    content_type                          Type of content               */
8561 /*    content_type_length                   Length of content type        */
8562 /*    additional_header                     Other HTTP headers            */
8563 /*    additional_header_length              Length of other HTTP headers  */
8564 /*                                                                        */
8565 /*  OUTPUT                                                                */
8566 /*                                                                        */
8567 /*    status                                Completion status             */
8568 /*                                                                        */
8569 /*  CALLS                                                                 */
8570 /*                                                                        */
8571 /*    _nx_web_http_server_response_packet_allocate                        */
8572 /*                                          Allocate response packet      */
8573 /*    nx_packet_data_append                 Append packet data            */
8574 /*    memcmp                                Compare string                */
8575 /*    _nx_utility_uint_to_string            Convert number to ASCII       */
8576 /*    _nx_web_http_server_date_to_string    Convert data to string        */
8577 /*    nx_packet_release                     Release packet                */
8578 /*                                                                        */
8579 /*  CALLED BY                                                             */
8580 /*                                                                        */
8581 /*    _nx_web_http_server_get_process                                     */
8582 /*    _nx_web_http_server_put_process                                     */
8583 /*    _nx_web_http_server_delete_process                                  */
8584 /*    _nx_web_http_server_response_send                                   */
8585 /*    _nx_web_http_server_callback_generate_response_header               */
8586 /*                                                                        */
8587 /*  RELEASE HISTORY                                                       */
8588 /*                                                                        */
8589 /*    DATE              NAME                      DESCRIPTION             */
8590 /*                                                                        */
8591 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8592 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8593 /*                                            resulting in version 6.1    */
8594 /*  08-02-2021     Yuxin Zhou               Modified comment(s),          */
8595 /*                                            improved the logic of       */
8596 /*                                            converting number to string,*/
8597 /*                                            resulting in version 6.1.8  */
8598 /*                                                                        */
8599 /**************************************************************************/
_nx_web_http_server_generate_response_header(NX_WEB_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)8600 UINT  _nx_web_http_server_generate_response_header(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr,
8601                                                    CHAR *status_code, UINT status_code_length,
8602                                                    UINT content_length, CHAR *content_type,
8603                                                    UINT content_type_length, CHAR* additional_header,
8604                                                    UINT additional_header_length)
8605 {
8606 
8607 UINT        status;
8608 UINT        temp;
8609 CHAR        temp_string[30];
8610 CHAR        crlf[2] = {13,10};
8611 NX_PACKET  *packet_ptr;
8612 CHAR        status_code_ok;
8613 CHAR        status_code_not_modified;
8614 
8615 
8616     /* Allocate a packet for sending the response back.  */
8617     status = _nx_web_http_server_response_packet_allocate(server_ptr, packet_pptr, NX_WAIT_FOREVER);
8618 
8619     /* Determine if an error occurred in the packet allocation.  */
8620     if(status != NX_SUCCESS)
8621     {
8622 
8623         /* Indicate an allocation error occurred.  */
8624         server_ptr -> nx_web_http_server_allocation_errors++;
8625 
8626         /* Just return.  */
8627         return status;
8628     }
8629     else
8630         packet_ptr = *packet_pptr;
8631 
8632     /* Check status code. */
8633     if(memcmp(status_code, NX_WEB_HTTP_STATUS_OK, sizeof(NX_WEB_HTTP_STATUS_OK)) == 0)
8634         status_code_ok = NX_TRUE;
8635     else
8636         status_code_ok = NX_FALSE;
8637 
8638     if(memcmp(status_code, NX_WEB_HTTP_STATUS_NOT_MODIFIED, sizeof(NX_WEB_HTTP_STATUS_NOT_MODIFIED)) == 0)
8639         status_code_not_modified = NX_TRUE;
8640     else
8641         status_code_not_modified = NX_FALSE;
8642 
8643     /* Insert the status line.  */
8644     /* Place HTTP-Version. */
8645     status = nx_packet_data_append(packet_ptr, NX_WEB_HTTP_VERSION, sizeof(NX_WEB_HTTP_VERSION) - 1,  server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8646 
8647     /* Insert space. */
8648     status += nx_packet_data_append(packet_ptr, " ", 1,  server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8649 
8650     status += nx_packet_data_append(packet_ptr, status_code, status_code_length,  server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8651 
8652     /* Place the <cr,lf> into the buffer.  */
8653     status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8654 
8655     /* Determine if there is content_type.  */
8656     if(content_type)
8657     {
8658 
8659         /* Insert the content type.  */
8660         status += nx_packet_data_append(packet_ptr, "Content-Type: ", 14,  server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8661         status += nx_packet_data_append(packet_ptr, content_type, content_type_length,  server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8662 
8663         /* Place the <cr,lf> into the buffer.  */
8664         status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8665     }
8666 
8667 #ifndef NX_WEB_HTTP_SERVER_OMIT_CONTENT_LENGTH
8668     /* Determine if there is content_length.  */
8669     if(content_length || (status_code_not_modified == NX_TRUE))
8670     {
8671 #ifndef NX_WEB_HTTP_KEEPALIVE_DISABLE
8672 
8673         /* Place the "Connection" field in the header.  */
8674         if(server_ptr -> nx_web_http_server_keepalive == NX_TRUE)
8675         {
8676 
8677             /* Keepalive. */
8678             status += nx_packet_data_append(packet_ptr, "Connection: keep-alive", 22,
8679                     server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8680         }
8681         else
8682 #endif /* NX_WEB_HTTP_KEEPALIVE_DISABLE */
8683         {
8684 
8685         /* Close. */
8686         status += nx_packet_data_append(packet_ptr, "Connection: Close", 17,
8687                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8688         }
8689 
8690         /* Place the <cr,lf> into the buffer.  */
8691         status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8692 
8693         if(content_length)
8694         {
8695 
8696             /* Convert the content_length to ASCII representation.  */
8697             temp = _nx_utility_uint_to_string(content_length, 10, temp_string, sizeof(temp_string));
8698 
8699             /* Place the "Content-Length" field in the header.  */
8700             status += nx_packet_data_append(packet_ptr, "Content-Length: ", 16,
8701                     server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8702             status += nx_packet_data_append(packet_ptr, temp_string, temp,
8703                     server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8704 
8705             /* Place the <cr,lf> into the buffer.  */
8706             status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8707         }
8708 
8709     }
8710     else
8711 #endif /* NX_WEB_HTTP_SERVER_OMIT_CONTENT_LENGTH */
8712     {
8713 
8714         /* Place the "Connection" field in the header.  */
8715 
8716         /* Force close the connection since there's no content-length. */
8717         status += nx_packet_data_append(packet_ptr, "Connection: Close", 17,
8718                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8719 
8720 #ifndef NX_WEB_HTTP_KEEPALIVE_DISABLE
8721         server_ptr -> nx_web_http_server_keepalive = NX_FALSE;
8722 #endif /* NX_WEB_HTTP_KEEPALIVE_DISABLE */
8723 
8724         /* Place the <cr,lf> into the buffer.  */
8725         status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8726     }
8727 
8728     /* Insert Date header if callback function is set. */
8729     if(server_ptr -> nx_web_http_server_gmt_get)
8730     {
8731     NX_WEB_HTTP_SERVER_DATE date;
8732 
8733         /* Get current date. */
8734         server_ptr -> nx_web_http_server_gmt_get(&date);
8735 
8736         /* Convert date to string. */
8737         temp = _nx_web_http_server_date_to_string(&date, temp_string);
8738 
8739         /* Place the "Date" field in the header.  */
8740         status += nx_packet_data_append(packet_ptr, "Date: ", 6,
8741                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8742 
8743         /* Insert date. */
8744         status += nx_packet_data_append(packet_ptr, temp_string, temp, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8745 
8746         /* Place the <cr,lf> into the buffer.  */
8747         status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8748 
8749         /* Set Cache Control if callback function is set. */
8750         if((server_ptr -> nx_web_http_server_cache_info_get) &&
8751            ((status_code_ok == NX_TRUE) || (status_code_not_modified == NX_TRUE)) &&
8752            (server_ptr -> nx_web_http_server_request_type == NX_WEB_HTTP_SERVER_GET_REQUEST))
8753         {
8754         UINT max_age;
8755 
8756             /* Get cache infomation. */
8757             if(server_ptr -> nx_web_http_server_cache_info_get(server_ptr -> nx_web_http_server_request_resource, &max_age, &date) == NX_TRUE)
8758             {
8759 
8760                 /* Place "Cache-control" header. */
8761                 status += nx_packet_data_append(packet_ptr, "Cache-Control: max-age=", 23,
8762                                                 server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8763 
8764                 /* Convert the max-age to ASCII representation.  */
8765                 temp = _nx_utility_uint_to_string(max_age, 10, temp_string, sizeof(temp_string));
8766                 status += nx_packet_data_append(packet_ptr, temp_string, temp,
8767                                                 server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8768 
8769                 /* Place the <cr,lf> into the buffer.  */
8770                 status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8771 
8772                 if(status_code_ok == NX_TRUE)
8773                 {
8774 
8775                     /* Convert date to string. */
8776                     temp = _nx_web_http_server_date_to_string(&date, temp_string);
8777 
8778                     /* Place the "Last-Modified" field in the header.  */
8779                     status += nx_packet_data_append(packet_ptr, "Last-Modified: ", 15,
8780                                                     server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8781 
8782                     /* Insert date. */
8783                     status += nx_packet_data_append(packet_ptr, temp_string, temp, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8784 
8785                     /* Place the <cr,lf> into the buffer.  */
8786                     status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8787                 }
8788             }
8789         }
8790     }
8791 
8792     /* Insert additional header. */
8793     if(additional_header)
8794     {
8795         status += nx_packet_data_append(packet_ptr, additional_header, additional_header_length,
8796                                         server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8797     }
8798 
8799     /* Place the <cr,lf> into the buffer.  */
8800     status += nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
8801 
8802     if (status != NX_SUCCESS)
8803     {
8804 
8805         /* Just release the packet.  */
8806         nx_packet_release(packet_ptr);
8807     }
8808 
8809     return status;
8810 }
8811 
8812 /**************************************************************************/
8813 /*                                                                        */
8814 /*  FUNCTION                                               RELEASE        */
8815 /*                                                                        */
8816 /*    _nx_web_http_server_request_read                    PORTABLE C      */
8817 /*                                                           6.1          */
8818 /*  AUTHOR                                                                */
8819 /*                                                                        */
8820 /*    Yuxin Zhou, Microsoft Corporation                                   */
8821 /*                                                                        */
8822 /*  DESCRIPTION                                                           */
8823 /*                                                                        */
8824 /*    This function gets the next data in byte.                           */
8825 /*                                                                        */
8826 /*  INPUT                                                                 */
8827 /*                                                                        */
8828 /*    Server_ptr                            Pointer to HTTP server        */
8829 /*    data                                  Returned data                 */
8830 /*    wait_option                           Suspension option             */
8831 /*    current_packet_pptr                   Pointer to the packet being   */
8832 /*                                            processed                   */
8833 /*    current_data_ptr                      Pointer to the data will be   */
8834 /*                                            processed                   */
8835 /*                                                                        */
8836 /*  OUTPUT                                                                */
8837 /*                                                                        */
8838 /*    status                                Completion status             */
8839 /*                                                                        */
8840 /*  CALLS                                                                 */
8841 /*                                                                        */
8842 /*    _nx_web_http_server_receive           Receive another packet        */
8843 /*                                                                        */
8844 /*  CALLED BY                                                             */
8845 /*                                                                        */
8846 /*    _nx_web_http_server_request_byte_expect                             */
8847 /*                                          Checks next byte is  expected */
8848 /*    _nx_web_http_server_chunked_size_get  Gets chunk size of request    */
8849 /*                                          packet chunk                  */
8850 /*                                                                        */
8851 /*  RELEASE HISTORY                                                       */
8852 /*                                                                        */
8853 /*    DATE              NAME                      DESCRIPTION             */
8854 /*                                                                        */
8855 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8856 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8857 /*                                            resulting in version 6.1    */
8858 /*                                                                        */
8859 /**************************************************************************/
_nx_web_http_server_request_read(NX_WEB_HTTP_SERVER * server_ptr,UCHAR * data,ULONG wait_option,NX_PACKET ** current_packet_pptr,UCHAR ** current_data_pptr)8860 UINT _nx_web_http_server_request_read(NX_WEB_HTTP_SERVER *server_ptr, UCHAR *data, ULONG wait_option,
8861                                       NX_PACKET **current_packet_pptr, UCHAR **current_data_pptr)
8862 {
8863 UINT status;
8864 
8865     /* If there is no remaining data.  */
8866     while (server_ptr -> nx_web_http_server_chunked_request_remaining_size == 0)
8867     {
8868 
8869         /* Release the previous received packet.  */
8870         if (server_ptr -> nx_web_http_server_request_packet)
8871         {
8872             nx_packet_release(server_ptr -> nx_web_http_server_request_packet);
8873             server_ptr -> nx_web_http_server_request_packet = NX_NULL;
8874         }
8875 
8876         /* Receive another packet.  */
8877         status = _nx_web_http_server_receive(server_ptr, &(server_ptr -> nx_web_http_server_request_packet), wait_option);
8878         if (status)
8879         {
8880             return(status);
8881         }
8882 
8883         /* Update the packet pointer, data pointer and remaining size.  */
8884         (*current_packet_pptr) = server_ptr -> nx_web_http_server_request_packet;
8885         (*current_data_pptr) = server_ptr -> nx_web_http_server_request_packet -> nx_packet_prepend_ptr;
8886         server_ptr -> nx_web_http_server_chunked_request_remaining_size = server_ptr -> nx_web_http_server_request_packet -> nx_packet_length;
8887     }
8888 
8889     /* Process the packet chain.  */
8890     if ((*current_data_pptr) == (*current_packet_pptr) -> nx_packet_append_ptr)
8891     {
8892 #ifndef NX_DISABLE_PACKET_CHAIN
8893         if ((*current_packet_pptr) -> nx_packet_next == NX_NULL)
8894         {
8895             return(NX_INVALID_PACKET);
8896         }
8897 
8898         (*current_packet_pptr) = (*current_packet_pptr) -> nx_packet_next;
8899         (*current_data_pptr) = (*current_packet_pptr) -> nx_packet_prepend_ptr;
8900 
8901         /* Release the processed packet in the packet chain.  */
8902         if (server_ptr -> nx_web_http_server_request_packet)
8903         {
8904             server_ptr -> nx_web_http_server_request_packet -> nx_packet_next = NX_NULL;
8905             nx_packet_release(server_ptr -> nx_web_http_server_request_packet);
8906             server_ptr -> nx_web_http_server_request_packet = (*current_packet_pptr);
8907         }
8908 #else
8909         return(NX_INVALID_PACKET);
8910 #endif /* NX_DISABLE_PACKET_CHAIN */
8911     }
8912 
8913     /* Set the returned data.  */
8914     *data = *(*current_data_pptr);
8915 
8916     /* Update the data pointer and remaining size.  */
8917     (*current_data_pptr)++;
8918     server_ptr -> nx_web_http_server_chunked_request_remaining_size--;
8919 
8920     return(NX_SUCCESS);
8921 }
8922 
8923 /**************************************************************************/
8924 /*                                                                        */
8925 /*  FUNCTION                                               RELEASE        */
8926 /*                                                                        */
8927 /*    _nx_web_http_server_request_byte_expect             PORTABLE C      */
8928 /*                                                           6.1          */
8929 /*  AUTHOR                                                                */
8930 /*                                                                        */
8931 /*    Yuxin Zhou, Microsoft Corporation                                   */
8932 /*                                                                        */
8933 /*  DESCRIPTION                                                           */
8934 /*                                                                        */
8935 /*    This function checks if next byte is the expected data.             */
8936 /*                                                                        */
8937 /*  INPUT                                                                 */
8938 /*                                                                        */
8939 /*    server_ptr                            Pointer to HTTP server        */
8940 /*    data                                  Expected data                 */
8941 /*    wait_option                           Suspension option             */
8942 /*    current_packet_pptr                   Pointer to the packet being   */
8943 /*                                            processed                   */
8944 /*    current_data_ptr                      Pointer to the data will be   */
8945 /*                                            processed                   */
8946 /*                                                                        */
8947 /*  OUTPUT                                                                */
8948 /*                                                                        */
8949 /*    status                                Compare result                */
8950 /*                                                                        */
8951 /*  CALLS                                                                 */
8952 /*                                                                        */
8953 /*    _nx_web_http_server_request_read      Get next data                 */
8954 /*                                                                        */
8955 /*  CALLED BY                                                             */
8956 /*                                                                        */
8957 /*    _nx_web_http_server_chunked_size_get  Gets chunk size of request    */
8958 /*    _nx_web_http_server_request_chunked_get                             */
8959 /*                                          Get chunk data from request   */
8960 /*                                                                        */
8961 /*  RELEASE HISTORY                                                       */
8962 /*                                                                        */
8963 /*    DATE              NAME                      DESCRIPTION             */
8964 /*                                                                        */
8965 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8966 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8967 /*                                            resulting in version 6.1    */
8968 /*                                                                        */
8969 /**************************************************************************/
_nx_web_http_server_request_byte_expect(NX_WEB_HTTP_SERVER * server_ptr,UCHAR data,ULONG wait_option,NX_PACKET ** current_packet_pptr,UCHAR ** current_data_pptr)8970 UINT _nx_web_http_server_request_byte_expect(NX_WEB_HTTP_SERVER *server_ptr, UCHAR data, ULONG wait_option,
8971                                              NX_PACKET **current_packet_pptr, UCHAR **current_data_pptr)
8972 {
8973 UINT status;
8974 UCHAR tmp;
8975 
8976     /* Get next data.  */
8977     status = _nx_web_http_server_request_read(server_ptr, &tmp, wait_option, current_packet_pptr, current_data_pptr);
8978 
8979     if (status)
8980     {
8981         return(status);
8982     }
8983 
8984     /* Return the compare result.  */
8985     if (tmp != data)
8986     {
8987         return(NX_NOT_FOUND);
8988     }
8989 
8990     return(NX_SUCCESS);
8991 }
8992 
8993 /**************************************************************************/
8994 /*                                                                        */
8995 /*  FUNCTION                                               RELEASE        */
8996 /*                                                                        */
8997 /*    _nx_web_http_server_chunked_size_get                PORTABLE C      */
8998 /*                                                           6.1          */
8999 /*  AUTHOR                                                                */
9000 /*                                                                        */
9001 /*    Yuxin Zhou, Microsoft Corporation                                   */
9002 /*                                                                        */
9003 /*  DESCRIPTION                                                           */
9004 /*                                                                        */
9005 /*    This function gets the chunk size of the request packet chunk.      */
9006 /*                                                                        */
9007 /*                                                                        */
9008 /*  INPUT                                                                 */
9009 /*                                                                        */
9010 /*    server_ptr                            Pointer to HTTP server        */
9011 /*    chunk_size                            Returned chunk size           */
9012 /*    wait_option                           Suspension option             */
9013 /*    current_packet_pptr                   Pointer to the packet being   */
9014 /*                                            processed                   */
9015 /*    current_data_ptr                      Pointer to the data will be   */
9016 /*                                            processed                   */
9017 /*                                                                        */
9018 /*  OUTPUT                                                                */
9019 /*                                                                        */
9020 /*    status                                Completion status             */
9021 /*                                                                        */
9022 /*  CALLS                                                                 */
9023 /*                                                                        */
9024 /*    _nx_web_http_server_chunked_size_get  Get chunk size                */
9025 /*    _nx_web_http_server_request_byte_expect                             */
9026 /*                                          Check if next byte is expected*/
9027 /*    nx_packet_release                     Release packet                */
9028 /*    nx_packet_append                      Append packet data            */
9029 /*                                                                        */
9030 /*  CALLED BY                                                             */
9031 /*                                                                        */
9032 /*    Application Code                                                    */
9033 /*                                                                        */
9034 /*  RELEASE HISTORY                                                       */
9035 /*                                                                        */
9036 /*    DATE              NAME                      DESCRIPTION             */
9037 /*                                                                        */
9038 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9039 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9040 /*                                            resulting in version 6.1    */
9041 /*                                                                        */
9042 /**************************************************************************/
_nx_web_http_server_chunked_size_get(NX_WEB_HTTP_SERVER * server_ptr,UINT * chunk_size,ULONG wait_option,NX_PACKET ** current_packet_pptr,UCHAR ** current_data_pptr)9043 UINT _nx_web_http_server_chunked_size_get(NX_WEB_HTTP_SERVER *server_ptr, UINT *chunk_size, ULONG wait_option,
9044                                           NX_PACKET **current_packet_pptr, UCHAR **current_data_pptr)
9045 {
9046 UINT status;
9047 UINT size = 0;
9048 UCHAR tmp;
9049 UINT  chunk_extension = 0;
9050 
9051     if (server_ptr -> nx_web_http_server_actual_bytes_received < server_ptr -> nx_web_http_server_expect_receive_bytes)
9052     {
9053 
9054         /* If there are bytes need to receive, set the size need to receive as chunk size.  */
9055         *chunk_size = server_ptr -> nx_web_http_server_expect_receive_bytes - server_ptr -> nx_web_http_server_actual_bytes_received;
9056     }
9057     else
9058     {
9059 
9060         /* Get the chunk size.  */
9061         while (1)
9062         {
9063 
9064             /* Read next byte from request packet.  */
9065             status = _nx_web_http_server_request_read(server_ptr, &tmp, wait_option, current_packet_pptr, current_data_pptr);
9066             if (status)
9067             {
9068                 return(status);
9069             }
9070 
9071             /* Skip the chunk extension.  */
9072             if (chunk_extension && (tmp != '\r'))
9073             {
9074                 continue;
9075             }
9076 
9077             /* Calculate the size.  */
9078             if ((tmp >= 'a') && (tmp <= 'f'))
9079             {
9080                 size = (size << 4) + 10 + (UINT)(tmp - 'a');
9081             }
9082             else if ((tmp >= 'A') && (tmp <= 'F'))
9083             {
9084                 size = (size << 4) + 10 + (UINT)(tmp - 'A');
9085             }
9086             else if ((tmp >= '0') && (tmp <= '9'))
9087             {
9088                 size = (size << 4) + (UINT)(tmp - '0');
9089             }
9090             else if (tmp == '\r')
9091             {
9092 
9093                 /* Find the end of chunk header.  */
9094                 break;
9095             }
9096             else if (tmp == ';')
9097             {
9098 
9099                 /* Find chunk extension.  */
9100                 chunk_extension = 1;
9101             }
9102             else
9103             {
9104                 return(NX_NOT_FOUND);
9105             }
9106         }
9107 
9108         /* Expect '\n'.  */
9109         status = _nx_web_http_server_request_byte_expect(server_ptr, '\n', wait_option, current_packet_pptr, current_data_pptr);
9110         if (status)
9111         {
9112             return(status);
9113         }
9114 
9115         *chunk_size = size;
9116     }
9117 
9118     /* If there is no remaining data, receive another packet.  */
9119     while (server_ptr -> nx_web_http_server_chunked_request_remaining_size == 0)
9120     {
9121         if (server_ptr -> nx_web_http_server_request_packet)
9122         {
9123             nx_packet_release(server_ptr -> nx_web_http_server_request_packet);
9124         }
9125 
9126         status = _nx_web_http_server_receive(server_ptr, &(server_ptr -> nx_web_http_server_request_packet), wait_option);
9127         if (status)
9128         {
9129             return(status);
9130         }
9131 
9132         /* Update the current request packet, data pointer and remaining size.  */
9133         (*current_packet_pptr) = server_ptr -> nx_web_http_server_request_packet;
9134         (*current_data_pptr) = server_ptr -> nx_web_http_server_request_packet -> nx_packet_prepend_ptr;
9135         server_ptr -> nx_web_http_server_chunked_request_remaining_size = server_ptr -> nx_web_http_server_request_packet -> nx_packet_length;
9136     }
9137 
9138     return(NX_SUCCESS);
9139 }
9140 
9141 /**************************************************************************/
9142 /*                                                                        */
9143 /*  FUNCTION                                               RELEASE        */
9144 /*                                                                        */
9145 /*    _nx_web_http_server_request_chunked_get             PORTABLE C      */
9146 /*                                                           6.1          */
9147 /*  AUTHOR                                                                */
9148 /*                                                                        */
9149 /*    Yuxin Zhou, Microsoft Corporation                                   */
9150 /*                                                                        */
9151 /*  DESCRIPTION                                                           */
9152 /*                                                                        */
9153 /*    This function gets the chunk data from chunked request.             */
9154 /*                                                                        */
9155 /*  INPUT                                                                 */
9156 /*                                                                        */
9157 /*    server_ptr                            Pointer to HTTP server        */
9158 /*    packet_pptr                           Pointer to the packet         */
9159 /*    wait_option                           Suspension option             */
9160 /*                                                                        */
9161 /*  OUTPUT                                                                */
9162 /*                                                                        */
9163 /*    status                                Completion status             */
9164 /*                                                                        */
9165 /*  CALLS                                                                 */
9166 /*                                                                        */
9167 /*    _nx_web_http_server_chunked_size_get  Get chunk size                */
9168 /*    _nx_web_http_server_request_byte_expect                             */
9169 /*                                          Check if next byte is expected*/
9170 /*    nx_packet_allocate                    Allocate packet               */
9171 /*    nx_packet_append                      Append packet data            */
9172 /*                                                                        */
9173 /*  CALLED BY                                                             */
9174 /*                                                                        */
9175 /*    _nx_web_http_server_packet_get        Get next packet from HTTP     */
9176 /*                                          server socket                 */
9177 /*                                                                        */
9178 /*  RELEASE HISTORY                                                       */
9179 /*                                                                        */
9180 /*    DATE              NAME                      DESCRIPTION             */
9181 /*                                                                        */
9182 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9183 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9184 /*                                            resulting in version 6.1    */
9185 /*                                                                        */
9186 /**************************************************************************/
_nx_web_http_server_request_chunked_get(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,ULONG wait_option)9187 UINT _nx_web_http_server_request_chunked_get(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr, ULONG wait_option)
9188 {
9189 UINT       status;
9190 UINT       chunk_size = 0, length = 0, temp_size = 0;
9191 UINT       remaining_size = 0;
9192 NX_PACKET *packet_ptr;
9193 NX_PACKET *current_packet_ptr = NX_NULL;
9194 UCHAR     *current_data_ptr = NX_NULL;
9195 
9196     /* Set pointer for processing packet data.  */
9197     current_packet_ptr = server_ptr -> nx_web_http_server_request_packet;
9198 
9199     if (current_packet_ptr)
9200     {
9201 
9202         /* Set current data pointer.  */
9203         current_data_ptr = current_packet_ptr -> nx_packet_prepend_ptr;
9204     }
9205 
9206     /* Get chunk size.  */
9207     status = _nx_web_http_server_chunked_size_get(server_ptr, &chunk_size, wait_option, &current_packet_ptr, &current_data_ptr);
9208     if (status)
9209     {
9210         return(status);
9211     }
9212 
9213     /* Check if it's the end.  */
9214     if (chunk_size == 0)
9215     {
9216 
9217         /* Read CRLF.  */
9218         status = _nx_web_http_server_request_byte_expect(server_ptr, '\r', wait_option, &current_packet_ptr, &current_data_ptr);
9219         if (status)
9220         {
9221             return(status);
9222         }
9223 
9224         status = _nx_web_http_server_request_byte_expect(server_ptr, '\n', wait_option, &current_packet_ptr, &current_data_ptr);
9225         if (status)
9226         {
9227             return(status);
9228         }
9229 
9230         *packet_pptr = NX_NULL;
9231 
9232         return(NX_WEB_HTTP_GET_DONE);
9233     }
9234 
9235     /* Set the return packet.  */
9236     *packet_pptr = server_ptr -> nx_web_http_server_request_packet;
9237     server_ptr -> nx_web_http_server_request_packet = NX_NULL;
9238     packet_ptr = *packet_pptr;
9239     packet_ptr -> nx_packet_prepend_ptr = current_data_ptr;
9240     remaining_size = server_ptr -> nx_web_http_server_chunked_request_remaining_size;
9241 
9242     /* Process the chunk data.  */
9243     if (chunk_size <= remaining_size)
9244     {
9245 
9246         /* One or more chunk in the remaining data.  */
9247         temp_size = chunk_size;
9248 
9249         /* Check if the chunk data is all in this packet.  */
9250         while (temp_size > (UINT)(current_packet_ptr -> nx_packet_append_ptr - current_data_ptr))
9251         {
9252 
9253 #ifndef NX_DISABLE_PACKET_CHAIN
9254             if (current_packet_ptr -> nx_packet_next == NX_NULL)
9255             {
9256                 return(NX_INVALID_PACKET);
9257             }
9258 
9259             temp_size -= (UINT)(current_packet_ptr -> nx_packet_append_ptr - current_data_ptr);
9260             current_packet_ptr = current_packet_ptr -> nx_packet_next;
9261             current_data_ptr = current_packet_ptr -> nx_packet_prepend_ptr;
9262 #else
9263             return(NX_INVALID_PACKET);
9264 #endif /* NX_DISABLE_PACKET_CHAIN */
9265         }
9266 
9267         /* Skip the chunk data.  */
9268         current_data_ptr += temp_size;
9269         server_ptr -> nx_web_http_server_chunked_request_remaining_size -= chunk_size;
9270         length = chunk_size;
9271 
9272         /* Read CRLF.  */
9273         status = _nx_web_http_server_request_byte_expect(server_ptr, '\r', wait_option, &current_packet_ptr, &current_data_ptr);
9274         if (status)
9275         {
9276             return(status);
9277         }
9278 
9279         status = _nx_web_http_server_request_byte_expect(server_ptr, '\n', wait_option, &current_packet_ptr, &current_data_ptr);
9280         if (status)
9281         {
9282             return(status);
9283         }
9284 
9285         /* Check the remaining data.  */
9286         if (server_ptr -> nx_web_http_server_chunked_request_remaining_size)
9287         {
9288             if (server_ptr -> nx_web_http_server_request_packet)
9289             {
9290 
9291                 /* If received new packet, adjust the prepend pointer of this packet.  */
9292                 server_ptr -> nx_web_http_server_request_packet -> nx_packet_prepend_ptr = current_data_ptr;
9293             }
9294             else
9295             {
9296 
9297                 /* Copy the remaining data to a new packet.  */
9298                 /* Allocate a packet.  */
9299                 status = nx_packet_allocate(server_ptr -> nx_web_http_server_packet_pool_ptr,
9300                                             &(server_ptr -> nx_web_http_server_request_packet),
9301                                             0, wait_option);
9302                 if (status)
9303                 {
9304                     return(status);
9305                 }
9306 
9307                 /* Copy the remaining data in current packet to the new packet.   */
9308                 temp_size = (UINT)(current_packet_ptr -> nx_packet_append_ptr - current_data_ptr);
9309                 status = nx_packet_data_append(server_ptr -> nx_web_http_server_request_packet,
9310                                                current_data_ptr,
9311                                                temp_size,
9312                                                server_ptr -> nx_web_http_server_packet_pool_ptr,
9313                                                wait_option);
9314                 if (status)
9315                 {
9316                     return(status);
9317                 }
9318 
9319                 /* Check if any remaining data not in current packet.  */
9320                 if (server_ptr -> nx_web_http_server_chunked_request_remaining_size > temp_size)
9321                 {
9322 #ifndef NX_DISABLE_PACKET_CHAIN
9323 
9324                     /* If there are chained packets, append the packets to the new packet.  */
9325                     if (current_packet_ptr -> nx_packet_next)
9326                     {
9327                         server_ptr -> nx_web_http_server_request_packet -> nx_packet_next = current_packet_ptr -> nx_packet_next;
9328                         server_ptr -> nx_web_http_server_request_packet -> nx_packet_last = current_packet_ptr -> nx_packet_last;
9329                         current_packet_ptr -> nx_packet_next = NX_NULL;
9330                     }
9331                     else
9332 #endif /* NX_DISABLE_PACKET_CHAIN */
9333                     {
9334                         return(NX_INVALID_PACKET);
9335                     }
9336                 }
9337             }
9338 
9339             /* Update the packet length.  */
9340             server_ptr -> nx_web_http_server_request_packet -> nx_packet_length = server_ptr -> nx_web_http_server_chunked_request_remaining_size;
9341         }
9342     }
9343     else
9344     {
9345 
9346         /* All the remaining data is in this chunk.  */
9347         server_ptr -> nx_web_http_server_chunked_request_remaining_size = 0;
9348         length = remaining_size;
9349     }
9350 
9351     /* Set the received bytes.  */
9352     server_ptr -> nx_web_http_server_expect_receive_bytes = chunk_size;
9353     server_ptr -> nx_web_http_server_actual_bytes_received = length;
9354 
9355 #ifndef NX_DISABLE_PACKET_CHAIN
9356     /* Set length of the packet chain header.  */
9357     (*packet_pptr) -> nx_packet_length = length;
9358 
9359     /* Find the last packet.  */
9360     while (packet_ptr -> nx_packet_next &&
9361            (length > (UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr)))
9362     {
9363         length -= (UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr);
9364         packet_ptr = packet_ptr -> nx_packet_next;
9365     }
9366 
9367     /* Set the last packet.  */
9368     (*packet_pptr) -> nx_packet_last = packet_ptr;
9369 
9370     /* Maybe the '\r\n' is in another packet, release this packet.  */
9371     if (packet_ptr -> nx_packet_next)
9372     {
9373         nx_packet_release(packet_ptr -> nx_packet_next);
9374         packet_ptr -> nx_packet_next = NX_NULL;
9375     }
9376 #endif /* NX_DISABLE_PACKET_CHAIN */
9377 
9378     /* Set packet length and append pointer.  */
9379     /* If the packet is chained, set the length and append pointer of the last packet.  */
9380     packet_ptr -> nx_packet_length = length;
9381     packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + length;
9382 
9383     return(NX_SUCCESS);
9384 }
9385 
9386 /**************************************************************************/
9387 /*                                                                        */
9388 /*  FUNCTION                                               RELEASE        */
9389 /*                                                                        */
9390 /*    _nxe_web_http_server_response_chunked_set           PORTABLE C      */
9391 /*                                                           6.1          */
9392 /*  AUTHOR                                                                */
9393 /*                                                                        */
9394 /*    Yuxin Zhou, Microsoft Corporation                                   */
9395 /*                                                                        */
9396 /*  DESCRIPTION                                                           */
9397 /*                                                                        */
9398 /*    This function checks for errors in the HTTP response chunked set    */
9399 /*    API call.                                                           */
9400 /*                                                                        */
9401 /*  INPUT                                                                 */
9402 /*                                                                        */
9403 /*                                                                        */
9404 /*    server_ptr                            Pointer to HTTP server        */
9405 /*    chunk_size                            Size of the chunk             */
9406 /*    packet_ptr                            Pointer to the packet         */
9407 /*                                                                        */
9408 /*  OUTPUT                                                                */
9409 /*                                                                        */
9410 /*    status                                Completion status             */
9411 /*                                                                        */
9412 /*  CALLS                                                                 */
9413 /*                                                                        */
9414 /*    _nx_web_http_server_response_chunked_set                            */
9415 /*                                          Actual response chunked set   */
9416 /*                                                                        */
9417 /*  CALLED BY                                                             */
9418 /*                                                                        */
9419 /*    Application Code                                                    */
9420 /*                                                                        */
9421 /*  RELEASE HISTORY                                                       */
9422 /*                                                                        */
9423 /*    DATE              NAME                      DESCRIPTION             */
9424 /*                                                                        */
9425 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9426 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9427 /*                                            resulting in version 6.1    */
9428 /*                                                                        */
9429 /**************************************************************************/
_nxe_web_http_server_response_chunked_set(NX_WEB_HTTP_SERVER * server_ptr,UINT chunk_size,NX_PACKET * packet_ptr)9430 UINT _nxe_web_http_server_response_chunked_set(NX_WEB_HTTP_SERVER *server_ptr, UINT chunk_size, NX_PACKET *packet_ptr)
9431 {
9432 UINT        status;
9433 
9434     /* Make sure the client instance makes sense. */
9435     if ((server_ptr == NX_NULL) || (packet_ptr == NX_NULL))
9436     {
9437         return(NX_PTR_ERROR);
9438     }
9439 
9440     /* Call actual response chunked set function.  */
9441     status =  _nx_web_http_server_response_chunked_set(server_ptr, chunk_size, packet_ptr);
9442 
9443     /* Return success to the caller.  */
9444     return(status);
9445 }
9446 
9447 
9448 /**************************************************************************/
9449 /*                                                                        */
9450 /*  FUNCTION                                               RELEASE        */
9451 /*                                                                        */
9452 /*    _nx_web_http_server_response_chunked_set            PORTABLE C      */
9453 /*                                                           6.1          */
9454 /*  AUTHOR                                                                */
9455 /*                                                                        */
9456 /*    Yuxin Zhou, Microsoft Corporation                                   */
9457 /*                                                                        */
9458 /*  DESCRIPTION                                                           */
9459 /*                                                                        */
9460 /*    This function sets the chunked information of chunked response.     */
9461 /*                                                                        */
9462 /*                                                                        */
9463 /*  INPUT                                                                 */
9464 /*                                                                        */
9465 /*    server_ptr                            Pointer to HTTP server        */
9466 /*    chunk_size                            Size of the chunk             */
9467 /*    packet_ptr                            Pointer to the packet         */
9468 /*                                                                        */
9469 /*  OUTPUT                                                                */
9470 /*                                                                        */
9471 /*    status                                Completion status             */
9472 /*                                                                        */
9473 /*  CALLS                                                                 */
9474 /*                                                                        */
9475 /*    nx_packet_data_append                 Append the packet data        */
9476 /*                                                                        */
9477 /*  CALLED BY                                                             */
9478 /*                                                                        */
9479 /*    Application Code                                                    */
9480 /*                                                                        */
9481 /*  RELEASE HISTORY                                                       */
9482 /*                                                                        */
9483 /*    DATE              NAME                      DESCRIPTION             */
9484 /*                                                                        */
9485 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9486 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9487 /*                                            resulting in version 6.1    */
9488 /*                                                                        */
9489 /**************************************************************************/
_nx_web_http_server_response_chunked_set(NX_WEB_HTTP_SERVER * server_ptr,UINT chunk_size,NX_PACKET * packet_ptr)9490 UINT _nx_web_http_server_response_chunked_set(NX_WEB_HTTP_SERVER *server_ptr, UINT chunk_size, NX_PACKET *packet_ptr)
9491 {
9492 UINT        status;
9493 UINT        temp_size, i, j;
9494 CHAR        temp_string[10];
9495 CHAR        crlf[2] = {13,10};
9496 
9497     /* Covert the size to ASCII.  */
9498     temp_size = chunk_size;
9499     i = 0;
9500 
9501     while (temp_size)
9502     {
9503 
9504         for (j = i; j > 0; j--)
9505         {
9506             temp_string[j] = temp_string[j - 1];
9507         }
9508 
9509         if ((temp_size & 0x0F) < 10)
9510         {
9511             temp_string[0] = (CHAR)((temp_size & 0x0F) + '0');
9512         }
9513         else
9514         {
9515             temp_string[0] = (CHAR)((temp_size & 0x0F) - 10 + 'a');
9516         }
9517         temp_size = temp_size >> 4;
9518         i++;
9519     }
9520 
9521     if (i == 0)
9522     {
9523         temp_string[i++] = '0';
9524     }
9525 
9526     /* Place the chunk size in the packet.  */
9527     status = nx_packet_data_append(packet_ptr, temp_string, i, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
9528     if (status)
9529     {
9530         return(status);
9531     }
9532 
9533     /* Place the CRLF to signal the end of the chunk size.  */
9534     status = nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
9535     if (status)
9536     {
9537         return(status);
9538     }
9539 
9540     /* Set the request chunked flag.  */
9541     server_ptr -> nx_web_http_server_response_chunked = NX_TRUE;
9542 
9543     /* The total bytes need to transfer is chunk size plus chunk header length.  */
9544     server_ptr -> nx_web_http_server_expect_transfer_bytes = chunk_size + i + 2;
9545     server_ptr -> nx_web_http_server_actual_bytes_transferred = 0;
9546 
9547     return(NX_SUCCESS);
9548 }
9549 
9550 
9551 /**************************************************************************/
9552 /*                                                                        */
9553 /*  FUNCTION                                               RELEASE        */
9554 /*                                                                        */
9555 /*    _nx_web_http_server_chunked_check                   PORTABLE C      */
9556 /*                                                           6.1          */
9557 /*  AUTHOR                                                                */
9558 /*                                                                        */
9559 /*    Yuxin Zhou, Microsoft Corporation                                   */
9560 /*                                                                        */
9561 /*  DESCRIPTION                                                           */
9562 /*                                                                        */
9563 /*    This function checks if the packet is chunked.                      */
9564 /*                                                                        */
9565 /*                                                                        */
9566 /*  INPUT                                                                 */
9567 /*                                                                        */
9568 /*    server_ptr                            Pointer to HTTP server        */
9569 /*    packet_ptr                            Pointer to the packet         */
9570 /*                                                                        */
9571 /*  OUTPUT                                                                */
9572 /*                                                                        */
9573 /*    status                                The packet is chunked or not  */
9574 /*                                                                        */
9575 /*  CALLS                                                                 */
9576 /*                                                                        */
9577 /*    _nx_web_http_server_field_value_get   Get filed value               */
9578 /*    _nx_web_http_server_memicmp           Compare two strings           */
9579 /*    _nx_utility_string_length_check       Check string length           */
9580 /*                                                                        */
9581 /*  CALLED BY                                                             */
9582 /*                                                                        */
9583 /*    _nx_web_http_server_packet_content_find                             */
9584 /*                                          Find content length in the    */
9585 /*                                          HTTP header                   */
9586 /*    _nx_web_http_server_content_get_extended                            */
9587 /*                                          Get user specified portion of */
9588 /*                                          HTTP header                   */
9589 /*    _nx_web_http_server_receive_data      HTTP Server receive processing*/
9590 /*                                                                        */
9591 /*  RELEASE HISTORY                                                       */
9592 /*                                                                        */
9593 /*    DATE              NAME                      DESCRIPTION             */
9594 /*                                                                        */
9595 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9596 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9597 /*                                            resulting in version 6.1    */
9598 /*                                                                        */
9599 /**************************************************************************/
_nx_web_http_server_chunked_check(NX_PACKET * packet_ptr)9600 UINT _nx_web_http_server_chunked_check(NX_PACKET *packet_ptr)
9601 {
9602 UINT status;
9603 CHAR temp_string[20];
9604 UINT temp_string_length;
9605 
9606     /* Check if the packet is chunked.  */
9607     status = _nx_web_http_server_field_value_get(packet_ptr, (UCHAR *)"Transfer-Encoding", 17, (UCHAR *)temp_string, sizeof(temp_string));
9608 
9609     if ((status == NX_SUCCESS) &&
9610         (_nx_utility_string_length_check(temp_string, &temp_string_length, sizeof(temp_string) - 1) == NX_SUCCESS) &&
9611         (_nx_web_http_server_memicmp((UCHAR *)temp_string, temp_string_length, (UCHAR *)"chunked", 7) == 0))
9612     {
9613         return(NX_TRUE);
9614     }
9615 
9616     return(NX_FALSE);
9617 }
9618 
9619 
9620 /**************************************************************************/
9621 /*                                                                        */
9622 /*  FUNCTION                                               RELEASE        */
9623 /*                                                                        */
9624 /*    _nxe_web_http_server_response_packet_allocate       PORTABLE C      */
9625 /*                                                           6.1          */
9626 /*  AUTHOR                                                                */
9627 /*                                                                        */
9628 /*    Yuxin Zhou, Microsoft Corporation                                   */
9629 /*                                                                        */
9630 /*  DESCRIPTION                                                           */
9631 /*                                                                        */
9632 /*    This function checks for errors in the call to allocate packets for */
9633 /*    an HTTP(S) server session, as used for PUT and POST operations.     */
9634 /*                                                                        */
9635 /*                                                                        */
9636 /*  INPUT                                                                 */
9637 /*                                                                        */
9638 /*    server_ptr                            Pointer to HTTP client        */
9639 /*    packet_ptr                            Pointer to allocated packet   */
9640 /*    wait_option                           Suspension option             */
9641 /*                                                                        */
9642 /*  OUTPUT                                                                */
9643 /*                                                                        */
9644 /*    status                                Completion status             */
9645 /*                                                                        */
9646 /*  CALLS                                                                 */
9647 /*                                                                        */
9648 /*    _nxe_web_http_server_response_packet_allocate                       */
9649 /*                                          Actual packet allocation call */
9650 /*                                                                        */
9651 /*  CALLED BY                                                             */
9652 /*                                                                        */
9653 /*    Application Code                                                    */
9654 /*                                                                        */
9655 /*  RELEASE HISTORY                                                       */
9656 /*                                                                        */
9657 /*    DATE              NAME                      DESCRIPTION             */
9658 /*                                                                        */
9659 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9660 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9661 /*                                            resulting in version 6.1    */
9662 /*                                                                        */
9663 /**************************************************************************/
_nxe_web_http_server_response_packet_allocate(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr,UINT wait_option)9664 UINT _nxe_web_http_server_response_packet_allocate(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr,
9665                                                    UINT wait_option)
9666 {
9667 UINT status;
9668 
9669     /* Check our pointers. */
9670     if(server_ptr == NX_NULL || packet_ptr == NX_NULL)
9671     {
9672         return(NX_PTR_ERROR);
9673     }
9674 
9675     /* Call the actual function. */
9676     status = _nx_web_http_server_response_packet_allocate(server_ptr, packet_ptr, wait_option);
9677 
9678     return(status);
9679 }
9680 
9681 
9682 /**************************************************************************/
9683 /*                                                                        */
9684 /*  FUNCTION                                               RELEASE        */
9685 /*                                                                        */
9686 /*    _nx_web_http_server_response_packet_allocate        PORTABLE C      */
9687 /*                                                           6.1          */
9688 /*  AUTHOR                                                                */
9689 /*                                                                        */
9690 /*    Yuxin Zhou, Microsoft Corporation                                   */
9691 /*                                                                        */
9692 /*  DESCRIPTION                                                           */
9693 /*                                                                        */
9694 /*    This function allocates a packet for Server HTTP(S) responses so    */
9695 /*    that servers needing to send large amounts of data (such as for     */
9696 /*    multi-part file upload) can allocated the needed.                   */
9697 /*                                                                        */
9698 /*                                                                        */
9699 /*  INPUT                                                                 */
9700 /*                                                                        */
9701 /*    server_ptr                            Pointer to HTTP server        */
9702 /*    packet_ptr                            Pointer to allocated packet   */
9703 /*    wait_option                           Suspension option             */
9704 /*                                                                        */
9705 /*  OUTPUT                                                                */
9706 /*                                                                        */
9707 /*    status                                Completion status             */
9708 /*                                                                        */
9709 /*  CALLS                                                                 */
9710 /*                                                                        */
9711 /*    nx_secure_tls_packet_allocate         Allocate a TLS packet         */
9712 /*    nx_packet_allocate                    Allocate a TCP packet         */
9713 /*                                                                        */
9714 /*  CALLED BY                                                             */
9715 /*                                                                        */
9716 /*    Application Code                                                    */
9717 /*                                                                        */
9718 /*  RELEASE HISTORY                                                       */
9719 /*                                                                        */
9720 /*    DATE              NAME                      DESCRIPTION             */
9721 /*                                                                        */
9722 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9723 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9724 /*                                            resulting in version 6.1    */
9725 /*                                                                        */
9726 /**************************************************************************/
_nx_web_http_server_response_packet_allocate(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr,UINT wait_option)9727 UINT _nx_web_http_server_response_packet_allocate(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr,
9728                                                   UINT wait_option)
9729 {
9730 UINT status;
9731 
9732     /* Allocate a packet.  */
9733 #ifdef NX_WEB_HTTPS_ENABLE
9734     if(server_ptr -> nx_web_http_is_https_server)
9735     {
9736         status = nx_secure_tls_packet_allocate(&(server_ptr -> nx_web_http_server_current_session_ptr -> nx_tcp_session_tls_session),
9737                                                server_ptr -> nx_web_http_server_packet_pool_ptr,
9738                                                packet_ptr, wait_option);
9739     }
9740     else
9741 #endif
9742     {
9743         status =  nx_packet_allocate(server_ptr -> nx_web_http_server_packet_pool_ptr,
9744                                      packet_ptr,
9745                                      NX_TCP_PACKET, wait_option);
9746     }
9747 
9748     return(status);
9749 }
9750 
9751 
9752 /**************************************************************************/
9753 /*                                                                        */
9754 /*  FUNCTION                                               RELEASE        */
9755 /*                                                                        */
9756 /*    _nxe_web_http_server_callback_generate_response_header              */
9757 /*                                                        PORTABLE C      */
9758 /*                                                           6.1          */
9759 /*  AUTHOR                                                                */
9760 /*                                                                        */
9761 /*    Yuxin Zhou, Microsoft Corporation                                   */
9762 /*                                                                        */
9763 /*  DESCRIPTION                                                           */
9764 /*                                                                        */
9765 /*    This function checks error for generating HTTP response header.     */
9766 /*                                                                        */
9767 /*  INPUT                                                                 */
9768 /*                                                                        */
9769 /*    server_ptr                            Pointer to HTTP server        */
9770 /*    packet_pptr                           Pointer to packet             */
9771 /*    status_code                           Status-code and reason-phrase */
9772 /*    content_length                        Length of content             */
9773 /*    content_type                          Type of content               */
9774 /*    additional_header                     Other HTTP headers            */
9775 /*                                                                        */
9776 /*  OUTPUT                                                                */
9777 /*                                                                        */
9778 /*    status                                Completion status             */
9779 /*                                                                        */
9780 /*  CALLS                                                                 */
9781 /*                                                                        */
9782 /*    _nx_web_http_server_callback_generate_response_header               */
9783 /*                                                                        */
9784 /*  CALLED BY                                                             */
9785 /*                                                                        */
9786 /*    Application Code                                                    */
9787 /*                                                                        */
9788 /*  RELEASE HISTORY                                                       */
9789 /*                                                                        */
9790 /*    DATE              NAME                      DESCRIPTION             */
9791 /*                                                                        */
9792 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9793 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9794 /*                                            resulting in version 6.1    */
9795 /*                                                                        */
9796 /**************************************************************************/
_nxe_web_http_server_callback_generate_response_header(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,CHAR * status_code,UINT content_length,CHAR * content_type,CHAR * additional_header)9797 UINT  _nxe_web_http_server_callback_generate_response_header(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr,
9798                                                          CHAR *status_code, UINT content_length, CHAR *content_type,
9799                                                          CHAR* additional_header)
9800 {
9801 
9802     /* Check for invalid input pointers.  */
9803     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
9804         (packet_pptr == NX_NULL) || (status_code == NX_NULL))
9805         return(NX_PTR_ERROR);
9806 
9807     return _nx_web_http_server_callback_generate_response_header(server_ptr, packet_pptr, status_code, content_length, content_type, additional_header);
9808 }
9809 
9810 
9811 /**************************************************************************/
9812 /*                                                                        */
9813 /*  FUNCTION                                               RELEASE        */
9814 /*                                                                        */
9815 /*    _nx_web_http_server_callback_generate_response_header               */
9816 /*                                                        PORTABLE C      */
9817 /*                                                           6.1          */
9818 /*  AUTHOR                                                                */
9819 /*                                                                        */
9820 /*    Yuxin Zhou, Microsoft Corporation                                   */
9821 /*                                                                        */
9822 /*  DESCRIPTION                                                           */
9823 /*                                                                        */
9824 /*    This function is used in callback function to generate HTTP         */
9825 /*    response header.                                                    */
9826 /*                                                                        */
9827 /*  INPUT                                                                 */
9828 /*                                                                        */
9829 /*    server_ptr                            Pointer to HTTP server        */
9830 /*    packet_pptr                           Pointer to packet             */
9831 /*    status_code                           Status-code and reason-phrase */
9832 /*    content_length                        Length of content             */
9833 /*    content_type                          Type of content               */
9834 /*    additional_header                     Other HTTP headers            */
9835 /*                                                                        */
9836 /*  OUTPUT                                                                */
9837 /*                                                                        */
9838 /*    status                                Completion status             */
9839 /*                                                                        */
9840 /*  CALLS                                                                 */
9841 /*                                                                        */
9842 /*    _nx_web_http_server_generate_response_header                        */
9843 /*                                          Generate response header      */
9844 /*    _nx_utility_string_length_check       Check string length           */
9845 /*                                                                        */
9846 /*  CALLED BY                                                             */
9847 /*                                                                        */
9848 /*    Application Code                                                    */
9849 /*                                                                        */
9850 /*  RELEASE HISTORY                                                       */
9851 /*                                                                        */
9852 /*    DATE              NAME                      DESCRIPTION             */
9853 /*                                                                        */
9854 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9855 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9856 /*                                            resulting in version 6.1    */
9857 /*                                                                        */
9858 /**************************************************************************/
_nx_web_http_server_callback_generate_response_header(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_pptr,CHAR * status_code,UINT content_length,CHAR * content_type,CHAR * additional_header)9859 UINT  _nx_web_http_server_callback_generate_response_header(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_pptr,
9860                                                             CHAR *status_code, UINT content_length, CHAR *content_type,
9861                                                             CHAR* additional_header)
9862 {
9863 UINT status_code_length = 0;
9864 UINT content_type_length = 0;
9865 UINT additional_header_length = 0;
9866 
9867     /* Check status code, content type and additional header length.  */
9868     if (_nx_utility_string_length_check(status_code, &status_code_length, NX_MAX_STRING_LENGTH) ||
9869         (content_type && _nx_utility_string_length_check(content_type, &content_type_length, NX_MAX_STRING_LENGTH)) ||
9870         (additional_header && _nx_utility_string_length_check(additional_header, &additional_header_length, NX_MAX_STRING_LENGTH)))
9871     {
9872         return(NX_WEB_HTTP_ERROR);
9873     }
9874 
9875     /* Call the internal HTTP response send function.  */
9876     return _nx_web_http_server_generate_response_header(server_ptr, packet_pptr, status_code,
9877                                                         status_code_length, content_length,
9878                                                         content_type, content_type_length,
9879                                                         additional_header, additional_header_length);
9880 }
9881 
9882 
9883 /**************************************************************************/
9884 /*                                                                        */
9885 /*  FUNCTION                                               RELEASE        */
9886 /*                                                                        */
9887 /*    _nxe_web_http_server_callback_generate_response_header_extended     */
9888 /*                                                        PORTABLE C      */
9889 /*                                                           6.1          */
9890 /*  AUTHOR                                                                */
9891 /*                                                                        */
9892 /*    Yuxin Zhou, Microsoft Corporation                                   */
9893 /*                                                                        */
9894 /*  DESCRIPTION                                                           */
9895 /*                                                                        */
9896 /*    This function checks error for generating HTTP response header.     */
9897 /*                                                                        */
9898 /*  INPUT                                                                 */
9899 /*                                                                        */
9900 /*    server_ptr                            Pointer to HTTP server        */
9901 /*    packet_pptr                           Pointer to packet             */
9902 /*    status_code                           Status-code and reason-phrase */
9903 /*    status_code_length                    Length of status-code         */
9904 /*    content_length                        Length of content             */
9905 /*    content_type                          Type of content               */
9906 /*    content_type_length                   Length of content type        */
9907 /*    additional_header                     Other HTTP headers            */
9908 /*    additional_header_length              Length of other HTTP headers  */
9909 /*                                                                        */
9910 /*  OUTPUT                                                                */
9911 /*                                                                        */
9912 /*    status                                Completion status             */
9913 /*                                                                        */
9914 /*  CALLS                                                                 */
9915 /*                                                                        */
9916 /*    _nx_web_http_server_callback_generate_response_header_extended      */
9917 /*                                          Actual generate header        */
9918 /*                                                                        */
9919 /*  CALLED BY                                                             */
9920 /*                                                                        */
9921 /*    Application Code                                                    */
9922 /*                                                                        */
9923 /*  RELEASE HISTORY                                                       */
9924 /*                                                                        */
9925 /*    DATE              NAME                      DESCRIPTION             */
9926 /*                                                                        */
9927 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9928 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9929 /*                                            resulting in version 6.1    */
9930 /*                                                                        */
9931 /**************************************************************************/
_nxe_web_http_server_callback_generate_response_header_extended(NX_WEB_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)9932 UINT  _nxe_web_http_server_callback_generate_response_header_extended(NX_WEB_HTTP_SERVER *server_ptr,
9933                                                                       NX_PACKET **packet_pptr, CHAR *status_code,
9934                                                                       UINT status_code_length, UINT content_length,
9935                                                                       CHAR *content_type, UINT content_type_length,
9936                                                                       CHAR *additional_header, UINT additional_header_length)
9937 {
9938 
9939     /* Check for invalid input pointers.  */
9940     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) ||
9941         (packet_pptr == NX_NULL) || (status_code == NX_NULL))
9942         return(NX_PTR_ERROR);
9943 
9944     /* Check for appropriate caller.  */
9945     NX_THREADS_ONLY_CALLER_CHECKING
9946 
9947     return _nx_web_http_server_callback_generate_response_header_extended(server_ptr, packet_pptr, status_code,
9948                                                                           status_code_length, content_length,
9949                                                                           content_type, content_type_length,
9950                                                                           additional_header, additional_header_length);
9951 }
9952 
9953 
9954 /**************************************************************************/
9955 /*                                                                        */
9956 /*  FUNCTION                                               RELEASE        */
9957 /*                                                                        */
9958 /*    _nx_web_http_server_callback_generate_response_header_extended      */
9959 /*                                                        PORTABLE C      */
9960 /*                                                           6.1          */
9961 /*  AUTHOR                                                                */
9962 /*                                                                        */
9963 /*    Yuxin Zhou, Microsoft Corporation                                   */
9964 /*                                                                        */
9965 /*  DESCRIPTION                                                           */
9966 /*                                                                        */
9967 /*    This function is used in callback function to generate HTTP         */
9968 /*    response header.                                                    */
9969 /*                                                                        */
9970 /*    Note: The strings of status_code, content_type and additional_header*/
9971 /*    must be NULL-terminated and length of each string matches the       */
9972 /*    length specified in the argument list.                              */
9973 /*                                                                        */
9974 /*  INPUT                                                                 */
9975 /*                                                                        */
9976 /*    server_ptr                            Pointer to HTTP server        */
9977 /*    packet_pptr                           Pointer to packet             */
9978 /*    status_code                           Status-code and reason-phrase */
9979 /*    status_code_length                    Length of status-code         */
9980 /*    content_length                        Length of content             */
9981 /*    content_type                          Type of content               */
9982 /*    content_type_length                   Length of content type        */
9983 /*    additional_header                     Other HTTP headers            */
9984 /*    additional_header_length              Length of other HTTP headers  */
9985 /*                                                                        */
9986 /*  OUTPUT                                                                */
9987 /*                                                                        */
9988 /*    status                                Completion status             */
9989 /*                                                                        */
9990 /*  CALLS                                                                 */
9991 /*                                                                        */
9992 /*    _nx_web_http_server_generate_response_header                        */
9993 /*                                          Generate response header      */
9994 /*    _nx_utility_string_length_check       Check string length           */
9995 /*                                                                        */
9996 /*  CALLED BY                                                             */
9997 /*                                                                        */
9998 /*    Application Code                                                    */
9999 /*                                                                        */
10000 /*  RELEASE HISTORY                                                       */
10001 /*                                                                        */
10002 /*    DATE              NAME                      DESCRIPTION             */
10003 /*                                                                        */
10004 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10005 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10006 /*                                            resulting in version 6.1    */
10007 /*                                                                        */
10008 /**************************************************************************/
_nx_web_http_server_callback_generate_response_header_extended(NX_WEB_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)10009 UINT  _nx_web_http_server_callback_generate_response_header_extended(NX_WEB_HTTP_SERVER *server_ptr,
10010                                                                      NX_PACKET **packet_pptr, CHAR *status_code,
10011                                                                      UINT status_code_length, UINT content_length,
10012                                                                      CHAR *content_type, UINT content_type_length,
10013                                                                      CHAR *additional_header, UINT additional_header_length)
10014 {
10015 UINT temp_status_code_length = 0;
10016 UINT temp_content_type_length = 0;
10017 UINT temp_add_header_length = 0;
10018 
10019     /* Check status code, content type and additional header length.  */
10020     if (_nx_utility_string_length_check(status_code, &temp_status_code_length, status_code_length) ||
10021         (content_type && _nx_utility_string_length_check(content_type, &temp_content_type_length, content_type_length)) ||
10022         (additional_header &&  _nx_utility_string_length_check(additional_header, &temp_add_header_length, additional_header_length)))
10023     {
10024         return(NX_WEB_HTTP_ERROR);
10025     }
10026 
10027     /* Validate string length.  */
10028     if ((status_code_length != temp_status_code_length) ||
10029         (content_type && content_type_length != temp_content_type_length) ||
10030         (additional_header && additional_header_length != temp_add_header_length))
10031     {
10032         return(NX_WEB_HTTP_ERROR);
10033     }
10034 
10035     /* Call the internal HTTP response send function.  */
10036     return _nx_web_http_server_generate_response_header(server_ptr, packet_pptr, status_code,
10037                                                         status_code_length, content_length,
10038                                                         content_type, content_type_length,
10039                                                         additional_header, additional_header_length);
10040 }
10041 
10042 
10043 /**************************************************************************/
10044 /*                                                                        */
10045 /*  FUNCTION                                               RELEASE        */
10046 /*                                                                        */
10047 /*    _nxe_web_http_server_callback_packet_send           PORTABLE C      */
10048 /*                                                           6.1          */
10049 /*  AUTHOR                                                                */
10050 /*                                                                        */
10051 /*    Yuxin Zhou, Microsoft Corporation                                   */
10052 /*                                                                        */
10053 /*  DESCRIPTION                                                           */
10054 /*                                                                        */
10055 /*    This function checks error for sending a packet.                    */
10056 /*                                                                        */
10057 /*  INPUT                                                                 */
10058 /*                                                                        */
10059 /*    server_ptr                            Pointer to HTTP server        */
10060 /*    packet_ptr                            Pointer to packet             */
10061 /*                                                                        */
10062 /*  OUTPUT                                                                */
10063 /*                                                                        */
10064 /*    status                                Completion status             */
10065 /*                                                                        */
10066 /*  CALLS                                                                 */
10067 /*                                                                        */
10068 /*    _nx_web_http_server_callback_packet_send                            */
10069 /*                                                                        */
10070 /*  CALLED BY                                                             */
10071 /*                                                                        */
10072 /*    Application Code                                                    */
10073 /*                                                                        */
10074 /*  RELEASE HISTORY                                                       */
10075 /*                                                                        */
10076 /*    DATE              NAME                      DESCRIPTION             */
10077 /*                                                                        */
10078 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10079 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10080 /*                                            resulting in version 6.1    */
10081 /*                                                                        */
10082 /**************************************************************************/
_nxe_web_http_server_callback_packet_send(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr)10083 UINT  _nxe_web_http_server_callback_packet_send(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr)
10084 {
10085 
10086     /* Check for invalid input pointers.  */
10087     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) || (packet_ptr == NX_NULL))
10088         return(NX_PTR_ERROR);
10089 
10090     return _nx_web_http_server_callback_packet_send(server_ptr, packet_ptr);
10091 }
10092 
10093 
10094 /**************************************************************************/
10095 /*                                                                        */
10096 /*  FUNCTION                                               RELEASE        */
10097 /*                                                                        */
10098 /*    _nx_web_http_server_callback_packet_send            PORTABLE C      */
10099 /*                                                           6.1          */
10100 /*  AUTHOR                                                                */
10101 /*                                                                        */
10102 /*    Yuxin Zhou, Microsoft Corporation                                   */
10103 /*                                                                        */
10104 /*  DESCRIPTION                                                           */
10105 /*                                                                        */
10106 /*    This function is used in callback function to send a packet.        */
10107 /*                                                                        */
10108 /*  INPUT                                                                 */
10109 /*                                                                        */
10110 /*    server_ptr                            Pointer to HTTP server        */
10111 /*    packet_ptr                            Pointer to packet             */
10112 /*                                                                        */
10113 /*  OUTPUT                                                                */
10114 /*                                                                        */
10115 /*    status                                Completion status             */
10116 /*                                                                        */
10117 /*  CALLS                                                                 */
10118 /*                                                                        */
10119 /*    _nx_web_http_server_send              Send packet to client         */
10120 /*    nx_packet_data_append                 Append packet data            */
10121 /*                                                                        */
10122 /*  CALLED BY                                                             */
10123 /*                                                                        */
10124 /*    Application Code                                                    */
10125 /*                                                                        */
10126 /*  RELEASE HISTORY                                                       */
10127 /*                                                                        */
10128 /*    DATE              NAME                      DESCRIPTION             */
10129 /*                                                                        */
10130 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10131 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10132 /*                                            resulting in version 6.1    */
10133 /*                                                                        */
10134 /**************************************************************************/
_nx_web_http_server_callback_packet_send(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr)10135 UINT  _nx_web_http_server_callback_packet_send(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr)
10136 {
10137 UINT status;
10138 CHAR crlf[2] = {13,10};
10139 UINT length = packet_ptr -> nx_packet_length;
10140 
10141     /* If the request is chunked, add CRLF at the end of the chunk.  */
10142     if (server_ptr -> nx_web_http_server_response_chunked)
10143     {
10144 
10145         /* Check the packet length.  */
10146         if (server_ptr -> nx_web_http_server_expect_transfer_bytes < (server_ptr -> nx_web_http_server_actual_bytes_transferred + length))
10147         {
10148             return(NX_INVALID_PACKET);
10149         }
10150 
10151         if (server_ptr -> nx_web_http_server_expect_transfer_bytes == (server_ptr -> nx_web_http_server_actual_bytes_transferred + length))
10152         {
10153 
10154             /* Place an extra CRLF to signal the end of the chunk.  */
10155             nx_packet_data_append(packet_ptr, crlf, 2, server_ptr -> nx_web_http_server_packet_pool_ptr, NX_WAIT_FOREVER);
10156         }
10157 
10158         /* Update the transferred bytes.  */
10159         server_ptr -> nx_web_http_server_actual_bytes_transferred += length;
10160     }
10161 
10162     /* Send internal. */
10163     status = _nx_web_http_server_send(server_ptr, packet_ptr, NX_WEB_HTTP_SERVER_TIMEOUT_SEND);
10164     if (status)
10165     {
10166         return(status);
10167     }
10168 
10169     return(NX_SUCCESS);
10170 }
10171 
10172 
10173 /**************************************************************************/
10174 /*                                                                        */
10175 /*  FUNCTION                                               RELEASE        */
10176 /*                                                                        */
10177 /*    _nxe_web_http_server_gmt_callback_set               PORTABLE C      */
10178 /*                                                           6.1          */
10179 /*  AUTHOR                                                                */
10180 /*                                                                        */
10181 /*    Yuxin Zhou, Microsoft Corporation                                   */
10182 /*                                                                        */
10183 /*  DESCRIPTION                                                           */
10184 /*                                                                        */
10185 /*    This function checks error for setting gmt callback function.       */
10186 /*                                                                        */
10187 /*  INPUT                                                                 */
10188 /*                                                                        */
10189 /*    server_ptr                            Pointer to HTTP server        */
10190 /*    gmt_get                               Pointer to application's      */
10191 /*                                            GMT time function           */
10192 /*                                                                        */
10193 /*  OUTPUT                                                                */
10194 /*                                                                        */
10195 /*    status                                Completion status             */
10196 /*                                                                        */
10197 /*  CALLS                                                                 */
10198 /*                                                                        */
10199 /*    _nx_web_http_server_gmt_callback_set                                */
10200 /*                                                                        */
10201 /*  CALLED BY                                                             */
10202 /*                                                                        */
10203 /*    Application Code                                                    */
10204 /*                                                                        */
10205 /*  RELEASE HISTORY                                                       */
10206 /*                                                                        */
10207 /*    DATE              NAME                      DESCRIPTION             */
10208 /*                                                                        */
10209 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10210 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10211 /*                                            resulting in version 6.1    */
10212 /*                                                                        */
10213 /**************************************************************************/
_nxe_web_http_server_gmt_callback_set(NX_WEB_HTTP_SERVER * server_ptr,VOID (* gmt_get)(NX_WEB_HTTP_SERVER_DATE *))10214 UINT  _nxe_web_http_server_gmt_callback_set(NX_WEB_HTTP_SERVER *server_ptr, VOID (*gmt_get)(NX_WEB_HTTP_SERVER_DATE *))
10215 {
10216 
10217     /* Check for invalid input pointers.  */
10218     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) || (gmt_get == NX_NULL))
10219         return(NX_PTR_ERROR);
10220 
10221     /* Send internal. */
10222     return _nx_web_http_server_gmt_callback_set(server_ptr, gmt_get);
10223 }
10224 
10225 
10226 /**************************************************************************/
10227 /*                                                                        */
10228 /*  FUNCTION                                               RELEASE        */
10229 /*                                                                        */
10230 /*    _nx_web_http_server_gmt_callback_set                PORTABLE C      */
10231 /*                                                           6.1          */
10232 /*  AUTHOR                                                                */
10233 /*                                                                        */
10234 /*    Yuxin Zhou, Microsoft Corporation                                   */
10235 /*                                                                        */
10236 /*  DESCRIPTION                                                           */
10237 /*                                                                        */
10238 /*    This function sets gmt callback function.                           */
10239 /*                                                                        */
10240 /*  INPUT                                                                 */
10241 /*                                                                        */
10242 /*    server_ptr                            Pointer to HTTP server        */
10243 /*    gmt_get                               Pointer to application's      */
10244 /*                                            GMT time function           */
10245 /*                                                                        */
10246 /*  OUTPUT                                                                */
10247 /*                                                                        */
10248 /*    status                                Completion status             */
10249 /*                                                                        */
10250 /*  CALLS                                                                 */
10251 /*                                                                        */
10252 /*                                                                        */
10253 /*  CALLED BY                                                             */
10254 /*                                                                        */
10255 /*    Application Code                                                    */
10256 /*                                                                        */
10257 /*  RELEASE HISTORY                                                       */
10258 /*                                                                        */
10259 /*    DATE              NAME                      DESCRIPTION             */
10260 /*                                                                        */
10261 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10262 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10263 /*                                            resulting in version 6.1    */
10264 /*                                                                        */
10265 /**************************************************************************/
_nx_web_http_server_gmt_callback_set(NX_WEB_HTTP_SERVER * server_ptr,VOID (* gmt_get)(NX_WEB_HTTP_SERVER_DATE *))10266 UINT  _nx_web_http_server_gmt_callback_set(NX_WEB_HTTP_SERVER *server_ptr, VOID (*gmt_get)(NX_WEB_HTTP_SERVER_DATE *))
10267 {
10268 
10269 TX_INTERRUPT_SAVE_AREA
10270 
10271     /* Lockout interrupts.  */
10272     TX_DISABLE
10273 
10274     /* Set the function pointer. */
10275     server_ptr -> nx_web_http_server_gmt_get = gmt_get;
10276 
10277     /* Restore interrupts.  */
10278     TX_RESTORE
10279 
10280     return NX_SUCCESS;
10281 }
10282 
10283 
10284 /**************************************************************************/
10285 /*                                                                        */
10286 /*  FUNCTION                                               RELEASE        */
10287 /*                                                                        */
10288 /*    _nxe_web_http_server_cache_info_callback_set        PORTABLE C      */
10289 /*                                                           6.1          */
10290 /*  AUTHOR                                                                */
10291 /*                                                                        */
10292 /*    Yuxin Zhou, Microsoft Corporation                                   */
10293 /*                                                                        */
10294 /*  DESCRIPTION                                                           */
10295 /*                                                                        */
10296 /*    This function checks error for setting cache info callback function.*/
10297 /*                                                                        */
10298 /*  INPUT                                                                 */
10299 /*                                                                        */
10300 /*    server_ptr                            Pointer to HTTP server        */
10301 /*    cache_info_get                        Pointer to application's      */
10302 /*                                            cache information function  */
10303 /*                                                                        */
10304 /*  OUTPUT                                                                */
10305 /*                                                                        */
10306 /*    status                                Completion status             */
10307 /*                                                                        */
10308 /*  CALLS                                                                 */
10309 /*                                                                        */
10310 /*    _nx_web_http_server_cache_info_callback_set                         */
10311 /*                                                                        */
10312 /*  CALLED BY                                                             */
10313 /*                                                                        */
10314 /*    Application Code                                                    */
10315 /*                                                                        */
10316 /*  RELEASE HISTORY                                                       */
10317 /*                                                                        */
10318 /*    DATE              NAME                      DESCRIPTION             */
10319 /*                                                                        */
10320 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10321 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10322 /*                                            resulting in version 6.1    */
10323 /*                                                                        */
10324 /**************************************************************************/
_nxe_web_http_server_cache_info_callback_set(NX_WEB_HTTP_SERVER * server_ptr,UINT (* cache_info_get)(CHAR *,UINT *,NX_WEB_HTTP_SERVER_DATE *))10325 UINT  _nxe_web_http_server_cache_info_callback_set(NX_WEB_HTTP_SERVER *server_ptr, UINT (*cache_info_get)(CHAR *, UINT *, NX_WEB_HTTP_SERVER_DATE *))
10326 {
10327 
10328     /* Check for invalid input pointers.  */
10329     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) || (cache_info_get == NX_NULL))
10330         return(NX_PTR_ERROR);
10331 
10332     /* Send internal. */
10333     return _nx_web_http_server_cache_info_callback_set(server_ptr, cache_info_get);
10334 }
10335 
10336 
10337 /**************************************************************************/
10338 /*                                                                        */
10339 /*  FUNCTION                                               RELEASE        */
10340 /*                                                                        */
10341 /*    _nx_web_http_server_cache_info_callback_set         PORTABLE C      */
10342 /*                                                           6.1          */
10343 /*  AUTHOR                                                                */
10344 /*                                                                        */
10345 /*    Yuxin Zhou, Microsoft Corporation                                   */
10346 /*                                                                        */
10347 /*  DESCRIPTION                                                           */
10348 /*                                                                        */
10349 /*    This function sets cache info callback function.                    */
10350 /*                                                                        */
10351 /*    Note: The string resource in callback functions authentication_check*/
10352 /*    and request_notify is built by internal logic and always            */
10353 /*    NULL-terminated.                                                    */
10354 /*                                                                        */
10355 /*  INPUT                                                                 */
10356 /*                                                                        */
10357 /*    server_ptr                            Pointer to HTTP server        */
10358 /*    cache_info_get                        Pointer to application's      */
10359 /*                                            cache information function  */
10360 /*                                                                        */
10361 /*  OUTPUT                                                                */
10362 /*                                                                        */
10363 /*    status                                Completion status             */
10364 /*                                                                        */
10365 /*  CALLS                                                                 */
10366 /*                                                                        */
10367 /*    None                                                                */
10368 /*                                                                        */
10369 /*  CALLED BY                                                             */
10370 /*                                                                        */
10371 /*    Application Code                                                    */
10372 /*                                                                        */
10373 /*  RELEASE HISTORY                                                       */
10374 /*                                                                        */
10375 /*    DATE              NAME                      DESCRIPTION             */
10376 /*                                                                        */
10377 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10378 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10379 /*                                            resulting in version 6.1    */
10380 /*                                                                        */
10381 /**************************************************************************/
_nx_web_http_server_cache_info_callback_set(NX_WEB_HTTP_SERVER * server_ptr,UINT (* cache_info_get)(CHAR *,UINT *,NX_WEB_HTTP_SERVER_DATE *))10382 UINT  _nx_web_http_server_cache_info_callback_set(NX_WEB_HTTP_SERVER *server_ptr, UINT (*cache_info_get)(CHAR *, UINT *, NX_WEB_HTTP_SERVER_DATE *))
10383 {
10384 
10385 TX_INTERRUPT_SAVE_AREA
10386 
10387     /* Lockout interrupts.  */
10388     TX_DISABLE
10389 
10390     /* Set the function pointer. */
10391     server_ptr -> nx_web_http_server_cache_info_get = cache_info_get;
10392 
10393     /* Restore interrupts.  */
10394     TX_RESTORE
10395 
10396     return NX_SUCCESS;
10397 }
10398 
10399 
10400 /**************************************************************************/
10401 /*                                                                        */
10402 /*  FUNCTION                                               RELEASE        */
10403 /*                                                                        */
10404 /*    _nx_web_http_server_date_to_string                  PORTABLE C      */
10405 /*                                                           6.1          */
10406 /*  AUTHOR                                                                */
10407 /*                                                                        */
10408 /*    Yuxin Zhou, Microsoft Corporation                                   */
10409 /*                                                                        */
10410 /*  DESCRIPTION                                                           */
10411 /*                                                                        */
10412 /*    This function converts from date to string.                         */
10413 /*                                                                        */
10414 /*  INPUT                                                                 */
10415 /*                                                                        */
10416 /*    date                                  Pointer to HTTP date          */
10417 /*    string                                Pointer to output buffer      */
10418 /*                                                                        */
10419 /*  OUTPUT                                                                */
10420 /*                                                                        */
10421 /*    status                                Completion status             */
10422 /*                                                                        */
10423 /*  CALLS                                                                 */
10424 /*                                                                        */
10425 /*    _nx_web_http_server_date_convert                                    */
10426 /*                                                                        */
10427 /*  CALLED BY                                                             */
10428 /*                                                                        */
10429 /*    _nx_web_http_server_get_process                                     */
10430 /*    _nx_web_http_server_generate_response_header                        */
10431 /*                                                                        */
10432 /*  RELEASE HISTORY                                                       */
10433 /*                                                                        */
10434 /*    DATE              NAME                      DESCRIPTION             */
10435 /*                                                                        */
10436 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10437 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10438 /*                                            resulting in version 6.1    */
10439 /*                                                                        */
10440 /**************************************************************************/
_nx_web_http_server_date_to_string(NX_WEB_HTTP_SERVER_DATE * date,CHAR * string)10441 UINT  _nx_web_http_server_date_to_string(NX_WEB_HTTP_SERVER_DATE *date, CHAR *string)
10442 {
10443 
10444 UINT index = 0;
10445 
10446     /* RDC1122-date. */
10447     /* Append weekday. */
10448     string[index++] = _nx_web_http_server_weekday[date -> nx_web_http_server_weekday][0];
10449     string[index++] = _nx_web_http_server_weekday[date -> nx_web_http_server_weekday][1];
10450     string[index++] = _nx_web_http_server_weekday[date -> nx_web_http_server_weekday][2];
10451     string[index++] = ',';
10452     string[index++] = ' ';
10453 
10454     /* Convert and append day. */
10455     _nx_web_http_server_date_convert(date -> nx_web_http_server_day, 2, &string[index]);
10456     index += 2;
10457     string[index++] = ' ';
10458 
10459     /* Append month. */
10460     string[index++] = _nx_web_http_server_month[date -> nx_web_http_server_month][0];
10461     string[index++] = _nx_web_http_server_month[date -> nx_web_http_server_month][1];
10462     string[index++] = _nx_web_http_server_month[date -> nx_web_http_server_month][2];
10463     string[index++] = ' ';
10464 
10465     /* Convert and append year. */
10466     _nx_web_http_server_date_convert(date -> nx_web_http_server_year, 4, &string[index]);
10467     index += 4;
10468     string[index++] = ' ';
10469 
10470     /* Convert and append hour. */
10471     _nx_web_http_server_date_convert(date -> nx_web_http_server_hour, 2, &string[index]);
10472     index += 2;
10473     string[index++] = ':';
10474 
10475     /* Convert and append minute. */
10476     _nx_web_http_server_date_convert(date -> nx_web_http_server_minute, 2, &string[index]);
10477     index += 2;
10478     string[index++] = ':';
10479 
10480     /* Convert and append second. */
10481     _nx_web_http_server_date_convert(date -> nx_web_http_server_second, 2, &string[index]);
10482     index += 2;
10483     string[index++] = ' ';
10484     string[index++] = 'G';
10485     string[index++] = 'M';
10486     string[index++] = 'T';
10487 
10488     return index;
10489 }
10490 
10491 
10492 /**************************************************************************/
10493 /*                                                                        */
10494 /*  FUNCTION                                               RELEASE        */
10495 /*                                                                        */
10496 /*    _nx_web_http_server_date_convert                    PORTABLE C      */
10497 /*                                                           6.1          */
10498 /*  AUTHOR                                                                */
10499 /*                                                                        */
10500 /*    Yuxin Zhou, Microsoft Corporation                                   */
10501 /*                                                                        */
10502 /*  DESCRIPTION                                                           */
10503 /*                                                                        */
10504 /*    This function converts a date from number to string.                */
10505 /*                                                                        */
10506 /*  INPUT                                                                 */
10507 /*                                                                        */
10508 /*    date                                  The number to convert         */
10509 /*    count                                 Digital count for string      */
10510 /*    string                                Pointer to output buffer      */
10511 /*                                                                        */
10512 /*  OUTPUT                                                                */
10513 /*                                                                        */
10514 /*    None                                                                */
10515 /*                                                                        */
10516 /*  CALLS                                                                 */
10517 /*                                                                        */
10518 /*                                                                        */
10519 /*  CALLED BY                                                             */
10520 /*                                                                        */
10521 /*    _nx_web_http_server_date_to_string                                  */
10522 /*                                                                        */
10523 /*  RELEASE HISTORY                                                       */
10524 /*                                                                        */
10525 /*    DATE              NAME                      DESCRIPTION             */
10526 /*                                                                        */
10527 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10528 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10529 /*                                            resulting in version 6.1    */
10530 /*                                                                        */
10531 /**************************************************************************/
_nx_web_http_server_date_convert(UINT date,UINT count,CHAR * string)10532 VOID  _nx_web_http_server_date_convert(UINT date, UINT count, CHAR *string)
10533 {
10534 
10535 UINT    digit;
10536 
10537     /* Initialize all 4 bytes to digit 0. */
10538     *((ULONG*)string) = 0x30303030;
10539     string[count] = 0;
10540 
10541     /* Loop to convert the number to ASCII.  */
10542     while(count > 0)
10543     {
10544         count--;
10545 
10546         /* Compute the next decimal digit.  */
10547         digit =  date % 10;
10548 
10549         /* Update the input date.  */
10550         date =  date / 10;
10551 
10552         /* Store the new digit in ASCII form.  */
10553         string[count] =  (CHAR) (digit + 0x30);
10554     }
10555 }
10556 
10557 
10558 /**************************************************************************/
10559 /*                                                                        */
10560 /*  FUNCTION                                               RELEASE        */
10561 /*                                                                        */
10562 /*    _nxe_web_http_server_mime_maps_additional_set       PORTABLE C      */
10563 /*                                                           6.1          */
10564 /*  AUTHOR                                                                */
10565 /*                                                                        */
10566 /*    Yuxin Zhou, Microsoft Corporation                                   */
10567 /*                                                                        */
10568 /*  DESCRIPTION                                                           */
10569 /*                                                                        */
10570 /*    This function checks error for setting additional MIME maps.        */
10571 /*                                                                        */
10572 /*  INPUT                                                                 */
10573 /*                                                                        */
10574 /*    server_ptr                            Pointer to HTTP server        */
10575 /*    mime_maps                             Pointer MIME map array        */
10576 /*    mime_maps_num                         Number of MIME map array      */
10577 /*                                                                        */
10578 /*  OUTPUT                                                                */
10579 /*                                                                        */
10580 /*    status                                Completion status             */
10581 /*                                                                        */
10582 /*  CALLS                                                                 */
10583 /*                                                                        */
10584 /*    _nx_web_http_server_mime_maps_additional_set                        */
10585 /*                                                                        */
10586 /*  CALLED BY                                                             */
10587 /*                                                                        */
10588 /*    Application Code                                                    */
10589 /*                                                                        */
10590 /*  RELEASE HISTORY                                                       */
10591 /*                                                                        */
10592 /*    DATE              NAME                      DESCRIPTION             */
10593 /*                                                                        */
10594 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10595 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10596 /*                                            resulting in version 6.1    */
10597 /*                                                                        */
10598 /**************************************************************************/
_nxe_web_http_server_mime_maps_additional_set(NX_WEB_HTTP_SERVER * server_ptr,NX_WEB_HTTP_SERVER_MIME_MAP * mime_maps,UINT mime_maps_num)10599 UINT  _nxe_web_http_server_mime_maps_additional_set(NX_WEB_HTTP_SERVER *server_ptr, NX_WEB_HTTP_SERVER_MIME_MAP *mime_maps, UINT mime_maps_num)
10600 {
10601 
10602     /* Check for invalid input pointers.  */
10603     if ((server_ptr == NX_NULL) || (server_ptr -> nx_web_http_server_id != NX_WEB_HTTP_SERVER_ID) || (mime_maps == NX_NULL))
10604         return(NX_PTR_ERROR);
10605 
10606     /* Send internal. */
10607     return _nx_web_http_server_mime_maps_additional_set(server_ptr, mime_maps, mime_maps_num);
10608 }
10609 
10610 
10611 /**************************************************************************/
10612 /*                                                                        */
10613 /*  FUNCTION                                               RELEASE        */
10614 /*                                                                        */
10615 /*    _nx_web_http_server_mime_maps_additional_set        PORTABLE C      */
10616 /*                                                           6.1          */
10617 /*  AUTHOR                                                                */
10618 /*                                                                        */
10619 /*    Yuxin Zhou, Microsoft Corporation                                   */
10620 /*                                                                        */
10621 /*  DESCRIPTION                                                           */
10622 /*                                                                        */
10623 /*    This function sets additional MIME maps.                            */
10624 /*                                                                        */
10625 /*  INPUT                                                                 */
10626 /*                                                                        */
10627 /*    server_ptr                            Pointer to HTTP server        */
10628 /*    mime_maps                             Pointer MIME map array        */
10629 /*    mime_maps_num                         Number of MIME map array      */
10630 /*                                                                        */
10631 /*  OUTPUT                                                                */
10632 /*                                                                        */
10633 /*    status                                Completion status             */
10634 /*                                                                        */
10635 /*  CALLS                                                                 */
10636 /*                                                                        */
10637 /*                                                                        */
10638 /*  CALLED BY                                                             */
10639 /*                                                                        */
10640 /*    Application Code                                                    */
10641 /*                                                                        */
10642 /*  RELEASE HISTORY                                                       */
10643 /*                                                                        */
10644 /*    DATE              NAME                      DESCRIPTION             */
10645 /*                                                                        */
10646 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10647 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10648 /*                                            resulting in version 6.1    */
10649 /*                                                                        */
10650 /**************************************************************************/
_nx_web_http_server_mime_maps_additional_set(NX_WEB_HTTP_SERVER * server_ptr,NX_WEB_HTTP_SERVER_MIME_MAP * mime_maps,UINT mime_maps_num)10651 UINT  _nx_web_http_server_mime_maps_additional_set(NX_WEB_HTTP_SERVER *server_ptr, NX_WEB_HTTP_SERVER_MIME_MAP *mime_maps, UINT mime_maps_num)
10652 {
10653 
10654 TX_INTERRUPT_SAVE_AREA
10655 
10656     /* Lockout interrupts.  */
10657     TX_DISABLE
10658 
10659     /* Set the mime maps. */
10660     server_ptr -> nx_web_http_server_mime_maps_additional = mime_maps;
10661     server_ptr -> nx_web_http_server_mime_maps_additional_num = mime_maps_num;
10662 
10663     /* Restore interrupts.  */
10664     TX_RESTORE
10665 
10666     return NX_SUCCESS;
10667 }
10668 
10669 #ifndef NX_WEB_HTTP_KEEPALIVE_DISABLE
10670 /**************************************************************************/
10671 /*                                                                        */
10672 /*  FUNCTION                                               RELEASE        */
10673 /*                                                                        */
10674 /*    _nx_web_http_server_get_client_keepalive            PORTABLE C      */
10675 /*                                                           6.1          */
10676 /*  AUTHOR                                                                */
10677 /*                                                                        */
10678 /*    Yuxin Zhou, Microsoft Corporation                                   */
10679 /*                                                                        */
10680 /*  DESCRIPTION                                                           */
10681 /*                                                                        */
10682 /*    This function indicates whether this connection will keep alive.    */
10683 /*                                                                        */
10684 /*  INPUT                                                                 */
10685 /*                                                                        */
10686 /*    server_ptr                            Pointer to HTTP server        */
10687 /*    packet_ptr                            Pointer to packet             */
10688 /*                                                                        */
10689 /*  OUTPUT                                                                */
10690 /*                                                                        */
10691 /*    None                                                                */
10692 /*                                                                        */
10693 /*  CALLS                                                                 */
10694 /*                                                                        */
10695 /*    _nx_web_http_server_field_value_get   Get field value               */
10696 /*    _nx_web_http_server_memicmp           Compare two strings           */
10697 /*    _nx_utility_string_length_check       Check string length           */
10698 /*                                                                        */
10699 /*  CALLED BY                                                             */
10700 /*                                                                        */
10701 /*    _nx_web_http_server_receive_data                                    */
10702 /*                                                                        */
10703 /*  RELEASE HISTORY                                                       */
10704 /*                                                                        */
10705 /*    DATE              NAME                      DESCRIPTION             */
10706 /*                                                                        */
10707 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10708 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10709 /*                                            resulting in version 6.1    */
10710 /*                                                                        */
10711 /**************************************************************************/
_nx_web_http_server_get_client_keepalive(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr)10712 VOID  _nx_web_http_server_get_client_keepalive(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr)
10713 {
10714 UCHAR   *ch;
10715 UINT    version = 0;
10716 UCHAR   connection_value[16];
10717 UINT    connection_value_length;
10718 
10719 
10720     /* Locate to HTTP version. */
10721     ch = packet_ptr -> nx_packet_prepend_ptr;
10722     while(ch + 11 < packet_ptr -> nx_packet_append_ptr)
10723     {
10724         if((*ch == ' ') &&
10725            (*(ch + 1) == 'H') &&
10726            (*(ch + 2) == 'T') &&
10727            (*(ch + 3) == 'T') &&
10728            (*(ch + 4) == 'P') &&
10729            (*(ch + 5) == '/'))
10730         {
10731 
10732             /* Find the HTTP version. */
10733             ch += 6;
10734             if((*ch >= '0') &&
10735                (*ch <= '9') &&
10736                (*(ch + 1) == '.') &&
10737                (*(ch + 2) >= '0') &&
10738                (*(ch + 2) <= '9'))
10739             {
10740 
10741                 /* Get the version. */
10742                 version = (UCHAR)((*ch - '0') << 4) | (UCHAR)(*(ch + 2) - '0');
10743             }
10744 
10745             break;
10746         }
10747         else if((*ch == 13) && (*(ch + 1) == 10))
10748         {
10749 
10750             /* Find the end of line. */
10751             break;
10752         }
10753 
10754         /* Move to the next byte. */
10755         ch++;
10756     }
10757 
10758     /* Is a valid HTTP version found? */
10759     if(version == 0)
10760     {
10761         server_ptr -> nx_web_http_server_keepalive = NX_FALSE;
10762         return;
10763     }
10764 
10765     /* Initialize the keepalive flag. */
10766     if(version > 0x10)
10767         server_ptr -> nx_web_http_server_keepalive = NX_TRUE;
10768     else
10769         server_ptr -> nx_web_http_server_keepalive = NX_FALSE;
10770 
10771     /* Searching for 'connection' header. */
10772     if(_nx_web_http_server_field_value_get(packet_ptr, (UCHAR *)"connection", 10, connection_value, sizeof(connection_value)) == NX_SUCCESS)
10773     {
10774         _nx_utility_string_length_check((CHAR *)connection_value, &connection_value_length, sizeof(connection_value) - 1);
10775 
10776         if(_nx_web_http_server_memicmp(connection_value, connection_value_length, (UCHAR *)"keep-alive", 10) == NX_SUCCESS)
10777             server_ptr -> nx_web_http_server_keepalive = NX_TRUE;
10778         else if(_nx_web_http_server_memicmp(connection_value, connection_value_length, (UCHAR *)"close", 5) == NX_SUCCESS)
10779             server_ptr -> nx_web_http_server_keepalive = NX_FALSE;
10780     }
10781 }
10782 #endif /* NX_WEB_HTTP_KEEPALIVE_DISABLE */
10783 
10784 /**************************************************************************/
10785 /*                                                                        */
10786 /*  FUNCTION                                               RELEASE        */
10787 /*                                                                        */
10788 /*    _nx_web_http_server_send                            PORTABLE C      */
10789 /*                                                           6.1          */
10790 /*  AUTHOR                                                                */
10791 /*                                                                        */
10792 /*    Yuxin Zhou, Microsoft Corporation                                   */
10793 /*                                                                        */
10794 /*  DESCRIPTION                                                           */
10795 /*                                                                        */
10796 /*    This function sends data to the remote host using either the TCP    */
10797 /*    socket for plain HTTP or the TLS session for HTTPS.                 */
10798 /*                                                                        */
10799 /*                                                                        */
10800 /*  INPUT                                                                 */
10801 /*                                                                        */
10802 /*    server_ptr                            Pointer to HTTP server        */
10803 /*    packet_ptr                            Pointer to packet to send.    */
10804 /*    wait_option                           Indicates behavior if packet  */
10805 /*                                             cannot be sent.            */
10806 /*                                                                        */
10807 /*  OUTPUT                                                                */
10808 /*                                                                        */
10809 /*    status                                Completion status             */
10810 /*                                                                        */
10811 /*  CALLS                                                                 */
10812 /*                                                                        */
10813 /*    nx_secure_tls_session_send            Send data using TLS session   */
10814 /*    nx_secure_tcp_socket_send             Send data using TCP socket    */
10815 /*                                                                        */
10816 /*  CALLED BY                                                             */
10817 /*                                                                        */
10818 /*                                                                        */
10819 /*                                                                        */
10820 /*  RELEASE HISTORY                                                       */
10821 /*                                                                        */
10822 /*    DATE              NAME                      DESCRIPTION             */
10823 /*                                                                        */
10824 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10825 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10826 /*                                            resulting in version 6.1    */
10827 /*                                                                        */
10828 /**************************************************************************/
_nx_web_http_server_send(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET * packet_ptr,ULONG wait_option)10829 UINT  _nx_web_http_server_send(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET *packet_ptr, ULONG wait_option)
10830 {
10831 
10832 UINT        status;
10833 NX_TCP_SOCKET *tcp_socket;
10834 #ifdef NX_WEB_HTTPS_ENABLE
10835 NX_SECURE_TLS_SESSION *tls_session;
10836 #endif
10837 
10838     tcp_socket = &(server_ptr -> nx_web_http_server_current_session_ptr -> nx_tcp_session_socket);
10839 
10840 #ifdef NX_WEB_HTTPS_ENABLE
10841 
10842     tls_session = &(server_ptr -> nx_web_http_server_current_session_ptr -> nx_tcp_session_tls_session);
10843 
10844     /* End TLS session if using HTTPS. */
10845     if(server_ptr -> nx_web_http_is_https_server)
10846     {
10847         status = nx_secure_tls_session_send(tls_session, packet_ptr, wait_option);
10848     }
10849     else
10850 #endif
10851     {
10852         status = nx_tcp_socket_send(tcp_socket, packet_ptr, wait_option);
10853     }
10854 
10855     /* Return status.  */
10856     return(status);
10857 }
10858 
10859 
10860 /**************************************************************************/
10861 /*                                                                        */
10862 /*  FUNCTION                                               RELEASE        */
10863 /*                                                                        */
10864 /*    _nx_web_http_server_receive                         PORTABLE C      */
10865 /*                                                           6.1          */
10866 /*  AUTHOR                                                                */
10867 /*                                                                        */
10868 /*    Yuxin Zhou, Microsoft Corporation                                   */
10869 /*                                                                        */
10870 /*  DESCRIPTION                                                           */
10871 /*                                                                        */
10872 /*    This function receives data from the remote host using either the   */
10873 /*    TCP socket for plain HTTP or the TLS session for HTTPS.             */
10874 /*                                                                        */
10875 /*                                                                        */
10876 /*  INPUT                                                                 */
10877 /*                                                                        */
10878 /*    server_ptr                            Pointer to HTTP server        */
10879 /*    packet_ptr                            Pointer to packet to send.    */
10880 /*    wait_option                           Indicates behavior if packet  */
10881 /*                                             cannot be received         */
10882 /*                                                                        */
10883 /*  OUTPUT                                                                */
10884 /*                                                                        */
10885 /*    status                                Completion status             */
10886 /*                                                                        */
10887 /*  CALLS                                                                 */
10888 /*                                                                        */
10889 /*    nx_secure_tls_session_receive            Receive data using TLS     */
10890 /*    nx_secure_tcp_socket_receive             Receive data using TCP     */
10891 /*                                                                        */
10892 /*  CALLED BY                                                             */
10893 /*                                                                        */
10894 /*    _nx_web_http_server_packet_get       Get next packet from HTTP      */
10895 /*                                         server socket.                 */
10896 /*    _nx_web_http_server_get_client_request                              */
10897 /*                                         Get complete HTTP request      */
10898 /*    _nx_web_http_server_request_read     Get the next data in byte      */
10899 /*    _nx_web_http_server_chunked_size_get Get chunk size of the request  */
10900 /*                                                                        */
10901 /*  RELEASE HISTORY                                                       */
10902 /*                                                                        */
10903 /*    DATE              NAME                      DESCRIPTION             */
10904 /*                                                                        */
10905 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10906 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10907 /*                                            resulting in version 6.1    */
10908 /*                                                                        */
10909 /**************************************************************************/
_nx_web_http_server_receive(NX_WEB_HTTP_SERVER * server_ptr,NX_PACKET ** packet_ptr,ULONG wait_option)10910 UINT  _nx_web_http_server_receive(NX_WEB_HTTP_SERVER *server_ptr, NX_PACKET **packet_ptr, ULONG wait_option)
10911 {
10912 
10913 UINT        status;
10914 NX_TCP_SOCKET *tcp_socket;
10915 #ifdef NX_WEB_HTTPS_ENABLE
10916 NX_SECURE_TLS_SESSION *tls_session;
10917 #endif
10918 
10919     tcp_socket = &(server_ptr -> nx_web_http_server_current_session_ptr -> nx_tcp_session_socket);
10920 
10921 #ifdef NX_WEB_HTTPS_ENABLE
10922     tls_session = &(server_ptr -> nx_web_http_server_current_session_ptr -> nx_tcp_session_tls_session);
10923 
10924     /* End TLS session if using HTTPS. */
10925     if(server_ptr -> nx_web_http_is_https_server)
10926     {
10927         status = nx_secure_tls_session_receive(tls_session, packet_ptr, wait_option);
10928     }
10929     else
10930 #endif
10931     {
10932         status = nx_tcp_socket_receive(tcp_socket, packet_ptr, wait_option);
10933     }
10934 
10935     /* Return status.  */
10936     return(status);
10937 }
10938 
10939 
10940 /**************************************************************************/
10941 /*                                                                        */
10942 /*  FUNCTION                                               RELEASE        */
10943 /*                                                                        */
10944 /*    _nx_web_http_server_connection_reset                PORTABLE C      */
10945 /*                                                           6.1          */
10946 /*  AUTHOR                                                                */
10947 /*                                                                        */
10948 /*    Yuxin Zhou, Microsoft Corporation                                   */
10949 /*                                                                        */
10950 /*  DESCRIPTION                                                           */
10951 /*                                                                        */
10952 /*    This function is used whenever the HTTP server needs to close the   */
10953 /*    network connection and reset to receive new requests. If the server */
10954 /*    is using TLS for HTTPS, then it also ends the TLS session.          */
10955 /*                                                                        */
10956 /*                                                                        */
10957 /*  INPUT                                                                 */
10958 /*                                                                        */
10959 /*    server_ptr                            Pointer to HTTP server        */
10960 /*    session_ptr                           Pointer to session            */
10961 /*    error_number                          Error status in caller        */
10962 /*                                                                        */
10963 /*  OUTPUT                                                                */
10964 /*                                                                        */
10965 /*    status                                Completion status             */
10966 /*                                                                        */
10967 /*  CALLS                                                                 */
10968 /*                                                                        */
10969 /*    _nx_web_http_server_connection_disconnect                           */
10970 /*                                          End TLS session, and calls    */
10971 /*                                          Disconnect and unaccept on the*/
10972 /*                                          socket                        */
10973 /*    _nx_tcp_server_socket_relisten        Reset socket to accept another*/
10974 /*                                          connection                    */
10975 /*                                                                        */
10976 /*  CALLED BY                                                             */
10977 /*                                                                        */
10978 /*    Application code                                                    */
10979 /*                                                                        */
10980 /*  RELEASE HISTORY                                                       */
10981 /*                                                                        */
10982 /*    DATE              NAME                      DESCRIPTION             */
10983 /*                                                                        */
10984 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10985 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10986 /*                                            resulting in version 6.1    */
10987 /*                                                                        */
10988 /**************************************************************************/
_nx_web_http_server_connection_reset(NX_WEB_HTTP_SERVER * server_ptr,NX_TCP_SESSION * session_ptr,UINT wait_option)10989 VOID _nx_web_http_server_connection_reset(NX_WEB_HTTP_SERVER *server_ptr, NX_TCP_SESSION *session_ptr, UINT wait_option)
10990 {
10991 NX_TCP_SOCKET *tcp_socket;
10992 
10993 
10994     tcp_socket = &(session_ptr -> nx_tcp_session_socket);
10995 
10996     /* Disconnect the server connection. */
10997     _nx_web_http_server_connection_disconnect(server_ptr, session_ptr, wait_option);
10998 
10999     /* Relisten on the HTTP(S) Server port.  */
11000     nx_tcp_server_socket_relisten(server_ptr -> nx_web_http_server_ip_ptr, server_ptr -> nx_web_http_server_listen_port, tcp_socket);
11001 
11002 }
11003 
11004 
11005 /**************************************************************************/
11006 /*                                                                        */
11007 /*  FUNCTION                                               RELEASE        */
11008 /*                                                                        */
11009 /*    _nx_web_http_server_connection_disconnect           PORTABLE C      */
11010 /*                                                           6.2.0        */
11011 /*  AUTHOR                                                                */
11012 /*                                                                        */
11013 /*    Yuxin Zhou, Microsoft Corporation                                   */
11014 /*                                                                        */
11015 /*  DESCRIPTION                                                           */
11016 /*                                                                        */
11017 /*    This function is used whenever the HTTP server needs to close the   */
11018 /*    network connection completely. If the server is using TLS for HTTPS */
11019 /*    then it also ends the TLS session.                                  */
11020 /*                                                                        */
11021 /*                                                                        */
11022 /*  INPUT                                                                 */
11023 /*                                                                        */
11024 /*    server_ptr                            Pointer to HTTP server        */
11025 /*    session_ptr                           Pointer to session            */
11026 /*    wait_option                           Wait option for TCP socket    */
11027 /*                                                                        */
11028 /*  OUTPUT                                                                */
11029 /*                                                                        */
11030 /*    status                                Completion status             */
11031 /*                                                                        */
11032 /*  CALLS                                                                 */
11033 /*                                                                        */
11034 /*    _nx_secure_tls_session_end            End TLS session               */
11035 /*                                                                        */
11036 /*  CALLED BY                                                             */
11037 /*                                                                        */
11038 /*                                                                        */
11039 /*                                                                        */
11040 /*  RELEASE HISTORY                                                       */
11041 /*                                                                        */
11042 /*    DATE              NAME                      DESCRIPTION             */
11043 /*                                                                        */
11044 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11045 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11046 /*                                            resulting in version 6.1    */
11047 /*  10-31-2022     Yuxin Zhou               Modified comment(s), and      */
11048 /*                                            supported random nonce,     */
11049 /*                                            resulting in version 6.2.0  */
11050 /*                                                                        */
11051 /**************************************************************************/
_nx_web_http_server_connection_disconnect(NX_WEB_HTTP_SERVER * server_ptr,NX_TCP_SESSION * session_ptr,UINT wait_option)11052 VOID _nx_web_http_server_connection_disconnect(NX_WEB_HTTP_SERVER *server_ptr, NX_TCP_SESSION *session_ptr, UINT wait_option)
11053 {
11054 NX_TCP_SOCKET *tcp_socket;
11055 #ifdef NX_WEB_HTTPS_ENABLE
11056 NX_SECURE_TLS_SESSION *tls_session;
11057 #endif /* NX_WEB_HTTPS_ENABLE */
11058 #ifdef NX_WEB_HTTP_DIGEST_ENABLE
11059 UINT i;
11060 #endif /* NX_WEB_HTTP_DIGEST_ENABLE  */
11061 
11062 #ifndef NX_WEB_HTTPS_ENABLE
11063     NX_PARAMETER_NOT_USED(server_ptr);
11064     NX_PARAMETER_NOT_USED(wait_option);
11065 #endif /* NX_WEB_HTTPS_ENABLE */
11066 
11067 #ifdef NX_WEB_HTTP_DIGEST_ENABLE
11068 
11069     /* Once the nonce has been accepted, set the state as invalid. */
11070     for (i = 0; i < NX_WEB_HTTP_SERVER_NONCE_MAX; i++)
11071     {
11072         if ((server_ptr -> nx_web_http_server_nonces[i].nonce_state == NX_WEB_HTTP_SERVER_NONCE_ACCEPTED) &&
11073             (server_ptr -> nx_web_http_server_nonces[i].nonce_session_ptr == session_ptr))
11074         {
11075             server_ptr -> nx_web_http_server_nonces[i].nonce_state = NX_WEB_HTTP_SERVER_NONCE_INVALID;
11076             break;
11077         }
11078     }
11079 #endif /* NX_WEB_HTTP_DIGEST_ENABLE  */
11080 
11081     tcp_socket = &(session_ptr -> nx_tcp_session_socket);
11082 
11083 #ifdef NX_WEB_HTTPS_ENABLE
11084 
11085     tls_session = &(session_ptr -> nx_tcp_session_tls_session);
11086 
11087     /* End TLS session if using HTTPS. */
11088     if(server_ptr -> nx_web_http_is_https_server)
11089     {
11090         _nx_secure_tls_session_end(tls_session, wait_option);
11091     }
11092 #endif
11093 
11094     /* Disconnect from the current connection.  */
11095     nx_tcp_socket_disconnect(tcp_socket, NX_WEB_HTTP_SERVER_TIMEOUT_DISCONNECT);
11096 
11097     /* Unaccept the connection.  */
11098     nx_tcp_server_socket_unaccept(tcp_socket);
11099 
11100 }
11101 
11102 
11103 /**************************************************************************/
11104 /*                                                                        */
11105 /*  FUNCTION                                               RELEASE        */
11106 /*                                                                        */
11107 /*    _nxe_web_http_server_digest_authenticate_notify_set PORTABLE C      */
11108 /*                                                           6.1          */
11109 /*  AUTHOR                                                                */
11110 /*                                                                        */
11111 /*    Yuxin Zhou, Microsoft Corporation                                   */
11112 /*                                                                        */
11113 /*  DESCRIPTION                                                           */
11114 /*                                                                        */
11115 /*    This function performs error checking for service to set digest     */
11116 /*    authenticate callback function.                                     */
11117 /*                                                                        */
11118 /*  INPUT                                                                 */
11119 /*                                                                        */
11120 /*    http_server_ptr                       Pointer to HTTP server        */
11121 /*    digest_authenticate_callback          Pointer to application's      */
11122 /*                                          digest authenticate callback  */
11123 /*                                          function                      */
11124 /*                                                                        */
11125 /*  OUTPUT                                                                */
11126 /*                                                                        */
11127 /*    status                                Completion status             */
11128 /*                                                                        */
11129 /*  CALLS                                                                 */
11130 /*                                                                        */
11131 /*    _nx_web_http_server_digest_authenticate_notify_set                  */
11132 /*                                                                        */
11133 /*  CALLED BY                                                             */
11134 /*                                                                        */
11135 /*    Application Code                                                    */
11136 /*                                                                        */
11137 /*  RELEASE HISTORY                                                       */
11138 /*                                                                        */
11139 /*    DATE              NAME                      DESCRIPTION             */
11140 /*                                                                        */
11141 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11142 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11143 /*                                            resulting in version 6.1    */
11144 /*                                                                        */
11145 /**************************************************************************/
_nxe_web_http_server_digest_authenticate_notify_set(NX_WEB_HTTP_SERVER * http_server_ptr,UINT (* digest_authenticate_callback)(NX_WEB_HTTP_SERVER * server_ptr,CHAR * name_ptr,CHAR * realm_ptr,CHAR * password_ptr,CHAR * method,CHAR * authorization_uri,CHAR * authorization_nc,CHAR * authorization_cnonce))11146 UINT _nxe_web_http_server_digest_authenticate_notify_set(NX_WEB_HTTP_SERVER *http_server_ptr,
11147                                                          UINT (*digest_authenticate_callback)(NX_WEB_HTTP_SERVER *server_ptr, CHAR *name_ptr,
11148                                                          CHAR *realm_ptr, CHAR *password_ptr, CHAR *method,
11149                                                          CHAR *authorization_uri, CHAR *authorization_nc,
11150                                                          CHAR *authorization_cnonce))
11151 {
11152 
11153     /* Check for invalid input pointers.  */
11154     if ((http_server_ptr == NX_NULL) || (digest_authenticate_callback == NX_NULL))
11155     {
11156         return(NX_PTR_ERROR);
11157     }
11158 
11159     return(_nx_web_http_server_digest_authenticate_notify_set(http_server_ptr, digest_authenticate_callback));
11160 }
11161 
11162 
11163 /**************************************************************************/
11164 /*                                                                        */
11165 /*  FUNCTION                                               RELEASE        */
11166 /*                                                                        */
11167 /*    _nx_web_http_server_digest_authenticate_notify_set  PORTABLE C      */
11168 /*                                                           6.1          */
11169 /*  AUTHOR                                                                */
11170 /*                                                                        */
11171 /*    Yuxin Zhou, Microsoft Corporation                                   */
11172 /*                                                                        */
11173 /*  DESCRIPTION                                                           */
11174 /*                                                                        */
11175 /*    This function sets digest authenticate callback function.           */
11176 /*                                                                        */
11177 /*    Note: The strings name_ptr, realm_ptr, password_ptr, method,        */
11178 /*    authorization_uri, authorization_nc and authorization_cnonce in     */
11179 /*    callback function digest_authenticate_callback is built by internal */
11180 /*    logic and always NULL-terminated.                                   */
11181 /*                                                                        */
11182 /*                                                                        */
11183 /*  INPUT                                                                 */
11184 /*                                                                        */
11185 /*    http_server_ptr                       Pointer to HTTP server        */
11186 /*    digest_authenticate_callback          Pointer to application's      */
11187 /*                                          digest authenticate callback  */
11188 /*                                          function                      */
11189 /*                                                                        */
11190 /*  OUTPUT                                                                */
11191 /*                                                                        */
11192 /*    status                                Completion status             */
11193 /*                                                                        */
11194 /*  CALLS                                                                 */
11195 /*                                                                        */
11196 /*    None                                                                */
11197 /*                                                                        */
11198 /*  CALLED BY                                                             */
11199 /*                                                                        */
11200 /*    Application Code                                                    */
11201 /*                                                                        */
11202 /*  RELEASE HISTORY                                                       */
11203 /*                                                                        */
11204 /*    DATE              NAME                      DESCRIPTION             */
11205 /*                                                                        */
11206 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11207 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11208 /*                                            resulting in version 6.1    */
11209 /*                                                                        */
11210 /**************************************************************************/
_nx_web_http_server_digest_authenticate_notify_set(NX_WEB_HTTP_SERVER * http_server_ptr,UINT (* digest_authenticate_callback)(NX_WEB_HTTP_SERVER * server_ptr,CHAR * name_ptr,CHAR * realm_ptr,CHAR * password_ptr,CHAR * method,CHAR * authorization_uri,CHAR * authorization_nc,CHAR * authorization_cnonce))11211 UINT _nx_web_http_server_digest_authenticate_notify_set(NX_WEB_HTTP_SERVER *http_server_ptr,
11212                                                         UINT (*digest_authenticate_callback)(NX_WEB_HTTP_SERVER *server_ptr, CHAR *name_ptr,
11213                                                         CHAR *realm_ptr, CHAR *password_ptr, CHAR *method,
11214                                                         CHAR *authorization_uri, CHAR *authorization_nc,
11215                                                         CHAR *authorization_cnonce))
11216 {
11217 
11218 #ifdef  NX_WEB_HTTP_DIGEST_ENABLE
11219     http_server_ptr -> nx_web_http_server_digest_authenticate_callback = digest_authenticate_callback;
11220 
11221     return(NX_SUCCESS);
11222 #else
11223     NX_PARAMETER_NOT_USED(http_server_ptr);
11224     NX_PARAMETER_NOT_USED(digest_authenticate_callback);
11225 
11226     return(NX_NOT_SUPPORTED);
11227 #endif
11228 }
11229 
11230 
11231 /**************************************************************************/
11232 /*                                                                        */
11233 /*  FUNCTION                                               RELEASE        */
11234 /*                                                                        */
11235 /*    _nxe_web_http_server_authentication_check_set       PORTABLE C      */
11236 /*                                                           6.1          */
11237 /*  AUTHOR                                                                */
11238 /*                                                                        */
11239 /*    Yuxin Zhou, Microsoft Corporation                                   */
11240 /*                                                                        */
11241 /*  DESCRIPTION                                                           */
11242 /*                                                                        */
11243 /*    This function checks errors for setting authentication checking     */
11244 /*    callback function.                                                  */
11245 /*                                                                        */
11246 /*                                                                        */
11247 /*  INPUT                                                                 */
11248 /*                                                                        */
11249 /*    http_server_ptr                       Pointer to HTTP server        */
11250 /*    authentication_check_extended         Pointer to application's      */
11251 /*                                            authentication checking     */
11252 /*                                                                        */
11253 /*  OUTPUT                                                                */
11254 /*                                                                        */
11255 /*    status                                Completion status             */
11256 /*                                                                        */
11257 /*  CALLS                                                                 */
11258 /*                                                                        */
11259 /*    _nx_http_server_authentication_check_set                            */
11260 /*                                          Set authentication callback   */
11261 /*                                                                        */
11262 /*  CALLED BY                                                             */
11263 /*                                                                        */
11264 /*    Application Code                                                    */
11265 /*                                                                        */
11266 /*  RELEASE HISTORY                                                       */
11267 /*                                                                        */
11268 /*    DATE              NAME                      DESCRIPTION             */
11269 /*                                                                        */
11270 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11271 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11272 /*                                            resulting in version 6.1    */
11273 /*                                                                        */
11274 /**************************************************************************/
_nxe_web_http_server_authentication_check_set(NX_WEB_HTTP_SERVER * http_server_ptr,UINT (* authentication_check_extended)(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,UINT * name_length,CHAR ** password,UINT * password_length,CHAR ** realm,UINT * realm_length))11275 UINT  _nxe_web_http_server_authentication_check_set(NX_WEB_HTTP_SERVER *http_server_ptr,
11276                                                     UINT (*authentication_check_extended)(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, UINT *name_length, CHAR **password, UINT *password_length, CHAR **realm, UINT *realm_length))
11277 {
11278 UINT status;
11279 
11280     /* Check for invalid input pointers.  */
11281     if ((http_server_ptr == NX_NULL) || (authentication_check_extended == NX_NULL))
11282     {
11283         return(NX_PTR_ERROR);
11284     }
11285 
11286     /* Check for appropriate caller.  */
11287     NX_THREADS_ONLY_CALLER_CHECKING
11288 
11289     /* Call the actual authentication checking set function.  */
11290     status= _nx_web_http_server_authentication_check_set(http_server_ptr, authentication_check_extended);
11291 
11292     /* Return staus.  */
11293     return(status);
11294 }
11295 
11296 
11297 /**************************************************************************/
11298 /*                                                                        */
11299 /*  FUNCTION                                               RELEASE        */
11300 /*                                                                        */
11301 /*    _nx_web_http_server_authentication_check_set        PORTABLE C      */
11302 /*                                                           6.1          */
11303 /*  AUTHOR                                                                */
11304 /*                                                                        */
11305 /*    Yuxin Zhou, Microsoft Corporation                                   */
11306 /*                                                                        */
11307 /*  DESCRIPTION                                                           */
11308 /*                                                                        */
11309 /*    This function sets the callback function of authentication checking.*/
11310 /*                                                                        */
11311 /*    Note: The strings of name, password and realm must be               */
11312 /*    NULL-terminated and length of each string matches the length        */
11313 /*    specified in the argument list. The string resource in callback     */
11314 /*    function authentication_check and request_notify is built by        */
11315 /*    internal logic and always NULL-terminated.                          */
11316 /*                                                                        */
11317 /*                                                                        */
11318 /*  INPUT                                                                 */
11319 /*                                                                        */
11320 /*    http_server_ptr                       Pointer to HTTP server        */
11321 /*    authentication_check_extended         Pointer to application's      */
11322 /*                                            authentication checking     */
11323 /*                                                                        */
11324 /*  OUTPUT                                                                */
11325 /*                                                                        */
11326 /*    status                                Completion status             */
11327 /*                                                                        */
11328 /*  CALLS                                                                 */
11329 /*                                                                        */
11330 /*    None                                                                */
11331 /*                                                                        */
11332 /*  CALLED BY                                                             */
11333 /*                                                                        */
11334 /*    Application Code                                                    */
11335 /*                                                                        */
11336 /*  RELEASE HISTORY                                                       */
11337 /*                                                                        */
11338 /*    DATE              NAME                      DESCRIPTION             */
11339 /*                                                                        */
11340 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11341 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11342 /*                                            resulting in version 6.1    */
11343 /*                                                                        */
11344 /**************************************************************************/
_nx_web_http_server_authentication_check_set(NX_WEB_HTTP_SERVER * http_server_ptr,UINT (* authentication_check_extended)(NX_WEB_HTTP_SERVER * server_ptr,UINT request_type,CHAR * resource,CHAR ** name,UINT * name_length,CHAR ** password,UINT * password_length,CHAR ** realm,UINT * realm_length))11345 UINT _nx_web_http_server_authentication_check_set(NX_WEB_HTTP_SERVER *http_server_ptr,
11346                                                   UINT (*authentication_check_extended)(NX_WEB_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, UINT *name_length, CHAR **password, UINT *password_length, CHAR **realm, UINT *realm_length))
11347 {
11348 
11349     /* Set the extended authentication checking function.  */
11350     http_server_ptr -> nx_web_http_server_authentication_check_extended = authentication_check_extended;
11351 
11352     /* Return success.  */
11353     return(NX_SUCCESS);
11354 }