refactoring the directory listing function in http-file.c
This commit is contained in:
parent
6fdf9e758b
commit
42765faff6
123
lib/http-file.c
123
lib/http-file.c
@ -79,6 +79,7 @@ struct file_t
|
|||||||
unsigned int keep_alive: 1;
|
unsigned int keep_alive: 1;
|
||||||
unsigned int req_content_length_unlimited: 1;
|
unsigned int req_content_length_unlimited: 1;
|
||||||
unsigned int req_qpath_ending_with_slash: 1;
|
unsigned int req_qpath_ending_with_slash: 1;
|
||||||
|
unsigned int req_qpath_is_root: 1;
|
||||||
unsigned int ever_attempted_to_write_to_client: 1;
|
unsigned int ever_attempted_to_write_to_client: 1;
|
||||||
unsigned int client_eof_detected: 1;
|
unsigned int client_eof_detected: 1;
|
||||||
unsigned int client_disconnected: 1;
|
unsigned int client_disconnected: 1;
|
||||||
@ -697,6 +698,61 @@ static HIO_INLINE int process_range_header (file_t* file, hio_htre_t* req, int*
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int open_peer_for_dir_listing (file_t* file, const hio_bch_t* dir_path, int* new_fd, hio_bch_t** new_file)
|
||||||
|
{
|
||||||
|
DIR* dp = HIO_NULL;
|
||||||
|
hio_bch_t* alt_file = HIO_NULL;
|
||||||
|
int alt_fd = -1;
|
||||||
|
struct dirent* de;
|
||||||
|
|
||||||
|
dp = opendir(dir_path);
|
||||||
|
if (!dp) goto oops;
|
||||||
|
|
||||||
|
alt_file = hio_dupbcstr(file->htts->hio, "/tmp/.XXXXXX", HIO_NULL);
|
||||||
|
if (!alt_file) goto oops;
|
||||||
|
|
||||||
|
/* TOOD: mkostemp instead and specify O_CLOEXEC and O_LARGEFILE? */
|
||||||
|
alt_fd = mkstemp(alt_file);
|
||||||
|
if (alt_fd <= -1) goto oops;
|
||||||
|
|
||||||
|
unlink (alt_file);
|
||||||
|
if (file->cbs && file->cbs->bfmt_dir)
|
||||||
|
{
|
||||||
|
/* TODO: can support sorting?? */
|
||||||
|
file->cbs->bfmt_dir (file->htts, alt_fd, HIO_SVC_HTTS_FILE_BFMT_DIR_HEADER, HIO_NULL, file->cbs->ctx);
|
||||||
|
while ((de = readdir(dp)))
|
||||||
|
{
|
||||||
|
file->cbs->bfmt_dir (file->htts, alt_fd, HIO_SVC_HTTS_FILE_BFMT_DIR_ENTRY, de->d_name, file->cbs->ctx);
|
||||||
|
}
|
||||||
|
file->cbs->bfmt_dir (file->htts, alt_fd, HIO_SVC_HTTS_FILE_BFMT_DIR_FOOTER, HIO_NULL, file->cbs->ctx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ((de = readdir(dp)))
|
||||||
|
{
|
||||||
|
if (strcmp(de->d_name, ".") != 0)
|
||||||
|
{
|
||||||
|
write (alt_fd, de->d_name, strlen(de->d_name));
|
||||||
|
write (alt_fd, "\n", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir (dp);
|
||||||
|
|
||||||
|
lseek (alt_fd, SEEK_SET, 0);
|
||||||
|
*new_fd = alt_fd;
|
||||||
|
*new_file = alt_file;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (alt_fd >= 0) close (alt_fd);
|
||||||
|
if (alt_file) hio_freemem (file->htts->hio, alt_file);
|
||||||
|
if (dp) closedir (dp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int open_peer_with_mode (file_t* file, const hio_bch_t* actual_file, int flags, int* error_status, const hio_bch_t** actual_mime_type)
|
static int open_peer_with_mode (file_t* file, const hio_bch_t* actual_file, int flags, int* error_status, const hio_bch_t** actual_mime_type)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -735,69 +791,19 @@ static int open_peer_with_mode (file_t* file, const hio_bch_t* actual_file, int
|
|||||||
if (alt_file)
|
if (alt_file)
|
||||||
{
|
{
|
||||||
alt_fd = open(alt_file, flags, 0644);
|
alt_fd = open(alt_file, flags, 0644);
|
||||||
if (alt_fd >= 0)
|
if (alt_fd <= -1)
|
||||||
{
|
{
|
||||||
|
hio_freemem (file->htts->hio, alt_file);
|
||||||
|
if ((file->options & HIO_SVC_HTTS_FILE_LIST_DIR) &&
|
||||||
|
open_peer_for_dir_listing(file, actual_file, &alt_fd, &alt_file) >= 0) goto open_ok;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
open_ok:
|
||||||
close (file->peer);
|
close (file->peer);
|
||||||
file->peer = alt_fd;
|
file->peer = alt_fd;
|
||||||
opened_file = alt_file;
|
opened_file = alt_file;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
hio_freemem (file->htts->hio, alt_file);
|
|
||||||
|
|
||||||
if (file->options & HIO_SVC_HTTS_FILE_LIST_DIR)
|
|
||||||
{
|
|
||||||
/* switch to directory listing */
|
|
||||||
DIR* dp;
|
|
||||||
|
|
||||||
dp = opendir(actual_file);
|
|
||||||
if (dp)
|
|
||||||
{
|
|
||||||
alt_file = hio_dupbcstr(file->htts->hio, "/tmp/.XXXXXX", HIO_NULL);
|
|
||||||
if (alt_file)
|
|
||||||
{
|
|
||||||
/* TOOD: mkostemp instead and specify O_CLOEXEC and O_LARGEFILE? */
|
|
||||||
alt_fd = mkstemp(alt_file);
|
|
||||||
if (alt_fd >= 0)
|
|
||||||
{
|
|
||||||
struct dirent* de;
|
|
||||||
|
|
||||||
unlink (alt_file);
|
|
||||||
if (file->cbs && file->cbs->bfmt_dir)
|
|
||||||
{
|
|
||||||
file->cbs->bfmt_dir (file->htts, alt_fd, HIO_SVC_HTTS_FILE_BFMT_DIR_HEADER, HIO_NULL, file->cbs->ctx);
|
|
||||||
while ((de = readdir(dp)))
|
|
||||||
{
|
|
||||||
file->cbs->bfmt_dir (file->htts, alt_fd, HIO_SVC_HTTS_FILE_BFMT_DIR_ENTRY, de->d_name, file->cbs->ctx);
|
|
||||||
}
|
|
||||||
file->cbs->bfmt_dir (file->htts, alt_fd, HIO_SVC_HTTS_FILE_BFMT_DIR_FOOTER, HIO_NULL, file->cbs->ctx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while ((de = readdir(dp)))
|
|
||||||
{
|
|
||||||
if (strcmp(de->d_name, ".") != 0)
|
|
||||||
{
|
|
||||||
write (alt_fd, de->d_name, strlen(de->d_name));
|
|
||||||
write (alt_fd, "\n", 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lseek (alt_fd, SEEK_SET, 0);
|
|
||||||
close (file->peer);
|
|
||||||
file->peer = alt_fd;
|
|
||||||
opened_file = alt_file;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hio_freemem (file->htts->hio, alt_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir (dp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -869,6 +875,7 @@ int hio_svc_htts_dofile (hio_svc_htts_t* htts, hio_dev_sck_t* csck, hio_htre_t*
|
|||||||
file->req_qpath = req_qpath;
|
file->req_qpath = req_qpath;
|
||||||
req_qpath = HIO_NULL; /* delegated to the file resource */
|
req_qpath = HIO_NULL; /* delegated to the file resource */
|
||||||
file->req_qpath_ending_with_slash = (hio_htre_getqpathlen(req) > 0 && hio_htre_getqpath(req)[hio_htre_getqpathlen(req) - 1] == '/');
|
file->req_qpath_ending_with_slash = (hio_htre_getqpathlen(req) > 0 && hio_htre_getqpath(req)[hio_htre_getqpathlen(req) - 1] == '/');
|
||||||
|
file->req_qpath_is_root = (hio_htre_getqpathlen(req) == 1 && hio_htre_getqpath(req)[0] == '/');
|
||||||
|
|
||||||
file->client_org_on_read = csck->on_read;
|
file->client_org_on_read = csck->on_read;
|
||||||
file->client_org_on_write = csck->on_write;
|
file->client_org_on_write = csck->on_write;
|
||||||
|
Loading…
Reference in New Issue
Block a user