import regex functions to parse request

This commit is contained in:
prx 2022-08-17 21:28:09 +02:00
parent bfd713c131
commit 2b835bc39c
4 changed files with 69 additions and 0 deletions

15
utils.c
View File

@ -1,5 +1,8 @@
#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <regex.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@ -115,3 +118,15 @@ print_file(FILE *fd)
datasent += fwrite(buffer, 1, nread, stdout);
return datasent;
}
void
getsubexp(const char *str, regmatch_t m, char *dst)
{
size_t len = 0;
if (m.rm_eo > m.rm_so) { /* skip empty substring */
len = m.rm_eo - m.rm_so;
memcpy(dst, str + m.rm_so, len);
dst[len] = '\0';
}
}

View File

@ -1,3 +1,4 @@
void getsubexp(const char *, regmatch_t, char *);
void echdir (const char *);
void epledge(const char *, const char *);
void eunveil(const char *, const char *);

52
vger.c
View File

@ -9,6 +9,7 @@
#include <fcntl.h>
#include <limits.h>
#include <pwd.h>
#include <regex.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@ -503,3 +504,54 @@ get_query(char *path, char *query, size_t querysiz)
}
return query;
}
void
split_request(const char *request, char *hostname, char *path, char *query)
{
regex_t greg = {0}; /* compiled gemini regex */
regmatch_t *match = {0}; /* matches founds */
size_t nmatch = 4; /* number of substrings to look for */
char buf[BUFSIZ] = {'\0'}; /* to handle error messages */
int ret = 0;
const char *gemini_regex = "^gemini://+([^/|^\?]*)/*([^\?]*)[\?]?(.*)$";
/*
* ^gemini://+ : in case of gemini:///
* 1: hostname
* ([^/|^\?]*) :
* catch everything, stop when / or ? is found
* then skip multiple /
* 2: path
* ([^\?]*) :
* catch everything and stop at ? if any
* 3 : query
* [\?]?(.*)$:
* catch everything after ? if any
*/
if ((ret = regcomp(&greg, gemini_regex, REG_EXTENDED)) != 0) {
regerror(ret, &greg, buf, sizeof(buf));
regfree(&greg);
status(50, "Internal server error");
stop(EXIT_FAILURE, "%s", buf);
}
if ((ret = regexec(&greg, request, nmatch, match, 0)) != 0) {
regerror(ret, &greg, buf, sizeof(buf));
regfree(&greg);
status(59, "Malformed request");
stop(EXIT_FAILURE, "Malformed request, error:%s", buf);
}
/* one may want to check the return of getsubexp
* and change memcpy to strlcpy
* to make sure we didn't try to copy too long
* and that string isn't trunkated.
* It is unlikely to happen since dest string are as long as request
*/
getsubexp(request, match[1], hostname);
getsubexp(request, match[2], path);
getsubexp(request, match[3], query);
regfree(&greg);
}

1
vger.h
View File

@ -31,6 +31,7 @@ char * get_query(char *, char *, size_t);
void status(const int, const char *, ...);
void strip_trailing_slash(char *);
int uridecode (char *);
void split_request(const char *, char *, char *, char *);
void stop(const int, const char *, ...);
#endif // vger_h_INCLUDED