import regex functions to parse request
This commit is contained in:
parent
bfd713c131
commit
2b835bc39c
15
utils.c
15
utils.c
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
|
1
utils.h
1
utils.h
|
@ -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
52
vger.c
|
@ -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
1
vger.h
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user