pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS

Difference between
modified post e0b45e18 by Anonymous on Wed 24th Jan 2024 16:57
original post d7e by Anonymous on Wed 24th Jan 2024 16:00
Download diff
Show old version | new version | both versions

    
11
/* urlparser1.c */
22
/*
33
 * MIT License
44
 *
55
 * Copyright (c) 2024 Roland Mainz <roland.mainz@nrubsig.org>
66
 *
77
 * Permission is hereby granted, free of charge, to any person obtaining a copy
88
 * of this software and associated documentation files (the "Software"), to deal
99
 * in the Software without restriction, including without limitation the rights
1010
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111
 * copies of the Software, and to permit persons to whom the Software is
1212
 * furnished to do so, subject to the following conditions:
1313
 *
1414
 * The above copyright notice and this permission notice shall be included in all
1515
 * copies or substantial portions of the Software.
1616
 *
1717
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323
 * SOFTWARE.
2424
 */
2525
2626
/* urlparser1.c - simple URL parser */
2727
2828
#include <stdlib.h>
2929
#include <stdbool.h>
3030
#include <string.h>
3131
#include <stdio.h>
3232
3333
#include "urlparser1.h"
3434
3535
/*
3636
 * Original extended regular expression:
3737
 *
3838
 * "^"
3939
 * "(.+?)"			 // scheme
4040
 * "://"  			 // '://'
4141
 * "("				 // login
4242
 * 	 "(?:"
4343
 * 		 "(.+?)"	 // user (optional)
4444
 * 		 "(?::(.+))?"	 // password (optional)
4545
 * 		 "@"
4646
 * 	 ")?"
4747
 * 	 "("			 // hostport
4848
 * 		 "(.+?)"	 // host
4949
 * 		 "(?::([[:digit:]]+))?" // port (optional)
5050
 * 	 ")"
5151
 * ")"
5252
 * "(?:/(.*?))?"  		 // path (optional)
5353
 * "$"
5454
 */
5555
5656
#define DBGNULLSTR(s) (((s)!=NULL)?(s):"<NULL>")
5757
#if 1
5858
#define D(x) x
5959
#else
6060
#define D(x)
6161
#endif
6262
6363
url_parser_context *url_parser_create_context(const char *in_url, unsigned int flags)
6464
{
6565
	url_parser_context *uctx;
6666
	char *s;
6767
	size_t in_url_len;
6868
	size_t context_len;
6969
7070
	if (!in_url)
7171
		return NULL;
7272
7373
	in_url_len = strlen(in_url);
7474
7575
	context_len = sizeof(url_parser_context) +
7676
		((in_url_len+1)*5);
7777
	uctx = malloc(context_len);
7878
	if (!uctx)
7979
		return NULL;
8080
8181
	s = (void *)(uctx+1);
8282
	uctx->in_url = s;		s+= in_url_len+1;
8383
	(void)strcpy(uctx->in_url, in_url);
8484
	uctx->scheme = s;		s+= in_url_len+1;
8585
	uctx->login.username = s;	s+= in_url_len+1;
8686
	uctx->hostport.hostname = s;	s+= in_url_len+1;
8787
	uctx->path = s;			s+= in_url_len+1;
8888
	uctx->hostport.port = -1;
8989
9090
	return uctx;
9191
}
9292
9393
int url_parser_parse(url_parser_context *uctx)
9494
{
9595
	D((void)fprintf(stderr, "## parser in_url='%s'\n", uctx->in_url));
9696
9797
	char *s;
9898
	const char *urlstr = uctx->in_url;
9999
	size_t slen;
100100
101101
	s = strstr(urlstr, "://");
102102
	if (!s) {
103103
		D((void)fprintf(stderr, "url_parser: Not an URL\n"));
104104
		return -1;
105105
	}
106106
107107
	slen = s-urlstr;
108108
	(void)memcpy(uctx->scheme, urlstr, slen*sizeof(char));
109109
	uctx->scheme[slen] = '\0';
110110
	urlstr += slen + 3;
111111
112112
	D((void)fprintf(stdout, "scheme='%s', rest='%s'\n", uctx->scheme, urlstr));
113113
114114
	s = strstr(urlstr, "@");
115115
	if (s) {
116116
		/* URL has user/password */
117117
		slen = s-urlstr;
118118
		(void)memcpy(uctx->login.username, urlstr, slen*sizeof(char));
119119
		uctx->login.username[slen] = '\0';
120120
		urlstr += slen + 1;
121121
122122
		s = strstr(uctx->login.username, ":");
123123
		if (s) {
124124
			/* found passwd */
125125
			uctx->login.passwd = s+1;
126126
			*s = '\0';
127127
		}
128128
		else
129129
		{
130130
			uctx->login.passwd = NULL;
131131
		}
132132
133133
		/* catch password-only URLs */
134134
		if (uctx->login.username[0] == '\0')
135135
			uctx->login.username = NULL;
136136
	}
137137
	else
138138
	{
139139
		uctx->login.username = NULL;
140140
		uctx->login.passwd = NULL;
141141
	}
142142
143143
	D((void)fprintf(stdout, "login='%s', passwd='%s', rest='%s'\n",
144144
		DBGNULLSTR(uctx->login.username),
145145
		DBGNULLSTR(uctx->login.passwd),
146146
		DBGNULLSTR(urlstr)));
147147
148148
	s = strstr(urlstr, "/");
149149
	if (s) {
150150
		/* URL has hostport */
151151
		slen = s-urlstr;
152152
		(void)memcpy(uctx->hostport.hostname, urlstr, slen*sizeof(char));
153153
		uctx->hostport.hostname[slen] = '\0';
154154
		urlstr += slen;
155155
156-
		s = strstr(uctx->hostport.hostname, ":");
156+
		/*
157-
		if (s) {
157+
		 * check for addresses within '[' and ']', like
158-
			/* found port number */
158+
		 * IPv6 addresses
159-
			uctx->hostport.port = atoi(s+1);
159+
		 */
160-
			*s = '\0';
160+
		s = uctx->hostport.hostname;
161+
		if (s[0] == '[')
161167
		}
168+
162174
	}
