xref: /trafficserver/proxy/hdrs/URL.h (revision 9b567e4e)
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   // 8 bytes + 1 bit, will result in padding
78 
79   // Marshaling Functions
80   int marshal(MarshalXlate *str_xlate, int num_xlate);
81   void unmarshal(intptr_t offset);
82   void move_strings(HdrStrHeap *new_heap);
83   void rehome_strings(HdrHeap *new_heap);
84   size_t strings_length();
85 
86   // Sanity Check Functions
87   void check_strings(HeapCheck *heaps, int num_heaps);
88 };
89 
90 using URLHashContext = CryptoContext;
91 
92 extern const char *URL_SCHEME_FILE;
93 extern const char *URL_SCHEME_FTP;
94 extern const char *URL_SCHEME_GOPHER;
95 extern const char *URL_SCHEME_HTTP;
96 extern const char *URL_SCHEME_HTTPS;
97 extern const char *URL_SCHEME_WS;
98 extern const char *URL_SCHEME_WSS;
99 extern const char *URL_SCHEME_MAILTO;
100 extern const char *URL_SCHEME_NEWS;
101 extern const char *URL_SCHEME_NNTP;
102 extern const char *URL_SCHEME_PROSPERO;
103 extern const char *URL_SCHEME_TELNET;
104 extern const char *URL_SCHEME_TUNNEL;
105 extern const char *URL_SCHEME_WAIS;
106 extern const char *URL_SCHEME_PNM;
107 extern const char *URL_SCHEME_RTSP;
108 extern const char *URL_SCHEME_RTSPU;
109 extern const char *URL_SCHEME_MMS;
110 extern const char *URL_SCHEME_MMSU;
111 extern const char *URL_SCHEME_MMST;
112 
113 extern int URL_WKSIDX_FILE;
114 extern int URL_WKSIDX_FTP;
115 extern int URL_WKSIDX_GOPHER;
116 extern int URL_WKSIDX_HTTP;
117 extern int URL_WKSIDX_HTTPS;
118 extern int URL_WKSIDX_WS;
119 extern int URL_WKSIDX_WSS;
120 extern int URL_WKSIDX_MAILTO;
121 extern int URL_WKSIDX_NEWS;
122 extern int URL_WKSIDX_NNTP;
123 extern int URL_WKSIDX_PROSPERO;
124 extern int URL_WKSIDX_TELNET;
125 extern int URL_WKSIDX_TUNNEL;
126 extern int URL_WKSIDX_WAIS;
127 extern int URL_WKSIDX_PNM;
128 extern int URL_WKSIDX_RTSP;
129 extern int URL_WKSIDX_RTSPU;
130 extern int URL_WKSIDX_MMS;
131 extern int URL_WKSIDX_MMSU;
132 extern int URL_WKSIDX_MMST;
133 
134 extern int URL_LEN_FILE;
135 extern int URL_LEN_FTP;
136 extern int URL_LEN_GOPHER;
137 extern int URL_LEN_HTTP;
138 extern int URL_LEN_HTTPS;
139 extern int URL_LEN_WS;
140 extern int URL_LEN_WSS;
141 extern int URL_LEN_MAILTO;
142 extern int URL_LEN_NEWS;
143 extern int URL_LEN_NNTP;
144 extern int URL_LEN_PROSPERO;
145 extern int URL_LEN_TELNET;
146 extern int URL_LEN_TUNNEL;
147 extern int URL_LEN_WAIS;
148 extern int URL_LEN_PNM;
149 extern int URL_LEN_RTSP;
150 extern int URL_LEN_RTSPU;
151 extern int URL_LEN_MMS;
152 extern int URL_LEN_MMSU;
153 extern int URL_LEN_MMST;
154 
155 /* Public */
156 bool validate_host_name(std::string_view addr);
157 void url_init();
158 
159 URLImpl *url_create(HdrHeap *heap);
160 void url_clear(URLImpl *url_impl);
161 void url_nuke_proxy_stuff(URLImpl *d_url);
162 
163 URLImpl *url_copy(URLImpl *s_url, HdrHeap *s_heap, HdrHeap *d_heap, bool inherit_strs = true);
164 void url_copy_onto(URLImpl *s_url, HdrHeap *s_heap, URLImpl *d_url, HdrHeap *d_heap, bool inherit_strs = true);
165 void url_copy_onto_as_server_url(URLImpl *s_url, HdrHeap *s_heap, URLImpl *d_url, HdrHeap *d_heap, bool inherit_strs = true);
166 
167 int url_print(URLImpl *u, char *buf, int bufsize, int *bufindex, int *dumpoffset, bool normalized = false);
168 void url_describe(HdrHeapObjImpl *raw, bool recurse);
169 
170 int url_length_get(URLImpl *url);
171 char *url_string_get(URLImpl *url, Arena *arena, int *length, HdrHeap *heap, bool normalized = false);
172 void url_clear_string_ref(URLImpl *url);
173 char *url_string_get_ref(HdrHeap *heap, URLImpl *url, int *length, bool normalized = false);
174 void url_called_set(URLImpl *url);
175 char *url_string_get_buf(URLImpl *url, char *dstbuf, int dstbuf_size, int *length);
176 
177 void url_CryptoHash_get(const URLImpl *url, CryptoHash *hash, cache_generation_t generation = -1);
178 void url_host_CryptoHash_get(URLImpl *url, CryptoHash *hash);
179 const char *url_scheme_set(HdrHeap *heap, URLImpl *url, const char *value, int value_wks_idx, int length, bool copy_string);
180 
181 /* Internet specific */
182 void url_user_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
183 void url_password_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
184 void url_host_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
185 void url_port_set(HdrHeap *heap, URLImpl *url, unsigned int port);
186 
187 /* HTTP specific */
188 void url_path_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
189 
190 void url_type_set(URLImpl *url, unsigned int type);
191 
192 /* HTTP specific */
193 void url_params_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
194 void url_query_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
195 void url_fragment_set(HdrHeap *heap, URLImpl *url, const char *value, int length, bool copy_string);
196 
197 ParseResult url_parse(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings,
198                       bool strict_uri_parsing = false);
199 ParseResult url_parse_no_path_component_breakdown(HdrHeap *heap, URLImpl *url, const char **start, const char *end,
200                                                   bool copy_strings);
201 ParseResult url_parse_internet(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings);
202 ParseResult url_parse_http(HdrHeap *heap, URLImpl *url, const char **start, const char *end, bool copy_strings);
203 ParseResult url_parse_http_no_path_component_breakdown(HdrHeap *heap, URLImpl *url, const char **start, const char *end,
204                                                        bool copy_strings);
205 
206 char *url_unescapify(Arena *arena, const char *str, int length);
207 
208 void unescape_str(char *&buf, char *buf_e, const char *&str, const char *str_e, int &state);
209 void unescape_str_tolower(char *&buf, char *end, const char *&str, const char *str_e, int &state);
210 
211 inline int
url_canonicalize_port(int type,int port)212 url_canonicalize_port(int type, int port)
213 {
214   if (port == 0) {
215     if (type == URL_TYPE_HTTP)
216       port = 80;
217     else if (type == URL_TYPE_HTTPS)
218       port = 443;
219   }
220   return (port);
221 }
222 
223 class URL : public HdrHeapSDKHandle
224 {
225 public:
226   URLImpl *m_url_impl = nullptr;
227 
228   URL();
229   ~URL();
230 
231   int valid() const;
232 
233   void create(HdrHeap *h);
234   void copy(const URL *url);
235   void copy_shallow(const URL *url);
236   void clear();
237   void reset();
238   // Note that URL::destroy() is inherited from HdrHeapSDKHandle.
239   void nuke_proxy_stuff();
240 
241   int print(char *buf, int bufsize, int *bufindex, int *dumpoffset, bool normalized = false);
242 
243   int length_get();
244   void clear_string_ref();
245   char *string_get(Arena *arena, int *length = nullptr, bool normalized = false);
246   char *string_get_ref(int *length = nullptr, bool normalized = false);
247   char *string_get_buf(char *dstbuf, int dsbuf_size, int *length = nullptr);
248   void hash_get(CryptoHash *hash, cache_generation_t generation = -1) const;
249   void host_hash_get(CryptoHash *hash);
250 
251   const char *scheme_get(int *length);
252   const std::string_view scheme_get();
253   int scheme_get_wksidx();
254   void scheme_set(const char *value, int length);
255 
256   const char *user_get(int *length);
257   void user_set(const char *value, int length);
258   const char *password_get(int *length);
259   void password_set(const char *value, int length);
260   const char *host_get(int *length);
261   void host_set(const char *value, int length);
262   int port_get();
263   int port_get_raw();
264   void port_set(int port);
265 
266   const char *path_get(int *length);
267   void path_set(const char *value, int length);
268 
269   int type_get();
270   void type_set(int type);
271 
272   const char *params_get(int *length);
273   void params_set(const char *value, int length);
274   const char *query_get(int *length);
275   void query_set(const char *value, int length);
276   const char *fragment_get(int *length);
277   void fragment_set(const char *value, int length);
278 
279   ParseResult parse(const char **start, const char *end);
280   ParseResult parse(const char *str, int length);
281   ParseResult parse_no_path_component_breakdown(const char *str, int length);
282 
283 public:
284   static char *unescapify(Arena *arena, const char *str, int length);
285   // No gratuitous copies!
286   URL(const URL &u) = delete;
287   URL &operator=(const URL &u) = delete;
288 };
289 
290 /*-------------------------------------------------------------------------
291   -------------------------------------------------------------------------*/
292 
URL()293 inline URL::URL() {}
294 
295 /*-------------------------------------------------------------------------
296   -------------------------------------------------------------------------*/
297 
~URL()298 inline URL::~URL() {}
299 
300 /*-------------------------------------------------------------------------
301   -------------------------------------------------------------------------*/
302 
303 inline int
valid() const304 URL::valid() const
305 {
306   return (m_heap && m_url_impl);
307 }
308 
309 /*-------------------------------------------------------------------------
310   -------------------------------------------------------------------------*/
311 
312 inline void
create(HdrHeap * heap)313 URL::create(HdrHeap *heap)
314 {
315   if (heap) {
316     m_heap = heap;
317   } else if (!m_heap) {
318     m_heap = new_HdrHeap();
319   }
320 
321   m_url_impl = url_create(m_heap);
322 }
323 
324 /*-------------------------------------------------------------------------
325   -------------------------------------------------------------------------*/
326 
327 inline void
copy(const URL * url)328 URL::copy(const URL *url)
329 {
330   ink_assert(url != nullptr && url->valid());
331   url_copy_onto(url->m_url_impl, url->m_heap, m_url_impl, m_heap);
332 }
333 
334 /*-------------------------------------------------------------------------
335   -------------------------------------------------------------------------*/
336 
337 inline void
copy_shallow(const URL * url)338 URL::copy_shallow(const URL *url)
339 {
340   ink_assert(url->valid());
341   this->set(url);
342   m_url_impl = url->m_url_impl;
343 }
344 
345 /*-------------------------------------------------------------------------
346   -------------------------------------------------------------------------*/
347 
348 inline void
clear()349 URL::clear()
350 {
351   m_url_impl = nullptr;
352   HdrHeapSDKHandle::clear();
353 }
354 
355 inline void
reset()356 URL::reset()
357 {
358   m_url_impl = nullptr;
359 }
360 
361 /*-------------------------------------------------------------------------
362   -------------------------------------------------------------------------*/
363 
364 inline void
nuke_proxy_stuff()365 URL::nuke_proxy_stuff()
366 {
367   ink_assert(valid());
368   url_nuke_proxy_stuff(m_url_impl);
369 }
370 
371 /*-------------------------------------------------------------------------
372   -------------------------------------------------------------------------*/
373 
374 inline int
print(char * buf,int bufsize,int * bufindex,int * dumpoffset,bool normalized)375 URL::print(char *buf, int bufsize, int *bufindex, int *dumpoffset, bool normalized)
376 {
377   ink_assert(valid());
378   return url_print(m_url_impl, buf, bufsize, bufindex, dumpoffset, normalized);
379 }
380 
381 /*-------------------------------------------------------------------------
382   -------------------------------------------------------------------------*/
383 
384 inline int
length_get()385 URL::length_get()
386 {
387   ink_assert(valid());
388   return url_length_get(m_url_impl);
389 }
390 
391 /*-------------------------------------------------------------------------
392   -------------------------------------------------------------------------*/
393 
394 inline char *
string_get(Arena * arena_or_null_for_malloc,int * length,bool normalized)395 URL::string_get(Arena *arena_or_null_for_malloc, int *length, bool normalized)
396 {
397   ink_assert(valid());
398   return url_string_get(m_url_impl, arena_or_null_for_malloc, length, m_heap, normalized);
399 }
400 
401 inline char *
string_get_ref(int * length,bool normalized)402 URL::string_get_ref(int *length, bool normalized)
403 {
404   ink_assert(valid());
405   return url_string_get_ref(m_heap, m_url_impl, length, normalized);
406 }
407 
408 inline void
clear_string_ref()409 URL::clear_string_ref()
410 {
411   ink_assert(valid());
412   url_clear_string_ref(m_url_impl);
413   return;
414 }
415 
416 /*-------------------------------------------------------------------------
417   -------------------------------------------------------------------------*/
418 inline char *
string_get_buf(char * dstbuf,int dsbuf_size,int * length)419 URL::string_get_buf(char *dstbuf, int dsbuf_size, int *length)
420 {
421   ink_assert(valid());
422   return url_string_get_buf(m_url_impl, dstbuf, dsbuf_size, length);
423 }
424 
425 /*-------------------------------------------------------------------------
426   -------------------------------------------------------------------------*/
427 
428 inline void
hash_get(CryptoHash * hash,cache_generation_t generation) const429 URL::hash_get(CryptoHash *hash, cache_generation_t generation) const
430 {
431   ink_assert(valid());
432   url_CryptoHash_get(m_url_impl, hash, generation);
433 }
434 
435 /*-------------------------------------------------------------------------
436   -------------------------------------------------------------------------*/
437 
438 inline void
host_hash_get(CryptoHash * hash)439 URL::host_hash_get(CryptoHash *hash)
440 {
441   ink_assert(valid());
442   url_host_CryptoHash_get(m_url_impl, hash);
443 }
444 
445 /*-------------------------------------------------------------------------
446   -------------------------------------------------------------------------*/
447 
448 inline const std::string_view
scheme_get()449 URL::scheme_get()
450 {
451   ink_assert(valid());
452 
453   if (m_url_impl->m_scheme_wks_idx >= 0) {
454     return std::string_view{hdrtoken_index_to_wks(m_url_impl->m_scheme_wks_idx),
455                             static_cast<size_t>(hdrtoken_index_to_length(m_url_impl->m_scheme_wks_idx))};
456   } else {
457     return std::string_view{m_url_impl->m_ptr_scheme, m_url_impl->m_len_scheme};
458   }
459 }
460 
461 inline const char *
scheme_get(int * length)462 URL::scheme_get(int *length)
463 {
464   std::string_view ret = this->scheme_get();
465   *length              = ret.size();
466   return ret.data();
467 }
468 
469 inline int
scheme_get_wksidx()470 URL::scheme_get_wksidx()
471 {
472   ink_assert(valid());
473   return (m_url_impl->m_scheme_wks_idx);
474 }
475 
476 /*-------------------------------------------------------------------------
477   -------------------------------------------------------------------------*/
478 
479 inline void
scheme_set(const char * value,int length)480 URL::scheme_set(const char *value, int length)
481 {
482   ink_assert(valid());
483   int scheme_wks_idx = (value ? hdrtoken_tokenize(value, length) : -1);
484   url_scheme_set(m_heap, m_url_impl, value, scheme_wks_idx, length, true);
485 }
486 
487 /*-------------------------------------------------------------------------
488   -------------------------------------------------------------------------*/
489 
490 inline const char *
user_get(int * length)491 URL::user_get(int *length)
492 {
493   ink_assert(valid());
494   *length = m_url_impl->m_len_user;
495   return m_url_impl->m_ptr_user;
496 }
497 
498 /*-------------------------------------------------------------------------
499   -------------------------------------------------------------------------*/
500 
501 inline void
user_set(const char * value,int length)502 URL::user_set(const char *value, int length)
503 {
504   ink_assert(valid());
505   url_user_set(m_heap, m_url_impl, value, length, true);
506 }
507 
508 /*-------------------------------------------------------------------------
509   -------------------------------------------------------------------------*/
510 
511 inline const char *
password_get(int * length)512 URL::password_get(int *length)
513 {
514   ink_assert(valid());
515   *length = m_url_impl->m_len_password;
516   return m_url_impl->m_ptr_password;
517 }
518 
519 /*-------------------------------------------------------------------------
520   -------------------------------------------------------------------------*/
521 
522 inline void
password_set(const char * value,int length)523 URL::password_set(const char *value, int length)
524 {
525   ink_assert(valid());
526   url_password_set(m_heap, m_url_impl, value, length, true);
527 }
528 
529 /*-------------------------------------------------------------------------
530   -------------------------------------------------------------------------*/
531 
532 inline const char *
host_get(int * length)533 URL::host_get(int *length)
534 {
535   ink_assert(valid());
536   *length = m_url_impl->m_len_host;
537   return m_url_impl->m_ptr_host;
538 }
539 
540 /*-------------------------------------------------------------------------
541   -------------------------------------------------------------------------*/
542 
543 inline void
host_set(const char * value,int length)544 URL::host_set(const char *value, int length)
545 {
546   ink_assert(valid());
547   url_host_set(m_heap, m_url_impl, value, length, true);
548 }
549 
550 /*-------------------------------------------------------------------------
551   -------------------------------------------------------------------------*/
552 
553 inline int
port_get()554 URL::port_get()
555 {
556   ink_assert(valid());
557   return url_canonicalize_port(m_url_impl->m_url_type, m_url_impl->m_port);
558 }
559 
560 /*-------------------------------------------------------------------------
561   -------------------------------------------------------------------------*/
562 
563 inline int
port_get_raw()564 URL::port_get_raw()
565 {
566   ink_assert(valid());
567   return m_url_impl->m_port;
568 }
569 
570 /*-------------------------------------------------------------------------
571   -------------------------------------------------------------------------*/
572 
573 inline void
port_set(int port)574 URL::port_set(int port)
575 {
576   ink_assert(valid());
577   url_port_set(m_heap, m_url_impl, port);
578 }
579 
580 /*-------------------------------------------------------------------------
581   -------------------------------------------------------------------------*/
582 
583 inline const char *
path_get(int * length)584 URL::path_get(int *length)
585 {
586   ink_assert(valid());
587   *length = m_url_impl->m_len_path;
588   return m_url_impl->m_ptr_path;
589 }
590 
591 /*-------------------------------------------------------------------------
592   -------------------------------------------------------------------------*/
593 
594 inline void
path_set(const char * value,int length)595 URL::path_set(const char *value, int length)
596 {
597   ink_assert(valid());
598   url_path_set(m_heap, m_url_impl, value, length, true);
599 }
600 
601 /*-------------------------------------------------------------------------
602   -------------------------------------------------------------------------*/
603 
604 inline int
type_get()605 URL::type_get()
606 {
607   ink_assert(valid());
608   return m_url_impl->m_type_code;
609 }
610 
611 /*-------------------------------------------------------------------------
612   -------------------------------------------------------------------------*/
613 
614 inline void
type_set(int type)615 URL::type_set(int type)
616 {
617   ink_assert(valid());
618   url_type_set(m_url_impl, type);
619 }
620 
621 /*-------------------------------------------------------------------------
622   -------------------------------------------------------------------------*/
623 
624 inline const char *
params_get(int * length)625 URL::params_get(int *length)
626 {
627   ink_assert(valid());
628   *length = m_url_impl->m_len_params;
629   return m_url_impl->m_ptr_params;
630 }
631 
632 /*-------------------------------------------------------------------------
633   -------------------------------------------------------------------------*/
634 
635 inline void
params_set(const char * value,int length)636 URL::params_set(const char *value, int length)
637 {
638   ink_assert(valid());
639   url_params_set(m_heap, m_url_impl, value, length, true);
640 }
641 
642 /*-------------------------------------------------------------------------
643   -------------------------------------------------------------------------*/
644 
645 inline const char *
query_get(int * length)646 URL::query_get(int *length)
647 {
648   ink_assert(valid());
649   *length = m_url_impl->m_len_query;
650   return m_url_impl->m_ptr_query;
651 }
652 
653 /*-------------------------------------------------------------------------
654   -------------------------------------------------------------------------*/
655 
656 inline void
query_set(const char * value,int length)657 URL::query_set(const char *value, int length)
658 {
659   ink_assert(valid());
660   url_query_set(m_heap, m_url_impl, value, length, true);
661 }
662 
663 /*-------------------------------------------------------------------------
664   -------------------------------------------------------------------------*/
665 
666 inline const char *
fragment_get(int * length)667 URL::fragment_get(int *length)
668 {
669   ink_assert(valid());
670   *length = m_url_impl->m_len_fragment;
671   return m_url_impl->m_ptr_fragment;
672 }
673 
674 /*-------------------------------------------------------------------------
675   -------------------------------------------------------------------------*/
676 
677 inline void
fragment_set(const char * value,int length)678 URL::fragment_set(const char *value, int length)
679 {
680   ink_assert(valid());
681   url_fragment_set(m_heap, m_url_impl, value, length, true);
682 }
683 
684 /**
685   Parser doesn't clear URL first, so if you parse over a non-clear URL,
686   the resulting URL may contain some of the previous data.
687 
688  */
689 inline ParseResult
parse(const char ** start,const char * end)690 URL::parse(const char **start, const char *end)
691 {
692   ink_assert(valid());
693   return url_parse(m_heap, m_url_impl, start, end, true);
694 }
695 
696 /**
697   Parser doesn't clear URL first, so if you parse over a non-clear URL,
698   the resulting URL may contain some of the previous data.
699 
700  */
701 inline ParseResult
parse(const char * str,int length)702 URL::parse(const char *str, int length)
703 {
704   ink_assert(valid());
705   if (length < 0)
706     length = (int)strlen(str);
707   return parse(&str, str + length);
708 }
709 
710 /**
711   Parser doesn't clear URL first, so if you parse over a non-clear URL,
712   the resulting URL may contain some of the previous data.
713 
714  */
715 inline ParseResult
parse_no_path_component_breakdown(const char * str,int length)716 URL::parse_no_path_component_breakdown(const char *str, int length)
717 {
718   ink_assert(valid());
719   if (length < 0)
720     length = (int)strlen(str);
721   ink_assert(valid());
722   return url_parse_no_path_component_breakdown(m_heap, m_url_impl, &str, str + length, true);
723 }
724 
725 /*-------------------------------------------------------------------------
726   -------------------------------------------------------------------------*/
727 
728 inline char *
unescapify(Arena * arena,const char * str,int length)729 URL::unescapify(Arena *arena, const char *str, int length)
730 {
731   return url_unescapify(arena, str, length);
732 }
733