mirror of https://github.com/nealey/eris.git
Works for "GET / HTTP/1.0"
This commit is contained in:
parent
45a5cd8fae
commit
ef5f424643
8
Makefile
8
Makefile
|
@ -1,14 +1,16 @@
|
||||||
VERSION := $(shell head -n 1 CHANGES | tr -d :)
|
VERSION := $(shell head -n 1 CHANGES | tr -d :)
|
||||||
|
|
||||||
CFLAGS = -DFNORD='fnord/$(VERSION)'
|
CFLAGS = -DFNORD='"fnord/$(VERSION)"'
|
||||||
|
|
||||||
all: fnord fnord-cgi fnord-idx
|
all: fnord fnord-cgi fnord-idx
|
||||||
|
|
||||||
fnord-cgi: httpd.c
|
|
||||||
fnord-cgi: CFLAGS += -DCGI
|
fnord-cgi: CFLAGS += -DCGI
|
||||||
|
fnord-cgi: fnord.c
|
||||||
|
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $<
|
||||||
|
|
||||||
fnord-idx: httpd.c
|
|
||||||
fnord-idx: CFLAGS += -DDIR_LIST
|
fnord-idx: CFLAGS += -DDIR_LIST
|
||||||
|
fnord-idx: fnord.c
|
||||||
|
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.[oa] fnord fnord-cgi fnord-idx
|
rm -f *.[oa] fnord fnord-cgi fnord-idx
|
||||||
|
|
377
fnord.c
377
fnord.c
|
@ -22,10 +22,14 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "str.c"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some things I use for debugging
|
* Some things I use for debugging
|
||||||
*/
|
*/
|
||||||
#ifdef DUMP
|
#define XXNODUMP
|
||||||
|
|
||||||
|
#ifndef NODUMP
|
||||||
#define DUMPf(fmt, args...) fprintf(stderr, "%s:%s:%d " fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##args)
|
#define DUMPf(fmt, args...) fprintf(stderr, "%s:%s:%d " fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##args)
|
||||||
#else
|
#else
|
||||||
#define DUMPf(fmt, args...)
|
#define DUMPf(fmt, args...)
|
||||||
|
@ -157,7 +161,7 @@ static long retcode = 404; /* used for logging code */
|
||||||
char *host = "?"; /* Host: header */
|
char *host = "?"; /* Host: header */
|
||||||
char *port; /* also Host: header, :80 part */
|
char *port; /* also Host: header, :80 part */
|
||||||
char *args; /* URL behind ? (for CGIs) */
|
char *args; /* URL behind ? (for CGIs) */
|
||||||
char *url; /* string between GET and HTTP/1.0,
|
char *url; /* string between GET and HTTP/1.0, *
|
||||||
* demangled */
|
* demangled */
|
||||||
char *ua = "?"; /* user-agent */
|
char *ua = "?"; /* user-agent */
|
||||||
char *refer; /* Referrer: header */
|
char *refer; /* Referrer: header */
|
||||||
|
@ -166,7 +170,7 @@ int httpversion; /* 0 == 1.0, 1 == 1.1 */
|
||||||
#ifdef KEEPALIVE
|
#ifdef KEEPALIVE
|
||||||
int keepalive = 0; /* should we keep the connection alive? */
|
int keepalive = 0; /* should we keep the connection alive? */
|
||||||
int rootdir; /* fd of root directory, so we can fchdir
|
int rootdir; /* fd of root directory, so we can fchdir
|
||||||
* back for keep-alive */
|
* * back for keep-alive */
|
||||||
#endif
|
#endif
|
||||||
#ifdef CGI
|
#ifdef CGI
|
||||||
char *cookie; /* Referrer: header */
|
char *cookie; /* Referrer: header */
|
||||||
|
@ -182,11 +186,11 @@ unsigned long post_len = 0;
|
||||||
#if _FILE_OFFSET_BITS == 64
|
#if _FILE_OFFSET_BITS == 64
|
||||||
static unsigned long long rangestart,
|
static unsigned long long rangestart,
|
||||||
rangeend; /* for ranged queries */
|
rangeend; /* for ranged queries */
|
||||||
|
#define strtorange strtoull
|
||||||
#else
|
#else
|
||||||
static unsigned long rangestart,
|
static unsigned long rangestart,
|
||||||
rangeend; /* for ranged queries */
|
rangeend; /* for ranged queries */
|
||||||
#define scan_range scan_ulong
|
#define strtorange strtoul
|
||||||
#define buffer_putrange buffer_putulong
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char days[] = "SunMonTueWedThuFriSat";
|
static const char days[] = "SunMonTueWedThuFriSat";
|
||||||
|
@ -202,9 +206,10 @@ char *remote_ident;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sanitize(char *ua)
|
sanitize(char *ua)
|
||||||
{ /* replace strings with underscores for
|
{ /* replace strings with underscores for *
|
||||||
* logging */
|
* logging */
|
||||||
int j;
|
int j;
|
||||||
|
if (! ua) return;
|
||||||
for (j = 0; ua[j]; ++j)
|
for (j = 0; ua[j]; ++j)
|
||||||
if (isspace(ua[j]))
|
if (isspace(ua[j]))
|
||||||
ua[j] = '_';
|
ua[j] = '_';
|
||||||
|
@ -215,8 +220,7 @@ dolog(off_t len)
|
||||||
{ /* write a log line to stderr */
|
{ /* write a log line to stderr */
|
||||||
sanitize(host);
|
sanitize(host);
|
||||||
sanitize(ua);
|
sanitize(ua);
|
||||||
if (refer)
|
sanitize(refer);
|
||||||
sanitize(refer);
|
|
||||||
|
|
||||||
fprintf(stderr, "%s %d %d %s %s %s %s\n",
|
fprintf(stderr, "%s %d %d %s %s %s %s\n",
|
||||||
remote_ip ? remote_ip : "0.0.0.0",
|
remote_ip ? remote_ip : "0.0.0.0",
|
||||||
|
@ -229,22 +233,21 @@ dolog(off_t len)
|
||||||
static void
|
static void
|
||||||
badrequest(long code, const char *httpcomment, const char *message)
|
badrequest(long code, const char *httpcomment, const char *message)
|
||||||
{
|
{
|
||||||
|
DUMP();
|
||||||
retcode = code;
|
retcode = code;
|
||||||
|
DUMP();
|
||||||
dolog(0);
|
dolog(0);
|
||||||
buffer_puts(buffer_1, "HTTP/1.0 ");
|
DUMP();
|
||||||
buffer_putulong(buffer_1, code);
|
printf("HTTP/1.0 %d %s\r\nConnection: close\r\n", code, httpcomment);
|
||||||
buffer_putspace(buffer_1);
|
if (message && message[0]) {
|
||||||
buffer_puts(buffer_1, httpcomment);
|
printf("Content-Length: %d\r\nContent-Type: text/html\r\n\r\n",
|
||||||
buffer_puts(buffer_1, "\r\nConnection: close\r\n");
|
strlen(message));
|
||||||
if (message[0]) {
|
fputs(message, stdout);
|
||||||
buffer_puts(buffer_1, "Content-Length: ");
|
|
||||||
buffer_putulong(buffer_1, strlen(message));
|
|
||||||
buffer_puts(buffer_1, "\r\nContent-Type: text/html\r\n\r\n");
|
|
||||||
buffer_puts(buffer_1, message);
|
|
||||||
} else {
|
} else {
|
||||||
buffer_puts(buffer_1, "\r\n");
|
printf("\r\n", stdout);
|
||||||
}
|
}
|
||||||
buffer_flush(buffer_1);
|
DUMP();
|
||||||
|
fflush(stdout);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,8 +439,8 @@ do_cgi(const char *pathinfo, const char *const *envp)
|
||||||
cgi_env[++i] = tmp;
|
cgi_env[++i] = tmp;
|
||||||
tmp += str_copy(tmp, "PATH_TRANSLATED=");
|
tmp += str_copy(tmp, "PATH_TRANSLATED=");
|
||||||
tmp +=
|
tmp +=
|
||||||
realpath(pathinfo, tmp) ? str_len(tmp) : str_copy(tmp,
|
realpath(pathinfo, tmp) ? strlen(tmp) : str_copy(tmp,
|
||||||
pathinfo);
|
pathinfo);
|
||||||
++tmp;
|
++tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +455,7 @@ do_cgi(const char *pathinfo, const char *const *envp)
|
||||||
/*
|
/*
|
||||||
* argv
|
* argv
|
||||||
*/
|
*/
|
||||||
if (args && (args[str_chr(args, '=')] == 0)) {
|
if (args && (strchr(args, '=') == 0)) {
|
||||||
int n = 3;
|
int n = 3;
|
||||||
for (i = 0; args[i]; ++i)
|
for (i = 0; args[i]; ++i)
|
||||||
if (args[i] == '+')
|
if (args[i] == '+')
|
||||||
|
@ -519,10 +522,11 @@ cgi_send_correct_http(const char *s, unsigned int sl)
|
||||||
++i;
|
++i;
|
||||||
goto out_nl;
|
goto out_nl;
|
||||||
} else {
|
} else {
|
||||||
if (s[i] != '\n')
|
if (s[i] != '\n') {
|
||||||
buffer_put(buffer_1, s + i, 1);
|
putchar(s[i]);
|
||||||
else {
|
} else {
|
||||||
out_nl:buffer_put(buffer_1, "\r\n", 2);
|
out_nl:
|
||||||
|
printf("\r\n");
|
||||||
if (ch == '\n') {
|
if (ch == '\n') {
|
||||||
++i;
|
++i;
|
||||||
break;
|
break;
|
||||||
|
@ -531,7 +535,7 @@ cgi_send_correct_http(const char *s, unsigned int sl)
|
||||||
}
|
}
|
||||||
ch = s[i];
|
ch = s[i];
|
||||||
}
|
}
|
||||||
buffer_put(buffer_1, s + i, sl - i);
|
printf("%.*s", sl - i, s + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -590,29 +594,26 @@ start_cgi(int nph, const char *pathinfo, const char *const *envp)
|
||||||
if (startup) {
|
if (startup) {
|
||||||
startup = 0;
|
startup = 0;
|
||||||
if (nph) { /* NPH-CGI */
|
if (nph) { /* NPH-CGI */
|
||||||
buffer_put(buffer_1, ibuf, n);
|
printf("%.*s", n, ibuf);
|
||||||
scan_ulong(ibuf + 9, &retcode); /* only
|
/*
|
||||||
* get
|
* skip HTTP/x.x
|
||||||
* error
|
*/
|
||||||
* code /
|
retcode = strtoul(ibuf + 9, NULL, 10);
|
||||||
* str_len("HTTP/x.x
|
|
||||||
* ")==9 */
|
|
||||||
} else { /* CGI */
|
} else { /* CGI */
|
||||||
if (byte_diff(ibuf, 10, "Location: ") == 0) {
|
if (memcmp(ibuf, "Location: ", 10) == 0) {
|
||||||
retcode = 302;
|
retcode = 302;
|
||||||
buffer_puts(buffer_1,
|
printf
|
||||||
"HTTP/1.0 302 CGI-Redirect\r\nConnection: close\r\n");
|
("HTTP/1.0 302 CGI-Redirect\r\nConnection: close\r\n");
|
||||||
signal(SIGCHLD, SIG_IGN);
|
signal(SIGCHLD, SIG_IGN);
|
||||||
cgi_send_correct_http(ibuf, n);
|
cgi_send_correct_http(ibuf, n);
|
||||||
buffer_flush(buffer_1);
|
fflush(stdout);
|
||||||
dolog(0);
|
dolog(0);
|
||||||
exit(0);
|
exit(0);
|
||||||
} else {
|
} else {
|
||||||
retcode = 200;
|
retcode = 200;
|
||||||
buffer_puts(buffer_1,
|
printf("HTTP/1.0 200 OK\r\nServer: "
|
||||||
"HTTP/1.0 200 OK\r\nServer: "
|
FNORD
|
||||||
FNORD
|
"\r\nPragma: no-cache\r\nConnection: close\r\n");
|
||||||
"\r\nPragma: no-cache\r\nConnection: close\r\n");
|
|
||||||
signal(SIGCHLD, SIG_IGN);
|
signal(SIGCHLD, SIG_IGN);
|
||||||
cgi_send_correct_http(ibuf, n);
|
cgi_send_correct_http(ibuf, n);
|
||||||
}
|
}
|
||||||
|
@ -622,7 +623,7 @@ start_cgi(int nph, const char *pathinfo, const char *const *envp)
|
||||||
* non startup
|
* non startup
|
||||||
*/
|
*/
|
||||||
else {
|
else {
|
||||||
buffer_put(buffer_1, ibuf, n);
|
printf("%.*s", n, ibuf);
|
||||||
}
|
}
|
||||||
size += n;
|
size += n;
|
||||||
if (pfd[0].revents & POLLHUP)
|
if (pfd[0].revents & POLLHUP)
|
||||||
|
@ -652,16 +653,13 @@ start_cgi(int nph, const char *pathinfo, const char *const *envp)
|
||||||
badrequest(500, "Internal Server Error",
|
badrequest(500, "Internal Server Error",
|
||||||
"Looks like the CGI crashed.");
|
"Looks like the CGI crashed.");
|
||||||
else {
|
else {
|
||||||
buffer_puts(buffer_1, "\n\n");
|
printf("\n\nLooks like the CGI crashed.\n\n");
|
||||||
buffer_puts(buffer_1,
|
|
||||||
"Looks like the CGI crashed.");
|
|
||||||
buffer_puts(buffer_1, "\n\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_flush(buffer_1);
|
fflush(stdout);
|
||||||
dolog(size);
|
dolog(size);
|
||||||
#ifdef TCP_CORK
|
#ifdef TCP_CORK
|
||||||
{
|
{
|
||||||
|
@ -706,7 +704,7 @@ fromhex(int c)
|
||||||
static char *
|
static char *
|
||||||
header(char *buf, int buflen, const char *hname)
|
header(char *buf, int buflen, const char *hname)
|
||||||
{
|
{
|
||||||
int slen = str_len(hname);
|
int slen = strlen(hname);
|
||||||
int i;
|
int i;
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
|
@ -793,14 +791,14 @@ getmimetype(char *url, int explicit)
|
||||||
{
|
{
|
||||||
char save;
|
char save;
|
||||||
int ext;
|
int ext;
|
||||||
ext = str_len(url);
|
ext = strlen(url);
|
||||||
while (ext > 0 && url[ext] != '.' && url[ext] != '/')
|
while (ext > 0 && url[ext] != '.' && url[ext] != '/')
|
||||||
--ext;
|
--ext;
|
||||||
if (url[ext] == '.') {
|
if (url[ext] == '.') {
|
||||||
++ext;
|
++ext;
|
||||||
if (str_equal(url + ext, "bz2"))
|
if (!strcmp(url + ext, "bz2"))
|
||||||
goto octetstream;
|
goto octetstream;
|
||||||
if (str_equal(url + ext, "gz")) {
|
if (!strcmp(url + ext, "gz")) {
|
||||||
if (!encoding) {
|
if (!encoding) {
|
||||||
if (explicit)
|
if (explicit)
|
||||||
goto octetstream;
|
goto octetstream;
|
||||||
|
@ -815,7 +813,7 @@ getmimetype(char *url, int explicit)
|
||||||
} else {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; mimetab[i].name; ++i)
|
for (i = 0; mimetab[i].name; ++i)
|
||||||
if (str_equal(mimetab[i].name, url + ext)) {
|
if (!strcmp(mimetab[i].name, url + ext)) {
|
||||||
mimetype = (char *) mimetab[i].type;
|
mimetype = (char *) mimetab[i].type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -833,8 +831,8 @@ matchcommalist(const char *needle, const char *haystack)
|
||||||
/*
|
/*
|
||||||
* return nonzero if match was found
|
* return nonzero if match was found
|
||||||
*/
|
*/
|
||||||
int len = str_len(needle);
|
int len = strlen(needle);
|
||||||
if (!byte_equal(needle, len, haystack))
|
if (strncmp(needle, haystack, len))
|
||||||
return 0;
|
return 0;
|
||||||
switch (haystack[len]) {
|
switch (haystack[len]) {
|
||||||
case ';':
|
case ';':
|
||||||
|
@ -910,7 +908,7 @@ findincommalist(const char *needle, const char *haystack)
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
static time_t
|
static time_t
|
||||||
timerfc(const char *s)
|
timerfc(const char *s)
|
||||||
{
|
{
|
||||||
static const int daytab[2][12] = {
|
static const int daytab[2][12] = {
|
||||||
|
@ -1129,19 +1127,16 @@ doit(char *buf, int buflen, char *url, int explicit)
|
||||||
* format: "bytes=17-23", "bytes=23-"
|
* format: "bytes=17-23", "bytes=23-"
|
||||||
*/
|
*/
|
||||||
if (!strncmp(accept, "bytes=", 6)) {
|
if (!strncmp(accept, "bytes=", 6)) {
|
||||||
int i;
|
|
||||||
accept += 6;
|
accept += 6;
|
||||||
i = scan_range(accept, &rangestart);
|
rangestart = strtorange(accept, &accept, 10);
|
||||||
if (i) {
|
if (*accept == '-') {
|
||||||
accept += i;
|
++accept;
|
||||||
if (*accept == '-') {
|
if (*accept) {
|
||||||
++accept;
|
rangeend = strtorange(accept, &accept, 10);
|
||||||
if (*accept) {
|
if (!*accept) {
|
||||||
i = scan_range(accept, &rangeend);
|
rangeend = st.st_size;
|
||||||
if (!i)
|
} else {
|
||||||
rangeend = st.st_size;
|
++rangeend;
|
||||||
else
|
|
||||||
++rangeend;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1162,8 +1157,8 @@ doit(char *buf, int buflen, char *url, int explicit)
|
||||||
static void
|
static void
|
||||||
redirectboilerplate()
|
redirectboilerplate()
|
||||||
{
|
{
|
||||||
buffer_puts(buffer_1,
|
printf
|
||||||
"HTTP/1.0 301 Go Away\r\nConnection: close\r\nContent-Length: 0\r\nLocation: ");
|
("HTTP/1.0 301 Go Away\r\nConnection: close\r\nContent-Length: 0\r\nLocation: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1181,27 +1176,27 @@ handleredirect(const char *url, const char *origurl)
|
||||||
* el-cheapo redirection
|
* el-cheapo redirection
|
||||||
*/
|
*/
|
||||||
redirectboilerplate();
|
redirectboilerplate();
|
||||||
buffer_put(buffer_1, symlink, len);
|
printf("%.*s", len, symlink);
|
||||||
#ifdef OLD_STYLE_REDIRECT
|
#ifdef OLD_STYLE_REDIRECT
|
||||||
fini:
|
fini:
|
||||||
#endif
|
#endif
|
||||||
retcode = 301;
|
retcode = 301;
|
||||||
buffer_puts(buffer_1, "\r\n\r\n");
|
printf("\r\n\r\n");
|
||||||
dolog(0);
|
dolog(0);
|
||||||
buffer_flush(buffer_1);
|
fflush(stdout);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
#ifdef OLD_STYLE_REDIRECT
|
#ifdef OLD_STYLE_REDIRECT
|
||||||
if ((env = getenv("REDIRECT_HOST"))) {
|
if ((env = getenv("REDIRECT_HOST"))) {
|
||||||
redirectboilerplate();
|
redirectboilerplate();
|
||||||
buffer_puts(buffer_1, env);
|
fputs(env, stdout);
|
||||||
while (*origurl == '/')
|
while (*origurl == '/')
|
||||||
++origurl;
|
++origurl;
|
||||||
buffer_puts(buffer_1, origurl);
|
fputs(origurl, stdout);
|
||||||
goto fini;
|
goto fini;
|
||||||
} else if ((env = getenv("REDIRECT_URI"))) {
|
} else if ((env = getenv("REDIRECT_URI"))) {
|
||||||
redirectboilerplate();
|
redirectboilerplate();
|
||||||
buffer_puts(buffer_1, env);
|
fputs(env, stdout);
|
||||||
goto fini;
|
goto fini;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1216,39 +1211,21 @@ hdl_encode_html(const char *s, unsigned int sl)
|
||||||
unsigned char ch = s[i];
|
unsigned char ch = s[i];
|
||||||
if (ch > 159) {
|
if (ch > 159) {
|
||||||
encode_dec:
|
encode_dec:
|
||||||
buffer_puts(buffer_1, "&#");
|
printf("&#%lu;", ch);
|
||||||
buffer_putulong(buffer_1, ch);
|
|
||||||
buffer_puts(buffer_1, ";");
|
|
||||||
} else if ((ch > 128) || (ch < 32)) {
|
} else if ((ch > 128) || (ch < 32)) {
|
||||||
buffer_put(buffer_1, " ", 1);
|
putchar('_');
|
||||||
} else if (ch == '"')
|
} else if (ch == '"')
|
||||||
buffer_puts(buffer_1, """);
|
fputs(""", stdout);
|
||||||
else if (ch == '&')
|
else if (ch == '&')
|
||||||
buffer_puts(buffer_1, "&");
|
fputs("&", stdout);
|
||||||
else if (ch == '<')
|
else if (ch == '<')
|
||||||
buffer_puts(buffer_1, "<");
|
fputs("<", stdout);
|
||||||
else if (ch == '>')
|
else if (ch == '>')
|
||||||
buffer_puts(buffer_1, ">");
|
fputs(">", stdout);
|
||||||
else
|
else
|
||||||
buffer_put(buffer_1, &ch, 1);
|
putchar(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int
|
|
||||||
buffer_puthex(unsigned int i)
|
|
||||||
{
|
|
||||||
unsigned int t;
|
|
||||||
char x[4];
|
|
||||||
t = '0' | (i >> 4) & 0xf;
|
|
||||||
if (t > '9')
|
|
||||||
t += 39;
|
|
||||||
i = '0' | (i & 0xf);
|
|
||||||
if (i > '9')
|
|
||||||
i += 39;
|
|
||||||
x[0] = '%';
|
|
||||||
x[1] = t;
|
|
||||||
x[2] = i;
|
|
||||||
return buffer_put(buffer_1, x, 3);
|
|
||||||
}
|
|
||||||
static void
|
static void
|
||||||
hdl_encode_uri(const char *s, unsigned int sl)
|
hdl_encode_uri(const char *s, unsigned int sl)
|
||||||
{
|
{
|
||||||
|
@ -1256,23 +1233,23 @@ hdl_encode_uri(const char *s, unsigned int sl)
|
||||||
for (i = 0; i < sl; ++i) {
|
for (i = 0; i < sl; ++i) {
|
||||||
unsigned char ch = s[i];
|
unsigned char ch = s[i];
|
||||||
if ((ch != '%') && (ch > 32) && (ch < 127))
|
if ((ch != '%') && (ch > 32) && (ch < 127))
|
||||||
buffer_put(buffer_1, &ch, 1);
|
putchar(ch);
|
||||||
else
|
else
|
||||||
buffer_puthex(ch);
|
printf("%%%02x", ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
handledirlist(const char *origurl)
|
handledirlist(const char *origurl)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
unsigned int nl = str_len(origurl);
|
unsigned int nl = strlen(origurl);
|
||||||
const char *nurl = origurl;
|
const char *nurl = origurl;
|
||||||
url = (char *) origurl;
|
url = (char *) origurl;
|
||||||
while (nurl[0] == '/')
|
while (nurl[0] == '/')
|
||||||
++nurl;
|
++nurl;
|
||||||
if (nurl <= origurl)
|
if (nurl <= origurl)
|
||||||
return;
|
return;
|
||||||
nl = str_len(nurl);
|
nl = strlen(nurl);
|
||||||
if (nurl[nl - 1] != '/')
|
if (nurl[nl - 1] != '/')
|
||||||
return;
|
return;
|
||||||
if (!stat(nl ? nurl : ".", &st) && (S_ISDIR(st.st_mode))
|
if (!stat(nl ? nurl : ".", &st) && (S_ISDIR(st.st_mode))
|
||||||
|
@ -1283,38 +1260,37 @@ handledirlist(const char *origurl)
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
unsigned int i,
|
unsigned int i,
|
||||||
size = 32 + nl;
|
size = 32 + nl;
|
||||||
buffer_puts(buffer_1,
|
fputs("HTTP/1.0 200 OK\r\nServer: " FNORD
|
||||||
"HTTP/1.0 200 OK\r\nServer: " FNORD
|
"\r\nConnection: close\r\n", stdout);
|
||||||
"\r\nConnection: close\r\n");
|
fputs("Content-Type: text/html\r\n", stdout);
|
||||||
buffer_puts(buffer_1, "Content-Type: text/html\r\n");
|
fputs("\r\n<h3>Directory Listing: /", stdout);
|
||||||
buffer_puts(buffer_1, "\r\n<h3>Directory Listing: /");
|
|
||||||
hdl_encode_html(nurl, nl);
|
hdl_encode_html(nurl, nl);
|
||||||
buffer_puts(buffer_1, "</h3>\n<pre>\n");
|
fputs("</h3>\n<pre>\n", stdout);
|
||||||
if (nl != 0) {
|
if (nl != 0) {
|
||||||
for (i = nl - 2; i > 0; --i)
|
for (i = nl - 2; i > 0; --i)
|
||||||
if (nurl[i] == '/')
|
if (nurl[i] == '/')
|
||||||
break;
|
break;
|
||||||
buffer_puts(buffer_1, "<a href=\"");
|
fputs("<a href=\"", stdout);
|
||||||
buffer_puts(buffer_1, "/");
|
fputs("/", stdout);
|
||||||
hdl_encode_uri(nurl, i);
|
hdl_encode_uri(nurl, i);
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
buffer_puts(buffer_1, "/");
|
fputs("/", stdout);
|
||||||
buffer_puts(buffer_1, "\">Parent directory");
|
fputs("\">Parent directory", stdout);
|
||||||
buffer_puts(buffer_1, "</a>\n");
|
fputs("</a>\n", stdout);
|
||||||
size += 40 + i;
|
size += 40 + i;
|
||||||
}
|
}
|
||||||
while (de = readdir(dir)) {
|
while (de = readdir(dir)) {
|
||||||
char symlink[1024];
|
char symlink[1024];
|
||||||
char *p = de->d_name;
|
char *p = de->d_name;
|
||||||
unsigned int pl,
|
unsigned int pl,
|
||||||
dl = str_len(de->d_name);
|
dl = strlen(de->d_name);
|
||||||
pl = dl;
|
pl = dl;
|
||||||
if (de->d_name[0] == '.')
|
if (de->d_name[0] == '.')
|
||||||
continue; /* hidden files -> skip */
|
continue; /* hidden files -> skip */
|
||||||
if (lstat(de->d_name, &st))
|
if (lstat(de->d_name, &st))
|
||||||
continue; /* can't stat -> skip */
|
continue; /* can't stat -> skip */
|
||||||
if (S_ISDIR(st.st_mode))
|
if (S_ISDIR(st.st_mode))
|
||||||
buffer_puts(buffer_1, "[DIR] ");
|
fputs("[DIR] ", stdout);
|
||||||
else if (S_ISLNK(st.st_mode)) {
|
else if (S_ISLNK(st.st_mode)) {
|
||||||
#ifdef SYSTEM_SYMLINK_DEREF
|
#ifdef SYSTEM_SYMLINK_DEREF
|
||||||
if (stat(de->d_name, &st)) /* dangling symlink */
|
if (stat(de->d_name, &st)) /* dangling symlink */
|
||||||
|
@ -1324,29 +1300,29 @@ handledirlist(const char *origurl)
|
||||||
continue;
|
continue;
|
||||||
p = symlink;
|
p = symlink;
|
||||||
}
|
}
|
||||||
buffer_puts(buffer_1, "[LNK] "); /* a symlink to
|
fputs("[LNK] ", stdout); /* a symlink to *
|
||||||
* something ... */
|
* something ... */
|
||||||
} else if (S_ISREG(st.st_mode))
|
} else if (S_ISREG(st.st_mode))
|
||||||
buffer_puts(buffer_1, "[TXT] ");
|
fputs("[TXT] ", stdout);
|
||||||
else
|
else
|
||||||
continue; /* not a file we can provide -> skip */
|
continue; /* not a file we can provide -> skip */
|
||||||
/*
|
/*
|
||||||
* write a href
|
* write a href
|
||||||
*/
|
*/
|
||||||
buffer_puts(buffer_1, "<a href=\"");
|
fputs("<a href=\"", stdout);
|
||||||
hdl_encode_uri(p, pl);
|
hdl_encode_uri(p, pl);
|
||||||
if (S_ISDIR(st.st_mode))
|
if (S_ISDIR(st.st_mode))
|
||||||
buffer_puts(buffer_1, "/"), ++size;
|
fputs("/", stdout), ++size;
|
||||||
buffer_puts(buffer_1, "\">");
|
fputs("\">", stdout);
|
||||||
if (de->d_name[0] == ':')
|
if (de->d_name[0] == ':')
|
||||||
de->d_name[0] = '.'; /* fnord special ... */
|
de->d_name[0] = '.'; /* fnord special ... */
|
||||||
hdl_encode_html(de->d_name, dl);
|
hdl_encode_html(de->d_name, dl);
|
||||||
buffer_puts(buffer_1, "</a>\n");
|
fputs("</a>\n", stdout);
|
||||||
size += 22 + (dl << 1);
|
size += 22 + (dl << 1);
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
buffer_puts(buffer_1, "</pre>\n");
|
fputs("</pre>\n", stdout);
|
||||||
buffer_flush(buffer_1);
|
fflush(stdout);
|
||||||
retcode = 200;
|
retcode = 200;
|
||||||
dolog(size);
|
dolog(size);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
@ -1360,12 +1336,12 @@ static int
|
||||||
handleindexcgi(const char *testurl, const char *origurl, char *space)
|
handleindexcgi(const char *testurl, const char *origurl, char *space)
|
||||||
{
|
{
|
||||||
unsigned int ul,
|
unsigned int ul,
|
||||||
ol = str_len(origurl);
|
ol = strlen(origurl);
|
||||||
char *test;
|
char *test;
|
||||||
while (testurl[0] == '/')
|
while (testurl[0] == '/')
|
||||||
++testurl, --ol;
|
++testurl, --ol;
|
||||||
ul = str_len(testurl);
|
ul = strlen(testurl);
|
||||||
if (str_diff(testurl + ol, "index.html"))
|
if (strcmp(testurl + ol, "index.html"))
|
||||||
return 0; /* no request for index.html */
|
return 0; /* no request for index.html */
|
||||||
test = space;
|
test = space;
|
||||||
++test;
|
++test;
|
||||||
|
@ -1395,7 +1371,7 @@ get_ucspi_env(void)
|
||||||
{
|
{
|
||||||
char *ucspi = getenv("PROTO");
|
char *ucspi = getenv("PROTO");
|
||||||
if (ucspi) {
|
if (ucspi) {
|
||||||
char *buf = alloca(str_len(ucspi) + 20);
|
char *buf = alloca(strlen(ucspi) + 20);
|
||||||
unsigned int tmp = str_copy(buf, ucspi);
|
unsigned int tmp = str_copy(buf, ucspi);
|
||||||
buf[tmp + str_copy(buf + tmp, "REMOTEIP")] = 0;
|
buf[tmp + str_copy(buf + tmp, "REMOTEIP")] = 0;
|
||||||
remote_ip = getenv(buf);
|
remote_ip = getenv(buf);
|
||||||
|
@ -1549,8 +1525,8 @@ serve_static_data(int fd)
|
||||||
read(fd, tmp, len); /* if read fails, we can't back down now.
|
read(fd, tmp, len); /* if read fails, we can't back down now.
|
||||||
* We already committed on the
|
* We already committed on the
|
||||||
* content-length */
|
* content-length */
|
||||||
buffer_put(buffer_1, tmp, len);
|
fwrite(tmp, len, 1, stdout);
|
||||||
buffer_flush(buffer_1);
|
fflush(stdout);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef USE_SENDFILE
|
#ifdef USE_SENDFILE
|
||||||
|
@ -1563,7 +1539,7 @@ serve_static_data(int fd)
|
||||||
corked = 1;
|
corked = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
buffer_flush(buffer_1);
|
fflush(stdout);
|
||||||
{
|
{
|
||||||
off_t l = rangeend - rangestart;
|
off_t l = rangeend - rangestart;
|
||||||
do {
|
do {
|
||||||
|
@ -1581,7 +1557,7 @@ serve_static_data(int fd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
buffer_flush(buffer_1);
|
fflush(stdout);
|
||||||
#ifdef TCP_CORK
|
#ifdef TCP_CORK
|
||||||
{
|
{
|
||||||
int one = 1;
|
int one = 1;
|
||||||
|
@ -1625,7 +1601,10 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
goto error500;
|
goto error500;
|
||||||
if ((tmp = getenv("GID"))) {
|
if ((tmp = getenv("GID"))) {
|
||||||
long gid;
|
long gid;
|
||||||
if (tmp[scan_ulong(tmp, &gid)] == 0) {
|
char *endptr;
|
||||||
|
|
||||||
|
gid = strtoul(tmp, &endptr, 0);
|
||||||
|
if (*endptr == 0) {
|
||||||
gid_t gi = gid;
|
gid_t gi = gid;
|
||||||
if (setgroups(1, &gi))
|
if (setgroups(1, &gi))
|
||||||
goto error500;
|
goto error500;
|
||||||
|
@ -1634,7 +1613,10 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
}
|
}
|
||||||
if ((tmp = getenv("UID"))) {
|
if ((tmp = getenv("UID"))) {
|
||||||
long uid;
|
long uid;
|
||||||
if (tmp[scan_ulong(tmp, &uid)] == 0) {
|
char *endptr;
|
||||||
|
|
||||||
|
uid = strtoul(tmp, &endptr, 0);
|
||||||
|
if (*endptr == 0) {
|
||||||
if (setuid(uid))
|
if (setuid(uid))
|
||||||
goto error500;
|
goto error500;
|
||||||
} else
|
} else
|
||||||
|
@ -1711,16 +1693,16 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
origurl = url;
|
origurl = url;
|
||||||
|
|
||||||
{
|
{
|
||||||
int nl = str_chr(buf, '\r');
|
char *nl = strchr(buf, '\r');
|
||||||
int space = str_chr(url, ' ');
|
char *space = strchr(url, ' ');
|
||||||
if (space >= nl)
|
if (space >= nl)
|
||||||
badrequest(400, "Bad Request",
|
badrequest(400, "Bad Request",
|
||||||
"<title>Bad Request</title>HTTP/0.9 not supported");
|
"<title>Bad Request</title>HTTP/0.9 not supported");
|
||||||
if (str_diffn(url + space + 1, "HTTP/1.", 7))
|
if (strncmp(space + 1, "HTTP/1.", 7))
|
||||||
badrequest(400, "Bad Request",
|
badrequest(400, "Bad Request",
|
||||||
"<title>Bad Request</title>Only HTTP 1.x supported");
|
"<title>Bad Request</title>Only HTTP 1.x supported");
|
||||||
url[space] = 0;
|
*space = 0;
|
||||||
httpversion = url[space + 8] - '0';
|
httpversion = space[8] - '0';
|
||||||
#ifdef KEEPALIVE
|
#ifdef KEEPALIVE
|
||||||
keepalive = 0;
|
keepalive = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1779,7 +1761,7 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
#ifdef KEEPALIVE
|
#ifdef KEEPALIVE
|
||||||
if ((tmp = header(buf, len, "Connection"))) { /* see if it's
|
if ((tmp = header(buf, len, "Connection"))) { /* see if it's
|
||||||
* "keep-alive" or
|
* "keep-alive" or
|
||||||
* "close" */
|
* * "close" */
|
||||||
if (!strcasecmp(tmp, "keep-alive"))
|
if (!strcasecmp(tmp, "keep-alive"))
|
||||||
keepalive = 1;
|
keepalive = 1;
|
||||||
else if (!strcasecmp(tmp, "close"))
|
else if (!strcasecmp(tmp, "close"))
|
||||||
|
@ -1813,13 +1795,13 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
if (!host)
|
if (!host)
|
||||||
i = 100;
|
i = 100;
|
||||||
else
|
else
|
||||||
i = str_len(host) + 7;
|
i = strlen(host) + 7;
|
||||||
Buf = alloca(i);
|
Buf = alloca(i);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
char *ip = getenv("TCPLOCALIP");
|
char *ip = getenv("TCPLOCALIP");
|
||||||
if (!ip)
|
if (!ip)
|
||||||
ip = "127.0.0.1";
|
ip = "127.0.0.1";
|
||||||
if (str_len(ip) + str_len(port) > 90)
|
if (strlen(ip) + strlen(port) > 90)
|
||||||
exit(101);
|
exit(101);
|
||||||
host = Buf;
|
host = Buf;
|
||||||
i = str_copy(Buf, ip);
|
i = str_copy(Buf, ip);
|
||||||
|
@ -1827,8 +1809,8 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
i += str_copy(Buf + i, port);
|
i += str_copy(Buf + i, port);
|
||||||
#ifdef NORMALIZE_HOST
|
#ifdef NORMALIZE_HOST
|
||||||
} else {
|
} else {
|
||||||
int colon = str_chr(host, ':');
|
char *colon = strchr(host, ':');
|
||||||
if (host[colon] == 0) {
|
if (*colon == 0) {
|
||||||
i = str_copy(Buf, host);
|
i = str_copy(Buf, host);
|
||||||
i += str_copy(Buf + i, ":");
|
i += str_copy(Buf + i, ":");
|
||||||
i += str_copy(Buf + i, port);
|
i += str_copy(Buf + i, port);
|
||||||
|
@ -1836,7 +1818,7 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
for (i = str_len(host); i >= 0; --i)
|
for (i = strlen(host); i >= 0; --i)
|
||||||
if ((host[i] = tolower(host[i])) == '/')
|
if ((host[i] = tolower(host[i])) == '/')
|
||||||
hostb0rken:
|
hostb0rken:
|
||||||
badrequest(400, "Bad Request",
|
badrequest(400, "Bad Request",
|
||||||
|
@ -1860,17 +1842,17 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
*/
|
*/
|
||||||
redirectboilerplate();
|
redirectboilerplate();
|
||||||
if (symlink[0] == '=') {
|
if (symlink[0] == '=') {
|
||||||
buffer_put(buffer_1, symlink + 1, linklen - 1);
|
fwrite(symlink + 1, linklen - 1, 1, stdout);
|
||||||
} else {
|
} else {
|
||||||
buffer_put(buffer_1, symlink, linklen);
|
fwrite(symlink, linklen, 1, stdout);
|
||||||
while (url[0] == '/')
|
while (url[0] == '/')
|
||||||
++url;
|
++url;
|
||||||
buffer_puts(buffer_1, url);
|
fputs(url, stdout);
|
||||||
}
|
}
|
||||||
retcode = 301;
|
retcode = 301;
|
||||||
buffer_puts(buffer_1, "\r\n\r\n");
|
fputs("\r\n\r\n", stdout);
|
||||||
dolog(0);
|
dolog(0);
|
||||||
buffer_flush(buffer_1);
|
fflush(stdout);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1913,26 +1895,25 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
|
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
|
||||||
retcode = 401;
|
retcode = 401;
|
||||||
dolog(0);
|
dolog(0);
|
||||||
buffer_puts(buffer_1,
|
fputs("HTTP/1.0 401 Authorization Required\r\n"
|
||||||
"HTTP/1.0 401 Authorization Required\r\n"
|
"WWW-Authenticate: Basic realm=\"", stdout);
|
||||||
"WWW-Authenticate: Basic realm=\"");
|
fputs(host, stdout);
|
||||||
buffer_puts(buffer_1, host);
|
fputs("\"\r\nConnection: close\r\n\r\n"
|
||||||
buffer_puts(buffer_1, "\"\r\nConnection: close\r\n\r\n"
|
"Access to this site is restricted.\r\n"
|
||||||
"Access to this site is restricted.\r\n"
|
"Please provide credentials.\r\n", stdout);
|
||||||
"Please provide credentials.\r\n");
|
fflush(stdout);
|
||||||
buffer_flush(buffer_1);
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* AUTH */
|
#endif /* AUTH */
|
||||||
nurl = url + str_len(url);
|
nurl = url + strlen(url);
|
||||||
if (nurl > url)
|
if (nurl > url)
|
||||||
--nurl;
|
--nurl;
|
||||||
if (*nurl == '/') {
|
if (*nurl == '/') {
|
||||||
int i;
|
int i;
|
||||||
nurl = alloca(str_len(url) + 12);
|
nurl = alloca(strlen(url) + 12);
|
||||||
i = str_copy(nurl, url);
|
i = str_copy(nurl, url);
|
||||||
i += str_copy(nurl + i, "index.html");
|
i += str_copy(nurl + i, "index.html");
|
||||||
nurl[i] = 0;
|
nurl[i] = 0;
|
||||||
|
@ -1953,7 +1934,7 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (pathinfo) {
|
if (pathinfo) {
|
||||||
int len = str_len(pathinfo) + 1;
|
int len = strlen(pathinfo) + 1;
|
||||||
tmp = alloca(len);
|
tmp = alloca(len);
|
||||||
memcpy(tmp, pathinfo, len);
|
memcpy(tmp, pathinfo, len);
|
||||||
*pathinfo = 0;
|
*pathinfo = 0;
|
||||||
|
@ -1992,14 +1973,14 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
/*
|
/*
|
||||||
* look if file.gz is also there and acceptable
|
* look if file.gz is also there and acceptable
|
||||||
*/
|
*/
|
||||||
char *fnord = alloca(str_len(url) + 4);
|
char *fnord = alloca(strlen(url) + 4);
|
||||||
int i,
|
int i,
|
||||||
fd2,
|
fd2,
|
||||||
trypng = 0;
|
trypng = 0;
|
||||||
char *oldencoding = encoding;
|
char *oldencoding = encoding;
|
||||||
char *oldmimetype = mimetype;
|
char *oldmimetype = mimetype;
|
||||||
i = str_copy(fnord, url);
|
i = str_copy(fnord, url);
|
||||||
if (i > 4 && str_equal(fnord + i - 4, ".gif")) {
|
if (i > 4 && !strcmp(fnord + i - 4, ".gif")) {
|
||||||
trypng = 1;
|
trypng = 1;
|
||||||
str_copy(fnord + i - 3, "png");
|
str_copy(fnord + i - 3, "png");
|
||||||
} else
|
} else
|
||||||
|
@ -2017,65 +1998,45 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
retcode = 200;
|
retcode = 200;
|
||||||
dolog(st.st_size);
|
dolog(st.st_size);
|
||||||
if (rangestart || rangeend != st.st_size)
|
if (rangestart || rangeend != st.st_size)
|
||||||
buffer_puts(buffer_1,
|
fputs("HTTP/1.0 206 Partial Content\r\n", stdout);
|
||||||
"HTTP/1.0 206 Partial Content\r\nServer: "
|
|
||||||
FNORD "\r\nContent-Type: ");
|
|
||||||
else
|
else
|
||||||
buffer_puts(buffer_1,
|
fputs("HTTP/1.0 200 OK\r\n", stdout);
|
||||||
"HTTP/1.0 200 OK\r\nServer: " FNORD
|
fputs("Server: " FNORD "\r\nContent-Type: ", stdout);
|
||||||
"\r\nContent-Type: ");
|
fputs(mimetype, stdout);
|
||||||
buffer_puts(buffer_1, mimetype);
|
fputs("\r\n", stdout);
|
||||||
buffer_puts(buffer_1, "\r\n");
|
|
||||||
#ifdef KEEPALIVE
|
#ifdef KEEPALIVE
|
||||||
switch (keepalive) {
|
switch (keepalive) {
|
||||||
case -1:
|
case -1:
|
||||||
buffer_puts(buffer_1, "Connection: close\r\n");
|
fputs("Connection: close\r\n", stdout);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
buffer_puts(buffer_1, "Connection: Keep-Alive\r\n");
|
fputs("Connection: Keep-Alive\r\n", stdout);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (encoding) {
|
if (encoding) {
|
||||||
buffer_puts(buffer_1, "Content-Encoding: ");
|
printf("Content-Encoding: %s\r\n");
|
||||||
buffer_puts(buffer_1, encoding);
|
|
||||||
buffer_puts(buffer_1, "\r\n");
|
|
||||||
}
|
}
|
||||||
buffer_puts(buffer_1, "Content-Length: ");
|
printf("Content-Length: %lu\r\n", rangeend - rangestart);
|
||||||
buffer_putrange(buffer_1, rangeend - rangestart);
|
printf("Last-Modified: ");
|
||||||
buffer_puts(buffer_1, "\r\nLast-Modified: ");
|
|
||||||
{
|
{
|
||||||
struct tm *x = gmtime(&st.st_mtime);
|
struct tm *x = gmtime(&st.st_mtime);
|
||||||
/*
|
/*
|
||||||
* "Sun, 06 Nov 1994 08:49:37 GMT"
|
* "Sun, 06 Nov 1994 08:49:37 GMT"
|
||||||
*/
|
*/
|
||||||
buffer_put(buffer_1, days + 3 * x->tm_wday, 3);
|
printf("%.3s, %02d %.3s %d %02d:%02d:%02d GMT\r\n",
|
||||||
buffer_puts(buffer_1, ", ");
|
days + (3 * x->tm_wday),
|
||||||
buffer_put2digits(buffer_1, x->tm_mday);
|
x->tm_mday,
|
||||||
buffer_puts(buffer_1, " ");
|
months + (3 * x->tm_mon),
|
||||||
buffer_put(buffer_1, months + 3 * x->tm_mon, 3);
|
x->tm_year + 1900,
|
||||||
buffer_puts(buffer_1, " ");
|
x->tm_hour, x->tm_min, x->tm_sec);
|
||||||
buffer_put2digits(buffer_1, (x->tm_year + 1900) / 100);
|
|
||||||
buffer_put2digits(buffer_1, (x->tm_year + 1900) % 100);
|
|
||||||
buffer_puts(buffer_1, " ");
|
|
||||||
buffer_put2digits(buffer_1, x->tm_hour);
|
|
||||||
buffer_puts(buffer_1, ":");
|
|
||||||
buffer_put2digits(buffer_1, x->tm_min);
|
|
||||||
buffer_puts(buffer_1, ":");
|
|
||||||
buffer_put2digits(buffer_1, x->tm_sec);
|
|
||||||
buffer_puts(buffer_1, " GMT\r\n");
|
|
||||||
}
|
}
|
||||||
if (rangestart || rangeend != st.st_size) {
|
if (rangestart || rangeend != st.st_size) {
|
||||||
buffer_puts(buffer_1,
|
printf
|
||||||
"Accept-Ranges: bytes\r\nContent-Range: bytes ");
|
("Accept-Ranges: bytes\r\nContent-Range: bytes %lu-%lu/%lu\r\n",
|
||||||
buffer_putrange(buffer_1, rangestart);
|
rangestart, rangeend - 1, st.st_size);
|
||||||
buffer_puts(buffer_1, "-");
|
|
||||||
buffer_putrange(buffer_1, rangeend - 1);
|
|
||||||
buffer_puts(buffer_1, "/");
|
|
||||||
buffer_putrange(buffer_1, st.st_size);
|
|
||||||
buffer_puts(buffer_1, "\r\n");
|
|
||||||
}
|
}
|
||||||
buffer_puts(buffer_1, "\r\n");
|
fputs("\r\n", stdout);
|
||||||
if (method == GET || method == POST) {
|
if (method == GET || method == POST) {
|
||||||
switch (serve_static_data(fd)) {
|
switch (serve_static_data(fd)) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -2104,7 +2065,7 @@ main(int argc, char *argv[], const char *const *envp)
|
||||||
error500:
|
error500:
|
||||||
retcode = 500;
|
retcode = 500;
|
||||||
} else
|
} else
|
||||||
buffer_flush(buffer_1);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef CHROOT
|
#ifdef CHROOT
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
unsigned int
|
||||||
|
str_copy(char *out, const char *in)
|
||||||
|
{
|
||||||
|
char *s = out;
|
||||||
|
const char *t = in;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (!(*s=*t)) break;
|
||||||
|
s += 1;
|
||||||
|
t += 1;
|
||||||
|
}
|
||||||
|
return s - out;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
str_start(const char *s, const char *t)
|
||||||
|
{
|
||||||
|
char x;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
x = *t++;
|
||||||
|
if (!x) return 1;
|
||||||
|
if (x != *s++) return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue