- /*
- * MIT License
- *
- * Copyright (c) 2024 Roland Mainz <roland.mainz@nrubsig.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
- /* urlparser1.c - simple URL parser */
- #include <stdlib.h>
- #include <stdbool.h>
- #include <string.h>
- #include <stdio.h>
- /*
- * Original extended regular expression:
- *
- * "^"
- * "(.+?)" // scheme
- * "://" // '://'
- * "(" // login
- * "(?:"
- * "(.+?)" // user (optional)
- * "(?::(.+))?" // password (optional)
- * "@"
- * ")?"
- * "(" // hostport
- * "(.+?)" // host
- * "(?::([[:digit:]]+))?" // port (optional)
- * ")"
- * ")"
- * "(?:/(.*?))?" // path (optional)
- * "$"
- */
- #define DBGNULLSTR(s) (((s)!=NULL)?(s):"<NULL>")
- typedef
- struct _url_parser_context {
- char *in_url;
- char *scheme;
- struct {
- char *username;
- char *passwd;
- } login;
- struct {
- char *hostname;
- signed int port;
- } hostport;
- char *path;
- } url_parser_context;
- url_parser_context *url_parser_create_context(const char *in_url, unsigned int flags)
- {
- url_parser_context *uctx;
- char *s;
- size_t in_url_len;
- size_t context_len;
- if (!in_url)
- return NULL;
- context_len = sizeof(url_parser_context) +
- ((in_url_len+1)*5);
- if (!uctx)
- return NULL;
- s = (void *)(uctx+1);
- uctx->in_url = s; s+= in_url_len+1;
- uctx->scheme = s; s+= in_url_len+1;
- uctx->login.username = s; s+= in_url_len+1;
- uctx->hostport.hostname = s; s+= in_url_len+1;
- uctx->path = s; s+= in_url_len+1;
- uctx->hostport.port = -1;
- return uctx;
- }
- int url_parser_parse(url_parser_context *uctx)
- {
- char *s;
- const char *urlstr = uctx->in_url;
- size_t slen;
- if (!s) {
- return -1;
- }
- slen = s-urlstr;
- uctx->scheme[slen] = '\0';
- urlstr += slen + 3;
- if (s) {
- /* URL has user/password */
- slen = s-urlstr;
- uctx->login.username[slen] = '\0';
- urlstr += slen + 1;
- if (s) {
- /* found passwd */
- uctx->login.passwd = s+1;
- *s = '\0';
- }
- else
- {
- uctx->login.passwd = NULL;
- }
- /* catch password-only URLs */
- if (uctx->login.username[0] == '\0')
- uctx->login.username = NULL;
- }
- else
- {
- uctx->login.username = NULL;
- }
- DBGNULLSTR(uctx->login.username),
- DBGNULLSTR(uctx->login.passwd),
- DBGNULLSTR(urlstr));
- if (s) {
- /* URL has hostport */
- slen = s-urlstr;
- uctx->hostport.hostname[slen] = '\0';
- urlstr += slen + 1;
- if (s) {
- /* found port number */
- *s = '\0';
- }
- }
- else
- {
- uctx->path = NULL;
- urlstr = NULL;
- }
- DBGNULLSTR(uctx->hostport.hostname),
- uctx->hostport.port,
- DBGNULLSTR(urlstr));
- if (!urlstr) {
- return 0;
- }
- return 0;
- }
- void url_parser_free_context(url_parser_context *c)
- {
- }
- void test_url_parser(const char *instr)
- {
- url_parser_context *c;
- c = url_parser_create_context(instr, 0);
- (void)url_parser_parse(c);
- url_parser_free_context(c);
- }
- int main(int ac, char *av[])
- {
- (void)test_url_parser("foo://hostbar/baz");
- (void)test_url_parser("foo://myuser@hostbar/baz");
- (void)test_url_parser("foo://myuser:mypasswd@hostbar/baz");
- (void)test_url_parser("foo://myuser:mypasswd@hostbar:666/baz");
- (void)test_url_parser("foo://:mypasswd2@hostbar2:667/baf");
- (void)test_url_parser("foo://hostbar");
- (void)test_url_parser("foo://hostbar:93");
- (void)test_url_parser("foo://");
- (void)test_url_parser("typo:/hostbar");
- (void)test_url_parser("wrong");
- return EXIT_SUCCESS;
- }
urlparser1.c - simple URL parser
Posted by Anonymous on Wed 24th Jan 2024 10:56
raw | new post
view followups (newest first): urlparser1.c - simple URL parser by Anonymous
modification of post by Anonymous (view diff)
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.