1 /** @file
2 
3   A brief file description
4 
5   @section license License
6 
7   Licensed to the Apache Software Foundation (ASF) under one
8   or more contributor license agreements.  See the NOTICE file
9   distributed with this work for additional information
10   regarding copyright ownership.  The ASF licenses this file
11   to you under the Apache License, Version 2.0 (the
12   "License"); you may not use this file except in compliance
13   with the License.  You may obtain a copy of the License at
14 
15       http://www.apache.org/licenses/LICENSE-2.0
16 
17   Unless required by applicable law or agreed to in writing, software
18   distributed under the License is distributed on an "AS IS" BASIS,
19   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   See the License for the specific language governing permissions and
21   limitations under the License.
22  */
23 
24 #pragma once
25 
26 #include "tscore/Arena.h"
27 #include "HdrToken.h"
28 #include "HdrHeap.h"
29 #include "tscore/CryptoHash.h"
30 #include "MIME.h"
31 #include <string_view>
32 
33 #include "tscore/ink_apidefs.h"
34 
35 typedef int64_t cache_generation_t;
36 
37 enum URLType {
38   URL_TYPE_NONE,
39   URL_TYPE_HTTP,
40   URL_TYPE_HTTPS,
41 };
42 
43 struct URLImpl : public HdrHeapObjImpl {
44   // HdrHeapObjImpl is 4 bytes
45   uint16_t m_len_scheme;
46   uint16_t m_len_user;
47   uint16_t m_len_password;
48   uint16_t m_len_host;
49   uint16_t m_len_port;
50   uint16_t m_len_path;
51   uint16_t m_len_params;
52   uint16_t m_len_query;
53   uint16_t m_len_fragment;
54   uint16_t m_len_printed_string;
55   // 4 + 20 byte = 24, 8 bytes aligned
56 
57   const char *m_ptr_scheme;
58   const char *m_ptr_user;
59   const char *m_ptr_password;
60   const char *m_ptr_host;
61   const char *m_ptr_port;
62   const char *m_ptr_path;
63   const char *m_ptr_params;
64   const char *m_ptr_query;
65   const char *m_ptr_fragment;
66   const char *m_ptr_printed_string;
67   // pointer aligned (4 or 8)
68 
69   // Tokenized values
70   int16_t m_scheme_wks_idx;
71   uint16_t m_port;
72   uint8_t m_url_type;  // e.g. HTTP
73   uint8_t m_type_code; // RFC 1738 limits type code to 1 char
74   // 6 bytes
75 
76   uint32_t m_clean : 1;
77   /// Whether the URI had an absolutely empty path, not even an initial '/'.
78   uint32_t m_path_is_empty : 1;
79   uint32_t m_normalization_flags : 2; // Only valid if both m_clean and m_ptr_printed_sting are non-zero.
80   // 8 bytes + 4 bits, will result in padding
81 
82   // Marshaling Functions
83   int marshal(MarshalXlate *str_xlate, int num_xlate);
84   void unmarshal(intptr_t offset);
85   void move_strings(HdrStrHeap *new_heap);
86   void rehome_strings(HdrHeap *new_heap);
87   size_t strings_length();
88 
89   // Sanity Check Functions
90   void check_strings(HeapCheck *heaps, int num_heaps);
91 };
92 
93 using URLHashContext = CryptoContext;
94 
95 extern const char *URL_SCHEME_FILE;
96 extern const char *URL_SCHEME_FTP;
97 extern const char *URL_SCHEME_GOPHER;
98 extern const char *URL_SCHEME_HTTP;
99 extern const char *URL_SCHEME_HTTPS;
100 extern const char *URL_SCHEME_WS;
101 extern const char *URL_SCHEME_WSS;
102 extern const char *URL_SCHEME_MAILTO;
103 extern const char *URL_SCHEME_NEWS;
104 extern const char *URL_SCHEME_NNTP;
105 extern const char *URL_SCHEME_PROSPERO;
106 extern const char *URL_SCHEME_TELNET;
107 extern const char *URL_SCHEME_TUNNEL;
108 extern const char *URL_SCHEME_WAIS;
109 extern const char *URL_SCHEME_PNM;
110 extern const char *URL_SCHEME_RTSP;
111 extern const char *URL_SCHEME_RTSPU;
112 extern const char *URL_SCHEME_MMS;
113 extern const char *URL_SCHEME_MMSU;
114 extern const char *URL_SCHEME_MMST;
115 
116 extern int URL_WKSIDX_FILE;
117 extern int URL_WKSIDX_FTP;
118 extern int URL_WKSIDX_GOPHER;
119 extern int URL_WKSIDX_HTTP;
120 extern int URL_WKSIDX_HTTPS;
121 extern int URL_WKSIDX_WS;
122 extern int URL_WKSIDX_WSS;
123 extern int URL_WKSIDX_MAILTO;
124 extern int URL_WKSIDX_NEWS;
125 extern int URL_WKSIDX_NNTP;
126 extern int URL_WKSIDX_PROSPERO;
127 extern int URL_WKSIDX_TELNET;
128 extern int URL_WKSIDX_TUNNEL;
129 extern int URL_WKSIDX_WAIS;
130 extern int URL_WKSIDX_PNM;
131 extern int URL_WKSIDX_RTSP;
132 extern int URL_WKSIDX_RTSPU;
133 extern int URL_WKSIDX_MMS;
134 extern int URL_WKSIDX_MMSU;
135 extern int URL_WKSIDX_MMST;
136 
137 extern int URL_LEN_FILE;
138 extern int URL_LEN_FTP;
139 extern int URL_LEN_GOPHER;
140 extern int URL_LEN_HTTP;
141 extern int URL_LEN_HTTPS;
142 extern int URL_LEN_WS;
143 extern int URL_LEN_WSS;
144 extern int URL_LEN_MAILTO;
145 extern int URL_LEN_NEWS;
146 extern int URL_LEN_NNTP;
147 extern int URL_LEN_PROSPERO;
148 extern int URL_LEN_TELNET;
149 extern int URL_LEN_TUNNEL;
150 extern int URL_LEN_WAIS;
151 extern int URL_LEN_PNM;
152 extern int URL_LEN_RTSP;
153 extern int URL_LEN_RTSPU;
154 extern int URL_LEN_MMS;
155 extern int URL_LEN_MMSU;
156 extern int URL_LEN_MMST;
157 
158 /* Public */
159 bool validate_host_name(std::string_view addr);
160 void url_init();
161 
162 URLImpl *url_create(HdrHeap *heap);
163 void url_clear(URLImpl *url_impl);
164 void url_nuke_proxy_stuff(URLImpl *d_url);
165 
166 URLImpl *url_copy(URLImpl *s_url, HdrHeap *s_heap, HdrHeap *d_heap, bool inherit_strs = true);
167 void url_copy_onto(URLImpl *s_url, HdrHeap *s_heap, URLImpl *d_url, HdrHeap *d_heap, bool inherit_strs = true);
168 void url_copy_onto_as_server_url(URLImpl *s_url, HdrHeap *s_heap, URLImpl *d_url, HdrHeap *d_heap, bool inherit_strs = true);
169 
170 // Normalization flag masks.
171 namespace URLNormalize
172 {
173 unsigned const NONE           = 0;
174 unsigned const IMPLIED_SCHEME = 1; // If scheme missing, add scheme implied by URL type.
175 unsigned const LC_SCHEME_HOST = 2; // Force scheme and host to lower case if necessary.
176 };                                 // namespace URLNormalize
177 
178 int url_print(URLImpl *u, char *buf, int bufsize, int *bufindex, int *dumpoffset,
179               unsigned normalization_flags = URLNormalize::NONE);
180 void url_describe(HdrHeapObjImpl *raw, bool recurse);
181 
182 int url_length_get(URLImpl *url, unsigned normalization_flags = URLNormalize::NONE);
183 char *url_string_get(URLImpl *url, Arena *arena, int *length, HdrHeap *heap);
184 void url_clear_string_ref(URLImpl *url);
185 char *url_string_get_ref(HdrHeap *heap, URLImpl *url, int *length, unsigned normalization_flags = URLNormalize::NONE);
186 void url_called_set(URLImpl *url);
187 char *url_string_get_buf(URLImpl *url, char *dstbuf, int dstbuf_size, int *length);
188 
189 void url_CryptoHash_get(const URLImpl *url, CryptoHash *hash, cache_generation_t generation = -1);
190 void url_host_CryptoHash_get(URLImpl *url, CryptoHash *hash);
191 const char *url_scheme_set(HdrHeap *heap, URLImpl *url, const char *value, int value_wks_idx, int length, bool copy_string);
192 
193 /* Internet specific */
194 void url_user_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
195 void url_password_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
196 void url_host_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
197 void url_port_set(HdrHeap *heap, URLImpl *url, unsigned int port);
198 
199 /* HTTP specific */
200 void url_path_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
201 
202 void url_type_set(URLImpl *url, unsigned int type);
203 
204 /* HTTP specific */
205 void url_params_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
206 void url_query_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
207 void url_fragment_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
208 
209 constexpr bool USE_STRICT_URI_PARSING = true;
210 
211 ParseResult url_parse(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings,
212                       bool strict_uri_parsing = false, bool verify_host_characters = true);
213 
214 constexpr bool COPY_STRINGS = true;
215 
216 ParseResult url_parse_regex(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings);
217 ParseResult url_parse_internet(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings,
218                                bool verify_host_characters);
219 ParseResult url_parse_http(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings,
220                            bool verify_host_characters);
221 ParseResult url_parse_http_regex(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings);
222 
223 char *url_unescapify(Arena *arena, const char *str, int length);
224 
225 void unescape_str(char *&buf, char *buf_e, const char *&str, const char *str_e, int &state);
226 void unescape_str_tolower(char *&buf, char *end, const char *&str, const char *str_e, int &state);
227 
228 inline int
url_canonicalize_port(int type,int port)229 url_canonicalize_port(int type, int port)
230 {
231   if (port == 0) {
232     if (type == URL_TYPE_HTTP)
233       port = 80;
234     else if (type == URL_TYPE_HTTPS)
235       port = 443;
236   }
237   return (port);
238 }
239 
240 class URL : public HdrHeapSDKHandle
241 {
242 public:
243   URLImpl *m_url_impl = nullptr;
244 
245   URL();
246   ~URL();
247 
248   int valid() const;
249 
250   void create(HdrHeap *h);
251   void copy(const URL *url);
252   void copy_shallow(const URL *url);
253   void clear();
254   void reset();
255   // Note that URL::destroy() is inherited from HdrHeapSDKHandle.
256   void nuke_proxy_stuff();
257 
258   int print(char *buf, int bufsize, int *bufindex, int *dumpoffset, unsigned normalization_flags = URLNormalize::NONE) const;
259 
260   int length_get(unsigned normalization_flags = URLNormalize::NONE) const;
261 
262   void clear_string_ref();
263 
264   char *string_get(Arena *arena, int *length = nullptr) const;
265   char *string_get_ref(int *length = nullptr, unsigned normalization_flags = URLNormalize::NONE) const;
266   char *string_get_buf(char *dstbuf, int dsbuf_size, int *length = nullptr) const;
267   void hash_get(CryptoHash *hash, cache_generation_t generation = -1) const;
268   void host_hash_get(CryptoHash *hash) const;
269 
270   const char *scheme_get(int *length);
271   const std::string_view scheme_get();
272   int scheme_get_wksidx() const;
273   void scheme_set(const char *value, int length);
274 
275   const char *user_get(int *length);
276   void user_set(const char *value, int length);
277   const char *password_get(int *length);
278   void password_set(const char *value, int length);
279   const char *host_get(int *length);
280   void host_set(const char *value, int length);
281 
282   int port_get() const;
283   int port_get_raw() const;
284   void port_set(int port);
285 
286   const char *path_get(int *length);
287   void path_set(const char *value, int length);
288 
289   int type_get();
290   void type_set(int type);
291 
292   const char *params_get(int *length);
293   void params_set(const char *value, int length);
294   const char *query_get(int *length);
295   void query_set(const char *value, int length);
296   const char *fragment_get(int *length);
297   void fragment_set(const char *value, int length);
298 
299   /**
300    * Parse the given URL string and populate URL state with the parts.
301    *
302    * @param[in] url The URL to parse.
303    *
304    * @return PARSE_RESULT_DONE if parsing was successful, PARSE_RESULT_ERROR
305    * otherwise.
306    */
307   ParseResult parse(std::string_view url);
308 
309   /** Same as parse() but do not verify that the host has proper FQDN
310    * characters.
311    *
312    * This is useful for RemapConfig To targets which have "$[0-9]" references
313    * in their host names which will later be substituted for other text.
314    */
315   ParseResult parse_no_host_check(std::string_view url);
316 
317   ParseResult parse(const char **start, const char *end);
318   ParseResult parse(const char *str, int length);
319 
320   /** Perform more simplified parsing that is resilient to receiving regular
321    * expressions.
322    *
323    * This simply looks for the first '/' in a URL and considers that the end of
324    * the authority and the beginning of the rest of the URL. This allows for
325    * the '?' character in an authority as a part of a regex without it being
326    * considered a query parameter and, thus, avoids confusing the parser.
327    *
328    * This is only used in RemapConfig and may have no other uses.
329    */
330   ParseResult parse_regex(std::string_view url);
331   ParseResult parse_regex(const char *str, int length);
332 
333 public:
334   static char *unescapify(Arena *arena, const char *str, int length);
335   // No gratuitous copies!
336   URL(const URL &u) = delete;
337   URL &operator=(const URL &u) = delete;
338 
339 private:
340   static constexpr bool VERIFY_HOST_CHARACTERS = true;
341 };
342 
343 /*-------------------------------------------------------------------------
344   -------------------------------------------------------------------------*/
345 
URL()346 inline URL::URL() {}
347 
348 /*-------------------------------------------------------------------------
349   -------------------------------------------------------------------------*/
350 
~URL()351 inline URL::~URL() {}
352 
353 /*-------------------------------------------------------------------------
354   -------------------------------------------------------------------------*/
355 
356 inline int
valid()357 URL::valid() const
358 {
359   return (m_heap && m_url_impl);
360 }
361 
362 /*-------------------------------------------------------------------------
363   -------------------------------------------------------------------------*/
364 
365 inline void
create(HdrHeap * heap)366 URL::create(HdrHeap *heap)
367 {
368   if (heap) {
369     m_heap = heap;
370   } else if (!m_heap) {
371     m_heap = new_HdrHeap();
372   }
373 
374   m_url_impl = url_create(m_heap);
375 }
376 
377 /*-------------------------------------------------------------------------
378   -------------------------------------------------------------------------*/
379 
380 inline void
copy(const URL * url)381 URL::copy(const URL *url)
382 {
383   ink_assert(url != nullptr && url->valid());
384   url_copy_onto(url->m_url_impl, url->m_heap, m_url_impl, m_heap);
385 }
386 
387 /*-------------------------------------------------------------------------
388   -------------------------------------------------------------------------*/
389 
390 inline void
copy_shallow(const URL * url)391 URL::copy_shallow(const URL *url)
392 {
393   ink_assert(url->valid());
394   this->set(url);
395   m_url_impl = url->m_url_impl;
396 }
397 
398 /*-------------------------------------------------------------------------
399   -------------------------------------------------------------------------*/
400 
401 inline void
clear()402 URL::clear()
403 {
404   m_url_impl = nullptr;
405   HdrHeapSDKHandle::clear();
406 }
407 
408 inline void
reset()409 URL::reset()
410 {
411   m_url_impl = nullptr;
412 }
413 
414 /*-------------------------------------------------------------------------
415   -------------------------------------------------------------------------*/
416 
417 inline void
nuke_proxy_stuff()418 URL::nuke_proxy_stuff()
419 {
420   ink_assert(valid());
421   url_nuke_proxy_stuff(m_url_impl);
422 }
423 
424 /*-------------------------------------------------------------------------
425   -------------------------------------------------------------------------*/
426 
427 inline int
print(char * buf,int bufsize,int * bufindex,int * dumpoffset,unsigned normalization_flags)428 URL::print(char *buf, int bufsize, int *bufindex, int *dumpoffset, unsigned normalization_flags) const
429 {
430   ink_assert(valid());
431   return url_print(m_url_impl, buf, bufsize, bufindex, dumpoffset, normalization_flags);
432 }
433 
434 /*-------------------------------------------------------------------------
435   -------------------------------------------------------------------------*/
436 
437 inline int
length_get(unsigned normalization_flags)438 URL::length_get(unsigned normalization_flags) const
439 {
440   ink_assert(valid());
441   return url_length_get(m_url_impl, normalization_flags);
442 }
443 
444 /*-------------------------------------------------------------------------
445   -------------------------------------------------------------------------*/
446 
447 inline char *
string_get(Arena * arena_or_null_for_malloc,int * length)448 URL::string_get(Arena *arena_or_null_for_malloc, int *length) const
449 {
450   ink_assert(valid());
451   return url_string_get(m_url_impl, arena_or_null_for_malloc, length, m_heap);
452 }
453 
454 inline char *
string_get_ref(int * length,unsigned normalization_flags)455 URL::string_get_ref(int *length, unsigned normalization_flags) const
456 {
457   ink_assert(valid());
458   return url_string_get_ref(m_heap, m_url_impl, length, normalization_flags);
459 }
460 
461 inline void
clear_string_ref()462 URL::clear_string_ref()
463 {
464   ink_assert(valid());
465   url_clear_string_ref(m_url_impl);
466   return;
467 }
468 
469 /*-------------------------------------------------------------------------
470   -------------------------------------------------------------------------*/
471 inline char *
string_get_buf(char * dstbuf,int dsbuf_size,int * length)472 URL::string_get_buf(char *dstbuf, int dsbuf_size, int *length) const
473 {
474   ink_assert(valid());
475   return url_string_get_buf(m_url_impl, dstbuf, dsbuf_size, length);
476 }
477 
478 /*-------------------------------------------------------------------------
479   -------------------------------------------------------------------------*/
480 
481 inline void
hash_get(CryptoHash * hash,cache_generation_t generation)482 URL::hash_get(CryptoHash *hash, cache_generation_t generation) const
483 {
484   ink_assert(valid());
485   url_CryptoHash_get(m_url_impl, hash, generation);
486 }
487 
488 /*-------------------------------------------------------------------------
489   -------------------------------------------------------------------------*/
490 
491 inline void
host_hash_get(CryptoHash * hash)492 URL::host_hash_get(CryptoHash *hash) const
493 {
494   ink_assert(valid());
495   url_host_CryptoHash_get(m_url_impl, hash);
496 }
497 
498 /*-------------------------------------------------------------------------
499   -------------------------------------------------------------------------*/
500 
501 inline const std::string_view
scheme_get()502 URL::scheme_get()
503 {
504   ink_assert(valid());
505 
506   if (m_url_impl->m_scheme_wks_idx >= 0) {
507     return std::string_view{hdrtoken_index_to_wks(m_url_impl->m_scheme_wks_idx),
508                             static_cast<size_t>(hdrtoken_index_to_length(m_url_impl->m_scheme_wks_idx))};
509   } else {
510     return std::string_view{m_url_impl->m_ptr_scheme, m_url_impl->m_len_scheme};
511   }
512 }
513 
514 inline const char *
scheme_get(int * length)515 URL::scheme_get(int *length)
516 {
517   std::string_view ret = this->scheme_get();
518   *length              = ret.size();
519   return ret.data();
520 }
521 
522 inline int
scheme_get_wksidx()523 URL::scheme_get_wksidx() const
524 {
525   ink_assert(valid());
526   return (m_url_impl->m_scheme_wks_idx);
527 }
528 
529 /*-------------------------------------------------------------------------
530   -------------------------------------------------------------------------*/
531 
532 inline void
scheme_set(const char * value,int length)533 URL::scheme_set(const char *value, int length)
534 {
535   ink_assert(valid());
536   int scheme_wks_idx = (value ? hdrtoken_tokenize(value, length) : -1);
537   url_scheme_set(m_heap, m_url_impl, value, scheme_wks_idx, length, true);
538 }
539 
540 /*-------------------------------------------------------------------------
541   -------------------------------------------------------------------------*/
542 
543 inline const char *
user_get(int * length)544 URL::user_get(int *length)
545 {
546   ink_assert(valid());
547   *length = m_url_impl->m_len_user;
548   return m_url_impl->m_ptr_user;
549 }
550 
551 /*-------------------------------------------------------------------------
552   -------------------------------------------------------------------------*/
553 
554 inline void
user_set(const char * value,int length)555 URL::user_set(const char *value, int length)
556 {
557   ink_assert(valid());
558   url_user_set(m_heap, m_url_impl, value, length, true);
559 }
560 
561 /*-------------------------------------------------------------------------
562   -------------------------------------------------------------------------*/
563 
564 inline const char *
password_get(int * length)565 URL::password_get(int *length)
566 {
567   ink_assert(valid());
568   *length = m_url_impl->m_len_password;
569   return m_url_impl->m_ptr_password;
570 }
571 
572 /*-------------------------------------------------------------------------
573   -------------------------------------------------------------------------*/
574 
575 inline void
password_set(const char * value,int length)576 URL::password_set(const char *value, int length)
577 {
578   ink_assert(valid());
579   url_password_set(m_heap, m_url_impl, value, length, true);
580 }
581 
582 /*-------------------------------------------------------------------------
583   -------------------------------------------------------------------------*/
584 
585 inline const char *
host_get(int * length)586 URL::host_get(int *length)
587 {
588   ink_assert(valid());
589   *length = m_url_impl->m_len_host;
590   return m_url_impl->m_ptr_host;
591 }
592 
593 /*-------------------------------------------------------------------------
594   -------------------------------------------------------------------------*/
595 
596 inline void
host_set(const char * value,int length)597 URL::host_set(const char *value, int length)
598 {
599   ink_assert(valid());
600   url_host_set(m_heap, m_url_impl, value, length, true);
601 }
602 
603 /*-------------------------------------------------------------------------
604   -------------------------------------------------------------------------*/
605 
606 inline int
port_get()607 URL::port_get() const
608 {
609   ink_assert(valid());
610   return url_canonicalize_port(m_url_impl->m_url_type, m_url_impl->m_port);
611 }
612 
613 /*-------------------------------------------------------------------------
614   -------------------------------------------------------------------------*/
615 
616 inline int
port_get_raw()617 URL::port_get_raw() const
618 {
619   ink_assert(valid());
620   return m_url_impl->m_port;
621 }
622 
623 /*-------------------------------------------------------------------------
624   -------------------------------------------------------------------------*/
625 
626 inline void
port_set(int port)627 URL::port_set(int port)
628 {
629   ink_assert(valid());
630   url_port_set(m_heap, m_url_impl, port);
631 }
632 
633 /*-------------------------------------------------------------------------
634   -------------------------------------------------------------------------*/
635 
636 inline const char *
path_get(int * length)637 URL::path_get(int *length)
638 {
639   ink_assert(valid());
640   *length = m_url_impl->m_len_path;
641   return m_url_impl->m_ptr_path;
642 }
643 
644 /*-------------------------------------------------------------------------
645   -------------------------------------------------------------------------*/
646 
647 inline void
path_set(const char * value,int length)648 URL::path_set(const char *value, int length)
649 {
650   ink_assert(valid());
651   url_path_set(m_heap, m_url_impl, value, length, true);
652 }
653 
654 /*-------------------------------------------------------------------------
655   -------------------------------------------------------------------------*/
656 
657 inline int
type_get()658 URL::type_get()
659 {
660   ink_assert(valid());
661   return m_url_impl->m_type_code;
662 }
663 
664 /*-------------------------------------------------------------------------
665   -------------------------------------------------------------------------*/
666 
667 inline void
type_set(int type)668 URL::type_set(int type)
669 {
670   ink_assert(valid());
671   url_type_set(m_url_impl, type);
672 }
673 
674 /*-------------------------------------------------------------------------
675   -------------------------------------------------------------------------*/
676 
677 inline const char *
params_get(int * length)678 URL::params_get(int *length)
679 {
680   ink_assert(valid());
681   *length = m_url_impl->m_len_params;
682   return m_url_impl->m_ptr_params;
683 }
684 
685 /*-------------------------------------------------------------------------
686   -------------------------------------------------------------------------*/
687 
688 inline void
params_set(const char * value,int length)689 URL::params_set(const char *value, int length)
690 {
691   ink_assert(valid());
692   url_params_set(m_heap, m_url_impl, value, length, true);
693 }
694 
695 /*-------------------------------------------------------------------------
696   -------------------------------------------------------------------------*/
697 
698 inline const char *
query_get(int * length)699 URL::query_get(int *length)
700 {
701   ink_assert(valid());
702   *length = m_url_impl->m_len_query;
703   return m_url_impl->m_ptr_query;
704 }
705 
706 /*-------------------------------------------------------------------------
707   -------------------------------------------------------------------------*/
708 
709 inline void
query_set(const char * value,int length)710 URL::query_set(const char *value, int length)
711 {
712   ink_assert(valid());
713   url_query_set(m_heap, m_url_impl, value, length, true);
714 }
715 
716 /*-------------------------------------------------------------------------
717   -------------------------------------------------------------------------*/
718 
719 inline const char *
fragment_get(int * length)720 URL::fragment_get(int *length)
721 {
722   ink_assert(valid());
723   *length = m_url_impl->m_len_fragment;
724   return m_url_impl->m_ptr_fragment;
725 }
726 
727 /*-------------------------------------------------------------------------
728   -------------------------------------------------------------------------*/
729 
730 inline void
fragment_set(const char * value,int length)731 URL::fragment_set(const char *value, int length)
732 {
733   ink_assert(valid());
734   url_fragment_set(m_heap, m_url_impl, value, length, true);
735 }
736 
737 /**
738   Parser doesn't clear URL first, so if you parse over a non-clear URL,
739   the resulting URL may contain some of the previous data.
740 
741  */
742 inline ParseResult
parse(std::string_view url)743 URL::parse(std::string_view url)
744 {
745   return this->parse(url.data(), static_cast<int>(url.size()));
746 }
747 
748 /**
749   Parser doesn't clear URL first, so if you parse over a non-clear URL,
750   the resulting URL may contain some of the previous data.
751 
752  */
753 inline ParseResult
parse_no_host_check(std::string_view url)754 URL::parse_no_host_check(std::string_view url)
755 {
756   ink_assert(valid());
757   const char *start = url.data();
758   const char *end   = url.data() + url.length();
759   return url_parse(m_heap, m_url_impl, &start, end, COPY_STRINGS, !USE_STRICT_URI_PARSING, !VERIFY_HOST_CHARACTERS);
760 }
761 
762 /**
763   Parser doesn't clear URL first, so if you parse over a non-clear URL,
764   the resulting URL may contain some of the previous data.
765 
766  */
767 inline ParseResult
parse(const char ** start,const char * end)768 URL::parse(const char **start, const char *end)
769 {
770   ink_assert(valid());
771   return url_parse(m_heap, m_url_impl, start, end, COPY_STRINGS);
772 }
773 
774 /**
775   Parser doesn't clear URL first, so if you parse over a non-clear URL,
776   the resulting URL may contain some of the previous data.
777 
778  */
779 inline ParseResult
parse(const char * str,int length)780 URL::parse(const char *str, int length)
781 {
782   ink_assert(valid());
783   if (length < 0)
784     length = (int)strlen(str);
785   return parse(&str, str + length);
786 }
787 
788 /**
789   Parser doesn't clear URL first, so if you parse over a non-clear URL,
790   the resulting URL may contain some of the previous data.
791 
792  */
793 inline ParseResult
parse_regex(std::string_view url)794 URL::parse_regex(std::string_view url)
795 {
796   ink_assert(valid());
797   const char *str = url.data();
798   return url_parse_regex(m_heap, m_url_impl, &str, str + url.length(), COPY_STRINGS);
799 }
800 
801 /**
802   Parser doesn't clear URL first, so if you parse over a non-clear URL,
803   the resulting URL may contain some of the previous data.
804 
805  */
806 inline ParseResult
parse_regex(const char * str,int length)807 URL::parse_regex(const char *str, int length)
808 {
809   ink_assert(valid());
810   if (length < 0)
811     length = (int)strlen(str);
812   ink_assert(valid());
813   return url_parse_regex(m_heap, m_url_impl, &str, str + length, COPY_STRINGS);
814 }
815 
816 /*-------------------------------------------------------------------------
817   -------------------------------------------------------------------------*/
818 
819 inline char *
unescapify(Arena * arena,const char * str,int length)820 URL::unescapify(Arena *arena, const char *str, int length)
821 {
822   return url_unescapify(arena, str, length);
823 }
824