enhanced httpd a bit
This commit is contained in:
@ -5,7 +5,7 @@ AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(includedir)
|
||||
|
||||
bin_PROGRAMS = http01 upxd01
|
||||
bin_PROGRAMS = httpd01 httpd02 upxd01
|
||||
|
||||
LDFLAGS += -L../../lib/cmn -L../../lib/net
|
||||
LDADD = -lqsenet -lqsecmn $(PTHREAD_LIBS) $(SOCKET_LIBS) $(SENDFILE_LIBS)
|
||||
@ -16,7 +16,9 @@ LDADD += $(UNICOWS_LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
http01_SOURCES = http01.c
|
||||
httpd01_SOURCES = httpd01.c
|
||||
httpd02_SOURCES = httpd02.c
|
||||
upxd01_SOURCES = upxd01.c
|
||||
|
||||
http01_LDADD = $(LDADD) $(SSL_LIBS)
|
||||
httpd01_LDADD = $(LDADD) $(SSL_LIBS)
|
||||
httpd02_LDADD = $(LDADD) $(SSL_LIBS)
|
||||
|
@ -34,7 +34,7 @@ PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
bin_PROGRAMS = http01$(EXEEXT) upxd01$(EXEEXT)
|
||||
bin_PROGRAMS = httpd01$(EXEEXT) httpd02$(EXEEXT) upxd01$(EXEEXT)
|
||||
@WCHAR_TRUE@@WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS)
|
||||
subdir = samples/net
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
@ -52,13 +52,16 @@ CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
PROGRAMS = $(bin_PROGRAMS)
|
||||
am_http01_OBJECTS = http01.$(OBJEXT)
|
||||
http01_OBJECTS = $(am_http01_OBJECTS)
|
||||
am_httpd01_OBJECTS = httpd01.$(OBJEXT)
|
||||
httpd01_OBJECTS = $(am_httpd01_OBJECTS)
|
||||
am__DEPENDENCIES_1 =
|
||||
@WCHAR_TRUE@@WIN32_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
|
||||
am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
http01_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1)
|
||||
httpd01_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1)
|
||||
am_httpd02_OBJECTS = httpd02.$(OBJEXT)
|
||||
httpd02_OBJECTS = $(am_httpd02_OBJECTS)
|
||||
httpd02_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1)
|
||||
am_upxd01_OBJECTS = upxd01.$(OBJEXT)
|
||||
upxd01_OBJECTS = $(am_upxd01_OBJECTS)
|
||||
upxd01_LDADD = $(LDADD)
|
||||
@ -77,8 +80,8 @@ CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(http01_SOURCES) $(upxd01_SOURCES)
|
||||
DIST_SOURCES = $(http01_SOURCES) $(upxd01_SOURCES)
|
||||
SOURCES = $(httpd01_SOURCES) $(httpd02_SOURCES) $(upxd01_SOURCES)
|
||||
DIST_SOURCES = $(httpd01_SOURCES) $(httpd02_SOURCES) $(upxd01_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
@ -243,9 +246,11 @@ AM_CPPFLAGS = \
|
||||
|
||||
LDADD = -lqsenet -lqsecmn $(PTHREAD_LIBS) $(SOCKET_LIBS) \
|
||||
$(SENDFILE_LIBS) $(am__append_1)
|
||||
http01_SOURCES = http01.c
|
||||
httpd01_SOURCES = httpd01.c
|
||||
httpd02_SOURCES = httpd02.c
|
||||
upxd01_SOURCES = upxd01.c
|
||||
http01_LDADD = $(LDADD) $(SSL_LIBS)
|
||||
httpd01_LDADD = $(LDADD) $(SSL_LIBS)
|
||||
httpd02_LDADD = $(LDADD) $(SSL_LIBS)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
@ -323,9 +328,12 @@ clean-binPROGRAMS:
|
||||
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
http01$(EXEEXT): $(http01_OBJECTS) $(http01_DEPENDENCIES) $(EXTRA_http01_DEPENDENCIES)
|
||||
@rm -f http01$(EXEEXT)
|
||||
$(LINK) $(http01_OBJECTS) $(http01_LDADD) $(LIBS)
|
||||
httpd01$(EXEEXT): $(httpd01_OBJECTS) $(httpd01_DEPENDENCIES) $(EXTRA_httpd01_DEPENDENCIES)
|
||||
@rm -f httpd01$(EXEEXT)
|
||||
$(LINK) $(httpd01_OBJECTS) $(httpd01_LDADD) $(LIBS)
|
||||
httpd02$(EXEEXT): $(httpd02_OBJECTS) $(httpd02_DEPENDENCIES) $(EXTRA_httpd02_DEPENDENCIES)
|
||||
@rm -f httpd02$(EXEEXT)
|
||||
$(LINK) $(httpd02_OBJECTS) $(httpd02_LDADD) $(LIBS)
|
||||
upxd01$(EXEEXT): $(upxd01_OBJECTS) $(upxd01_DEPENDENCIES) $(EXTRA_upxd01_DEPENDENCIES)
|
||||
@rm -f upxd01$(EXEEXT)
|
||||
$(LINK) $(upxd01_OBJECTS) $(upxd01_LDADD) $(LIBS)
|
||||
@ -336,7 +344,8 @@ mostlyclean-compile:
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http01.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd01.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/httpd02.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upxd01.Po@am__quote@
|
||||
|
||||
.c.o:
|
||||
|
@ -33,7 +33,7 @@ static void sigint (int sig)
|
||||
if (g_httpd) qse_httpd_stop (g_httpd);
|
||||
}
|
||||
|
||||
int httpd_main (int argc, qse_char_t* argv[])
|
||||
static int httpd_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_httpd_t* httpd = QSE_NULL;
|
||||
int ret = -1, i;
|
||||
@ -66,7 +66,7 @@ int httpd_main (int argc, qse_char_t* argv[])
|
||||
signal (SIGPIPE, SIG_IGN);
|
||||
|
||||
qse_httpd_setoption (httpd, QSE_HTTPD_CGIERRTONUL);
|
||||
ret = qse_httpd_loopstd (httpd, 10000);
|
||||
ret = qse_httpd_loopstd (httpd, QSE_NULL, 10000);
|
||||
|
||||
signal (SIGINT, SIG_DFL);
|
||||
signal (SIGPIPE, SIG_DFL);
|
249
qse/samples/net/httpd02.c
Normal file
249
qse/samples/net/httpd02.c
Normal file
@ -0,0 +1,249 @@
|
||||
|
||||
#include <qse/net/httpd.h>
|
||||
#include <qse/cmn/stdio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/mem.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
#include <qse/cmn/time.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <locale.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
# include <tchar.h>
|
||||
# include <process.h>
|
||||
#elif defined(__OS2__)
|
||||
# define INCL_DOSPROCESS
|
||||
# define INCL_DOSEXCEPTIONS
|
||||
# define INCL_ERRORS
|
||||
# include <os2.h>
|
||||
#elif defined(__DOS__)
|
||||
# include <dos.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
typedef struct xtn_t xtn_t;
|
||||
struct xtn_t
|
||||
{
|
||||
qse_mchar_t basedir[4096];
|
||||
};
|
||||
|
||||
static int process_request (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_htre_t* req, int peek)
|
||||
{
|
||||
int method;
|
||||
qse_httpd_task_t* task;
|
||||
int content_received;
|
||||
xtn_t* xtn;
|
||||
|
||||
method = qse_htre_getqmethodtype(req);
|
||||
content_received = (qse_htre_getcontentlen(req) > 0);
|
||||
|
||||
xtn = (xtn_t*) qse_httpd_getxtn (httpd);
|
||||
|
||||
if (peek) qse_perdechttpstr (qse_htre_getqpath(req), qse_htre_getqpath(req));
|
||||
|
||||
qse_printf (QSE_T("================================\n"));
|
||||
qse_printf (QSE_T("[%lu] %hs REQUEST ==> [%hs] version[%d.%d %hs] method[%hs]\n"),
|
||||
(unsigned long)time(NULL),
|
||||
(peek? QSE_MT("PEEK"): QSE_MT("HANDLE")),
|
||||
qse_htre_getqpath(req),
|
||||
qse_htre_getmajorversion(req),
|
||||
qse_htre_getminorversion(req),
|
||||
qse_htre_getverstr(req),
|
||||
qse_htre_getqmethodname(req)
|
||||
);
|
||||
if (qse_htre_getqparam(req))
|
||||
qse_printf (QSE_T("PARAMS ==> [%hs]\n"), qse_htre_getqparam(req));
|
||||
|
||||
if (peek)
|
||||
{
|
||||
if (method != QSE_HTTP_POST && method != QSE_HTTP_PUT)
|
||||
{
|
||||
/* i'll discard request contents if the method is none of
|
||||
* post and put */
|
||||
qse_httpd_discardcontent (httpd, req);
|
||||
}
|
||||
|
||||
if ((req->attr.flags & QSE_HTRE_ATTR_EXPECT100) &&
|
||||
(req->version.major > 1 ||
|
||||
(req->version.major == 1 && req->version.minor >= 1)) &&
|
||||
!content_received)
|
||||
{
|
||||
/* TODO: check method.... */
|
||||
/* "expect" in the header, version 1.1 or higher,
|
||||
* and no content received yet */
|
||||
|
||||
/* TODO: determine if to return 100-continue or other errors */
|
||||
if (qse_httpd_entaskcontinue (
|
||||
httpd, client, QSE_NULL, req) == QSE_NULL) return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (method == QSE_HTTP_GET || method == QSE_HTTP_POST)
|
||||
{
|
||||
const qse_mchar_t* qpath = qse_htre_getqpath(req);
|
||||
const qse_mchar_t* dot = qse_mbsrchr (qpath, QSE_MT('.'));
|
||||
|
||||
if (dot && qse_mbscmp (dot, QSE_MT(".cgi")) == 0)
|
||||
{
|
||||
if (peek)
|
||||
{
|
||||
/* cgi */
|
||||
if (method == QSE_HTTP_POST &&
|
||||
!(req->attr.flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||
!(req->attr.flags & QSE_HTRE_ATTR_CHUNKED))
|
||||
{
|
||||
req->attr.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||
task = qse_httpd_entaskerror (
|
||||
httpd, client, QSE_NULL, 411, req);
|
||||
/* 411 can't keep alive */
|
||||
if (task) qse_httpd_entaskdisconnect (httpd, client, QSE_NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
task = qse_httpd_entaskcgi (
|
||||
httpd, client, QSE_NULL, qpath, req);
|
||||
if (task == QSE_NULL) goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (peek)
|
||||
{
|
||||
/* TODO: combine qpath with xtn->basedir */
|
||||
qse_httpd_discardcontent (httpd, req);
|
||||
task = qse_httpd_entaskpath (httpd, client, QSE_NULL, qpath, req);
|
||||
if (task == QSE_NULL) goto oops;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!peek)
|
||||
{
|
||||
task = qse_httpd_entaskerror (httpd, client, QSE_NULL, 405, req);
|
||||
if (task == QSE_NULL) goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE))
|
||||
{
|
||||
if (!peek)
|
||||
{
|
||||
task = qse_httpd_entaskdisconnect (httpd, client, QSE_NULL);
|
||||
if (task == QSE_NULL) goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
/*qse_httpd_markbadclient (httpd, client);*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int peek_request (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req)
|
||||
{
|
||||
return process_request (httpd, client, req, 1);
|
||||
}
|
||||
|
||||
static int handle_request (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req)
|
||||
{
|
||||
return process_request (httpd, client, req, 0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static qse_httpd_t* g_httpd = QSE_NULL;
|
||||
|
||||
static void sigint (int sig)
|
||||
{
|
||||
if (g_httpd) qse_httpd_stop (g_httpd);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
static int httpd_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_httpd_t* httpd = QSE_NULL;
|
||||
int ret = -1, i;
|
||||
static qse_httpd_rcb_t rcb = { peek_request, handle_request };
|
||||
|
||||
if (argc <= 1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("Usage: %s <listener_uri> ...\n"), argv[0]);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
httpd = qse_httpd_openstd (QSE_SIZEOF(xtn_t));
|
||||
if (httpd == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("Cannot open httpd\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (qse_httpd_addserver (httpd, argv[i]) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR,
|
||||
QSE_T("Failed to add httpd listener - %s\n"), argv[i]);
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
g_httpd = httpd;
|
||||
signal (SIGINT, sigint);
|
||||
signal (SIGPIPE, SIG_IGN);
|
||||
|
||||
qse_httpd_setoption (httpd, QSE_HTTPD_CGIERRTONUL);
|
||||
ret = qse_httpd_loopstd (httpd, &rcb, 10000);
|
||||
|
||||
signal (SIGINT, SIG_DFL);
|
||||
signal (SIGPIPE, SIG_DFL);
|
||||
g_httpd = QSE_NULL;
|
||||
|
||||
if (ret <= -1) qse_fprintf (QSE_STDERR, QSE_T("Httpd error\n"));
|
||||
|
||||
oops:
|
||||
if (httpd) qse_httpd_close (httpd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
char locale[100];
|
||||
UINT codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||
qse_setdflcmgr (qse_utf8cmgr);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (locale, ".%u", (unsigned int)codepage);
|
||||
setlocale (LC_ALL, locale);
|
||||
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
||||
}
|
||||
#else
|
||||
setlocale (LC_ALL, "");
|
||||
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
||||
#endif
|
||||
|
||||
return qse_runmain (argc, argv, httpd_main);
|
||||
}
|
||||
|
Reference in New Issue
Block a user