3232#include "keys.h"
3333#include "socket.h"
3434
35+ const unsigned int MAX_URL = 256 ;
36+
3537static const struct option long_options [] = {
3638 {"port" , 1 , 0 , 'p' },
39+ {"endpoint" , 1 , 0 , 'e' },
3740 {"listen" , 0 , 0 , 'l' },
3841 {"version" , 0 , 0 , 'v' },
3942 {"help" , 0 , 0 , 'h' },
@@ -45,6 +48,7 @@ print_help(const char *name)
4548{
4649 fprintf (stderr , "Usage: %s [OPTIONS] <jwkdir>\n" , name );
4750 fprintf (stderr , " -p, --port=PORT Specify the port to listen (default 9090)\n" );
51+ fprintf (stderr , " -e, --endpoint=ENDPOINT Specify endpoint to listen (empty by default)\n" );
4852 fprintf (stderr , " -l, --listen Run as a service and wait for connections\n" );
4953 fprintf (stderr , " -v, --version Display program version\n" );
5054 fprintf (stderr , " -h, --help Show this help message\n" );
@@ -184,19 +188,19 @@ rec(http_method_t method, const char *path, const char *body,
184188 "\r\n%s" , strlen (enc ), enc );
185189}
186190
187- static struct http_dispatch dispatch [] = {
188- { adv , 1 << HTTP_GET , 2 , "^/+adv/+([0-9A-Za-z_-]+)$" },
189- { adv , 1 << HTTP_GET , 2 , "^/+adv/*$" },
190- { rec , 1 << HTTP_POST , 2 , "^/+rec/+([0-9A-Za-z_-]+)$" },
191- {}
192- };
193-
194191#define DEFAULT_PORT 9090
195192
193+ static struct http_dispatch s_dispatch [] = {
194+ { adv , 1 << HTTP_GET , 2 , "^/+adv/+([0-9A-Za-z_-]+)$" },
195+ { adv , 1 << HTTP_GET , 2 , "^/+adv/*$" },
196+ { rec , 1 << HTTP_POST , 2 , "^/+rec/+([0-9A-Za-z_-]+)$" },
197+ {}
198+ };
199+
196200static int
197201process_request (const char * jwkdir , int in_fileno )
198202{
199- struct http_state state = { .dispatch = dispatch , .misc = (char * )jwkdir };
203+ struct http_state state = { .dispatch = s_dispatch , .misc = (char * )jwkdir };
200204 http_parser_t parser ;
201205 struct stat st = {};
202206 char req [4096 ] = {};
@@ -244,9 +248,10 @@ main(int argc, char *argv[])
244248 int listen = 0 ;
245249 int port = DEFAULT_PORT ;
246250 const char * jwkdir = NULL ;
251+ const char * endpoint = NULL ;
247252
248253 while (1 ) {
249- int c = getopt_long (argc , argv , "lp:vh" , long_options , NULL );
254+ int c = getopt_long (argc , argv , "lp:e: vh" , long_options , NULL );
250255 if (c == -1 )
251256 break ;
252257
@@ -260,6 +265,9 @@ main(int argc, char *argv[])
260265 case 'p' :
261266 port = atoi (optarg );
262267 break ;
268+ case 'e' :
269+ endpoint = optarg ;
270+ break ;
263271 case 'l' :
264272 listen = 1 ;
265273 break ;
@@ -272,9 +280,25 @@ main(int argc, char *argv[])
272280 }
273281 jwkdir = argv [optind ++ ];
274282
283+ // Adjust endpoint
284+ char adv_endpoint [MAX_URL ];
285+ char adv_thp_endpoint [MAX_URL ];
286+ char rec_endpoint [MAX_URL ];
287+ if (endpoint != NULL ) {
288+ char * endpoint_ptr = (char * )endpoint ;
289+ while (* endpoint_ptr == '/' ) {
290+ endpoint_ptr ++ ;
291+ }
292+ snprintf (adv_endpoint , MAX_URL , "^/%s/+adv/+([0-9A-Za-z_-]+)$" , endpoint_ptr );
293+ snprintf (adv_thp_endpoint , MAX_URL , "^/%s/+adv/*$" , endpoint_ptr );
294+ snprintf (rec_endpoint , MAX_URL , "^/%s/+rec/+([0-9A-Za-z_-]+)$" , endpoint_ptr );
295+ s_dispatch [0 ].re = adv_endpoint ;
296+ s_dispatch [1 ].re = adv_thp_endpoint ;
297+ s_dispatch [2 ].re = rec_endpoint ;
298+ }
275299 if (listen == 0 ) { /* process one-shot query from stdin */
276- return process_request (jwkdir , STDIN_FILENO );
300+ return process_request (jwkdir , STDIN_FILENO );
277301 } else { /* listen and process all incoming connections */
278- return run_service (jwkdir , port , process_request );
302+ return run_service (jwkdir , port , process_request );
279303 }
280304}
0 commit comments