Coverage Report

Created: 2026-03-28 06:49

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