0.00% Lines (0/22) 0.00% Functions (0/2)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com) 2   // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 4   // Distributed under the Boost Software License, Version 1.0. (See accompanying
5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/cppalliance/http 7   // Official repository: https://github.com/cppalliance/http
8   // 8   //
9   9  
10   #include <boost/http/server/encode_url.hpp> 10   #include <boost/http/server/encode_url.hpp>
11   11  
12   namespace boost { 12   namespace boost {
13   namespace http { 13   namespace http {
14   14  
15   namespace { 15   namespace {
16   16  
17   // Check if character needs encoding 17   // Check if character needs encoding
18   // Unreserved + reserved chars that are allowed in URLs 18   // Unreserved + reserved chars that are allowed in URLs
19   bool 19   bool
MISUBC 20   is_safe( char c ) noexcept 20   is_safe( char c ) noexcept
21   { 21   {
22   // Unreserved: A-Z a-z 0-9 - _ . ~ 22   // Unreserved: A-Z a-z 0-9 - _ . ~
MISUBC 23   if( ( c >= 'A' && c <= 'Z' ) || 23   if( ( c >= 'A' && c <= 'Z' ) ||
MISUBC 24   ( c >= 'a' && c <= 'z' ) || 24   ( c >= 'a' && c <= 'z' ) ||
MISUBC 25   ( c >= '0' && c <= '9' ) || 25   ( c >= '0' && c <= '9' ) ||
MISUBC 26   c == '-' || c == '_' || c == '.' || c == '~' ) 26   c == '-' || c == '_' || c == '.' || c == '~' )
MISUBC 27   return true; 27   return true;
28   28  
29   // Reserved chars allowed in URLs: ! # $ & ' ( ) * + , / : ; = ? @ 29   // Reserved chars allowed in URLs: ! # $ & ' ( ) * + , / : ; = ? @
MISUBC 30   switch( c ) 30   switch( c )
31   { 31   {
MISUBC 32   case '!': 32   case '!':
33   case '#': 33   case '#':
34   case '$': 34   case '$':
35   case '&': 35   case '&':
36   case '\'': 36   case '\'':
37   case '(': 37   case '(':
38   case ')': 38   case ')':
39   case '*': 39   case '*':
40   case '+': 40   case '+':
41   case ',': 41   case ',':
42   case '/': 42   case '/':
43   case ':': 43   case ':':
44   case ';': 44   case ';':
45   case '=': 45   case '=':
46   case '?': 46   case '?':
47   case '@': 47   case '@':
MISUBC 48   return true; 48   return true;
MISUBC 49   default: 49   default:
MISUBC 50   return false; 50   return false;
51   } 51   }
52   } 52   }
53   53  
54   constexpr char hex_chars[] = "0123456789ABCDEF"; 54   constexpr char hex_chars[] = "0123456789ABCDEF";
55   55  
56   } // (anon) 56   } // (anon)
57   57  
58   std::string 58   std::string
MISUBC 59   encode_url( core::string_view url ) 59   encode_url( core::string_view url )
60   { 60   {
MISUBC 61   std::string result; 61   std::string result;
MISUBC 62   result.reserve( url.size() ); 62   result.reserve( url.size() );
63   63  
MISUBC 64   for( unsigned char c : url ) 64   for( unsigned char c : url )
65   { 65   {
MISUBC 66   if( is_safe( static_cast<char>( c ) ) ) 66   if( is_safe( static_cast<char>( c ) ) )
67   { 67   {
MISUBC 68   result.push_back( static_cast<char>( c ) ); 68   result.push_back( static_cast<char>( c ) );
69   } 69   }
70   else 70   else
71   { 71   {
MISUBC 72   result.push_back( '%' ); 72   result.push_back( '%' );
MISUBC 73   result.push_back( hex_chars[c >> 4] ); 73   result.push_back( hex_chars[c >> 4] );
MISUBC 74   result.push_back( hex_chars[c & 0x0F] ); 74   result.push_back( hex_chars[c & 0x0F] );
75   } 75   }
76   } 76   }
77   77  
MISUBC 78   return result; 78   return result;
MISUBC 79   } 79   }
80   80  
81   } // http 81   } // http
82   } // boost 82   } // boost