File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -540,3 +540,59 @@ int hv_parse_url(hurl_t* stURL, const char* strURL) {
540540 stURL -> fields [HV_URL_FRAGMENT ].len = ep - sp ;
541541 return 0 ;
542542}
543+
544+ int hv_normalize_path (char * path ) {
545+ if (* path != '/' ) return 0 ;
546+ int pos = 1 ;
547+ #ifdef OS_WIN
548+ int sum = 0 ;
549+ #endif
550+ for (int i = 1 ; path [i ] != '\0' ; ++ i ) {
551+ switch (path [i ]) {
552+ case '\\' :
553+ case '/' :
554+ if (path [pos - 1 ] != '/' ) path [pos ++ ] = '/' ;
555+ break ;
556+
557+ case '.' :
558+ if (path [pos - 1 ] == '/' ) {
559+ if (path [i + 1 ] == '.' && (path [i + 2 ] == '/' || path [i + 2 ] == '\\' || path [i + 2 ] == '\0' )) {
560+ while (-- pos > 0 ) {
561+ if (path [pos - 1 ] == '/' ) break ;
562+ }
563+ if (pos < 1 ) return 0 ;
564+ i += path [i + 2 ] == '\0' ? 1 : 2 ;
565+ break ;
566+ }
567+ if (path [i + 1 ] == '\0' ) break ;
568+ if (path [i + 1 ] == '/' || path [i + 1 ] == '\\' ) {
569+ ++ i ;
570+ break ;
571+ }
572+ }
573+ path [pos ++ ] = '.' ;
574+ #ifdef OS_WIN
575+ // windows does not have a trailing '.'
576+ sum = 1 ;
577+ while (path [i + sum ] == '.' ) {
578+ path [pos ++ ] = '.' ;
579+ ++ sum ;
580+ }
581+ if (path [i + sum ] == '\0' ) pos -= sum ;
582+ i += sum - 1 ;
583+ #endif
584+ break ;
585+
586+ default :
587+ #ifdef OS_WIN
588+ // windows is not case sensitive
589+ path [pos ++ ] = (char )tolower (path [i ]);
590+ #else
591+ path [pos ++ ] = path [i ];
592+ #endif
593+ break ;
594+ }
595+ }
596+ path [pos ] = '\0' ;
597+ return pos ;
598+ }
Original file line number Diff line number Diff line change @@ -140,6 +140,8 @@ typedef struct hurl_s {
140140
141141HV_EXPORT int hv_parse_url (hurl_t * stURL , const char * strURL );
142142
143+ HV_EXPORT int hv_normalize_path (char * path );
144+
143145END_EXTERN_C
144146
145147#endif // HV_BASE_H_
Original file line number Diff line number Diff line change @@ -524,14 +524,15 @@ int HttpHandler::defaultRequestHandler() {
524524int HttpHandler::defaultStaticHandler () {
525525 // file service
526526 std::string path = req->Path ();
527- const char * req_path = path.c_str ();
528- // path safe check
529- if (req_path[ 0 ] != ' / ' || strstr (req_path, " /.. " ) || strstr (req_path, " \\ .. " )) {
527+ path. resize ( hv_normalize_path ( const_cast < char *>( path.c_str ())) );
528+ if ( path. empty ()) {
529+ hloge ( " [%s:%d] Illegal relative path: %s " , ip, port, req-> path . c_str ());
530530 return HTTP_STATUS_BAD_REQUEST;
531531 }
532532
533+ const char * req_path = path.c_str ();
533534 std::string filepath;
534- bool is_dir = path.back () == ' /' &&
535+ const bool is_dir = path.back () == ' /' &&
535536 service->index_of .size () > 0 &&
536537 hv_strstartswith (req_path, service->index_of .c_str ());
537538 if (is_dir) {
You can’t perform that action at this time.
0 commit comments