cosmopolitan/net/http/uriparse.c
2021-01-17 09:42:52 -08:00

724 lines
20 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2021 Justine Alexandra Roberts Tunney │
│ │
│ Permission to use, copy, modify, and/or distribute this software for │
│ any purpose with or without fee is hereby granted, provided that the │
│ above copyright notice and this permission notice appear in all copies. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/dce.h"
#include "libc/dns/dns.h"
#include "libc/log/log.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
#include "net/http/uri.h"
/*
* GENERATED BY
*
* ragel -o net/http/uriparse.c net/http/uriparse.rl
*
* TODO(jart): Rewrite in normal C.
*/
#define static
/* clang-format off */
#line 32 "net/http/uriparse.rl"
#line 37 "build/bootstrap/net/http/uriparse.c"
static const char _uriparse_actions[] = {
0, 1, 0, 1, 1, 1, 2, 1,
3, 1, 4, 1, 5, 1, 6, 1,
8, 1, 11, 1, 12, 2, 0, 2,
2, 4, 8, 2, 5, 8, 2, 6,
9, 2, 6, 10, 2, 7, 9, 2,
7, 10, 2, 8, 0, 2, 11, 0,
3, 4, 8, 0, 3, 5, 8, 0,
3, 6, 9, 0, 3, 7, 9, 0
};
static const short _uriparse_key_offsets[] = {
0, 0, 6, 12, 18, 24, 37, 43,
49, 64, 70, 76, 91, 97, 103, 118,
124, 130, 145, 151, 157, 169, 188, 202,
208, 214, 224, 226, 233, 241, 256, 273,
279, 285, 302, 308, 314, 326, 332, 338,
357, 371, 377, 383, 393, 395, 410, 416,
422, 437, 443, 449, 456, 464, 479, 494,
509, 520, 531, 546, 564, 581, 598, 614,
625, 630, 634, 653, 671, 689, 707, 727,
728, 739, 742, 759, 775, 777, 797
};
static const char _uriparse_trans_keys[] = {
48, 57, 65, 70, 97, 102, 48, 57,
65, 70, 97, 102, 48, 57, 65, 70,
97, 102, 48, 57, 65, 70, 97, 102,
33, 37, 61, 95, 126, 36, 46, 48,
58, 64, 90, 97, 122, 48, 57, 65,
70, 97, 102, 48, 57, 65, 70, 97,
102, 33, 37, 93, 95, 126, 36, 43,
45, 46, 48, 58, 65, 91, 97, 122,
48, 57, 65, 70, 97, 102, 48, 57,
65, 70, 97, 102, 33, 37, 93, 95,
126, 36, 43, 45, 46, 48, 58, 65,
91, 97, 122, 48, 57, 65, 70, 97,
102, 48, 57, 65, 70, 97, 102, 33,
36, 37, 63, 93, 95, 126, 39, 43,
45, 58, 65, 91, 97, 122, 48, 57,
65, 70, 97, 102, 48, 57, 65, 70,
97, 102, 33, 36, 37, 63, 93, 95,
126, 39, 43, 45, 58, 65, 91, 97,
122, 48, 57, 65, 70, 97, 102, 48,
57, 65, 70, 97, 102, 33, 37, 47,
61, 95, 126, 36, 58, 64, 90, 97,
122, 33, 37, 43, 58, 61, 63, 91,
95, 126, 36, 44, 45, 46, 48, 57,
65, 90, 97, 122, 33, 37, 61, 64,
95, 126, 36, 46, 48, 58, 63, 90,
97, 122, 48, 57, 65, 70, 97, 102,
48, 57, 65, 70, 97, 102, 43, 91,
45, 46, 48, 57, 65, 90, 97, 122,
48, 57, 46, 48, 58, 65, 70, 97,
102, 46, 93, 48, 58, 65, 70, 97,
102, 33, 37, 58, 61, 64, 95, 126,
36, 46, 48, 57, 63, 90, 97, 122,
33, 37, 38, 44, 47, 61, 64, 91,
93, 95, 126, 36, 58, 63, 90, 97,
122, 48, 57, 65, 70, 97, 102, 48,
57, 65, 70, 97, 102, 33, 37, 38,
44, 47, 61, 64, 91, 93, 95, 126,
36, 58, 63, 90, 97, 122, 48, 57,
65, 70, 97, 102, 48, 57, 65, 70,
97, 102, 33, 37, 47, 61, 95, 126,
36, 59, 63, 90, 97, 122, 48, 57,
65, 70, 97, 102, 48, 57, 65, 70,
97, 102, 33, 37, 43, 58, 61, 63,
91, 95, 126, 36, 44, 45, 46, 48,
57, 65, 90, 97, 122, 33, 37, 61,
64, 95, 126, 36, 46, 48, 58, 63,
90, 97, 122, 48, 57, 65, 70, 97,
102, 48, 57, 65, 70, 97, 102, 43,
91, 45, 46, 48, 57, 65, 90, 97,
122, 48, 57, 33, 37, 93, 95, 126,
36, 43, 45, 46, 48, 58, 65, 91,
97, 122, 48, 57, 65, 70, 97, 102,
48, 57, 65, 70, 97, 102, 33, 37,
93, 95, 126, 36, 43, 45, 46, 48,
58, 65, 91, 97, 122, 48, 57, 65,
70, 97, 102, 48, 57, 65, 70, 97,
102, 46, 48, 58, 65, 70, 97, 102,
46, 93, 48, 58, 65, 70, 97, 102,
33, 37, 58, 61, 64, 95, 126, 36,
46, 48, 57, 63, 90, 97, 122, 33,
35, 37, 47, 59, 61, 64, 95, 126,
36, 57, 65, 90, 97, 122, 33, 35,
37, 47, 59, 61, 63, 95, 126, 36,
57, 64, 90, 97, 122, 33, 37, 61,
95, 126, 36, 59, 63, 90, 97, 122,
33, 37, 61, 95, 126, 36, 59, 63,
90, 97, 122, 33, 35, 37, 47, 59,
61, 63, 95, 126, 36, 58, 64, 90,
97, 122, 33, 35, 37, 47, 59, 61,
63, 93, 95, 126, 36, 43, 45, 58,
65, 91, 97, 122, 33, 35, 37, 47,
59, 63, 93, 95, 126, 36, 43, 45,
58, 65, 91, 97, 122, 33, 35, 37,
38, 61, 63, 93, 95, 126, 36, 43,
45, 58, 65, 91, 97, 122, 33, 35,
37, 38, 63, 93, 95, 126, 36, 43,
45, 58, 65, 91, 97, 122, 35, 43,
47, 58, 63, 45, 57, 65, 90, 97,
122, 35, 47, 63, 48, 57, 35, 47,
58, 63, 33, 35, 37, 43, 47, 58,
61, 63, 64, 95, 126, 36, 44, 45,
57, 65, 90, 97, 122, 33, 35, 37,
47, 58, 61, 63, 64, 95, 126, 36,
46, 48, 57, 65, 90, 97, 122, 33,
35, 37, 38, 44, 47, 61, 64, 91,
93, 95, 126, 36, 58, 63, 90, 97,
122, 33, 35, 37, 38, 44, 47, 61,
64, 91, 93, 95, 126, 36, 58, 63,
90, 97, 122, 33, 35, 37, 43, 47,
58, 59, 61, 63, 64, 95, 126, 36,
44, 45, 57, 65, 90, 97, 122, 35,
43, 58, 59, 45, 46, 48, 57, 65,
90, 97, 122, 59, 48, 57, 33, 37,
59, 61, 93, 95, 126, 36, 43, 45,
46, 48, 58, 65, 91, 97, 122, 33,
37, 59, 93, 95, 126, 36, 43, 45,
46, 48, 58, 65, 91, 97, 122, 58,
59, 33, 37, 43, 58, 59, 61, 63,
64, 95, 126, 36, 44, 45, 46, 48,
57, 65, 90, 97, 122, 33, 37, 58,
59, 61, 64, 95, 126, 36, 46, 48,
57, 63, 90, 97, 122, 0
};
static const char _uriparse_single_lengths[] = {
0, 0, 0, 0, 0, 5, 0, 0,
5, 0, 0, 5, 0, 0, 7, 0,
0, 7, 0, 0, 6, 9, 6, 0,
0, 2, 0, 1, 2, 7, 11, 0,
0, 11, 0, 0, 6, 0, 0, 9,
6, 0, 0, 2, 0, 5, 0, 0,
5, 0, 0, 1, 2, 7, 9, 9,
5, 5, 9, 10, 9, 9, 8, 5,
3, 4, 11, 10, 12, 12, 12, 1,
3, 1, 7, 6, 2, 10, 8
};
static const char _uriparse_range_lengths[] = {
0, 3, 3, 3, 3, 4, 3, 3,
5, 3, 3, 5, 3, 3, 4, 3,
3, 4, 3, 3, 3, 5, 4, 3,
3, 4, 1, 3, 3, 4, 3, 3,
3, 3, 3, 3, 3, 3, 3, 5,
4, 3, 3, 4, 1, 5, 3, 3,
5, 3, 3, 3, 3, 4, 3, 3,
3, 3, 3, 4, 4, 4, 4, 3,
1, 0, 4, 4, 3, 3, 4, 0,
4, 1, 5, 5, 0, 5, 4
};
static const short _uriparse_index_offsets[] = {
0, 0, 4, 8, 12, 16, 26, 30,
34, 45, 49, 53, 64, 68, 72, 84,
88, 92, 104, 108, 112, 122, 137, 148,
152, 156, 163, 165, 170, 176, 188, 203,
207, 211, 226, 230, 234, 244, 248, 252,
267, 278, 282, 286, 293, 295, 306, 310,
314, 325, 329, 333, 338, 344, 356, 369,
382, 391, 400, 413, 428, 442, 456, 469,
478, 483, 488, 504, 519, 535, 551, 568,
570, 578, 581, 594, 606, 609, 625
};
static const unsigned char _uriparse_indicies[] = {
0, 0, 0, 1, 2, 2, 2, 1,
3, 3, 3, 1, 4, 4, 4, 1,
5, 6, 5, 5, 5, 5, 5, 5,
5, 1, 7, 7, 7, 1, 5, 5,
5, 1, 8, 9, 8, 8, 8, 8,
8, 8, 8, 8, 1, 10, 10, 10,
1, 11, 11, 11, 1, 12, 13, 12,
12, 12, 12, 12, 12, 12, 12, 1,
14, 14, 14, 1, 15, 15, 15, 1,
16, 16, 17, 16, 16, 16, 16, 16,
16, 16, 16, 1, 18, 18, 18, 1,
19, 19, 19, 1, 20, 20, 21, 20,
20, 20, 20, 20, 20, 20, 20, 1,
22, 22, 22, 1, 23, 23, 23, 1,
5, 6, 24, 5, 5, 5, 5, 5,
5, 1, 25, 26, 27, 25, 25, 25,
28, 25, 25, 25, 27, 27, 27, 27,
1, 29, 30, 29, 31, 29, 29, 29,
29, 29, 29, 1, 32, 32, 32, 1,
29, 29, 29, 1, 33, 28, 33, 33,
33, 33, 1, 34, 1, 35, 35, 35,
35, 1, 36, 37, 36, 36, 36, 1,
29, 30, 29, 29, 31, 29, 29, 29,
38, 29, 29, 1, 39, 40, 29, 29,
16, 29, 31, 16, 16, 39, 39, 39,
39, 39, 1, 41, 41, 41, 1, 42,
42, 42, 1, 43, 44, 29, 29, 20,
29, 31, 20, 20, 43, 43, 43, 43,
43, 1, 45, 45, 45, 1, 46, 46,
46, 1, 47, 48, 49, 47, 47, 47,
47, 47, 47, 1, 50, 50, 50, 1,
47, 47, 47, 1, 51, 52, 53, 51,
51, 51, 54, 51, 51, 51, 53, 53,
53, 53, 1, 55, 56, 55, 57, 55,
55, 55, 55, 55, 55, 1, 58, 58,
58, 1, 55, 55, 55, 1, 59, 60,
59, 59, 59, 59, 1, 61, 1, 62,
63, 62, 62, 62, 62, 62, 62, 62,
62, 1, 64, 64, 64, 1, 65, 65,
65, 1, 66, 67, 66, 66, 66, 66,
66, 66, 66, 66, 1, 68, 68, 68,
1, 69, 69, 69, 1, 70, 70, 70,
70, 1, 71, 72, 71, 71, 71, 1,
55, 56, 55, 55, 57, 55, 55, 55,
73, 55, 55, 1, 74, 75, 76, 49,
74, 74, 74, 74, 74, 74, 77, 77,
1, 4, 78, 79, 80, 4, 4, 81,
4, 4, 4, 4, 4, 1, 82, 83,
82, 82, 82, 82, 82, 82, 1, 2,
84, 2, 2, 2, 2, 2, 2, 1,
5, 78, 6, 80, 85, 5, 81, 5,
5, 5, 5, 5, 1, 11, 86, 87,
88, 89, 90, 91, 11, 11, 11, 11,
11, 11, 11, 1, 15, 92, 93, 94,
95, 96, 15, 15, 15, 15, 15, 15,
15, 1, 19, 97, 98, 99, 100, 19,
19, 19, 19, 19, 19, 19, 19, 1,
23, 101, 102, 103, 23, 23, 23, 23,
23, 23, 23, 23, 1, 104, 105, 106,
107, 108, 105, 105, 105, 1, 109, 110,
112, 111, 1, 113, 114, 115, 116, 1,
29, 104, 30, 117, 106, 118, 29, 119,
31, 29, 29, 29, 117, 117, 117, 1,
29, 109, 30, 110, 29, 29, 121, 31,
29, 29, 29, 120, 29, 29, 1, 42,
97, 122, 123, 29, 19, 124, 31, 19,
19, 42, 42, 42, 42, 42, 1, 46,
101, 125, 126, 29, 23, 29, 31, 23,
23, 46, 46, 46, 46, 46, 1, 4,
78, 79, 127, 80, 128, 4, 4, 81,
4, 4, 4, 4, 127, 127, 127, 1,
75, 1, 129, 130, 131, 129, 129, 129,
129, 1, 133, 132, 1, 65, 134, 135,
136, 65, 65, 65, 65, 65, 65, 65,
65, 1, 69, 137, 138, 69, 69, 69,
69, 69, 69, 69, 69, 1, 139, 140,
1, 55, 56, 141, 142, 131, 55, 55,
57, 55, 55, 55, 141, 141, 141, 141,
1, 55, 56, 55, 133, 55, 57, 55,
55, 55, 143, 55, 55, 1, 0
};
static const char _uriparse_trans_targs[] = {
2, 0, 57, 4, 55, 58, 6, 7,
59, 9, 10, 59, 60, 12, 13, 60,
61, 15, 16, 61, 62, 18, 19, 62,
21, 22, 23, 66, 27, 22, 23, 25,
24, 63, 64, 28, 28, 65, 67, 68,
31, 32, 68, 69, 34, 35, 69, 71,
37, 20, 38, 40, 41, 77, 51, 40,
41, 43, 42, 72, 51, 73, 74, 46,
47, 74, 75, 49, 50, 75, 52, 52,
76, 78, 55, 56, 3, 70, 56, 3,
5, 14, 57, 1, 1, 8, 56, 9,
5, 8, 11, 14, 56, 12, 5, 8,
14, 56, 15, 14, 17, 56, 18, 14,
56, 63, 5, 26, 14, 56, 5, 64,
14, 56, 5, 26, 14, 66, 29, 30,
67, 30, 31, 30, 33, 34, 30, 70,
36, 72, 44, 45, 73, 45, 46, 45,
48, 49, 45, 44, 45, 77, 53, 78
};
static const char _uriparse_trans_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0,
1, 1, 0, 0, 1, 1, 0, 0,
0, 1, 1, 1, 0, 0, 0, 7,
0, 1, 1, 1, 0, 9, 1, 1,
1, 0, 0, 1, 1, 0, 0, 19,
0, 1, 0, 1, 1, 1, 1, 0,
0, 7, 0, 1, 0, 1, 1, 1,
0, 0, 1, 1, 0, 0, 1, 0,
9, 1, 1, 0, 1, 1, 17, 0,
45, 17, 1, 1, 0, 17, 30, 0,
56, 30, 13, 30, 36, 0, 60, 36,
36, 33, 0, 33, 13, 39, 0, 39,
24, 0, 48, 9, 24, 27, 52, 0,
27, 15, 42, 0, 15, 0, 9, 24,
0, 27, 0, 33, 13, 0, 39, 0,
3, 0, 9, 9, 0, 11, 0, 30,
13, 0, 36, 0, 0, 0, 9, 0
};
static const char _uriparse_eof_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 17,
21, 5, 17, 30, 36, 33, 39, 24,
27, 15, 24, 27, 33, 39, 17, 0,
9, 11, 30, 36, 0, 9, 11
};
static const int uriparse_start = 54;
static const int uriparse_first_final = 54;
static const int uriparse_error = 0;
static const int uriparse_en_sip = 39;
static const int uriparse_en_uri = 54;
#line 33 "net/http/uriparse.rl"
/* clang-format on */
/**
* Parses URI.
*
* This is a general URL parser. It's typically used for HTTP. Support
* for the bonus syntax needed by SIP is provided. The whirlwhind tour
* of the URI rabbit hole is as follows:
*
* /foo.html
* //justine.local/foo.html
* http://justine.local/foo.html
* http://bettersearchengine.local/search.cgi?q=my%20query
* file:///etc/passwd
* gs://bucket/object.txt
* zip:///usr/share/zoneinfo/GMT
* sip:127.0.0.1:5060;lr
* sip:+12125650666@gateway.example
* sip:bob%20barker:priceisright@[dead:beef::666]:5060;isup-oli=00
* data:video/mpeg;base64,gigabytesofhex
*
* This parser operates on slices rather than C strings. It performs
* slicing and validation only. Operations like turning "%20"→" " or
* "80"→80 and perfect hashing can be done later, if needed.
*
* The Uri object is owned by the caller; it has a lifecycle like the
* following:
*
* struct Uri uri;
* memset(&uri, 0, sizeof(uri));
*
* uriparse(&uri, s1, strlen(s1));
* CHECK_EQ(kUriSchemeHttp, urischeme(uri->scheme, s1));
*
* uriparse(&uri, s2, strlen(s2));
* printf("host = %`.*s\n", uri->host.n, s2 + uri->host.i);
*
* Inner arrays may be granted memory by the caller. The uri->𝐴.i field
* is cleared at the mark of this function. No more than uri->𝐴.n items
* can be inserted. If we need more than that, then ENOMEM is returned
* rather than dynamically extending uri->𝐴.p. However, if uri->𝐴.n==0,
* we assume caller doesn't care about uri->𝐴 and its data is discarded.
*
* @param uri is owned by caller
* @param p is caller-owned uri string; won't copy/alias/mutate
* @return 0 on success, or -1 w/ errno
* @see RFC2396: Uniform Resource Identifiers (URI): Generic Syntax
* @see RFC3261: SIP: Session Initiation Protocol
*/
int uriparse(struct Uri *uri, const char *p, size_t size) {
unsigned zero, cs;
struct UriKeyval kv;
const char *pe, *eof, *buf, *mark;
assert(p || !size);
assert(size <= 0x7ffff000);
#define ABSENT ((struct UriSlice){zero, zero})
#define SLICE ((struct UriSlice){mark - buf, p - mark})
cs = zero = VEIL("r", 0u);
eof = pe = (mark = buf = p) + size;
uri->scheme = ABSENT;
uri->opaque = ABSENT;
uri->userinfo = ABSENT;
uri->host = ABSENT;
uri->port = ABSENT;
uri->fragment = ABSENT;
uri->segs.i = zero;
uri->paramsegs.i = zero;
uri->params.i = zero;
uri->queries.i = zero;
/* clang-format off */
#line 229 "net/http/uriparse.rl"
#line 435 "build/bootstrap/net/http/uriparse.c"
{
cs = uriparse_start;
}
#line 232 "net/http/uriparse.rl"
cs = uriparse_en_uri;
#line 443 "build/bootstrap/net/http/uriparse.c"
{
int _klen;
unsigned int _trans;
const char *_acts;
unsigned int _nacts;
const char *_keys;
if ( p == pe )
goto _test_eof;
if ( cs == 0 )
goto _out;
_resume:
_keys = _uriparse_trans_keys + _uriparse_key_offsets[cs];
_trans = _uriparse_index_offsets[cs];
_klen = _uriparse_single_lengths[cs];
if ( _klen > 0 ) {
const char *_lower = _keys;
const char *_mid;
const char *_upper = _keys + _klen - 1;
while (1) {
if ( _upper < _lower )
break;
_mid = _lower + ((_upper-_lower) >> 1);
if ( (*p) < *_mid )
_upper = _mid - 1;
else if ( (*p) > *_mid )
_lower = _mid + 1;
else {
_trans += (unsigned int)(_mid - _keys);
goto _match;
}
}
_keys += _klen;
_trans += _klen;
}
_klen = _uriparse_range_lengths[cs];
if ( _klen > 0 ) {
const char *_lower = _keys;
const char *_mid;
const char *_upper = _keys + (_klen<<1) - 2;
while (1) {
if ( _upper < _lower )
break;
_mid = _lower + (((_upper-_lower) >> 1) & ~1);
if ( (*p) < _mid[0] )
_upper = _mid - 2;
else if ( (*p) > _mid[1] )
_lower = _mid + 2;
else {
_trans += (unsigned int)((_mid - _keys)>>1);
goto _match;
}
}
_trans += _klen;
}
_match:
_trans = _uriparse_indicies[_trans];
cs = _uriparse_trans_targs[_trans];
if ( _uriparse_trans_actions[_trans] == 0 )
goto _again;
_acts = _uriparse_actions + _uriparse_trans_actions[_trans];
_nacts = (unsigned int) *_acts++;
while ( _nacts-- > 0 )
{
switch ( *_acts++ )
{
case 0:
#line 110 "net/http/uriparse.rl"
{ mark = p; }
break;
case 1:
#line 111 "net/http/uriparse.rl"
{ uri->scheme = SLICE; }
break;
case 3:
#line 113 "net/http/uriparse.rl"
{ uri->userinfo = SLICE; }
break;
case 4:
#line 114 "net/http/uriparse.rl"
{ uri->host = SLICE; }
break;
case 5:
#line 115 "net/http/uriparse.rl"
{ uri->port = SLICE; }
break;
case 6:
#line 117 "net/http/uriparse.rl"
{
kv.k = SLICE;
kv.v = (struct UriSlice){zero, zero};
}
break;
case 7:
#line 122 "net/http/uriparse.rl"
{
kv.v = SLICE;
}
break;
case 8:
#line 126 "net/http/uriparse.rl"
{
uri->segs.i = zero;
uri->paramsegs.i = zero;
}
break;
case 9:
#line 131 "net/http/uriparse.rl"
{
if (uri->params.n) {
if (uri->params.i < uri->params.n) {
uri->params.p[uri->params.i++] = kv;
} else {
return enomem();
}
}
}
break;
case 10:
#line 141 "net/http/uriparse.rl"
{
if (uri->queries.n) {
if (uri->queries.i < uri->queries.n) {
uri->queries.p[uri->queries.i++] = kv;
} else {
return enomem();
}
}
}
break;
case 11:
#line 151 "net/http/uriparse.rl"
{
if (p > mark && uri->segs.n) {
if (uri->segs.i < uri->segs.n) {
uri->segs.p[uri->segs.i++] = SLICE;
} else {
return enomem();
}
}
}
break;
case 12:
#line 161 "net/http/uriparse.rl"
{
switch (urischeme(uri->scheme, buf)) {
case kUriSchemeSip:
case kUriSchemeSips:
--p;
{cs = 39;goto _again;}
default:
if (uricspn(p, pe - p) == pe - p) {
uri->opaque = (struct UriSlice){p - buf, pe - p};
return zero;
} else {
return einval();
}
}
}
break;
#line 611 "build/bootstrap/net/http/uriparse.c"
}
}
_again:
if ( cs == 0 )
goto _out;
if ( ++p != pe )
goto _resume;
_test_eof: {}
if ( p == eof )
{
const char *__acts = _uriparse_actions + _uriparse_eof_actions[cs];
unsigned int __nacts = (unsigned int) *__acts++;
while ( __nacts-- > 0 ) {
switch ( *__acts++ ) {
case 0:
#line 110 "net/http/uriparse.rl"
{ mark = p; }
break;
case 2:
#line 112 "net/http/uriparse.rl"
{ uri->fragment = SLICE; }
break;
case 4:
#line 114 "net/http/uriparse.rl"
{ uri->host = SLICE; }
break;
case 5:
#line 115 "net/http/uriparse.rl"
{ uri->port = SLICE; }
break;
case 6:
#line 117 "net/http/uriparse.rl"
{
kv.k = SLICE;
kv.v = (struct UriSlice){zero, zero};
}
break;
case 7:
#line 122 "net/http/uriparse.rl"
{
kv.v = SLICE;
}
break;
case 8:
#line 126 "net/http/uriparse.rl"
{
uri->segs.i = zero;
uri->paramsegs.i = zero;
}
break;
case 9:
#line 131 "net/http/uriparse.rl"
{
if (uri->params.n) {
if (uri->params.i < uri->params.n) {
uri->params.p[uri->params.i++] = kv;
} else {
return enomem();
}
}
}
break;
case 10:
#line 141 "net/http/uriparse.rl"
{
if (uri->queries.n) {
if (uri->queries.i < uri->queries.n) {
uri->queries.p[uri->queries.i++] = kv;
} else {
return enomem();
}
}
}
break;
case 11:
#line 151 "net/http/uriparse.rl"
{
if (p > mark && uri->segs.n) {
if (uri->segs.i < uri->segs.n) {
uri->segs.p[uri->segs.i++] = SLICE;
} else {
return enomem();
}
}
}
break;
#line 699 "build/bootstrap/net/http/uriparse.c"
}
}
}
_out: {}
}
#line 234 "net/http/uriparse.rl"
/* clang-format on */
if (cs >= uriparse_first_final) {
if (uri->host.n <= DNS_NAME_MAX && uri->port.n <= 6) {
return zero;
} else {
return eoverflow();
}
} else {
return einval();
}
}