175+
	}
163176
	else
164177
	{
165178
		(void)strcpy(uctx->hostport.hostname, urlstr);
166179
		uctx->path = NULL;
167180
		urlstr = NULL;
168181
	}
169182
170183
	D((void)fprintf(stdout, "hostport='%s', port=%d, rest='%s'\n",
171184
		DBGNULLSTR(uctx->hostport.hostname),
172185
		uctx->hostport.port,
173186
		DBGNULLSTR(urlstr)));
174187
175188
	if (!urlstr) {
176189
		return 0;
177190
	}
178191
179192
	(void)strcpy(uctx->path, urlstr);
180193
	D((void)fprintf(stdout, "path='%s'\n", uctx->path));
181194
182195
	return 0;
183196
}
184197
185198
void url_parser_free_context(url_parser_context *c)
186199
{
187200
	free(c);
188201
}
189202
190203
void test_url_parser(const char *instr)
191204
{
192205
	url_parser_context *c;
193206
194207
	c = url_parser_create_context(instr, 0);
195208
196209
	(void)url_parser_parse(c);
197210
198211
	(void)fputc('\n', stdout);
199212
200213
	url_parser_free_context(c);
201214
}
202215
203216
int main(int ac, char *av[])
204217
{
205218
	(void)puts("#start");
206219
207220
	(void)setvbuf(stdout, NULL, _IONBF, 0);
208221
	(void)setvbuf(stderr, NULL, _IONBF, 0);
209222
210223
	(void)test_url_parser("foo://hostbar/baz");
211224
	(void)test_url_parser("foo://myuser@hostbar/baz");
212225
	(void)test_url_parser("foo://myuser:mypasswd@hostbar/baz");
213226
	(void)test_url_parser("foo://myuser:mypasswd@hostbar:666/baz");
227+
	(void)test_url_parser("foo://myuser:mypasswd@[fe80::21b:1bff:fec3:7713]:666/baz");
214228
	(void)test_url_parser("foo://:mypasswd2@hostbar2:667/baf");
215229
	(void)test_url_parser("foo://hostbar");
216230
	(void)test_url_parser("foo://hostbar:93");
217231
	(void)test_url_parser("foo://");
218232
	(void)test_url_parser("typo:/hostbar");
219233
	(void)test_url_parser("wrong");
220234
221235
	(void)puts("#done");
222236
223237
	return EXIT_SUCCESS;
224238
}
225239
/* urlparser1.h */
226240
/*
227241
 * MIT License
228242
 *
229243
 * Copyright (c) 2024 Roland Mainz <roland.mainz@nrubsig.org>
230244
 *
231245
 * Permission is hereby granted, free of charge, to any person obtaining a copy
232246
 * of this software and associated documentation files (the "Software"), to deal
233247
 * in the Software without restriction, including without limitation the rights
234248
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
235249
 * copies of the Software, and to permit persons to whom the Software is
236250
 * furnished to do so, subject to the following conditions:
237251
 *
238252
 * The above copyright notice and this permission notice shall be included in all
239253
 * copies or substantial portions of the Software.
240254
 *
241255
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
242256
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
243257
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
244258
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
245259
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
246260
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
247261
 * SOFTWARE.
248262
 */
249263
250264
/* urlparser1.h - header for simple URL parser */
251265
252266
#ifndef __URLPARSER1_H__
253267
#define __URLPARSER1_H__
254268
255269
#include <stdlib.h>
256270
257271
typedef
258272
struct _url_parser_context {
259273
	char *in_url;
260274
261275
	char *scheme;
262276
	struct {
263277
		char *username;
264278
		char *passwd;
265279
	} login;
266280
	struct {
267281
		char *hostname;
268282
		signed int port;
269283
	} hostport;
270284
	char *path;
271285
} url_parser_context;
272286
273287
/* Prototypes */
274288
url_parser_context *url_parser_create_context(const char *in_url, unsigned int flags);
275289
int url_parser_parse(url_parser_context *uctx);
276290
void url_parser_free_context(url_parser_context *c);
277291
278292
#endif /* !__URLPARSER1_H__ */
279293

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at