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