added qse_nwadequal()

touched up httpd a bit more
This commit is contained in:
hyung-hwan 2012-10-01 13:30:44 +00:00
parent 2bf8d7610f
commit d2572d9c46
8 changed files with 206 additions and 197 deletions

View File

@ -75,6 +75,11 @@ enum qse_nwadtostr_flag_t
extern "C" {
#endif
int qse_nwadequal (
const qse_nwad_t* x,
const qse_nwad_t* y
);
int qse_mbstonwad (
const qse_mchar_t* mbs,
qse_nwad_t* nwad

View File

@ -310,9 +310,6 @@ struct qse_httpd_client_t
qse_httpd_client_t* bad_next;
qse_httpd_client_t* prev_tasked;
qse_httpd_client_t* next_tasked;
struct
{
int count;
@ -362,7 +359,10 @@ struct qse_httpd_rsrc_t
const qse_mchar_t* path;
} dir;
int error;
struct
{
int code;
} error;
struct
{
@ -714,6 +714,9 @@ void* qse_httpd_getserverxtnstd (
qse_httpd_server_t* server
);
qse_httpd_cbstd_t* qse_httpd_getdflcbstd (
qse_httpd_t* httpd
);
int qse_httpd_loopstd (
qse_httpd_t* httpd,

View File

@ -25,6 +25,27 @@
#include <qse/cmn/fmt.h>
#include "mem.h"
int qse_nwadequal (const qse_nwad_t* x, const qse_nwad_t* y)
{
if (x->type != y->type) return 0;
switch (x->type)
{
case QSE_NWAD_IN4:
return (x->u.in4.port == y->u.in4.port &&
QSE_MEMCMP (&x->u.in4.addr, &y->u.in4.addr, QSE_SIZEOF(x->u.in4.addr)) == 0)? 1: 0;
case QSE_NWAD_IN6:
return (x->u.in6.port == y->u.in6.port &&
x->u.in6.scope == y->u.in6.scope &&
QSE_MEMCMP (&x->u.in6.addr, &y->u.in6.addr, QSE_SIZEOF(x->u.in6.addr)) == 0)? 1: 0;
default:
/* can't compare */
return -1;
}
}
int qse_mbstonwad (const qse_mchar_t* str, qse_nwad_t* nwad)
{
return qse_mbsntonwad (str, qse_mbslen(str), nwad);

View File

@ -337,10 +337,6 @@ static int init_xtn_ssl (
{
SSL_CTX* ctx;
SSL_library_init ();
SSL_load_error_strings ();
/*SSLeay_add_ssl_algorithms();*/
ctx = SSL_CTX_new (SSLv23_server_method());
if (ctx == QSE_NULL) return -1;
@ -353,14 +349,15 @@ static int init_xtn_ssl (
{
qse_mchar_t buf[128];
ERR_error_string_n(ERR_get_error(), buf, QSE_COUNTOF(buf));
/* TODO: logging */
qse_fprintf (QSE_STDERR, QSE_T("Error: %hs\n"), buf);
SSL_CTX_free (ctx);
return -1;
}
/* TODO: CRYPTO_set_id_callback ();
TODO: CRYPTO_set_locking_callback ();*/
/* TODO: CRYPTO_set_id_callback (); */
/* TODO: CRYPTO_set_locking_callback (); */
SSL_CTX_set_read_ahead (ctx, 0);
xtn->ssl_ctx = ctx;
@ -369,16 +366,9 @@ static int init_xtn_ssl (
static void fini_xtn_ssl (httpd_xtn_t* xtn)
{
/* TODO: CRYPTO_set_id_callback (QSE_NULL);
TODO: CRYPTO_set_locking_callback (QSE_NULL); */
/* TODO: CRYPTO_set_id_callback (QSE_NULL); */
/* TODO: CRYPTO_set_locking_callback (QSE_NULL); */
SSL_CTX_free (xtn->ssl_ctx);
/*ERR_remove_state ();*/
ENGINE_cleanup ();
ERR_free_strings ();
EVP_cleanup ();
CRYPTO_cleanup_all_ex_data ();
}
#endif
@ -464,11 +454,11 @@ qse_httpd_server_t* qse_httpd_attachserverstd (
if (qse_strtouri (uri, &xuri, QSE_STRTOURI_NOQUERY) <= -1) goto invalid;
if (qse_strxcmp (xuri.scheme.ptr, xuri.scheme.len, QSE_T("http")) == 0)
if (qse_strxcasecmp (xuri.scheme.ptr, xuri.scheme.len, QSE_T("http")) == 0)
{
default_port = DEFAULT_PORT;
}
else if (qse_strxcmp (xuri.scheme.ptr, xuri.scheme.len, QSE_T("https")) == 0)
else if (qse_strxcasecmp (xuri.scheme.ptr, xuri.scheme.len, QSE_T("https")) == 0)
{
server.flags |= QSE_HTTPD_SERVER_SECURE;
default_port = DEFAULT_SECURE_PORT;
@ -1540,7 +1530,7 @@ if (qse_htre_getqparam(req))
qse_htb_walk (&req->hdrtab, walk, QSE_NULL);
if (qse_htre_getcontentlen(req) > 0)
{
qse_printf (QSE_T("CONTENT before discard = [%.*S]\n"), (int)qse_htre_getcontentlen(req), qse_htre_getcontentptr(req));
qse_printf (QSE_T("CONTENT [%.*S]\n"), (int)qse_htre_getcontentlen(req), qse_htre_getcontentptr(req));
}
if (peek)
@ -1562,21 +1552,11 @@ if (qse_htre_getcontentlen(req) > 0)
* and no content received yet */
/* TODO: determine if to return 100-continue or other errors */
{
qse_ntime_t now;
qse_gettime (&now);
qse_printf (QSE_T("entasking continue at %lld\n"), (long long)now);
}
if (qse_httpd_entaskcontinue (
httpd, client, QSE_NULL, req) == QSE_NULL) return -1;
}
}
if (qse_htre_getcontentlen(req) > 0)
{
qse_printf (QSE_T("CONTENT after discard = [%.*S]\n"), (int)qse_htre_getcontentlen(req), qse_htre_getcontentptr(req));
}
if (method == QSE_HTTP_GET || method == QSE_HTTP_POST)
{
if (peek)
@ -1638,81 +1618,16 @@ oops:
return -1;
}
static int proxy_request (
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req, int peek)
{
qse_httpd_task_t* task;
/* TODO: investigate if the proxy need to handle 100-continue */
if (peek)
{
qse_nwad_t nwad;
#if 0
if (qse_nwadequal (&client->local_addr, &client->orgdst_addr))
{
//qse_strtonwad (QSE_T("192.168.1.55:9000"), &nwad);
//qse_strtonwad (QSE_T("1.234.53.142:80"), &nwad);
}
else
{
#endif
nwad = client->orgdst_addr;
#if 0
}
#endif
task = qse_httpd_entaskproxy (httpd, client, QSE_NULL, &nwad, QSE_NULL, 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:
return -1;
}
static int peek_request (
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req)
{
/*
if (QSE_MEMCMP (&client->local_addr, &client->orgdst_addr, sizeof(client->orgdst_addr)) == 0)
{
*/
return process_request (httpd, client, req, 1);
/*
}
else
{
return proxy_request (httpd, client, req, 1);
}
*/
}
static int handle_request (
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req)
{
/*
if (QSE_MEMCMP (&client->local_addr, &client->orgdst_addr, sizeof(client->orgdst_addr)) == 0)
{
*/
return process_request (httpd, client, req, 0);
/*
}
else
{
return proxy_request (httpd, client, req, 0);
}
*/
}
static qse_httpd_scb_t httpd_system_callbacks =
@ -1973,6 +1888,11 @@ static qse_httpd_cbstd_t httpd_cbstd =
free_resource
};
qse_httpd_cbstd_t* qse_httpd_getdflcbstd (qse_httpd_t* httpd)
{
return &httpd_cbstd;
}
int qse_httpd_loopstd (qse_httpd_t* httpd, qse_httpd_cbstd_t* cbstd, qse_ntime_t timeout)
{
httpd_xtn_t* xtn;

View File

@ -395,7 +395,8 @@ qse_httpd_task_t* qse_httpd_entaskrsrc (
case QSE_HTTPD_RSRC_ERROR:
qse_httpd_discardcontent (httpd, req);
task = qse_httpd_entaskerror (httpd, client, QSE_NULL, rsrc->u.error, req);
task = qse_httpd_entaskerror (httpd, client, QSE_NULL, rsrc->u.error.code, req);
break;
case QSE_HTTPD_RSRC_FILE:
qse_httpd_discardcontent (httpd, req);

View File

@ -350,26 +350,16 @@ static void purge_client (qse_httpd_t* httpd, qse_httpd_client_t* client)
{
qse_httpd_client_t* prev;
qse_httpd_client_t* next;
qse_httpd_client_t* prev_tasked;
qse_httpd_client_t* next_tasked;
prev = client->prev;
next = client->next;
prev_tasked = client->prev_tasked;
next_tasked = client->next_tasked;
free_client (httpd, client);
if (prev) prev->next = next;
else httpd->client.list.head = next;
if (next) next->prev = prev;
else httpd->client.list.tail = prev;
if (prev_tasked) prev_tasked->next_tasked = next_tasked;
else httpd->client.tasked.head = next_tasked;
if (next_tasked) next_tasked->prev_tasked = prev_tasked;
else httpd->client.tasked.tail = prev_tasked;
}
static void purge_client_list (qse_httpd_t* httpd)
@ -474,44 +464,6 @@ qse_printf (QSE_T("connection %d accepted %s(%s from %s\n"), client->handle.i, t
return 0;
}
static void insert_client_to_tasked_list (
qse_httpd_t* httpd, qse_httpd_client_t* client)
{
QSE_ASSERT (client->prev_tasked == QSE_NULL);
QSE_ASSERT (client->next_tasked == QSE_NULL);
if (httpd->client.tasked.tail)
{
QSE_ASSERT (httpd->client.tasked.head);
client->prev_tasked = httpd->client.tasked.tail;
httpd->client.tasked.tail->next_tasked = client;
httpd->client.tasked.tail = client;
}
else
{
httpd->client.tasked.head = client;
httpd->client.tasked.tail = client;
}
}
static void delete_client_from_tasked_list (
qse_httpd_t* httpd, qse_httpd_client_t* client)
{
qse_httpd_client_t* prev_tasked;
qse_httpd_client_t* next_tasked;
prev_tasked = client->prev_tasked;
next_tasked = client->next_tasked;
if (prev_tasked) prev_tasked->next_tasked = next_tasked;
else httpd->client.tasked.head = next_tasked;
if (next_tasked) next_tasked->prev_tasked = prev_tasked;
else httpd->client.tasked.tail = prev_tasked;
client->prev_tasked = QSE_NULL;
client->next_tasked = QSE_NULL;
}
/* --------------------------------------------------- */
static void deactivate_servers (qse_httpd_t* httpd)
@ -1096,9 +1048,6 @@ qse_httpd_task_t* qse_httpd_entask (
}
else if (new_task->prev == QSE_NULL)
{
/* this new task is the first task for a client */
/*insert_client_to_tasked_list (httpd, client);*/
/* arrange to invokde this task so long as
* the client-side handle is writable. */
QSE_ASSERT (client->status & CLIENT_HANDLE_IN_MUX);

View File

@ -26,6 +26,12 @@
# include <errno.h>
#endif
#if defined(HAVE_SSL)
# include <openssl/ssl.h>
# include <openssl/err.h>
# include <openssl/engine.h>
#endif
static qse_httpd_t* g_httpd = QSE_NULL;
static void sigint (int sig)
@ -81,9 +87,14 @@ oops:
int qse_main (int argc, qse_achar_t* argv[])
{
int ret;
#if defined(_WIN32)
char locale[100];
UINT codepage = GetConsoleOutputCP();
UINT codepage;
WSADATA wsadata;
codepage = GetConsoleOutputCP();
if (codepage == CP_UTF8)
{
/*SetConsoleOUtputCP (CP_UTF8);*/
@ -95,11 +106,37 @@ int qse_main (int argc, qse_achar_t* argv[])
setlocale (LC_ALL, locale);
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
}
if (WSAStartup (MAKEWORD(2,0), &wsadata) != 0)
{
qse_fprintf (QSE_STDERR, QSE_T("Failed to start up winsock\n"));
return -1;
}
#else
setlocale (LC_ALL, "");
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
#endif
return qse_runmain (argc, argv, httpd_main);
#if defined(HAVE_SSL)
SSL_load_error_strings ();
SSL_library_init ();
#endif
ret = qse_runmain (argc, argv, httpd_main);
#if defined(HAVE_SSL)
/*ERR_remove_state ();*/
ENGINE_cleanup ();
ERR_free_strings ();
EVP_cleanup ();
CRYPTO_cleanup_all_ex_data ();
#endif
#if defined(_WIN32)
WSACleanup ();
#endif
return ret;
}

View File

@ -27,22 +27,83 @@
#endif
#if defined(HAVE_SSL)
# include <openssl/ssl.h>
# include <openssl/err.h>
# include <openssl/engine.h>
#endif
/* --------------------------------------------------------------------- */
typedef struct xtn_t xtn_t;
struct xtn_t
typedef struct server_xtn_t server_xtn_t;
struct server_xtn_t
{
qse_mchar_t basedir[4096];
int tproxy;
};
static int makersrc (
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req, qse_httpd_rsrc_t* rsrc)
{
return -1;
server_xtn_t* server_xtn;
server_xtn = qse_httpd_getserverxtnstd (httpd, client->server);
if (server_xtn->tproxy)
{
if (qse_nwadequal(&client->orgdst_addr, &client->local_addr)) /* both equal and error */
{
/* TODO: implement a better check that the
* destination is not one of the local addresses */
rsrc->type = QSE_HTTPD_RSRC_ERROR;
rsrc->u.error.code = 500;
}
else
{
rsrc->type = QSE_HTTPD_RSRC_PROXY;
rsrc->u.proxy.dst = client->orgdst_addr;
rsrc->u.proxy.src = client->remote_addr;
if (rsrc->u.proxy.src.type == QSE_NWAD_IN4)
rsrc->u.proxy.src.u.in4.port = 0; /* reset the port to 0. */
else if (rsrc->u.proxy.src.type == QSE_NWAD_IN6)
rsrc->u.proxy.src.u.in6.port = 0; /* reset the port to 0. */
}
static void freersrc (qse_httpd_t* httpd, qse_httpd_rsrc_t* rsrc)
return 0;
}
else
{
qse_httpd_cbstd_t* dflcbstd = qse_httpd_getdflcbstd (httpd);
#if 0
if (dflcbstd->makersrc (httpd, client, req, rsrc) <= -1) return -1;
if (rsrc->type == QSE_HTTPD_RSRC_DIR)
{
/* no directory listing - */
rsrc->type = QSE_HTTPD_RSRC_ERROR;
rsrc->u.error.code = 500;
}
return 0;
#endif
return dflcbstd->makersrc (httpd, client, req, rsrc);
}
}
static void freersrc (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req, qse_httpd_rsrc_t* rsrc)
{
server_xtn_t* server_xtn;
server_xtn = qse_httpd_getserverxtnstd (httpd, client->server);
if (server_xtn->tproxy)
{
/* nothing to do */
}
else
{
qse_httpd_cbstd_t* dflcbstd = qse_httpd_getdflcbstd (httpd);
return dflcbstd->freersrc (httpd, client, req, rsrc);
}
}
/* --------------------------------------------------------------------- */
@ -55,46 +116,26 @@ static void sigint (int sig)
}
/* --------------------------------------------------------------------- */
#if 0
static qse_httpd_server_t* attach_server (qse_httpd_t* httpd, const qse_char_t* uri)
static qse_httpd_server_t* attach_server (qse_httpd_t* httpd, qse_char_t* uri)
{
qse_httpd_server_t server, * xserver;
const qse_char_t* docroot;
qse_httpd_server_t* server;
server_xtn_t* server_xtn;
qse_uri_t xuri;
int tproxy = 0;
if (qse_ripuri (uri, &xuri, QSE_RIPURI_NOQUERY | QSE_RIP_URI_NOFRAGMENT) <= -1)
return QSE_NULL;
/* if (parse_server_uri (httpd, uri, &server, &docroot) <= -1) return QSE_NULL;*/
server.predetach = predetach_server;
xserver = qse_httpd_attachserver (
httpd, &server, QSE_SIZEOF(*server_xtn) + xtnsize);
if (xserver == QSE_NULL) return QSE_NULL;
if (docroot[0] == QSE_T('/') && docroot[1] != QSE_T('\0'))
if (qse_strzcasecmp (uri, QSE_T("http-tproxy://"), 14) == 0)
{
server_xtn = qse_httpd_getserverxtn (httpd, xserver);
#if defined(QSE_CHAR_IS_MCHAR)
server_xtn->docroot.ptr = qse_mbsdup (docroot, httpd->mmgr);
#else
server_xtn->docroot.ptr = qse_wcstombsdup (docroot, httpd->mmgr);
#endif
if (server_xtn->docroot.ptr == QSE_NULL)
{
qse_httpd_detachserver (httpd, xserver);
httpd->errnum = QSE_HTTPD_ENOMEM;
return QSE_NULL;
tproxy = 1;
qse_strcpy (&uri[4], &uri[11]);
}
server_xtn->docroot.len = qse_mbslen(server_xtn->docroot.ptr);
}
server = qse_httpd_attachserverstd (httpd, uri, QSE_SIZEOF(server_xtn_t));
if (server == QSE_NULL) return QSE_NULL;
return xserver;
server_xtn = qse_httpd_getserverxtnstd (httpd, server);
server_xtn->tproxy = tproxy;
return server;
}
#endif
/* --------------------------------------------------------------------- */
static int httpd_main (int argc, qse_char_t* argv[])
@ -109,7 +150,7 @@ static int httpd_main (int argc, qse_char_t* argv[])
goto oops;
}
httpd = qse_httpd_openstd (QSE_SIZEOF(xtn_t));
httpd = qse_httpd_openstd (QSE_SIZEOF(server_xtn_t));
if (httpd == QSE_NULL)
{
qse_fprintf (QSE_STDERR, QSE_T("Cannot open httpd\n"));
@ -118,7 +159,7 @@ static int httpd_main (int argc, qse_char_t* argv[])
for (i = 1; i < argc; i++)
{
if (qse_httpd_attachserverstd (httpd, argv[i], 0) == QSE_NULL)
if (attach_server (httpd, argv[i]) == QSE_NULL)
{
qse_fprintf (QSE_STDERR,
QSE_T("Failed to add httpd listener - %s\n"), argv[i]);
@ -148,9 +189,14 @@ oops:
int qse_main (int argc, qse_achar_t* argv[])
{
int ret;
#if defined(_WIN32)
char locale[100];
UINT codepage = GetConsoleOutputCP();
UINT codepage;
WSADATA wsadata;
codepage = GetConsoleOutputCP();
if (codepage == CP_UTF8)
{
/*SetConsoleOUtputCP (CP_UTF8);*/
@ -162,11 +208,38 @@ int qse_main (int argc, qse_achar_t* argv[])
setlocale (LC_ALL, locale);
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
}
if (WSAStartup (MAKEWORD(2,0), &wsadata) != 0)
{
qse_fprintf (QSE_STDERR, QSE_T("Failed to start up winsock\n"));
return -1;
}
#else
setlocale (LC_ALL, "");
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
#endif
return qse_runmain (argc, argv, httpd_main);
#if defined(HAVE_SSL)
SSL_load_error_strings ();
SSL_library_init ();
#endif
ret = qse_runmain (argc, argv, httpd_main);
#if defined(HAVE_SSL)
/*ERR_remove_state ();*/
ENGINE_cleanup ();
ERR_free_strings ();
EVP_cleanup ();
CRYPTO_cleanup_all_ex_data ();
#endif
#if defined(_WIN32)
WSACleanup ();
#endif
return ret;
}