• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef SRC_NODE_URL_H_
2 #define SRC_NODE_URL_H_
3 
4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5 
6 #include "node.h"
7 
8 #include <string>
9 
10 namespace node {
11 namespace url {
12 
13 #define PARSESTATES(XX)                                                       \
14   XX(kSchemeStart)                                                            \
15   XX(kScheme)                                                                 \
16   XX(kNoScheme)                                                               \
17   XX(kSpecialRelativeOrAuthority)                                             \
18   XX(kPathOrAuthority)                                                        \
19   XX(kRelative)                                                               \
20   XX(kRelativeSlash)                                                          \
21   XX(kSpecialAuthoritySlashes)                                                \
22   XX(kSpecialAuthorityIgnoreSlashes)                                          \
23   XX(kAuthority)                                                              \
24   XX(kHost)                                                                   \
25   XX(kHostname)                                                               \
26   XX(kPort)                                                                   \
27   XX(kFile)                                                                   \
28   XX(kFileSlash)                                                              \
29   XX(kFileHost)                                                               \
30   XX(kPathStart)                                                              \
31   XX(kPath)                                                                   \
32   XX(kCannotBeBase)                                                           \
33   XX(kQuery)                                                                  \
34   XX(kFragment)
35 
36 #define FLAGS(XX)                                                             \
37   XX(URL_FLAGS_NONE, 0)                                                       \
38   XX(URL_FLAGS_FAILED, 0x01)                                                  \
39   XX(URL_FLAGS_CANNOT_BE_BASE, 0x02)                                          \
40   XX(URL_FLAGS_INVALID_PARSE_STATE, 0x04)                                     \
41   XX(URL_FLAGS_TERMINATED, 0x08)                                              \
42   XX(URL_FLAGS_SPECIAL, 0x10)                                                 \
43   XX(URL_FLAGS_HAS_USERNAME, 0x20)                                            \
44   XX(URL_FLAGS_HAS_PASSWORD, 0x40)                                            \
45   XX(URL_FLAGS_HAS_HOST, 0x80)                                                \
46   XX(URL_FLAGS_HAS_PATH, 0x100)                                               \
47   XX(URL_FLAGS_HAS_QUERY, 0x200)                                              \
48   XX(URL_FLAGS_HAS_FRAGMENT, 0x400)                                           \
49   XX(URL_FLAGS_IS_DEFAULT_SCHEME_PORT, 0x800)                                 \
50 
51 enum url_parse_state {
52   kUnknownState = -1,
53 #define XX(name) name,
54   PARSESTATES(XX)
55 #undef XX
56 };
57 
58 enum url_flags {
59 #define XX(name, val) name = val,
60   FLAGS(XX)
61 #undef XX
62 };
63 
64 struct url_data {
65   int32_t flags = URL_FLAGS_NONE;
66   int port = -1;
67   std::string scheme;
68   std::string username;
69   std::string password;
70   std::string host;
71   std::string query;
72   std::string fragment;
73   std::vector<std::string> path;
74 };
75 
76 namespace table_data {
77 extern const char hex[1024];
78 extern const uint8_t C0_CONTROL_ENCODE_SET[32];
79 extern const uint8_t FRAGMENT_ENCODE_SET[32];
80 extern const uint8_t PATH_ENCODE_SET[32];
81 extern const uint8_t USERINFO_ENCODE_SET[32];
82 extern const uint8_t QUERY_ENCODE_SET_NONSPECIAL[32];
83 extern const uint8_t QUERY_ENCODE_SET_SPECIAL[32];
84 }
85 
86 class URL {
87  public:
88   static void Parse(const char* input,
89                     size_t len,
90                     enum url_parse_state state_override,
91                     struct url_data* url,
92                     bool has_url,
93                     const struct url_data* base,
94                     bool has_base);
95 
URL(const char * input,const size_t len)96   URL(const char* input, const size_t len) {
97     Parse(input, len, kUnknownState, &context_, false, nullptr, false);
98   }
99 
URL(const char * input,const size_t len,const URL * base)100   URL(const char* input, const size_t len, const URL* base) {
101     if (base != nullptr)
102       Parse(input, len, kUnknownState,
103             &context_, false,
104             &(base->context_), true);
105     else
106       Parse(input, len, kUnknownState, &context_, false, nullptr, false);
107   }
108 
URL(const char * input,const size_t len,const char * base,const size_t baselen)109   URL(const char* input, const size_t len,
110       const char* base, const size_t baselen) {
111     if (base != nullptr && baselen > 0) {
112       URL _base(base, baselen);
113       Parse(input, len, kUnknownState,
114             &context_, false,
115             &(_base.context_), true);
116     } else {
117       Parse(input, len, kUnknownState, &context_, false, nullptr, false);
118     }
119   }
120 
URL(const std::string & input)121   explicit URL(const std::string& input) :
122       URL(input.c_str(), input.length()) {}
123 
URL(const std::string & input,const URL * base)124   URL(const std::string& input, const URL* base) :
125       URL(input.c_str(), input.length(), base) {}
126 
URL(const std::string & input,const URL & base)127   URL(const std::string& input, const URL& base) :
128       URL(input.c_str(), input.length(), &base) {}
129 
URL(const std::string & input,const std::string & base)130   URL(const std::string& input, const std::string& base) :
131       URL(input.c_str(), input.length(), base.c_str(), base.length()) {}
132 
flags()133   int32_t flags() const {
134     return context_.flags;
135   }
136 
port()137   int port() const {
138     return context_.port;
139   }
140 
protocol()141   const std::string& protocol() const {
142     return context_.scheme;
143   }
144 
username()145   const std::string& username() const {
146     return context_.username;
147   }
148 
password()149   const std::string& password() const {
150     return context_.password;
151   }
152 
host()153   const std::string& host() const {
154     return context_.host;
155   }
156 
query()157   const std::string& query() const {
158     return context_.query;
159   }
160 
fragment()161   const std::string& fragment() const {
162     return context_.fragment;
163   }
164 
path()165   std::string path() const {
166     std::string ret;
167     for (const std::string& element : context_.path) {
168       ret += '/' + element;
169     }
170     return ret;
171   }
172 
173   // Get the path of the file: URL in a format consumable by native file system
174   // APIs. Returns an empty string if something went wrong.
175   std::string ToFilePath() const;
176   // Get the file URL from native file system path.
177   static URL FromFilePath(const std::string& file_path);
178 
179   v8::MaybeLocal<v8::Value> ToObject(Environment* env) const;
180 
181   URL(const URL&) = default;
182   URL& operator=(const URL&) = default;
183   URL(URL&&) = default;
184   URL& operator=(URL&&) = default;
185 
URL()186   URL() : URL("") {}
187 
188  private:
189   struct url_data context_;
190 };
191 
192 }  // namespace url
193 
194 }  // namespace node
195 
196 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
197 
198 #endif  // SRC_NODE_URL_H_
199