mirror of
https://github.com/emikulic/darkhttpd.git
synced 2023-08-10 21:13:08 +03:00
. Added lastmod (reply, not request) to struct connection
. Added xstrdup() . Made expand_tilde use xstrdup() instead of strdup() (whoops) . process_get() now handles "If-Modified-Since:" . lastmod is generated before Date: so that only one asprintf() is needed to construct the header in process_get()
This commit is contained in:
parent
72d0b5b301
commit
5a6c7cf08e
@ -14,7 +14,7 @@
|
|||||||
* . Generate directory listings.
|
* . Generate directory listings.
|
||||||
* x Log to file.
|
* x Log to file.
|
||||||
* . Partial content.
|
* . Partial content.
|
||||||
* . If-Modified-Since.
|
* x If-Modified-Since.
|
||||||
* . Keep-alive connections.
|
* . Keep-alive connections.
|
||||||
* . Chroot, set{uid|gid}.
|
* . Chroot, set{uid|gid}.
|
||||||
* . Port to Win32.
|
* . Port to Win32.
|
||||||
@ -77,7 +77,7 @@ struct connection
|
|||||||
int header_dont_free, header_only, http_code;
|
int header_dont_free, header_only, http_code;
|
||||||
|
|
||||||
enum { REPLY_GENERATED, REPLY_FROMFILE } reply_type;
|
enum { REPLY_GENERATED, REPLY_FROMFILE } reply_type;
|
||||||
char *reply;
|
char *reply, *lastmod; /* reply lastmod, not request if-mod-since */
|
||||||
int reply_dont_free;
|
int reply_dont_free;
|
||||||
FILE *reply_file;
|
FILE *reply_file;
|
||||||
unsigned int reply_sent, reply_length;
|
unsigned int reply_sent, reply_length;
|
||||||
@ -168,6 +168,18 @@ static void *xrealloc(void *original, const size_t size)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------
|
||||||
|
* strdup() that errx()s if it can't allocate.
|
||||||
|
*/
|
||||||
|
static char *xstrdup(const char *src)
|
||||||
|
{
|
||||||
|
char *dest = strdup(src);
|
||||||
|
if (dest == NULL) errx(1, "out of memory in strdup()");
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
* Split string out of src with range [left:right-1]
|
* Split string out of src with range [left:right-1]
|
||||||
*/
|
*/
|
||||||
@ -490,7 +502,7 @@ static char *expand_tilde(const char *path)
|
|||||||
const char *home;
|
const char *home;
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
|
|
||||||
if (path[0] != '~') return strdup(path); /* do nothing */
|
if (path[0] != '~') return xstrdup(path); /* do nothing */
|
||||||
|
|
||||||
home = getenv("HOME");
|
home = getenv("HOME");
|
||||||
if (home == NULL)
|
if (home == NULL)
|
||||||
@ -604,7 +616,7 @@ static struct connection *new_connection(void)
|
|||||||
conn->header_sent = conn->header_length = 0;
|
conn->header_sent = conn->header_length = 0;
|
||||||
conn->header_dont_free = conn->header_only = 0;
|
conn->header_dont_free = conn->header_only = 0;
|
||||||
conn->http_code = 0;
|
conn->http_code = 0;
|
||||||
conn->reply = NULL;
|
conn->reply = conn->lastmod = NULL;
|
||||||
conn->reply_dont_free = 0;
|
conn->reply_dont_free = 0;
|
||||||
conn->reply_file = NULL;
|
conn->reply_file = NULL;
|
||||||
conn->reply_sent = conn->reply_length = 0;
|
conn->reply_sent = conn->reply_length = 0;
|
||||||
@ -661,6 +673,7 @@ static void free_connection(struct connection *conn)
|
|||||||
if (conn->user_agent != NULL) free(conn->user_agent);
|
if (conn->user_agent != NULL) free(conn->user_agent);
|
||||||
if (conn->header != NULL && !conn->header_dont_free) free(conn->header);
|
if (conn->header != NULL && !conn->header_dont_free) free(conn->header);
|
||||||
if (conn->reply != NULL && !conn->reply_dont_free) free(conn->reply);
|
if (conn->reply != NULL && !conn->reply_dont_free) free(conn->reply);
|
||||||
|
if (conn->lastmod != NULL) free(conn->lastmod);
|
||||||
if (conn->reply_file != NULL) fclose(conn->reply_file);
|
if (conn->reply_file != NULL) fclose(conn->reply_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -851,7 +864,7 @@ static void parse_request(struct connection *conn)
|
|||||||
*/
|
*/
|
||||||
static void process_get(struct connection *conn)
|
static void process_get(struct connection *conn)
|
||||||
{
|
{
|
||||||
char *decoded_url, *safe_url, *target, *tmp;
|
char *decoded_url, *safe_url, *target, *if_mod_since;
|
||||||
const char *mimetype = NULL;
|
const char *mimetype = NULL;
|
||||||
struct stat filestat;
|
struct stat filestat;
|
||||||
|
|
||||||
@ -882,8 +895,9 @@ static void process_get(struct connection *conn)
|
|||||||
free(safe_url);
|
free(safe_url);
|
||||||
safe_url = NULL;
|
safe_url = NULL;
|
||||||
|
|
||||||
|
debugf("uri=%s, target=%s, content-type=%s\n",
|
||||||
|
conn->uri, target, mimetype);
|
||||||
conn->reply_file = fopen(target, "rb");
|
conn->reply_file = fopen(target, "rb");
|
||||||
debugf("target = %s\n", target);
|
|
||||||
free(target);
|
free(target);
|
||||||
target = NULL;
|
target = NULL;
|
||||||
|
|
||||||
@ -912,30 +926,32 @@ static void process_get(struct connection *conn)
|
|||||||
|
|
||||||
conn->reply_type = REPLY_FROMFILE;
|
conn->reply_type = REPLY_FROMFILE;
|
||||||
conn->reply_length = filestat.st_size;
|
conn->reply_length = filestat.st_size;
|
||||||
|
conn->lastmod = xstrdup(rfc1123_date(filestat.st_mtime));
|
||||||
|
|
||||||
asprintf(&tmp,
|
/* the browser might already have it */
|
||||||
|
if_mod_since = parse_field(conn, "If-Modified-Since: ");
|
||||||
|
if (if_mod_since != NULL &&
|
||||||
|
strcmp(if_mod_since, conn->lastmod) == 0)
|
||||||
|
{
|
||||||
|
debugf("not modified since %s\n", if_mod_since);
|
||||||
|
default_reply(conn, 304, "Not Modified", "");
|
||||||
|
conn->header_only = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn->header_length = asprintf(&(conn->header),
|
||||||
"HTTP/1.1 200 OK\r\n"
|
"HTTP/1.1 200 OK\r\n"
|
||||||
"Date: %s\r\n"
|
"Date: %s\r\n"
|
||||||
"Server: %s\r\n"
|
"Server: %s\r\n"
|
||||||
"Connection: close\r\n"
|
"Connection: close\r\n"
|
||||||
"Content-Length: %d\r\n"
|
"Content-Length: %d\r\n"
|
||||||
"Content-Type: %s\r\n"
|
"Content-Type: %s\r\n"
|
||||||
,
|
|
||||||
rfc1123_date(time(NULL)), pkgname, conn->reply_length,
|
|
||||||
mimetype
|
|
||||||
);
|
|
||||||
if (tmp == NULL) errx(1, "out of memory in asprintf()");
|
|
||||||
|
|
||||||
debugf("uri=%s, content-type=%s\n", conn->uri, mimetype);
|
|
||||||
|
|
||||||
conn->header_length = asprintf(&(conn->header),
|
|
||||||
"%s"
|
|
||||||
"Last-Modified: %s\r\n"
|
"Last-Modified: %s\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
,
|
,
|
||||||
tmp, rfc1123_date(filestat.st_mtime)
|
rfc1123_date(time(NULL)), pkgname, conn->reply_length,
|
||||||
|
mimetype, conn->lastmod
|
||||||
);
|
);
|
||||||
free(tmp);
|
|
||||||
if (conn->header == NULL) errx(1, "out of memory in asprintf()");
|
if (conn->header == NULL) errx(1, "out of memory in asprintf()");
|
||||||
conn->http_code = 200;
|
conn->http_code = 200;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user