From 0917ae22bc82c991d38a66222846c31ee0d6692d Mon Sep 17 00:00:00 2001 From: op Date: Sat, 6 Aug 2022 17:11:36 +0000 Subject: add a -t flag to change the request timeout original diff from Alfred Morgan (alfred [at] 54 dot org) ok florian@ and manpage tweaks by me. --- Makefile | 2 +- slowcgi.8 | 11 ++++++++-- slowcgi.c | 24 +++++++++++++++++---- strtonum.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 strtonum.c diff --git a/Makefile b/Makefile index 95cd170..09c3eaa 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ PROG = slowcgi -OBJS = slowcgi.o getdtablecount.o strlcpy.o +OBJS = slowcgi.o getdtablecount.o strlcpy.o strtonum.o LIBS = libevent PREFIX ?= /usr/local diff --git a/slowcgi.8 b/slowcgi.8 index cfc4dee..e1f0afb 100644 --- a/slowcgi.8 +++ b/slowcgi.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: slowcgi.8,v 1.16 2021/09/02 14:14:44 jmc Exp $ +.\" $OpenBSD: slowcgi.8,v 1.17 2022/08/06 17:11:36 op Exp $ .\" .\" Copyright (c) 2013 Florian Obser .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 2 2021 $ +.Dd $Mdocdate: August 6 2022 $ .Dt SLOWCGI 8 .Os .Sh NAME @@ -25,6 +25,7 @@ .Op Fl dv .Op Fl p Ar path .Op Fl s Ar socket +.Op Fl t Ar timeout .Op Fl U Ar user .Op Fl u Ar user .Sh DESCRIPTION @@ -76,6 +77,12 @@ effectively disables the chroot. .It Fl s Ar socket Create and bind to alternative local socket at .Ar socket . +.It Fl t Ar timeout +Terminate the request after +.Ar timeout +seconds instead of the default 120 seconds. +The CGI script is left to run but its standard input, output and error +will be closed. .It Fl U Ar user Change the owner of .Pa /var/www/run/slowcgi.sock diff --git a/slowcgi.c b/slowcgi.c index 9999ac8..fc0e596 100644 --- a/slowcgi.c +++ b/slowcgi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: slowcgi.c,v 1.62 2021/09/02 14:14:44 jmc Exp $ */ +/* $OpenBSD: slowcgi.c,v 1.63 2022/08/06 17:11:36 op Exp $ */ /* * Copyright (c) 2013 David Gwynne * Copyright (c) 2013 Florian Obser @@ -48,6 +48,14 @@ size_t strlcpy(char *, const char *, size_t); #endif +#ifdef strtonum +#define HAVE_STRTONUM +#else +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp); +#endif + #ifndef __packed #define __packed __attribute__((packed)) #endif @@ -57,6 +65,7 @@ size_t strlcpy(char *, const char *, size_t); #endif #define TIMEOUT_DEFAULT 120 +#define TIMEOUT_MAX (86400 * 365) #define SLOWCGI_USER "www" #define FCGI_CONTENT_SIZE 65535 @@ -269,8 +278,8 @@ usage(void) { extern char *__progname; fprintf(stderr, - "usage: %s [-dv] [-p path] [-s socket] [-U user] [-u user]\n", - __progname); + "usage: %s [-dv] [-p path] [-s socket] [-t timeout] [-U user] " + " [-u user]\n", __progname); exit(1); } @@ -292,6 +301,7 @@ main(int argc, char *argv[]) const char *chrootpath = NULL; const char *sock_user = SLOWCGI_USER; const char *slowcgi_user = SLOWCGI_USER; + const char *errstr; /* * Ensure we have fds 0-2 open so that we have no fd overlaps @@ -310,7 +320,7 @@ main(int argc, char *argv[]) } } - while ((c = getopt(argc, argv, "dp:s:U:u:v")) != -1) { + while ((c = getopt(argc, argv, "dp:s:t:U:u:v")) != -1) { switch (c) { case 'd': debug++; @@ -321,6 +331,12 @@ main(int argc, char *argv[]) case 's': fcgi_socket = optarg; break; + case 't': + timeout.tv_sec = strtonum(optarg, 1, TIMEOUT_MAX, + &errstr); + if (errstr != NULL) + errx(1, "timeout is %s: %s", errstr, optarg); + break; case 'U': sock_user = optarg; break; diff --git a/strtonum.c b/strtonum.c new file mode 100644 index 0000000..c54a47a --- /dev/null +++ b/strtonum.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2004 Ted Unangst and Todd Miller + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef HAVE_STRTONUM + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp); + +#include +#include +#include + +#define INVALID 1 +#define TOOSMALL 2 +#define TOOLARGE 3 + +long long +strtonum(const char *numstr, long long minval, long long maxval, + const char **errstrp) +{ + long long ll = 0; + int error = 0; + char *ep; + struct errval { + const char *errstr; + int err; + } ev[4] = { + { NULL, 0 }, + { "invalid", EINVAL }, + { "too small", ERANGE }, + { "too large", ERANGE }, + }; + + ev[0].err = errno; + errno = 0; + if (minval > maxval) { + error = INVALID; + } else { + ll = strtoll(numstr, &ep, 10); + if (numstr == ep || *ep != '\0') + error = INVALID; + else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) + error = TOOSMALL; + else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) + error = TOOLARGE; + } + if (errstrp != NULL) + *errstrp = ev[error].errstr; + errno = ev[error].err; + if (error) + ll = 0; + + return (ll); +} + +#endif -- cgit v1.2.3-2-gb3c3