enhanced httpd for win32

This commit is contained in:
hyung-hwan 2012-12-04 16:44:59 +00:00
parent 120992a242
commit d0dd9a3347
13 changed files with 304 additions and 269 deletions

View File

@ -44,6 +44,9 @@ enum qse_fio_flag_t
/** don't close an I/O handle in qse_fio_fini() and qse_fio_close() */ /** don't close an I/O handle in qse_fio_fini() and qse_fio_close() */
QSE_FIO_NOCLOSE = (1 << 10), QSE_FIO_NOCLOSE = (1 << 10),
/** treat the path name as a multi-byte string */
QSE_FIO_MBSPATH = (1 << 11),
/* normal open flags */ /* normal open flags */
QSE_FIO_READ = (1 << 14), QSE_FIO_READ = (1 << 14),
QSE_FIO_WRITE = (1 << 15), QSE_FIO_WRITE = (1 << 15),

View File

@ -50,7 +50,8 @@ enum qse_mux_errnum_t
typedef enum qse_mux_errnum_t qse_mux_errnum_t; typedef enum qse_mux_errnum_t qse_mux_errnum_t;
#if defined(_WIN32) #if defined(_WIN32)
typedef qse_uintptr_t qse_mux_hnd_t; /*TODO: typedef qse_uintptr_t qse_mux_hnd_t;*/
typedef int qse_mux_hnd_t;
#elif defined(__OS2__) #elif defined(__OS2__)
typedef int qse_mux_hnd_t; typedef int qse_mux_hnd_t;
#elif defined(__DOS__) #elif defined(__DOS__)
@ -82,36 +83,36 @@ struct qse_mux_evt_t
extern "C" { extern "C" {
#endif #endif
qse_mux_t* qse_mux_open ( QSE_EXPORT qse_mux_t* qse_mux_open (
qse_mmgr_t* mmgr, qse_mmgr_t* mmgr,
qse_size_t xtnsize, qse_size_t xtnsize,
qse_mux_evtfun_t evtfun, qse_mux_evtfun_t evtfun,
qse_size_t capahint qse_size_t capahint
); );
void qse_mux_close ( QSE_EXPORT void qse_mux_close (
qse_mux_t* mux qse_mux_t* mux
); );
qse_mmgr_t* qse_mux_getmmgr ( QSE_EXPORT qse_mmgr_t* qse_mux_getmmgr (
qse_mux_t* mux qse_mux_t* mux
); );
void* qse_mux_getxtn ( QSE_EXPORT void* qse_mux_getxtn (
qse_mux_t* mux qse_mux_t* mux
); );
int qse_mux_insert ( QSE_EXPORT int qse_mux_insert (
qse_mux_t* mux, qse_mux_t* mux,
const qse_mux_evt_t* evt const qse_mux_evt_t* evt
); );
int qse_mux_delete ( QSE_EXPORT int qse_mux_delete (
qse_mux_t* mux, qse_mux_t* mux,
const qse_mux_evt_t* evt const qse_mux_evt_t* evt
); );
int qse_mux_poll ( QSE_EXPORT int qse_mux_poll (
qse_mux_t* mux, qse_mux_t* mux,
const qse_ntime_t* tmout const qse_ntime_t* tmout
); );

View File

@ -33,6 +33,11 @@
#define QSE_EPOCH_DAY (1) #define QSE_EPOCH_DAY (1)
#define QSE_EPOCH_WDAY (4) #define QSE_EPOCH_WDAY (4)
/* windows specific epoch time */
#define QSE_EPOCH_YEAR_WIN (1601)
#define QSE_EPOCH_MON_WIN (1)
#define QSE_EPOCH_DAY_WIN (1)
#define QSE_BTIME_YEAR_BASE (1900) #define QSE_BTIME_YEAR_BASE (1900)
#define QSE_DAYS_PER_NORMYEAR (365) #define QSE_DAYS_PER_NORMYEAR (365)

View File

@ -147,9 +147,6 @@ struct qse_httpd_scb_t
struct struct
{ {
int (*executable) (
qse_httpd_t* httpd, const qse_mchar_t* path);
int (*stat) ( int (*stat) (
qse_httpd_t* httpd, const qse_mchar_t* path, qse_httpd_t* httpd, const qse_mchar_t* path,
qse_httpd_stat_t* stat); qse_httpd_stat_t* stat);

View File

@ -234,9 +234,10 @@ int qse_fio_init (
{ {
qse_ntime_t now; qse_ntime_t now;
if (flags & QSE_FIO_HANDLE) if (flags & (QSE_FIO_HANDLE | QSE_FIO_MBSPATH))
{ {
/* QSE_FIO_TEMPORARY and QSE_FIO_HANDLE are mutually exclusive */ /* QSE_FIO_TEMPORARY and QSE_FIO_HANDLE/QSE_FIO_MBSPATH
* are mutually exclusive */
fio->errnum = QSE_FIO_EINVAL; fio->errnum = QSE_FIO_EINVAL;
return -1; return -1;
} }
@ -364,11 +365,22 @@ int qse_fio_init (
if (flags & QSE_FIO_SEQUENTIAL) if (flags & QSE_FIO_SEQUENTIAL)
flag_and_attr |= FILE_FLAG_SEQUENTIAL_SCAN; flag_and_attr |= FILE_FLAG_SEQUENTIAL_SCAN;
handle = CreateFile ( if (flags & QSE_FIO_MBSPATH)
path, desired_access, share_mode, {
QSE_NULL, /* set noinherit by setting no secattr */ handle = CreateFileA (
creation_disposition, flag_and_attr, 0 (const qse_mchar_t*)path, desired_access, share_mode,
); QSE_NULL, /* set noinherit by setting no secattr */
creation_disposition, flag_and_attr, 0
);
}
else
{
handle = CreateFile (
path, desired_access, share_mode,
QSE_NULL, /* set noinherit by setting no secattr */
creation_disposition, flag_and_attr, 0
);
}
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
{ {
DWORD e = GetLastError(); DWORD e = GetLastError();
@ -388,11 +400,22 @@ int qse_fio_init (
desired_access |= GENERIC_WRITE; desired_access |= GENERIC_WRITE;
} }
handle = CreateFile ( if (flags & QSE_FIO_MBSPATH)
path, desired_access, share_mode, {
QSE_NULL, /* set noinherit by setting no secattr */ handle = CreateFileA (
creation_disposition, flag_and_attr, 0 path, desired_access, share_mode,
); QSE_NULL, /* set noinherit by setting no secattr */
creation_disposition, flag_and_attr, 0
);
}
else
{
handle = CreateFile (
path, desired_access, share_mode,
QSE_NULL, /* set noinherit by setting no secattr */
creation_disposition, flag_and_attr, 0
);
}
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
{ {
if (flags & QSE_FIO_TEMPORARY) goto retry_temporary; if (flags & QSE_FIO_TEMPORARY) goto retry_temporary;
@ -442,25 +465,32 @@ int qse_fio_init (
qse_size_t wl, ml; qse_size_t wl, ml;
int px; int px;
path_mb = path_mb_buf; if (flags & QSE_FIO_MBSPATH)
ml = QSE_COUNTOF(path_mb_buf);
px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2)
{ {
/* the static buffer is too small. path_mb = (qse_mchar_t*)path;
* dynamically allocate a buffer */ }
path_mb = qse_wcstombsdup (path, QSE_NULL, mmgr); else
if (path_mb == QSE_NULL) {
path_mb = path_mb_buf;
ml = QSE_COUNTOF(path_mb_buf);
px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2)
{ {
fio->errnum = QSE_FIO_ENOMEM; /* the static buffer is too small.
* dynamically allocate a buffer */
path_mb = qse_wcstombsdup (path, QSE_NULL, mmgr);
if (path_mb == QSE_NULL)
{
fio->errnum = QSE_FIO_ENOMEM;
return -1;
}
}
else if (px <= -1)
{
fio->errnum = QSE_FIO_EINVAL;
return -1; return -1;
} }
} }
else if (px <= -1)
{
fio->errnum = QSE_FIO_EINVAL;
return -1;
}
#endif #endif
zero.ulLo = 0; zero.ulLo = 0;
@ -651,25 +681,32 @@ int qse_fio_init (
qse_size_t wl, ml; qse_size_t wl, ml;
int px; int px;
path_mb = path_mb_buf; if (flags & QSE_FIO_MBSPATH)
ml = QSE_COUNTOF(path_mb_buf);
px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2)
{ {
/* the static buffer is too small. path_mb = (qse_mchar_t*)path;
* allocate a buffer */ }
path_mb = qse_wcstombsdup (path, mmgr); else
if (path_mb == QSE_NULL) {
path_mb = path_mb_buf;
ml = QSE_COUNTOF(path_mb_buf);
px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2)
{ {
fio->errnum = QSE_FIO_ENOMEM; /* the static buffer is too small.
* allocate a buffer */
path_mb = qse_wcstombsdup (path, mmgr);
if (path_mb == QSE_NULL)
{
fio->errnum = QSE_FIO_ENOMEM;
return -1;
}
}
else if (px <= -1)
{
fio->errnum = QSE_FIO_EINVAL;
return -1; return -1;
} }
} }
else if (px <= -1)
{
fio->errnum = QSE_FIO_EINVAL;
return -1;
}
#endif #endif
rab = (struct RAB*)QSE_MMGR_ALLOC ( rab = (struct RAB*)QSE_MMGR_ALLOC (
@ -775,25 +812,32 @@ int qse_fio_init (
qse_size_t wl, ml; qse_size_t wl, ml;
int px; int px;
path_mb = path_mb_buf; if (flags & QSE_FIO_MBSPATH)
ml = QSE_COUNTOF(path_mb_buf);
px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2)
{ {
/* the static buffer is too small. path_mb = (qse_mchar_t*)path;
* allocate a buffer */ }
path_mb = qse_wcstombsdup (path, QSE_NULL, mmgr); else
if (path_mb == QSE_NULL) {
path_mb = path_mb_buf;
ml = QSE_COUNTOF(path_mb_buf);
px = qse_wcstombs (path, &wl, path_mb, &ml);
if (px == -2)
{ {
fio->errnum = QSE_FIO_ENOMEM; /* the static buffer is too small.
* allocate a buffer */
path_mb = qse_wcstombsdup (path, QSE_NULL, mmgr);
if (path_mb == QSE_NULL)
{
fio->errnum = QSE_FIO_ENOMEM;
return -1;
}
}
else if (px <= -1)
{
fio->errnum = QSE_FIO_EINVAL;
return -1; return -1;
} }
} }
else if (px <= -1)
{
fio->errnum = QSE_FIO_EINVAL;
return -1;
}
#endif #endif
/* /*
* rwa -> RDWR | APPEND * rwa -> RDWR | APPEND
@ -1098,10 +1142,10 @@ qse_ssize_t qse_fio_read (qse_fio_t* fio, void* buf, qse_size_t size)
#if defined(_WIN32) #if defined(_WIN32)
DWORD count; DWORD count;
if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD))) if (size > (QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD)))
size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD); size = QSE_TYPE_MAX(qse_ssize_t) & QSE_TYPE_MAX(DWORD);
if (ReadFile (fio->handle, if (ReadFile (fio->handle, buf, (DWORD)size, &count, QSE_NULL) == FALSE)
buf, (DWORD)size, &count, QSE_NULL) == FALSE)
{ {
fio->errnum = syserr_to_errnum (GetLastError()); fio->errnum = syserr_to_errnum (GetLastError());
return -1; return -1;

View File

@ -561,7 +561,7 @@ int qse_mux_poll (qse_mux_t* mux, const qse_ntime_t* tmout)
qse_mux_hnd_t i; qse_mux_hnd_t i;
qse_mux_evt_t* evt, xevt; qse_mux_evt_t* evt, xevt;
for (i = 0 ; i <= mux->maxhnd; i++) for (i = 0; i <= mux->maxhnd; i++)
{ {
evt = mux->me.ptr[i]; evt = mux->me.ptr[i];
if (!evt || evt->hnd != i) continue; if (!evt || evt->hnd != i) continue;

View File

@ -43,11 +43,7 @@
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
#define WIN_EPOCH_YEAR (1601) #define EPOCH_DIFF_YEARS (QSE_EPOCH_YEAR-QSE_EPOCH_YEAR_WIN)
#define WIN_EPOCH_MON (1)
#define WIN_EPOCH_DAY (1)
#define EPOCH_DIFF_YEARS (QSE_EPOCH_YEAR-WIN_EPOCH_YEAR)
#define EPOCH_DIFF_DAYS ((qse_long_t)EPOCH_DIFF_YEARS*365+EPOCH_DIFF_YEARS/4-3) #define EPOCH_DIFF_DAYS ((qse_long_t)EPOCH_DIFF_YEARS*365+EPOCH_DIFF_YEARS/4-3)
#define EPOCH_DIFF_SECS ((qse_long_t)EPOCH_DIFF_DAYS*24*60*60) #define EPOCH_DIFF_SECS ((qse_long_t)EPOCH_DIFF_DAYS*24*60*60)
#endif #endif

View File

@ -24,4 +24,5 @@ libqsenet_la_SOURCES = \
upxd.c upxd.c
libqsenet_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L$(libdir) libqsenet_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L$(libdir)
libqsenet_la_LIBADD = -lqsecmn libqsenet_la_LIBADD = -lqsecmn $(SOCKET_LIBS) $(SENDFILE_LIBS) $(SSL_LIBS)

View File

@ -78,7 +78,9 @@ am__uninstall_files_from_dir = { \
} }
am__installdirs = "$(DESTDIR)$(libdir)" am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES) LTLIBRARIES = $(lib_LTLIBRARIES)
libqsenet_la_DEPENDENCIES = am__DEPENDENCIES_1 =
libqsenet_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am_libqsenet_la_OBJECTS = http.lo htre.lo htrd.lo httpd.lo \ am_libqsenet_la_OBJECTS = http.lo htre.lo htrd.lo httpd.lo \
httpd-cgi.lo httpd-dir.lo httpd-file.lo httpd-proxy.lo \ httpd-cgi.lo httpd-dir.lo httpd-file.lo httpd-proxy.lo \
httpd-resol.lo httpd-std.lo httpd-task.lo httpd-text.lo \ httpd-resol.lo httpd-std.lo httpd-task.lo httpd-text.lo \
@ -301,7 +303,7 @@ libqsenet_la_SOURCES = \
upxd.c upxd.c
libqsenet_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L$(libdir) libqsenet_la_LDFLAGS = -version-info 1:0:0 -no-undefined -L../cmn -L$(libdir)
libqsenet_la_LIBADD = -lqsecmn libqsenet_la_LIBADD = -lqsecmn $(SOCKET_LIBS) $(SENDFILE_LIBS) $(SSL_LIBS)
all: all-am all: all-am
.SUFFIXES: .SUFFIXES:

View File

@ -30,11 +30,15 @@
#include <qse/cmn/path.h> #include <qse/cmn/path.h>
#include <qse/cmn/mux.h> #include <qse/cmn/mux.h>
#include <qse/cmn/dir.h> #include <qse/cmn/dir.h>
#include <qse/cmn/fio.h>
#if defined(_WIN32) #if defined(_WIN32)
# include <winsock2.h> # include <winsock2.h>
# include <ws2tcpip.h> /* sockaddr_in6 */ # include <ws2tcpip.h> /* sockaddr_in6 */
# include <windows.h> # include <windows.h>
# define EPOCH_DIFF_YEARS (QSE_EPOCH_YEAR-QSE_EPOCH_YEAR_WIN)
# define EPOCH_DIFF_DAYS ((qse_long_t)EPOCH_DIFF_YEARS*365+EPOCH_DIFF_YEARS/4-3)
# define EPOCH_DIFF_SECS ((qse_long_t)EPOCH_DIFF_DAYS*24*60*60)
#elif defined(__OS2__) #elif defined(__OS2__)
/* TODO */ /* TODO */
@ -232,41 +236,38 @@ static qse_httpd_errnum_t syserr_to_errnum (int e)
#define MAX_SEND_SIZE 4096 #define MAX_SEND_SIZE 4096
#if defined(_WIN32) static qse_ssize_t send_file (
/* TODO */ int out_fd, qse_ubi_t in_fd, qse_foff_t* offset, qse_size_t count)
/* TODO: WIN32 TransmitFile */ {
#elif defined(__OS2__) #if defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE64)
/* TODO */
#elif defined(__DOS__)
/* TODO */
#elif defined(HAVE_SENDFILE) && defined(HAVE_SENDFILE64) qse_ubi_t infd = qse_fio_gethandleasubi (in_fd.ptr);
# if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64)
# define xsendfile(out,in,offset,count) sendfile64(out,in,offset,count) #if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64)
# else return sendfile64 (out_f_fdd, infd.i, offset, count);
# define xsendfile(out,in,offset,count) sendfile(out,in,offset,count) #else
# endif return sendfile (out_fd, infd.i, offset, count);
#endif
#elif defined(HAVE_SENDFILE) #elif defined(HAVE_SENDFILE)
# define xsendfile(out,in,offset,count) sendfile(out,in,offset,count) qse_ubi_t infd = qse_fio_gethandleasubi (in_fd.ptr);
return sendfile (out_fd, infd.i, offset, count);
#elif defined(HAVE_SENDFILE64) #elif defined(HAVE_SENDFILE64)
# define xsendfile(out,in,offset,count) sendfile64(out,in,offset,count) qse_ubi_t infd = qse_fio_gethandleasubi (in_fd.ptr);
return sendfile64 (out_fd, in_fd.i, offset, count);
#elif defined(HAVE_SENDFILEV) || defined(HAVE_SENDFILEV64) #elif defined(HAVE_SENDFILEV) || defined(HAVE_SENDFILEV64)
static qse_ssize_t xsendfile ( #if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64)
int out_fd, int in_fd, qse_foff_t* offset, qse_size_t count)
{
#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64)
struct sendfilevec64 vec; struct sendfilevec64 vec;
#else #else
struct sendfilevec vec; struct sendfilevec vec;
#endif #endif
size_t xfer; size_t xfer;
ssize_t n; ssize_t n;
vec.sfv_fd = in_fd; vec.sfv_fd = in_fd.i;
vec.sfv_flag = 0; vec.sfv_flag = 0;
if (offset) if (offset)
{ {
@ -274,16 +275,16 @@ static qse_ssize_t xsendfile (
} }
else else
{ {
vec.sfv_off = QSE_LSEEK (in_fd, 0, SEEK_CUR); vec.sfv_off = QSE_LSEEK (in_fd.i, 0, SEEK_CUR);
if (vec.sfv_off == (off_t)-1) return (qse_ssize_t)-1; if (vec.sfv_off == (off_t)-1) return (qse_ssize_t)-1;
} }
vec.sfv_len = count; vec.sfv_len = count;
#if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64) #if !defined(_LP64) && (QSE_SIZEOF_VOID_P<8) && defined(HAVE_SENDFILE64)
n = sendfilev64 (out_fd, &vec, 1, &xfer); n = sendfilev64 (out_fd, &vec, 1, &xfer);
#else #else
n = sendfilev (out_fd, &vec, 1, &xfer); n = sendfilev (out_fd, &vec, 1, &xfer);
#endif #endif
if (offset) *offset = *offset + xfer; if (offset) *offset = *offset + xfer;
/* TODO: xfer contains number of byte written even on failure /* TODO: xfer contains number of byte written even on failure
@ -291,45 +292,58 @@ on success xfer == n.
on failure xfer != n. on failure xfer != n.
*/ */
return n; return n;
}
#else #else
static qse_ssize_t xsendfile (
int out_fd, int in_fd, qse_foff_t* offset, qse_size_t count)
{
qse_mchar_t buf[MAX_SEND_SIZE]; qse_mchar_t buf[MAX_SEND_SIZE];
qse_ssize_t n; qse_ssize_t n;
if (offset && QSE_LSEEK (in_fd, *offset, SEEK_SET) != *offset) #if 0
if (offset && QSE_LSEEK (in_fd.i, *offset, SEEK_SET) != *offset)
return (qse_ssize_t)-1; return (qse_ssize_t)-1;
if (count > QSE_COUNTOF(buf)) count = QSE_COUNTOF(buf); if (count > QSE_COUNTOF(buf)) count = QSE_COUNTOF(buf);
n = read (in_fd, buf, count); n = QSE_READ (in_fd.i, buf, count);
if (n == (qse_ssize_t)-1 || n == 0) return n;
#endif
if (offset && qse_fio_seek (in_fd.ptr, *offset, QSE_FIO_BEGIN) != *offset)
return (qse_ssize_t)-1;
if (count > QSE_COUNTOF(buf)) count = QSE_COUNTOF(buf);
n = qse_fio_read (in_fd.ptr, buf, count);
if (n == (qse_ssize_t)-1 || n == 0) return n; if (n == (qse_ssize_t)-1 || n == 0) return n;
n = send (out_fd, buf, n, 0); n = send (out_fd, buf, n, 0);
if (n > 0 && offset) *offset = *offset + n; if (n > 0 && offset) *offset = *offset + n;
return n; return n;
}
#endif #endif
}
/* ------------------------------------------------------------------- */ /* ------------------------------------------------------------------- */
#if defined(HAVE_SSL) #if defined(HAVE_SSL)
static qse_ssize_t xsendfile_ssl ( static qse_ssize_t send_file_ssl (
SSL* out, int in_fd, qse_foff_t* offset, qse_size_t count) SSL* out, qse_ubi_t in_fd, qse_foff_t* offset, qse_size_t count)
{ {
qse_mchar_t buf[MAX_SEND_SIZE]; qse_mchar_t buf[MAX_SEND_SIZE];
qse_ssize_t n; qse_ssize_t n;
if (offset && QSE_LSEEK (in_fd, *offset, SEEK_SET) != *offset) #if 0
if (offset && QSE_LSEEK (in_fd.i, *offset, SEEK_SET) != *offset)
return (qse_ssize_t)-1; return (qse_ssize_t)-1;
if (count > QSE_COUNTOF(buf)) count = QSE_COUNTOF(buf); if (count > QSE_COUNTOF(buf)) count = QSE_COUNTOF(buf);
n = read (in_fd, buf, count); n = QSE_READ (in_fd.i, buf, count);
if (n == (qse_ssize_t)-1 || n == 0) return n;
#endif
if (offset && qse_fio_seek (in_fd.ptr, *offset, QSE_FIO_BEGIN) != *offset)
return (qse_ssize_t)-1;
if (count > QSE_COUNTOF(buf)) count = QSE_COUNTOF(buf);
n = qse_fio_read (in_fd.ptr, buf, count);
if (n == (qse_ssize_t)-1 || n == 0) return n; if (n == (qse_ssize_t)-1 || n == 0) return n;
n = SSL_write (out, buf, count); n = SSL_write (out, buf, count);
@ -498,12 +512,12 @@ IP_TRANSPRENT is needed for:
if (server->flags & QSE_HTTPD_SERVER_BINDTONWIF) if (server->flags & QSE_HTTPD_SERVER_BINDTONWIF)
{ {
#if defined(SO_BINDTODEVICE)
qse_mchar_t tmp[64]; qse_mchar_t tmp[64];
qse_size_t len; qse_size_t len;
len = qse_nwifindextombs (server->nwif, tmp, QSE_COUNTOF(tmp)); len = qse_nwifindextombs (server->nwif, tmp, QSE_COUNTOF(tmp));
#if defined(SO_BINDTODEVICE)
if (len <= 0 || setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, len) <= -1) if (len <= 0 || setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, len) <= -1)
{ {
/* TODO: logging ... */ /* TODO: logging ... */
@ -980,13 +994,84 @@ static int stat_file (
{ {
#if defined(_WIN32) #if defined(_WIN32)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); HANDLE fh;
return -1; WIN32_FIND_DATAA fdata;
ULARGE_INTEGER li;
/* fail if the path name contains a wilecard letter */
if (qse_mbspbrk (path, QSE_MT("?*")) != QSE_NULL) return -1;
if (path[0] == QSE_MT('/') && path[1] == QSE_MT('\0'))
{
/* the root directory won't work well with FindFirstFile().*/
QSE_MEMSET (hst, 0, QSE_SIZEOF(*hst));
hst->isdir = 1;
/* TODO: hst->dev can be set to the drive letter's index. */
}
else
{
/* TODO: hst->dev can be set to the drive letter's index. */
fh = FindFirstFileA (path, &fdata);
if (fh == INVALID_HANDLE_VALUE) return -1;
QSE_MEMSET (hst, 0, QSE_SIZEOF(*hst));
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) hst->isdir = 1;
hst->size = ((qse_foff_t)fdata.nFileSizeHigh << 32) | fdata.nFileSizeLow;
li.LowPart = fdata.ftLastWriteTime.dwLowDateTime;
li.HighPart = fdata.ftLastWriteTime.dwHighDateTime;
/* li.QuadPart is in the 100-nanosecond intervals */
hst->mtime.sec = (li.QuadPart / (QSE_NSECS_PER_SEC / 100)) - EPOCH_DIFF_SECS;
hst->mtime.nsec = (li.QuadPart % (QSE_NSECS_PER_SEC / 100)) * 100;
FindClose (fh);
}
return 0;
#elif defined(__OS2__) #elif defined(__OS2__)
/* TODO: */ APIRET rc;
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); HDIR h;
return -1; FILEFINDBUF3L ffb;
ULONG count;
qse_btime_t bt;
qse_ntime_t nt;
/* fail if the path name contains a wilecard letter */
if (qse_mbspbrk (path, QSE_MT("?*")) != QSE_NULL) return -1;
rc = DosFindFirst (
mptr,
&h,
FILE_DIRECTORY | FILE_READONLY,
&ffb,
QSE_SIZEOF(ffb),
&count,
FIL_STANDARDL);
if (rc != NO_ERROR) return -1;
DosFindClose (&h);
QSE_MEMSET (&bt, 0, QSE_SIZEOF(bt));
bt.mday = ffb.fdateLastWrite.day;
bt.mon = ffb.fdateLastWrite.month - 1;
bt.year = ffb.fdateLastWrite.year + 80;
bt.hour = ffb.ftimeLastWrite.hours;
bt.min = ffb.ftimeLastWrite.minutes;
bt.min = ffb.ftimeLastWrite.twosecs * 2;
bt.isdst = -1;
if (qse_timelocal (&bt, &nt) <= -1) return -1;
QSE_MEMSET (hst, 0, QSE_SIZEOF(*hst));
if (ffb.attrFile & FILE_DIRECTORY) hst->isdir = 1;
hst->size = ffb.cbFile;
hst->mtime = nt;
return 0;
#elif defined(__DOS__) #elif defined(__DOS__)
/* TODO: */ /* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL); qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
@ -1032,27 +1117,6 @@ static int stat_file (
/* ------------------------------------------------------------------- */ /* ------------------------------------------------------------------- */
static int file_executable (qse_httpd_t* httpd, const qse_mchar_t* path)
{
#if defined(_WIN32)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#elif defined(__OS2__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#elif defined(__DOS__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#else
if (access (path, X_OK) == -1)
return (errno == EACCES)? 0 /*no*/: -1 /*error*/;
return 1; /* yes */
#endif
}
static int file_stat ( static int file_stat (
qse_httpd_t* httpd, const qse_mchar_t* path, qse_httpd_stat_t* hst) qse_httpd_t* httpd, const qse_mchar_t* path, qse_httpd_stat_t* hst)
{ {
@ -1062,141 +1126,66 @@ static int file_stat (
static int file_ropen ( static int file_ropen (
qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* handle) qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* handle)
{ {
#if defined(_WIN32) qse_fio_t* fio;
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#elif defined(__OS2__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#elif defined(__DOS__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#else
int fd; fio = qse_fio_open (
int flags; httpd->mmgr, 0, (const qse_char_t*)path,
QSE_FIO_READ | QSE_FIO_MBSPATH, 0);
flags = O_RDONLY; if (fio == QSE_NULL)
#if defined(O_LARGEFILE)
flags |= O_LARGEFILE;
#endif
qse_printf (QSE_T("opening file [%hs] for reading\n"), path);
fd = QSE_OPEN (path, flags, 0);
if (fd <= -1)
{ {
qse_httpd_seterrnum (httpd, syserr_to_errnum(errno)); /* TODO: translate fio error to a proper error code */
qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL);
return -1; return -1;
} }
flags = fcntl (fd, F_GETFD); handle->ptr = fio;
if (flags >= 0) fcntl (fd, F_SETFD, flags | FD_CLOEXEC); qse_printf (QSE_T("opened rfile [%hs][%p][%p]\n"), path, handle->ptr, fio->handle);
handle->i = fd;
qse_printf (QSE_T("opened file %hs\n"), path);
return 0; return 0;
#endif
} }
static int file_wopen ( static int file_wopen (
qse_httpd_t* httpd, const qse_mchar_t* path, qse_httpd_t* httpd, const qse_mchar_t* path,
qse_ubi_t* handle) qse_ubi_t* handle)
{ {
#if defined(_WIN32) qse_fio_t* fio;
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#elif defined(__OS2__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#elif defined(__DOS__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#else
int fd;
int flags;
flags = O_WRONLY | O_CREAT | O_TRUNC; fio = qse_fio_open (
#if defined(O_LARGEFILE) httpd->mmgr, 0, (const qse_char_t*)path,
flags |= O_LARGEFILE; QSE_FIO_WRITE | QSE_FIO_CREATE |
#endif QSE_FIO_TRUNCATE | QSE_FIO_MBSPATH, 0644);
if (fio == QSE_NULL)
qse_printf (QSE_T("opening file [%hs] for writing\n"), path);
fd = QSE_OPEN (path, flags, 0644);
if (fd <= -1)
{ {
qse_httpd_seterrnum (httpd, syserr_to_errnum(errno)); /* TODO: translate fio error to a proper error code */
qse_httpd_seterrnum (httpd, QSE_HTTPD_EINVAL);
return -1; return -1;
} }
handle->i = fd; handle->ptr = fio;
qse_printf (QSE_T("opened wfile [%hs][%p][%p]\n"), path, handle->ptr, fio->handle);
return 0; return 0;
#endif
} }
static void file_close (qse_httpd_t* httpd, qse_ubi_t handle) static void file_close (qse_httpd_t* httpd, qse_ubi_t handle)
{ {
#if defined(_WIN32) qse_printf (QSE_T("closed file....%p\n"), handle.ptr);
/* TODO: */ qse_fio_close (handle.ptr);
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
#elif defined(__OS2__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
#elif defined(__DOS__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
#else
qse_printf (QSE_T("closing file %d\n"), handle.i);
QSE_CLOSE (handle.i);
#endif
} }
static qse_ssize_t file_read ( static qse_ssize_t file_read (
qse_httpd_t* httpd, qse_ubi_t handle, qse_httpd_t* httpd, qse_ubi_t handle,
qse_mchar_t* buf, qse_size_t len) qse_mchar_t* buf, qse_size_t len)
{ {
#if defined(_WIN32) /* TODO: error code conversion */
/* TODO: */ return qse_fio_read (handle.ptr, buf, len);
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#elif defined(__OS2__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#elif defined(__DOS__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#else
return QSE_READ (handle.i, buf, len);
#endif
} }
static qse_ssize_t file_write ( static qse_ssize_t file_write (
qse_httpd_t* httpd, qse_ubi_t handle, qse_httpd_t* httpd, qse_ubi_t handle,
const qse_mchar_t* buf, qse_size_t len) const qse_mchar_t* buf, qse_size_t len)
{ {
#if defined(_WIN32) /* TODO: error code conversion */
/* TODO: */ return qse_fio_write (handle.ptr, buf, len);
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#elif defined(__OS2__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#elif defined(__DOS__)
/* TODO: */
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#else
return QSE_WRITE (handle.i, buf, len);
#endif
} }
/* ------------------------------------------------------------------- */ /* ------------------------------------------------------------------- */
@ -1227,7 +1216,9 @@ static int dir_open (qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* han
return -1; return -1;
} }
d->dp = qse_dir_open (httpd->mmgr, 0, (const qse_char_t*)path, QSE_DIR_MBSPATH | QSE_DIR_SORT); qse_printf (QSE_T("OPENDING DIRECTORY [%hs]\n"), path);
d->dp = qse_dir_open (httpd->mmgr, 0,
(const qse_char_t*)path, QSE_DIR_MBSPATH | QSE_DIR_SORT);
if (d->dp == QSE_NULL) if (d->dp == QSE_NULL)
{ {
qse_httpd_seterrnum (httpd, syserr_to_errnum(errno)); qse_httpd_seterrnum (httpd, syserr_to_errnum(errno));
@ -1236,6 +1227,7 @@ static int dir_open (qse_httpd_t* httpd, const qse_mchar_t* path, qse_ubi_t* han
return -1; return -1;
} }
qse_printf (QSE_T("OPENED DIRECTORY [%hs]\n"), path);
handle->ptr = d; handle->ptr = d;
return 0; return 0;
} }
@ -1380,14 +1372,14 @@ static qse_ssize_t client_sendfile (
if (client->status & CLIENT_SECURE) if (client->status & CLIENT_SECURE)
{ {
#if defined(HAVE_SSL) #if defined(HAVE_SSL)
return xsendfile_ssl (client->handle2.ptr, handle.i, offset, count); return send_file_ssl (client->handle2.ptr, handle, offset, count);
#else #else
return -1; return -1;
#endif #endif
} }
else else
{ {
return xsendfile (client->handle.i, handle.i, offset, count); return send_file (client->handle.i, handle, offset, count);
} }
} }
@ -1768,8 +1760,7 @@ static qse_httpd_scb_t httpd_system_callbacks =
}, },
/* file operation */ /* file operation */
{ file_executable, { file_stat,
file_stat,
file_ropen, file_ropen,
file_wopen, file_wopen,
file_close, file_close,
@ -1947,7 +1938,7 @@ static int make_resource (
const qse_mchar_t* qpath; const qse_mchar_t* qpath;
const qse_mchar_t* idxfile; const qse_mchar_t* idxfile;
qse_mchar_t* xpath; qse_mchar_t* xpath;
qse_stat_t st; qse_httpd_stat_t st;
qse_size_t i; qse_size_t i;
int n; int n;
@ -1955,6 +1946,7 @@ static int make_resource (
QSE_MEMSET (target, 0, QSE_SIZEOF(*target)); QSE_MEMSET (target, 0, QSE_SIZEOF(*target));
qse_printf (QSE_T(">>> MAKING RESOURCE [%hs]\n"), qpath);
server_xtn = qse_httpd_getserverxtn (httpd, client->server); server_xtn = qse_httpd_getserverxtn (httpd, client->server);
if (server_xtn->cfg[SERVER_XTN_CFG_REALM] && if (server_xtn->cfg[SERVER_XTN_CFG_REALM] &&
@ -1983,17 +1975,10 @@ auth_ok:
xpath = merge_paths (httpd, server_xtn->cfg[SERVER_XTN_CFG_DOCROOT], qpath); xpath = merge_paths (httpd, server_xtn->cfg[SERVER_XTN_CFG_DOCROOT], qpath);
if (xpath == QSE_NULL) return -1; if (xpath == QSE_NULL) return -1;
#if defined(_WIN32) qse_printf (QSE_T(">>> check if [%hs] is a directory\n"), xpath);
/* TODO */ if (httpd->scb->file.stat (httpd, xpath, &st) >= 0 && st.isdir)
#elif defined(__OS2__)
/* TODO */
#elif defined(__DOS__)
/* TODO */
#else
if (QSE_STAT (xpath, &st) == 0 && S_ISDIR(st.st_mode))
#endif
{ {
qse_printf (QSE_T(">>> [%hs] is a directory\n"), xpath);
/* it is a directory */ /* it is a directory */
if (server_xtn->cfg2.s.idxstd) if (server_xtn->cfg2.s.idxstd)
{ {
@ -2009,16 +1994,7 @@ auth_ok:
return -1; return -1;
} }
#if defined(_WIN32) if (httpd->scb->file.stat (httpd, tpath, &st) >= 0 && st.isdir)
/* TODO */
#elif defined(__OS2__)
/* TODO */
#elif defined(__DOS__)
/* TODO */
#else
if (QSE_STAT (tpath, &st) == 0 && S_ISREG(st.st_mode))
#endif
{ {
/* the index file is found */ /* the index file is found */
QSE_MMGR_FREE (httpd->mmgr, xpath); QSE_MMGR_FREE (httpd->mmgr, xpath);
@ -2033,9 +2009,11 @@ auth_ok:
target->type = QSE_HTTPD_RSRC_DIR; target->type = QSE_HTTPD_RSRC_DIR;
target->u.dir.path = xpath; target->u.dir.path = xpath;
qse_printf (QSE_T(">>> MADE DIREcTORY RESOURCE [%hs]\n"), xpath);
} }
else else
{ {
qse_printf (QSE_T(">>> [%hs] is a file\n"), xpath);
attempt_file: attempt_file:
if (server_xtn->cfg2.s.cgistd) if (server_xtn->cfg2.s.cgistd)
{ {

View File

@ -252,12 +252,12 @@ static qse_httpd_task_t* entask_status (
return qse_httpd_entaskformat ( return qse_httpd_entaskformat (
httpd, client, pred, httpd, client, pred,
QSE_MT("HTTP/%d.%d %d %s\r\nServer: %s\r\nDate: %s\r\nConnection: %s\r\nContent-Type: text/html\r\nContent-Length: %lu\r\n%s%s%s\r\n%s"), QSE_MT("HTTP/%d.%d %d %s\r\nServer: %s\r\nDate: %s\r\nConnection: %s\r\nContent-Type: text/html\r\nContent-Length: %u\r\n%s%s%s\r\n%s"),
version->major, version->minor, version->major, version->minor,
code, msg, qse_httpd_getname (httpd), code, msg, qse_httpd_getname (httpd),
qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0), qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0),
(keepalive? QSE_MT("keep-alive"): QSE_MT("close")), (keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
(unsigned long)qse_mbslen(text), (unsigned int)qse_mbslen(text), /* unsigned int should be large enough since text is small */
extrapre, extraval, extrapst, text); extrapre, extraval, extrapst, text);
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/

View File

@ -77,7 +77,9 @@ static int httpd_main (int argc, qse_char_t* argv[])
g_httpd = httpd; g_httpd = httpd;
signal (SIGINT, sigint); signal (SIGINT, sigint);
#if defined(SIGPIPE)
signal (SIGPIPE, SIG_IGN); signal (SIGPIPE, SIG_IGN);
#endif
qse_httpd_setoption (httpd, QSE_HTTPD_CGIERRTONUL); qse_httpd_setoption (httpd, QSE_HTTPD_CGIERRTONUL);
@ -86,7 +88,9 @@ static int httpd_main (int argc, qse_char_t* argv[])
ret = qse_httpd_loopstd (httpd, &tmout); ret = qse_httpd_loopstd (httpd, &tmout);
signal (SIGINT, SIG_DFL); signal (SIGINT, SIG_DFL);
#if defined(SIGPIPE)
signal (SIGPIPE, SIG_DFL); signal (SIGPIPE, SIG_DFL);
#endif
g_httpd = QSE_NULL; g_httpd = QSE_NULL;
if (ret <= -1) qse_fprintf (QSE_STDERR, QSE_T("Httpd error\n")); if (ret <= -1) qse_fprintf (QSE_STDERR, QSE_T("Httpd error\n"));

View File

@ -213,7 +213,9 @@ static int httpd_main (int argc, qse_char_t* argv[])
g_httpd = httpd; g_httpd = httpd;
signal (SIGINT, sigint); signal (SIGINT, sigint);
#if defined(SIGPIPE)
signal (SIGPIPE, SIG_IGN); signal (SIGPIPE, SIG_IGN);
#endif
qse_httpd_setname (httpd, QSE_MT("httpd02/qse 1.0")); qse_httpd_setname (httpd, QSE_MT("httpd02/qse 1.0"));
@ -224,7 +226,9 @@ static int httpd_main (int argc, qse_char_t* argv[])
ret = qse_httpd_loopstd (httpd, &tmout); ret = qse_httpd_loopstd (httpd, &tmout);
signal (SIGINT, SIG_DFL); signal (SIGINT, SIG_DFL);
#if defined(SIGPIPE)
signal (SIGPIPE, SIG_DFL); signal (SIGPIPE, SIG_DFL);
#endif
g_httpd = QSE_NULL; g_httpd = QSE_NULL;
if (ret <= -1) qse_fprintf (QSE_STDERR, QSE_T("Httpd error\n")); if (ret <= -1) qse_fprintf (QSE_STDERR, QSE_T("Httpd error\n"));