Added qse_str_amend()
almost finished primitive url rewriting
This commit is contained in:
parent
0bb946c800
commit
1ba63f1829
@ -2747,6 +2747,13 @@ QSE_EXPORT qse_size_t qse_mbs_del (
|
||||
qse_size_t size
|
||||
);
|
||||
|
||||
QSE_EXPORT qse_size_t qse_mbs_amend (
|
||||
qse_mbs_t* str,
|
||||
qse_size_t index,
|
||||
qse_size_t size,
|
||||
const qse_mchar_t* repl
|
||||
);
|
||||
|
||||
QSE_EXPORT qse_size_t qse_mbs_trm (
|
||||
qse_mbs_t* str
|
||||
);
|
||||
@ -2956,6 +2963,19 @@ QSE_EXPORT qse_size_t qse_wcs_del (
|
||||
qse_size_t size
|
||||
);
|
||||
|
||||
/**
|
||||
* The qse_wcs_amend() function is a versatile string editing function.
|
||||
* It selects a string segment as long as \a size characters starting from
|
||||
* the \a index position and changes it to the replacement string \a repl.
|
||||
* \return (qse_size_t)-1 on failure, string length on success.
|
||||
*/
|
||||
QSE_EXPORT qse_size_t qse_wcs_amend (
|
||||
qse_wcs_t* str,
|
||||
qse_size_t index,
|
||||
qse_size_t size,
|
||||
const qse_wchar_t* repl
|
||||
);
|
||||
|
||||
QSE_EXPORT qse_size_t qse_wcs_trm (
|
||||
qse_wcs_t* str
|
||||
);
|
||||
@ -3001,6 +3021,7 @@ QSE_EXPORT qse_size_t qse_wcs_fmt (
|
||||
# define qse_str_ccat(str,c) qse_mbs_ccat(str,c)
|
||||
# define qse_str_nccat(str,c,len) qse_mbs_nccat(str,c,len)
|
||||
# define qse_str_del(str,index,size) qse_mbs_del(str,index,size)
|
||||
# define qse_str_amend(str,index,size,repl) qse_mbs_amend(str,index,size,repl)
|
||||
# define qse_str_trm(str) qse_mbs_trm(str)
|
||||
# define qse_str_pac(str) qse_mbs_pac(str)
|
||||
# define qse_str_fcat qse_mbs_fcat
|
||||
@ -3032,6 +3053,7 @@ QSE_EXPORT qse_size_t qse_wcs_fmt (
|
||||
# define qse_str_ccat(str,c) qse_wcs_ccat(str,c)
|
||||
# define qse_str_nccat(str,c,len) qse_wcs_nccat(str,c,len)
|
||||
# define qse_str_del(str,index,size) qse_wcs_del(str,index,size)
|
||||
# define qse_str_amend(str,index,size,repl) qse_wcs_amend(str,index,size,repl)
|
||||
# define qse_str_trm(str) qse_wcs_trm(str)
|
||||
# define qse_str_pac(str) qse_wcs_pac(str)
|
||||
# define qse_str_fcat qse_wcs_fcat
|
||||
|
@ -136,6 +136,7 @@ static int mbs_to_wcs (
|
||||
#undef str_ccat
|
||||
#undef str_nccat
|
||||
#undef str_del
|
||||
#undef str_amend
|
||||
#undef str_trm
|
||||
#undef str_pac
|
||||
#undef str_fmt
|
||||
@ -183,6 +184,7 @@ static int mbs_to_wcs (
|
||||
#define str_ccat qse_mbs_ccat
|
||||
#define str_nccat qse_mbs_nccat
|
||||
#define str_del qse_mbs_del
|
||||
#define str_amend qse_mbs_amend
|
||||
#define str_trm qse_mbs_trm
|
||||
#define str_pac qse_mbs_pac
|
||||
#define str_fmt qse_mbs_fmt
|
||||
@ -233,6 +235,7 @@ static int mbs_to_wcs (
|
||||
#undef str_ccat
|
||||
#undef str_nccat
|
||||
#undef str_del
|
||||
#undef str_amend
|
||||
#undef str_trm
|
||||
#undef str_pac
|
||||
#undef str_fmt
|
||||
@ -280,6 +283,7 @@ static int mbs_to_wcs (
|
||||
#define str_ccat qse_wcs_ccat
|
||||
#define str_nccat qse_wcs_nccat
|
||||
#define str_del qse_wcs_del
|
||||
#define str_amend qse_wcs_amend
|
||||
#define str_trm qse_wcs_trm
|
||||
#define str_pac qse_wcs_pac
|
||||
#define str_fmt qse_wcs_fmt
|
||||
|
@ -153,7 +153,7 @@ qse_size_t str_setcapa (str_t* str, qse_size_t capa)
|
||||
str->mmgr, QSE_SIZEOF(char_t)*(capa+1));
|
||||
if (tmp == QSE_NULL) return (qse_size_t)-1;
|
||||
|
||||
if (str->val.ptr != QSE_NULL)
|
||||
if (str->val.ptr)
|
||||
{
|
||||
qse_size_t ncopy = (str->val.len <= capa)? str->val.len: capa;
|
||||
QSE_MEMCPY (tmp, str->val.ptr,
|
||||
@ -203,7 +203,7 @@ qse_size_t str_setlen (str_t* str, qse_size_t len)
|
||||
void str_clear (str_t* str)
|
||||
{
|
||||
str->val.len = 0;
|
||||
if (str->val.ptr != QSE_NULL)
|
||||
if (str->val.ptr)
|
||||
{
|
||||
QSE_ASSERT (str->capa >= 1);
|
||||
str->val.ptr[0] = T('\0');
|
||||
@ -385,7 +385,7 @@ qse_size_t str_nccat (str_t* str, char_t c, qse_size_t len)
|
||||
|
||||
qse_size_t str_del (str_t* str, qse_size_t index, qse_size_t size)
|
||||
{
|
||||
if (str->val.ptr != QSE_NULL && index < str->val.len && size > 0)
|
||||
if (str->val.ptr && index < str->val.len && size > 0)
|
||||
{
|
||||
qse_size_t nidx = index + size;
|
||||
if (nidx >= str->val.len)
|
||||
@ -405,9 +405,33 @@ qse_size_t str_del (str_t* str, qse_size_t index, qse_size_t size)
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
qse_size_t str_amend (str_t* str, qse_size_t pos, qse_size_t len, const char_t* repl)
|
||||
{
|
||||
qse_size_t max_len;
|
||||
qse_size_t repl_len = strlen(repl);
|
||||
|
||||
if (pos >= str->val.len) pos = str->val.len;
|
||||
max_len = str->val.len - pos;
|
||||
if (len > max_len) len = max_len;
|
||||
|
||||
if (len > repl_len)
|
||||
{
|
||||
str_del (str, pos, len - repl_len);
|
||||
}
|
||||
else if (len < repl_len)
|
||||
{
|
||||
qse_size_t old_str_len = str->val.len;
|
||||
if (str_setlen (str, str->val.len + repl_len - len) == (qse_size_t)-1) return (qse_size_t)-1;
|
||||
QSE_MEMMOVE (&str->val.ptr[pos + repl_len], &str->val.ptr[pos + len], QSE_SIZEOF(*repl) * (old_str_len - (pos + len)));
|
||||
}
|
||||
|
||||
if (repl_len > 0) QSE_MEMMOVE (&str->val.ptr[pos], repl, QSE_SIZEOF(*repl) * repl_len);
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
qse_size_t str_trm (str_t* str)
|
||||
{
|
||||
if (str->val.ptr != QSE_NULL)
|
||||
if (str->val.ptr)
|
||||
{
|
||||
str->val.len = strxtrm (str->val.ptr, str->val.len);
|
||||
}
|
||||
@ -417,7 +441,7 @@ qse_size_t str_trm (str_t* str)
|
||||
|
||||
qse_size_t str_pac (str_t* str)
|
||||
{
|
||||
if (str->val.ptr != QSE_NULL)
|
||||
if (str->val.ptr)
|
||||
{
|
||||
str->val.len = strxpac (str->val.ptr, str->val.len);
|
||||
}
|
||||
|
@ -194,11 +194,11 @@ static qse_mchar_t* parse_initial_line (qse_htrd_t* htrd, qse_mchar_t* line)
|
||||
#endif
|
||||
|
||||
/* the method should start with an alphabet */
|
||||
if (!is_upalpha_octet(*p)) goto badre;
|
||||
if (!is_alpha_octet(*p)) goto badre;
|
||||
|
||||
/* get the method name */
|
||||
tmp.ptr = p;
|
||||
do { p++; } while (is_upalpha_octet(*p));
|
||||
do { p++; } while (is_alpha_octet(*p));
|
||||
tmp.len = p - tmp.ptr;
|
||||
|
||||
htrd->re.type = QSE_HTRE_Q;
|
||||
@ -390,7 +390,19 @@ static qse_mchar_t* parse_initial_line (qse_htrd_t* htrd, qse_mchar_t* line)
|
||||
#endif
|
||||
|
||||
if (htrd->option & QSE_HTRD_CANONQPATH)
|
||||
qse_canonmbspath (htrd->re.u.q.path, htrd->re.u.q.path, 0);
|
||||
{
|
||||
qse_mchar_t* qpath = htrd->re.u.q.path;
|
||||
|
||||
/* if the url begins with xxx://,
|
||||
* skip xxx:/ and canonicalize from the second slash */
|
||||
while (is_alpha_octet(*qpath)) qpath++;
|
||||
if (qse_mbszcmp (qpath, QSE_MT("://"), 3) == 0)
|
||||
qpath = qpath + 2; /* set the position to the second / in :// */
|
||||
else
|
||||
qpath = htrd->re.u.q.path;
|
||||
|
||||
qse_canonmbspath (qpath, qpath, 0);
|
||||
}
|
||||
|
||||
/* skip spaces after the url part */
|
||||
do { p++; } while (is_space_octet(*p));
|
||||
|
@ -38,14 +38,19 @@ struct task_proxy_t
|
||||
#define PROXY_INIT_FAILED (1 << 0)
|
||||
#define PROXY_RAW (1 << 1)
|
||||
#define PROXY_TRANSPARENT (1 << 2)
|
||||
#define PROXY_RESOLVE_PEER_NAME (1 << 3)
|
||||
#define PROXY_PEER_NAME_RESOLVED (1 << 4)
|
||||
#define PROXY_PEER_NAME_UNRESOLVED (1 << 5)
|
||||
#define PROXY_REWRITE_URL (1 << 6)
|
||||
#define PROXY_URL_REWRITTEN (1 << 7)
|
||||
#define PROXY_X_FORWARDED_FOR (1 << 8) /* X-Forwarded-For added */
|
||||
#define PROXY_VIA (1 << 9) /* Via added to the request */
|
||||
#define PROXY_VIA_RETURNING (1 << 10) /* Via added to the response */
|
||||
#define PROXY_OUTBAND_PEER_NAME (1 << 3) /* the peer_name pointer points to
|
||||
a separate memory chunk outside
|
||||
the task_proxy_t chunk. explicit
|
||||
deallocatin is required */
|
||||
#define PROXY_RESOLVE_PEER_NAME (1 << 4)
|
||||
#define PROXY_PEER_NAME_RESOLVED (1 << 5)
|
||||
#define PROXY_PEER_NAME_UNRESOLVED (1 << 6)
|
||||
#define PROXY_REWRITE_URL (1 << 7)
|
||||
#define PROXY_URL_REWRITTEN (1 << 8)
|
||||
#define PROXY_URL_REDIRECTED (1 << 9)
|
||||
#define PROXY_X_FORWARDED_FOR (1 << 10) /* X-Forwarded-For added */
|
||||
#define PROXY_VIA (1 << 11) /* Via added to the request */
|
||||
#define PROXY_VIA_RETURNING (1 << 12) /* Via added to the response */
|
||||
int flags;
|
||||
qse_httpd_t* httpd;
|
||||
qse_httpd_client_t* client;
|
||||
@ -54,7 +59,11 @@ struct task_proxy_t
|
||||
qse_http_version_t version;
|
||||
int keepalive; /* taken from the request */
|
||||
|
||||
qse_httpd_task_t* task;
|
||||
qse_mchar_t* url_to_rewrite;
|
||||
qse_size_t qpath_pos_in_reqfwdbuf;
|
||||
qse_size_t qpath_len_in_reqfwdbuf;
|
||||
|
||||
qse_mchar_t* pseudonym;
|
||||
qse_htrd_t* peer_htrd;
|
||||
|
||||
@ -850,7 +859,7 @@ qse_printf (QSE_T("PROXY FORWARD: @@@@@@@@@@WRITING[%.*hs]\n"),
|
||||
}
|
||||
else if (n > 0)
|
||||
{
|
||||
/* TODO: improve performance.. instead of copying the remaing part
|
||||
/* TODO: improve performance.. instead of copying the remaining part
|
||||
to the head all the time.. grow the buffer to a certain limit. */
|
||||
qse_mbs_del (proxy->reqfwdbuf, 0, n);
|
||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) <= 0)
|
||||
@ -875,6 +884,26 @@ to the head all the time.. grow the buffer to a certain limit. */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static void adjust_peer_name_and_port (task_proxy_t* proxy)
|
||||
{
|
||||
qse_mchar_t* colon;
|
||||
colon = qse_mbschr (proxy->peer_name, QSE_MT(':'));
|
||||
if (colon)
|
||||
{
|
||||
qse_mchar_t* endptr;
|
||||
/* handle a port number after the colon sign */
|
||||
|
||||
*colon = QSE_MT('\0');
|
||||
QSE_MBSTONUM (proxy->peer_port, colon + 1, &endptr, 10);
|
||||
/* TODO: check if *endptr is QSE_T('\0')? */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (proxy->flags & PROXY_RAW) proxy->peer_port = QSE_HTTPD_DEFAULT_SECURE_PORT;
|
||||
else proxy->peer_port = QSE_HTTPD_DEFAULT_PORT;
|
||||
}
|
||||
}
|
||||
|
||||
static int task_init_proxy (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
||||
{
|
||||
@ -894,6 +923,8 @@ static int task_init_proxy (
|
||||
proxy->version = *qse_htre_getversion(arg->req);
|
||||
proxy->keepalive = (arg->req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
|
||||
proxy->task = task; /* needed for url rewriting */
|
||||
|
||||
proxy->pseudonym = (qse_mchar_t*)(proxy + 1);
|
||||
if (arg->rsrc->pseudonym)
|
||||
{
|
||||
@ -910,62 +941,59 @@ static int task_init_proxy (
|
||||
|
||||
if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_URS)
|
||||
{
|
||||
#if 0
|
||||
const qse_mchar_t* qpath;
|
||||
const qse_mchar_t* metnam;
|
||||
const qse_htre_hdrval_t* hosthv;
|
||||
const qse_mchar_t* host_ptr;
|
||||
qse_mchar_t cliaddrbuf[128];
|
||||
qse_size_t total_len;
|
||||
|
||||
qpath = qse_htre_getqpath(arg->req);
|
||||
metnam = qse_httpmethodtombs(proxy->method);
|
||||
|
||||
total_len = qse_mbslen(qpath) + qse_mbslen(metnam);
|
||||
|
||||
if (arg->rsrc->host)
|
||||
{
|
||||
host_ptr = arg->rsrc->host;
|
||||
total_len += qse_mbslen(host_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
const qse_htre_hdrval_t* hosthv;
|
||||
hosthv = qse_htre_getheaderval(arg->req, QSE_MT("Host"));
|
||||
if (hosthv)
|
||||
{
|
||||
/* the first host header only */
|
||||
host_ptr = hosthv->ptr;
|
||||
total_len += hosthv->len;
|
||||
}
|
||||
}
|
||||
|
||||
total_len += qse_nwadtombs (&client->remote_addr, cliaddrbuf, QSE_COUNTOF(cliaddrbuf), QSE_NWADTOMBS_ADDR);
|
||||
|
||||
total_len += 128; /* extra space */
|
||||
|
||||
proxy->url_to_rewrite = qse_httpd_allocmem (httpd, total_len);
|
||||
if (proxy->url_to_rewrite == QSE_NULL) goto oops;
|
||||
|
||||
/* URL client-ip/client-fqdn ident method */
|
||||
qpath = qse_htre_getqpath(htreq);
|
||||
method = qse_htre_getqmethodtype(htreq);
|
||||
metnam = qse_httpmethodtombs(method);
|
||||
hosthv = qse_htre_getheaderval(htreq, QSE_MT("Host"));
|
||||
if (hosthv) printf ("hosthv -> %s\n", hosthv->ptr);
|
||||
qse_nwadtombs (&client->remote_addr, cliaddrbuf, QSE_COUNTOF(cliaddrbuf), QSE_NWADTOMBS_ADDR);
|
||||
#endif
|
||||
if (proxy->method != QSE_HTTP_CONNECT && host_ptr)
|
||||
qse_mbsxfmt (proxy->url_to_rewrite, total_len, QSE_MT("http://%s%s %s/- - %s"), host_ptr, qpath, cliaddrbuf, metnam);
|
||||
else
|
||||
qse_mbsxfmt (proxy->url_to_rewrite, total_len, QSE_MT("%s %s/- - %s"), qpath, cliaddrbuf, metnam);
|
||||
|
||||
printf (">>>>>>>>>>>>>>>>>>>>>>>> [%s] <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", proxy->url_to_rewrite);
|
||||
/* enable url rewriting */
|
||||
proxy->flags |= PROXY_REWRITE_URL;
|
||||
|
||||
#if 0
|
||||
/* TODO: build URL TO REWRITE */
|
||||
if (method == QSE_HTTP_CONNECT)
|
||||
url_len = qse_mbsxfmt (QSE_NULL, 0, QSE_MT("%s %s/- - %s"), qpath, cliaddrbuf, metnam);
|
||||
else if (host)
|
||||
url_len = qse_mbsxfmt (QSE_NULL, 0, QSE_MT("http://%s%s %s/- - %s"), host, qpath, cliaddrbuf, metnam);
|
||||
else if (hosthv)
|
||||
url_len = qse_mbsxfmt (QSE_NULL, 0, QSE_MT("http://%s%s %s/- - %s"), hosthv->ptr, qpath, cliaddrbuf, metnam);
|
||||
else
|
||||
url_len = qse_mbsxfmt (QSE_NULL, 0, QSE_MT("%s %s/- - %s"), qpath, cliaddrbuf, metnam);
|
||||
#endif
|
||||
}
|
||||
|
||||
proxy->peer.local = arg->rsrc->src.nwad;
|
||||
if (arg->rsrc->flags & QSE_HTTPD_RSRC_PROXY_DST_STR)
|
||||
{
|
||||
qse_mchar_t* colon;
|
||||
|
||||
proxy->flags |= PROXY_RESOLVE_PEER_NAME;
|
||||
proxy->peer_name = proxy->pseudonym + len + 1;
|
||||
qse_mbscpy (proxy->peer_name, arg->rsrc->dst.str);
|
||||
|
||||
colon = qse_mbschr (proxy->peer_name, QSE_MT(':'));
|
||||
if (colon)
|
||||
{
|
||||
qse_mchar_t* endptr;
|
||||
|
||||
/* handle a port number after the colon sign */
|
||||
*colon = QSE_MT('\0');
|
||||
QSE_MBSTONUM (proxy->peer_port, colon + 1, &endptr, 10);
|
||||
|
||||
/* TODO: check if *endptr is QSE_T('\0')? */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (proxy->flags & PROXY_RAW) proxy->peer_port = QSE_HTTPD_DEFAULT_SECURE_PORT;
|
||||
else proxy->peer_port = QSE_HTTPD_DEFAULT_PORT;
|
||||
}
|
||||
adjust_peer_name_and_port (proxy);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1009,8 +1037,11 @@ static int task_init_proxy (
|
||||
* received from the client */
|
||||
|
||||
if (qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqmethodname(arg->req)) == (qse_size_t)-1 ||
|
||||
qse_mbs_cat (proxy->reqfwdbuf, QSE_MT(" ")) == (qse_size_t)-1 ||
|
||||
qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqpath(arg->req)) == (qse_size_t)-1) goto oops;
|
||||
qse_mbs_cat (proxy->reqfwdbuf, QSE_MT(" ")) == (qse_size_t)-1) goto oops;
|
||||
|
||||
proxy->qpath_pos_in_reqfwdbuf = QSE_STR_LEN(proxy->reqfwdbuf);
|
||||
if (qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqpath(arg->req)) == (qse_size_t)-1) goto oops;
|
||||
proxy->qpath_len_in_reqfwdbuf = QSE_STR_LEN(proxy->reqfwdbuf) - proxy->qpath_pos_in_reqfwdbuf;
|
||||
|
||||
if (qse_htre_getqparam(arg->req))
|
||||
{
|
||||
@ -1068,7 +1099,6 @@ static int task_init_proxy (
|
||||
(int)proxy->version.major, (int)proxy->version.minor,
|
||||
pseudonym, qse_httpd_getname(httpd));
|
||||
if (tmp == (qse_size_t)-1) goto oops;
|
||||
|
||||
}
|
||||
|
||||
if (arg->req->state & QSE_HTRE_DISCARDED)
|
||||
@ -1201,9 +1231,18 @@ qse_printf (QSE_T("GOING TO PROXY [%hs]\n"), QSE_MBS_PTR(proxy->reqfwdbuf));
|
||||
oops:
|
||||
|
||||
printf ("init_proxy failed...........................................\n");
|
||||
|
||||
/* since a new task can't be added in the initializer,
|
||||
* i mark that initialization failed and let task_main_proxy()
|
||||
* add an error task */
|
||||
|
||||
if (proxy->url_to_rewrite)
|
||||
{
|
||||
qse_httpd_freemem (httpd, proxy->url_to_rewrite);
|
||||
proxy->url_to_rewrite = QSE_NULL;
|
||||
proxy->flags &= ~PROXY_REWRITE_URL;
|
||||
}
|
||||
|
||||
if (proxy->reqfwdbuf)
|
||||
{
|
||||
qse_mbs_close (proxy->reqfwdbuf);
|
||||
@ -1231,6 +1270,8 @@ static void task_fini_proxy (
|
||||
if (proxy->peer_htrd) qse_htrd_close (proxy->peer_htrd);
|
||||
if (proxy->reqfwdbuf) qse_mbs_close (proxy->reqfwdbuf);
|
||||
if (proxy->req) qse_htre_unsetconcb (proxy->req);
|
||||
if (proxy->url_to_rewrite) qse_httpd_freemem (httpd, proxy->url_to_rewrite);
|
||||
if (proxy->flags & PROXY_OUTBAND_PEER_NAME) qse_httpd_freemem (httpd, proxy->peer_name);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -1868,14 +1909,139 @@ static void on_url_rewritten (qse_httpd_t* httpd, const qse_mchar_t* url, const
|
||||
qse_httpd_task_t* task = (qse_httpd_task_t*)ctx;
|
||||
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||
|
||||
/* TODO: HANDLE THIS PROPERLY */
|
||||
proxy->flags |= PROXY_INIT_FAILED;
|
||||
printf ("XXXXXXXXXXXXXXXXXXXXXXXXXX URL REWRITTEN ....\n");
|
||||
//new_url = "302:http://www.google.com/login.html";
|
||||
//new_url = "127.0.0.1:443";
|
||||
new_url = "http://www.google.com/a/b/c";
|
||||
if (new_url)
|
||||
{
|
||||
qse_nwad_t nwad;
|
||||
|
||||
proxy->flags &= ~PROXY_REWRITE_URL;
|
||||
|
||||
if (new_url[0] == QSE_MT('\0'))
|
||||
{
|
||||
/* no change. carry on */
|
||||
}
|
||||
else if (qse_mbstonwad (new_url, &nwad) >= 0)
|
||||
{
|
||||
/* if a network address is returned, change the peer address only */
|
||||
/* TODO: prevent proxying to self */
|
||||
proxy->peer.nwad = nwad;
|
||||
proxy->flags |= PROXY_URL_REWRITTEN;
|
||||
proxy->flags &= ~PROXY_RESOLVE_PEER_NAME; /* skip dns */
|
||||
}
|
||||
else if (new_url[0] >= QSE_MT('0') && new_url[0] <= QSE_MT('9'))
|
||||
{
|
||||
/* redirection */
|
||||
int redir_code = 0;
|
||||
qse_httpd_status_reloc_t reloc;
|
||||
const qse_mchar_t* nuptr = new_url;
|
||||
do
|
||||
{
|
||||
redir_code = redir_code * 10 + (*nuptr - QSE_MT('0'));
|
||||
nuptr++;
|
||||
}
|
||||
while (*nuptr >= QSE_MT('0') && *nuptr <= QSE_MT('9'));
|
||||
if (*nuptr != QSE_MT(':')) goto fail;
|
||||
if (redir_code != 301 && redir_code != 302 && redir_code != 307) redir_code = 301;
|
||||
nuptr++;
|
||||
|
||||
reloc.dst = nuptr;
|
||||
reloc.redir = 0; /* don't want to append extra / */
|
||||
|
||||
if (qse_httpd_entask_status (
|
||||
httpd, proxy->client, proxy->task, redir_code, &reloc,
|
||||
proxy->method, &proxy->version, proxy->keepalive) == QSE_NULL)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
proxy->flags |= PROXY_URL_REDIRECTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (proxy->flags & PROXY_RAW)
|
||||
{
|
||||
qse_mchar_t* tmp;
|
||||
|
||||
QSE_ASSERT (QSE_STR_LEN(proxy->reqfwdbuf) == 0);
|
||||
|
||||
tmp = qse_mbsdup (new_url, qse_httpd_getmmgr(httpd));
|
||||
if (tmp == QSE_NULL)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
proxy->flags |= PROXY_RESOLVE_PEER_NAME | PROXY_OUTBAND_PEER_NAME;
|
||||
proxy->peer_name = tmp;
|
||||
adjust_peer_name_and_port (proxy);
|
||||
}
|
||||
else
|
||||
{
|
||||
QSE_ASSERT (QSE_STR_LEN(proxy->reqfwdbuf) > 0);
|
||||
|
||||
/* TODO: Host rewriting?? */
|
||||
/* TODO: Host rewriting - to support it, headers must be made available thru request cloning.
|
||||
* the request may not be valid after task_init_proxy */
|
||||
|
||||
if (qse_mbszcasecmp (new_url, QSE_MT("http://"), 7) == 0)
|
||||
{
|
||||
const qse_mchar_t* host;
|
||||
|
||||
host = new_url + 7;
|
||||
if (host[0] != QSE_MT('/') && host[0] != QSE_MT('\0'))
|
||||
{
|
||||
const qse_mchar_t* slash;
|
||||
qse_mchar_t* tmp;
|
||||
|
||||
slash = qse_mbschr (host, QSE_MT('/'));
|
||||
if (slash)
|
||||
{
|
||||
tmp = qse_mbsxdup (host, slash - host, qse_httpd_getmmgr(httpd));
|
||||
new_url = slash;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = qse_mbsdup (host, qse_httpd_getmmgr(httpd));
|
||||
new_url = QSE_MT("/");
|
||||
}
|
||||
|
||||
if (tmp == QSE_NULL)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
proxy->flags |= PROXY_RESOLVE_PEER_NAME | PROXY_OUTBAND_PEER_NAME;
|
||||
proxy->peer_name = tmp;
|
||||
adjust_peer_name_and_port (proxy);
|
||||
}
|
||||
}
|
||||
|
||||
if (qse_mbs_amend (proxy->reqfwdbuf, proxy->qpath_pos_in_reqfwdbuf, proxy->qpath_len_in_reqfwdbuf, new_url) == (qse_size_t)-1)
|
||||
{
|
||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
proxy->flags |= PROXY_URL_REWRITTEN;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fail:
|
||||
/* url rewriting failed */
|
||||
proxy->flags |= PROXY_INIT_FAILED;
|
||||
}
|
||||
|
||||
if (qse_httpd_activatetasktrigger (httpd, proxy->client, task) <= -1)
|
||||
{
|
||||
proxy->flags |= PROXY_INIT_FAILED;
|
||||
}
|
||||
|
||||
printf ("XXXXXXXXXXXXXXXXXXXXXXXXXX URL REWRITTEN ....\n");
|
||||
}
|
||||
|
||||
static int task_main_proxy (
|
||||
@ -1892,6 +2058,8 @@ static int task_main_proxy (
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (proxy->flags & PROXY_URL_REDIRECTED) return 0; /* URL redirected. task finished */
|
||||
|
||||
if (proxy->flags & PROXY_REWRITE_URL)
|
||||
{
|
||||
/* note that url_to_rewrite is URL + extra information. */
|
||||
|
@ -2656,20 +2656,21 @@ static int make_resource (
|
||||
if (server_xtn->query (httpd, client->server, QSE_NULL, QSE_NULL, QSE_HTTPD_SERVERSTD_PSEUDONYM, &target->u.proxy.pseudonym) <= -1)
|
||||
target->u.proxy.pseudonym = QSE_NULL;
|
||||
|
||||
/******************************************************************/
|
||||
/*TODO: load this from configuration. reamove this after debugging */
|
||||
//target->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_URS;
|
||||
/******************************************************************/
|
||||
/* mark that this request is going to be proxied. */
|
||||
req->attr.flags |= QSE_HTRE_ATTR_PROXIED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* htrd compacts double slashes to a single slash.
|
||||
* so inspect if the query path begins with http:/ instead of http:// */
|
||||
/*if (qse_mbszcasecmp (tmp.qpath, QSE_MT("http://"), 7) == 0)*/
|
||||
if (qse_mbszcasecmp (tmp.qpath, QSE_MT("http:/"), 6) == 0)
|
||||
if (qse_mbszcasecmp (tmp.qpath, QSE_MT("http://"), 7) == 0)
|
||||
{
|
||||
/* TODO: check if proxying is allowed.... */
|
||||
qse_mchar_t* host, * slash;
|
||||
|
||||
host = tmp.qpath + 6;
|
||||
host = tmp.qpath + 7;
|
||||
slash = qse_mbschr (host, QSE_MT('/'));
|
||||
|
||||
if (slash && slash - host > 0)
|
||||
@ -2702,10 +2703,9 @@ static int make_resource (
|
||||
/* TODO: refrain from manipulating the request like this */
|
||||
req->u.q.path = slash; /* TODO: use setqpath or something... */
|
||||
|
||||
|
||||
/******************************************************************/
|
||||
/*TODO: load this from configuration. reamove this after debugging */
|
||||
//target->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_URS;
|
||||
target->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_URS;
|
||||
/******************************************************************/
|
||||
|
||||
/* mark that this request is going to be proxied. */
|
||||
|
@ -158,14 +158,8 @@ qse_httpd_task_t* qse_httpd_entaskformat (
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct status_reloc_t status_reloc_t;
|
||||
struct status_reloc_t
|
||||
{
|
||||
const qse_mchar_t* dst;
|
||||
int redir;
|
||||
};
|
||||
|
||||
static qse_httpd_task_t* entask_status (
|
||||
qse_httpd_task_t* qse_httpd_entask_status (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, int code, void* extra,
|
||||
qse_http_method_t method, const qse_http_version_t* version,
|
||||
@ -188,8 +182,8 @@ static qse_httpd_task_t* entask_status (
|
||||
case 302:
|
||||
case 307:
|
||||
{
|
||||
status_reloc_t* reloc;
|
||||
reloc = (status_reloc_t*)extra;
|
||||
qse_httpd_status_reloc_t* reloc;
|
||||
reloc = (qse_httpd_status_reloc_t*)extra;
|
||||
extrapre = QSE_MT("Location: ");
|
||||
extrapst = reloc->redir? QSE_MT("/\r\n"): QSE_MT("\r\n");
|
||||
extraval = reloc->dst;
|
||||
@ -237,14 +231,14 @@ qse_httpd_task_t* qse_httpd_entask_err (
|
||||
qse_httpd_task_t* pred, int code,
|
||||
qse_http_method_t method, const qse_http_version_t* version, int keepalive)
|
||||
{
|
||||
return entask_status (httpd, client, pred, code, QSE_NULL, method, version, keepalive);
|
||||
return qse_httpd_entask_status (httpd, client, pred, code, QSE_NULL, method, version, keepalive);
|
||||
}
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entaskerr (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, int code, qse_htre_t* req)
|
||||
{
|
||||
return entask_status (
|
||||
return qse_httpd_entask_status (
|
||||
httpd, client, pred, code, QSE_NULL,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
@ -270,7 +264,7 @@ qse_httpd_task_t* qse_httpd_entaskauth (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, const qse_mchar_t* realm, qse_htre_t* req)
|
||||
{
|
||||
return entask_status (
|
||||
return qse_httpd_entask_status (
|
||||
httpd, client, pred, 401, (void*)realm,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
@ -284,12 +278,12 @@ qse_httpd_task_t* qse_httpd_entaskreloc (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, const qse_mchar_t* dst, qse_htre_t* req)
|
||||
{
|
||||
status_reloc_t reloc;
|
||||
qse_httpd_status_reloc_t reloc;
|
||||
|
||||
reloc.dst = dst;
|
||||
reloc.redir = 0;
|
||||
|
||||
return entask_status (
|
||||
return qse_httpd_entask_status (
|
||||
httpd, client, pred, 301, (void*)&reloc,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
@ -300,12 +294,12 @@ qse_httpd_task_t* qse_httpd_entaskredir (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, const qse_mchar_t* dst, qse_htre_t* req)
|
||||
{
|
||||
status_reloc_t reloc;
|
||||
qse_httpd_status_reloc_t reloc;
|
||||
|
||||
reloc.dst = dst;
|
||||
reloc.redir = 1;
|
||||
|
||||
return entask_status (
|
||||
return qse_httpd_entask_status (
|
||||
httpd, client, pred, 301, (void*)&reloc,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
@ -318,7 +312,7 @@ qse_httpd_task_t* qse_httpd_entask_nomod (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* pred,
|
||||
qse_http_method_t method, const qse_http_version_t* version, int keepalive)
|
||||
{
|
||||
return entask_status (
|
||||
return qse_httpd_entask_status (
|
||||
httpd, client, pred, 304, QSE_NULL, method, version, keepalive);
|
||||
}
|
||||
|
||||
@ -326,7 +320,7 @@ qse_httpd_task_t* qse_httpd_entasknomod (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, qse_htre_t* req)
|
||||
{
|
||||
return entask_status (
|
||||
return qse_httpd_entask_status (
|
||||
httpd, client, pred, 304, QSE_NULL,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
|
@ -97,6 +97,13 @@ struct qse_httpd_real_task_t
|
||||
qse_httpd_real_task_t* next;
|
||||
};
|
||||
|
||||
typedef struct qse_httpd_status_reloc_t qse_httpd_status_reloc_t;
|
||||
struct qse_httpd_status_reloc_t
|
||||
{
|
||||
const qse_mchar_t* dst;
|
||||
int redir;
|
||||
};
|
||||
|
||||
#define MAX_SEND_SIZE 4096
|
||||
#define MAX_RECV_SIZE 4096
|
||||
|
||||
@ -130,6 +137,17 @@ void qse_httpd_fini (
|
||||
qse_httpd_t* httpd
|
||||
);
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entask_status (
|
||||
qse_httpd_t* httpd,
|
||||
qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred,
|
||||
int code,
|
||||
void* extra,
|
||||
qse_http_method_t method,
|
||||
const qse_http_version_t* version,
|
||||
int keepalive
|
||||
);
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entask_err (
|
||||
qse_httpd_t* httpd,
|
||||
qse_httpd_client_t* client,
|
||||
|
Loading…
Reference in New Issue
Block a user