enhanced proxying to handle protocol upgrade.
enhanced qse_mbsword() and its family to accept an extra delimiter
This commit is contained in:
parent
8a32cbc4f1
commit
1df4e0bc9f
@ -1584,40 +1584,52 @@ QSE_EXPORT qse_wchar_t* qse_wcsxnrcasestr (
|
|||||||
|
|
||||||
const qse_mchar_t* qse_mbsword (
|
const qse_mchar_t* qse_mbsword (
|
||||||
const qse_mchar_t* str,
|
const qse_mchar_t* str,
|
||||||
const qse_mchar_t* word
|
const qse_mchar_t* word,
|
||||||
|
qse_mchar_t extra_delim
|
||||||
);
|
);
|
||||||
|
|
||||||
const qse_wchar_t* qse_wcsword (
|
const qse_wchar_t* qse_wcsword (
|
||||||
const qse_wchar_t* str,
|
const qse_wchar_t* str,
|
||||||
const qse_wchar_t* word
|
const qse_wchar_t* word,
|
||||||
|
qse_wchar_t extra_delim
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_mbsxword() function finds a whole word in a string.
|
* The qse_mbsxword() function finds a whole word in a string.
|
||||||
|
* The word can be delimited by white spaces or an extra delimiter
|
||||||
|
* \a extra_delim. Pass QSE_MT('\0') if no extra delimiter is
|
||||||
|
* needed.
|
||||||
*/
|
*/
|
||||||
const qse_mchar_t* qse_mbsxword (
|
const qse_mchar_t* qse_mbsxword (
|
||||||
const qse_mchar_t* str,
|
const qse_mchar_t* str,
|
||||||
qse_size_t len,
|
qse_size_t len,
|
||||||
const qse_mchar_t* word
|
const qse_mchar_t* word,
|
||||||
|
qse_mchar_t extra_delim
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The qse_wcsxword() function finds a whole word in a string.
|
* The qse_wcsxword() function finds a whole word in a string.
|
||||||
|
* The word can be delimited by white spaces or an extra delimiter
|
||||||
|
* \a extra_delim. Pass QSE_WT('\0') if no extra delimiter is
|
||||||
|
* needed.
|
||||||
*/
|
*/
|
||||||
const qse_wchar_t* qse_wcsxword (
|
const qse_wchar_t* qse_wcsxword (
|
||||||
const qse_wchar_t* str,
|
const qse_wchar_t* str,
|
||||||
qse_size_t len,
|
qse_size_t len,
|
||||||
const qse_wchar_t* word
|
const qse_wchar_t* word,
|
||||||
|
qse_wchar_t extra_delim
|
||||||
);
|
);
|
||||||
|
|
||||||
const qse_mchar_t* qse_mbscaseword (
|
const qse_mchar_t* qse_mbscaseword (
|
||||||
const qse_mchar_t* str,
|
const qse_mchar_t* str,
|
||||||
const qse_mchar_t* word
|
const qse_mchar_t* word,
|
||||||
|
qse_mchar_t extra_delim
|
||||||
);
|
);
|
||||||
|
|
||||||
const qse_wchar_t* qse_wcscaseword (
|
const qse_wchar_t* qse_wcscaseword (
|
||||||
const qse_wchar_t* str,
|
const qse_wchar_t* str,
|
||||||
const qse_wchar_t* word
|
const qse_wchar_t* word,
|
||||||
|
qse_wchar_t extra_delim
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1627,7 +1639,8 @@ const qse_wchar_t* qse_wcscaseword (
|
|||||||
const qse_mchar_t* qse_mbsxcaseword (
|
const qse_mchar_t* qse_mbsxcaseword (
|
||||||
const qse_mchar_t* str,
|
const qse_mchar_t* str,
|
||||||
qse_size_t len,
|
qse_size_t len,
|
||||||
const qse_mchar_t* word
|
const qse_mchar_t* word,
|
||||||
|
qse_mchar_t extra_delim
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1637,19 +1650,20 @@ const qse_mchar_t* qse_mbsxcaseword (
|
|||||||
const qse_wchar_t* qse_wcsxcaseword (
|
const qse_wchar_t* qse_wcsxcaseword (
|
||||||
const qse_wchar_t* str,
|
const qse_wchar_t* str,
|
||||||
qse_size_t len,
|
qse_size_t len,
|
||||||
const qse_wchar_t* word
|
const qse_wchar_t* word,
|
||||||
|
qse_wchar_t extra_delim
|
||||||
);
|
);
|
||||||
|
|
||||||
#if defined(QSE_CHAR_IS_MCHAR)
|
#if defined(QSE_CHAR_IS_MCHAR)
|
||||||
# define qse_strword(str,word) qse_mbsword(str,word)
|
# define qse_strword(str,word,edelim) qse_mbsword(str,word,edelim)
|
||||||
# define qse_strxword(str,len,word) qse_mbsxword(str,len,word)
|
# define qse_strxword(str,len,word,edelim) qse_mbsxword(str,len,word,edelim)
|
||||||
# define qse_strcaseword(str,word) qse_mbscaseword(str,word)
|
# define qse_strcaseword(str,word,edelim) qse_mbscaseword(str,word,edelim)
|
||||||
# define qse_strxcaseword(str,len,word) qse_mbsxcaseword(str,len,word)
|
# define qse_strxcaseword(str,len,word,edelim) qse_mbsxcaseword(str,len,word,edelim)
|
||||||
#else
|
#else
|
||||||
# define qse_strword(str,word) qse_wcsword(str,word)
|
# define qse_strword(str,word,edelim) qse_wcsword(str,word,edelim)
|
||||||
# define qse_strxword(str,len,word) qse_wcsxword(str,len,word)
|
# define qse_strxword(str,len,word,edelim) qse_wcsxword(str,len,word,edelim)
|
||||||
# define qse_strcaseword(str,word) qse_wcscaseword(str,word)
|
# define qse_strcaseword(str,word,edelim) qse_wcscaseword(str,word,edelim)
|
||||||
# define qse_strxcaseword(str,len,word) qse_wcsxcaseword(str,len,word)
|
# define qse_strxcaseword(str,len,word,edelim) qse_wcsxcaseword(str,len,word,edelim)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,7 +38,8 @@ enum qse_htrd_errnum_t
|
|||||||
QSE_HTRD_EBADRE,
|
QSE_HTRD_EBADRE,
|
||||||
QSE_HTRD_EBADHDR,
|
QSE_HTRD_EBADHDR,
|
||||||
QSE_HTRD_ERECBS,
|
QSE_HTRD_ERECBS,
|
||||||
QSE_HTRD_ECONCB
|
QSE_HTRD_ECONCB,
|
||||||
|
QSE_HTRD_ESUSPENDED
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum qse_htrd_errnum_t qse_htrd_errnum_t;
|
typedef enum qse_htrd_errnum_t qse_htrd_errnum_t;
|
||||||
@ -56,8 +57,7 @@ enum qse_htrd_option_t
|
|||||||
QSE_HTRD_REQUEST = (1 << 4), /**< parse input as a request */
|
QSE_HTRD_REQUEST = (1 << 4), /**< parse input as a request */
|
||||||
QSE_HTRD_RESPONSE = (1 << 5), /**< parse input as a response */
|
QSE_HTRD_RESPONSE = (1 << 5), /**< parse input as a response */
|
||||||
QSE_HTRD_TRAILERS = (1 << 6), /**< store trailers in a separate table */
|
QSE_HTRD_TRAILERS = (1 << 6), /**< store trailers in a separate table */
|
||||||
QSE_HTRD_STRICT = (1 << 7), /**< be more picky */
|
QSE_HTRD_STRICT = (1 << 7) /**< be more picky */
|
||||||
QSE_HTRD_DUMMY = (1 << 8) /**< be dummy */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum qse_htrd_option_t qse_htrd_option_t;
|
typedef enum qse_htrd_option_t qse_htrd_option_t;
|
||||||
@ -75,6 +75,7 @@ struct qse_htrd_t
|
|||||||
qse_mmgr_t* mmgr;
|
qse_mmgr_t* mmgr;
|
||||||
qse_htrd_errnum_t errnum;
|
qse_htrd_errnum_t errnum;
|
||||||
int option;
|
int option;
|
||||||
|
int flags;
|
||||||
|
|
||||||
const qse_htrd_recbs_t* recbs;
|
const qse_htrd_recbs_t* recbs;
|
||||||
|
|
||||||
@ -149,7 +150,7 @@ QSE_EXPORT void qse_htrd_clear (
|
|||||||
);
|
);
|
||||||
|
|
||||||
QSE_EXPORT int qse_htrd_getoption (
|
QSE_EXPORT int qse_htrd_getoption (
|
||||||
qse_htrd_t* htrd
|
qse_htrd_t* htrd
|
||||||
);
|
);
|
||||||
|
|
||||||
QSE_EXPORT void qse_htrd_setoption (
|
QSE_EXPORT void qse_htrd_setoption (
|
||||||
@ -185,6 +186,22 @@ QSE_EXPORT int qse_htrd_halt (
|
|||||||
qse_htrd_t* htrd
|
qse_htrd_t* htrd
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT void qse_htrd_suspend (
|
||||||
|
qse_htrd_t* htrd
|
||||||
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT void qse_htrd_resume (
|
||||||
|
qse_htrd_t* htrd
|
||||||
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT void qse_htrd_dummify (
|
||||||
|
qse_htrd_t* htrd
|
||||||
|
);
|
||||||
|
|
||||||
|
QSE_EXPORT void qse_htrd_undummify (
|
||||||
|
qse_htrd_t* htrd
|
||||||
|
);
|
||||||
|
|
||||||
QSE_EXPORT int qse_htrd_scanqparam (
|
QSE_EXPORT int qse_htrd_scanqparam (
|
||||||
qse_htrd_t* http,
|
qse_htrd_t* http,
|
||||||
const qse_mcstr_t* cstr
|
const qse_mcstr_t* cstr
|
||||||
|
@ -21,32 +21,34 @@
|
|||||||
#include <qse/cmn/str.h>
|
#include <qse/cmn/str.h>
|
||||||
#include <qse/cmn/chr.h>
|
#include <qse/cmn/chr.h>
|
||||||
|
|
||||||
const qse_mchar_t* qse_mbsword (
|
#define IS_MDELIM(x,delim) (QSE_ISMSPACE(x) || (x) == delim)
|
||||||
const qse_mchar_t* str, const qse_mchar_t* word)
|
#define IS_WDELIM(x,delim) (QSE_ISWSPACE(x) || (x) == delim)
|
||||||
|
|
||||||
|
const qse_mchar_t* qse_mbsword (const qse_mchar_t* str, const qse_mchar_t* word, qse_mchar_t extra_delim)
|
||||||
{
|
{
|
||||||
/* find a full word in a string */
|
/* find a full word in a string */
|
||||||
|
|
||||||
const qse_mchar_t* ptr = str;
|
const qse_mchar_t* ptr = str;
|
||||||
|
|
||||||
|
if (extra_delim == QSE_MT('\0')) extra_delim = QSE_MT(' ');
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
const qse_mchar_t* s;
|
const qse_mchar_t* s;
|
||||||
|
|
||||||
while (QSE_ISMSPACE(*ptr)) ptr++;
|
while (IS_MDELIM(*ptr,extra_delim)) ptr++;
|
||||||
if (*ptr == QSE_MT('\0')) return QSE_NULL;
|
if (*ptr == QSE_MT('\0')) return QSE_NULL;
|
||||||
|
|
||||||
s = ptr;
|
s = ptr;
|
||||||
while (*ptr != QSE_MT('\0') && !QSE_ISMSPACE(*ptr)) ptr++;
|
while (*ptr != QSE_MT('\0') && !IS_MDELIM(*ptr,extra_delim)) ptr++;
|
||||||
|
|
||||||
if (qse_mbsxcmp (s, ptr-s, word) == 0) return s;
|
if (qse_mbsxcmp (s, ptr - s, word) == 0) return s;
|
||||||
}
|
}
|
||||||
while (*ptr != QSE_MT('\0'));
|
while (*ptr != QSE_MT('\0'));
|
||||||
|
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qse_mchar_t* qse_mbsxword (
|
const qse_mchar_t* qse_mbsxword (const qse_mchar_t* str, qse_size_t len, const qse_mchar_t* word, qse_mchar_t extra_delim)
|
||||||
const qse_mchar_t* str, qse_size_t len, const qse_mchar_t* word)
|
|
||||||
{
|
{
|
||||||
/* find a full word in a string */
|
/* find a full word in a string */
|
||||||
|
|
||||||
@ -54,93 +56,93 @@ const qse_mchar_t* qse_mbsxword (
|
|||||||
const qse_mchar_t* end = str + len;
|
const qse_mchar_t* end = str + len;
|
||||||
const qse_mchar_t* s;
|
const qse_mchar_t* s;
|
||||||
|
|
||||||
|
if (extra_delim == QSE_MT('\0')) extra_delim = QSE_MT(' ');
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
while (ptr < end && QSE_ISMSPACE(*ptr)) ptr++;
|
while (ptr < end && IS_MDELIM(*ptr,extra_delim)) ptr++;
|
||||||
if (ptr >= end) return QSE_NULL;
|
if (ptr >= end) return QSE_NULL;
|
||||||
|
|
||||||
s = ptr;
|
s = ptr;
|
||||||
while (ptr < end && !QSE_ISMSPACE(*ptr)) ptr++;
|
while (ptr < end && !IS_MDELIM(*ptr,extra_delim)) ptr++;
|
||||||
|
|
||||||
if (qse_mbsxcmp (s, ptr-s, word) == 0) return s;
|
if (qse_mbsxcmp (s, ptr - s, word) == 0) return s;
|
||||||
}
|
}
|
||||||
while (ptr < end);
|
while (ptr < end);
|
||||||
|
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qse_mchar_t* qse_mbscaseword (
|
const qse_mchar_t* qse_mbscaseword (const qse_mchar_t* str, const qse_mchar_t* word, qse_mchar_t extra_delim)
|
||||||
const qse_mchar_t* str, const qse_mchar_t* word)
|
|
||||||
{
|
{
|
||||||
/* find a full word in a string */
|
/* find a full word in a string */
|
||||||
|
|
||||||
const qse_mchar_t* ptr = str;
|
const qse_mchar_t* ptr = str;
|
||||||
|
|
||||||
|
if (extra_delim == QSE_MT('\0')) extra_delim = QSE_MT(' ');
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
const qse_mchar_t* s;
|
const qse_mchar_t* s;
|
||||||
|
|
||||||
while (QSE_ISMSPACE(*ptr)) ptr++;
|
while (IS_MDELIM(*ptr,extra_delim)) ptr++;
|
||||||
if (*ptr == QSE_MT('\0')) return QSE_NULL;
|
if (*ptr == QSE_MT('\0')) return QSE_NULL;
|
||||||
|
|
||||||
s = ptr;
|
s = ptr;
|
||||||
while (*ptr != QSE_MT('\0') && !QSE_ISMSPACE(*ptr)) ptr++;
|
while (*ptr != QSE_MT('\0') && !IS_MDELIM(*ptr,extra_delim)) ptr++;
|
||||||
|
|
||||||
if (qse_mbsxcasecmp (s, ptr-s, word) == 0) return s;
|
if (qse_mbsxcasecmp (s, ptr - s, word) == 0) return s;
|
||||||
}
|
}
|
||||||
while (*ptr != QSE_MT('\0'));
|
while (*ptr != QSE_MT('\0'));
|
||||||
|
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qse_mchar_t* qse_mbsxcaseword (
|
const qse_mchar_t* qse_mbsxcaseword (const qse_mchar_t* str, qse_size_t len, const qse_mchar_t* word, qse_mchar_t extra_delim)
|
||||||
const qse_mchar_t* str, qse_size_t len, const qse_mchar_t* word)
|
|
||||||
{
|
{
|
||||||
const qse_mchar_t* ptr = str;
|
const qse_mchar_t* ptr = str;
|
||||||
const qse_mchar_t* end = str + len;
|
const qse_mchar_t* end = str + len;
|
||||||
const qse_mchar_t* s;
|
const qse_mchar_t* s;
|
||||||
|
|
||||||
|
if (extra_delim == QSE_MT('\0')) extra_delim = QSE_MT(' ');
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
while (ptr < end && QSE_ISMSPACE(*ptr)) ptr++;
|
while (ptr < end && IS_MDELIM(*ptr,extra_delim)) ptr++;
|
||||||
if (ptr >= end) return QSE_NULL;
|
if (ptr >= end) return QSE_NULL;
|
||||||
|
|
||||||
s = ptr;
|
s = ptr;
|
||||||
while (ptr < end && !QSE_ISMSPACE(*ptr)) ptr++;
|
while (ptr < end && !IS_MDELIM(*ptr,extra_delim)) ptr++;
|
||||||
|
|
||||||
if (qse_mbsxcasecmp (s, ptr-s, word) == 0) return s;
|
if (qse_mbsxcasecmp (s, ptr - s, word) == 0) return s;
|
||||||
}
|
}
|
||||||
while (ptr < end);
|
while (ptr < end);
|
||||||
|
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qse_wchar_t* qse_wcsword (
|
const qse_wchar_t* qse_wcsword (const qse_wchar_t* str, const qse_wchar_t* word, qse_wchar_t extra_delim)
|
||||||
const qse_wchar_t* str, const qse_wchar_t* word)
|
|
||||||
{
|
{
|
||||||
/* find a full word in a string */
|
/* find a full word in a string */
|
||||||
|
|
||||||
const qse_wchar_t* ptr = str;
|
const qse_wchar_t* ptr = str;
|
||||||
|
|
||||||
|
if (extra_delim == QSE_WT('\0')) extra_delim = QSE_WT(' ');
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
const qse_wchar_t* s;
|
const qse_wchar_t* s;
|
||||||
|
|
||||||
while (QSE_ISWSPACE(*ptr)) ptr++;
|
while (IS_WDELIM(*ptr,extra_delim)) ptr++;
|
||||||
if (*ptr == QSE_WT('\0')) return QSE_NULL;
|
if (*ptr == QSE_WT('\0')) return QSE_NULL;
|
||||||
|
|
||||||
s = ptr;
|
s = ptr;
|
||||||
while (*ptr != QSE_WT('\0') && !QSE_ISWSPACE(*ptr)) ptr++;
|
while (*ptr != QSE_WT('\0') && !IS_WDELIM(*ptr,extra_delim)) ptr++;
|
||||||
|
|
||||||
if (qse_wcsxcmp (s, ptr-s, word) == 0) return s;
|
if (qse_wcsxcmp (s, ptr - s, word) == 0) return s;
|
||||||
}
|
}
|
||||||
while (*ptr != QSE_WT('\0'));
|
while (*ptr != QSE_WT('\0'));
|
||||||
|
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qse_wchar_t* qse_wcsxword (
|
const qse_wchar_t* qse_wcsxword (const qse_wchar_t* str, qse_size_t len, const qse_wchar_t* word, qse_wchar_t extra_delim)
|
||||||
const qse_wchar_t* str, qse_size_t len, const qse_wchar_t* word)
|
|
||||||
{
|
{
|
||||||
/* find a full word in a string */
|
/* find a full word in a string */
|
||||||
|
|
||||||
@ -148,61 +150,62 @@ const qse_wchar_t* qse_wcsxword (
|
|||||||
const qse_wchar_t* end = str + len;
|
const qse_wchar_t* end = str + len;
|
||||||
const qse_wchar_t* s;
|
const qse_wchar_t* s;
|
||||||
|
|
||||||
|
if (extra_delim == QSE_WT('\0')) extra_delim = QSE_WT(' ');
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
while (ptr < end && QSE_ISWSPACE(*ptr)) ptr++;
|
while (ptr < end && IS_WDELIM(*ptr,extra_delim)) ptr++;
|
||||||
if (ptr >= end) return QSE_NULL;
|
if (ptr >= end) return QSE_NULL;
|
||||||
|
|
||||||
s = ptr;
|
s = ptr;
|
||||||
while (ptr < end && !QSE_ISWSPACE(*ptr)) ptr++;
|
while (ptr < end && !IS_WDELIM(*ptr,extra_delim)) ptr++;
|
||||||
|
|
||||||
if (qse_wcsxcmp (s, ptr-s, word) == 0) return s;
|
if (qse_wcsxcmp (s, ptr - s, word) == 0) return s;
|
||||||
}
|
}
|
||||||
while (ptr < end);
|
while (ptr < end);
|
||||||
|
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qse_wchar_t* qse_wcscaseword (
|
const qse_wchar_t* qse_wcscaseword (const qse_wchar_t* str, const qse_wchar_t* word, qse_wchar_t extra_delim)
|
||||||
const qse_wchar_t* str, const qse_wchar_t* word)
|
|
||||||
{
|
{
|
||||||
/* find a full word in a string */
|
/* find a full word in a string */
|
||||||
|
|
||||||
const qse_wchar_t* ptr = str;
|
const qse_wchar_t* ptr = str;
|
||||||
|
|
||||||
|
if (extra_delim == QSE_WT('\0')) extra_delim = QSE_WT(' ');
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
const qse_wchar_t* s;
|
const qse_wchar_t* s;
|
||||||
|
|
||||||
while (QSE_ISWSPACE(*ptr)) ptr++;
|
while (IS_WDELIM(*ptr,extra_delim)) ptr++;
|
||||||
if (*ptr == QSE_WT('\0')) return QSE_NULL;
|
if (*ptr == QSE_WT('\0')) return QSE_NULL;
|
||||||
|
|
||||||
s = ptr;
|
s = ptr;
|
||||||
while (*ptr != QSE_WT('\0') && !QSE_ISWSPACE(*ptr)) ptr++;
|
while (*ptr != QSE_WT('\0') && !IS_WDELIM(*ptr,extra_delim)) ptr++;
|
||||||
|
|
||||||
if (qse_wcsxcasecmp (s, ptr-s, word) == 0) return s;
|
if (qse_wcsxcasecmp (s, ptr - s, word) == 0) return s;
|
||||||
}
|
}
|
||||||
while (*ptr != QSE_WT('\0'));
|
while (*ptr != QSE_WT('\0'));
|
||||||
|
|
||||||
return QSE_NULL;
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const qse_wchar_t* qse_wcsxcaseword (
|
const qse_wchar_t* qse_wcsxcaseword (const qse_wchar_t* str, qse_size_t len, const qse_wchar_t* word, qse_wchar_t extra_delim)
|
||||||
const qse_wchar_t* str, qse_size_t len, const qse_wchar_t* word)
|
|
||||||
{
|
{
|
||||||
const qse_wchar_t* ptr = str;
|
const qse_wchar_t* ptr = str;
|
||||||
const qse_wchar_t* end = str + len;
|
const qse_wchar_t* end = str + len;
|
||||||
const qse_wchar_t* s;
|
const qse_wchar_t* s;
|
||||||
|
|
||||||
|
if (extra_delim == QSE_WT('\0')) extra_delim = QSE_WT(' ');
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
while (ptr < end && QSE_ISWSPACE(*ptr)) ptr++;
|
while (ptr < end && IS_WDELIM(*ptr,extra_delim)) ptr++;
|
||||||
if (ptr >= end) return QSE_NULL;
|
if (ptr >= end) return QSE_NULL;
|
||||||
|
|
||||||
s = ptr;
|
s = ptr;
|
||||||
while (ptr < end && !QSE_ISWSPACE(*ptr)) ptr++;
|
while (ptr < end && !IS_WDELIM(*ptr,extra_delim)) ptr++;
|
||||||
|
|
||||||
if (qse_wcsxcasecmp (s, ptr-s, word) == 0) return s;
|
if (qse_wcsxcasecmp (s, ptr - s, word) == 0) return s;
|
||||||
}
|
}
|
||||||
while (ptr < end);
|
while (ptr < end);
|
||||||
|
|
||||||
|
@ -25,8 +25,13 @@
|
|||||||
|
|
||||||
static const qse_mchar_t NUL = QSE_MT('\0');
|
static const qse_mchar_t NUL = QSE_MT('\0');
|
||||||
|
|
||||||
|
/* for htrd->fed.s.flags */
|
||||||
#define CONSUME_UNTIL_CLOSE (1 << 0)
|
#define CONSUME_UNTIL_CLOSE (1 << 0)
|
||||||
|
|
||||||
|
/* for htrd->flags */
|
||||||
|
#define FEEDING_SUSPENDED (1 << 0)
|
||||||
|
#define FEEDING_DUMMIFIED (1 << 1)
|
||||||
|
|
||||||
static QSE_INLINE int is_whspace_octet (qse_mchar_t c)
|
static QSE_INLINE int is_whspace_octet (qse_mchar_t c)
|
||||||
{
|
{
|
||||||
return c == QSE_MT(' ') || c == QSE_MT('\t') || c == QSE_MT('\r') || c == QSE_MT('\n');
|
return c == QSE_MT(' ') || c == QSE_MT('\t') || c == QSE_MT('\r') || c == QSE_MT('\n');
|
||||||
@ -457,6 +462,7 @@ badre:
|
|||||||
void qse_htrd_clear (qse_htrd_t* htrd)
|
void qse_htrd_clear (qse_htrd_t* htrd)
|
||||||
{
|
{
|
||||||
clear_feed (htrd);
|
clear_feed (htrd);
|
||||||
|
htrd->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
qse_mmgr_t* qse_htrd_getmmgr (qse_htrd_t* htrd)
|
qse_mmgr_t* qse_htrd_getmmgr (qse_htrd_t* htrd)
|
||||||
@ -491,21 +497,21 @@ void qse_htrd_setrecbs (qse_htrd_t* htrd, const qse_htrd_recbs_t* recbs)
|
|||||||
|
|
||||||
static int capture_connection (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
static int capture_connection (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
||||||
{
|
{
|
||||||
int n;
|
|
||||||
qse_htre_hdrval_t* val;
|
qse_htre_hdrval_t* val;
|
||||||
|
|
||||||
val = QSE_HTB_VPTR(pair);
|
val = QSE_HTB_VPTR(pair);
|
||||||
while (val->next) val = val->next;
|
while (val->next) val = val->next;
|
||||||
|
|
||||||
n = qse_mbscmp (val->ptr, QSE_MT("close"));
|
/* The value for Connection: may get comma-separated.
|
||||||
if (n == 0)
|
* so use qse_mbscaseword() instead of qse_mbscmp(). */
|
||||||
|
|
||||||
|
if (qse_mbscaseword (val->ptr, QSE_MT("close"), QSE_MT(',')))
|
||||||
{
|
{
|
||||||
htrd->re.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
htrd->re.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = qse_mbscmp (val->ptr, QSE_MT("keep-alive"));
|
if (qse_mbscaseword (val->ptr, QSE_MT("keep-alive"), QSE_MT(',')))
|
||||||
if (n == 0)
|
|
||||||
{
|
{
|
||||||
htrd->re.flags |= QSE_HTRE_ATTR_KEEPALIVE;
|
htrd->re.flags |= QSE_HTRE_ATTR_KEEPALIVE;
|
||||||
return 0;
|
return 0;
|
||||||
@ -758,7 +764,7 @@ static qse_htb_pair_t* hdr_cbserter (
|
|||||||
* character is used by Set-Cookie in a way that conflicts with
|
* character is used by Set-Cookie in a way that conflicts with
|
||||||
* such folding.
|
* such folding.
|
||||||
*
|
*
|
||||||
* So i just maintain the list of valuea for a key instead of
|
* So i just maintain the list of values for a key instead of
|
||||||
* folding them.
|
* folding them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -826,7 +832,7 @@ qse_mchar_t* parse_header_field (
|
|||||||
{
|
{
|
||||||
/* ignore a line without a colon */
|
/* ignore a line without a colon */
|
||||||
p++;
|
p++;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto badhdr;
|
goto badhdr;
|
||||||
@ -945,7 +951,6 @@ static QSE_INLINE int parse_initial_line_and_headers (
|
|||||||
}
|
}
|
||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1061,10 +1066,10 @@ static const qse_mchar_t* get_trailing_headers (
|
|||||||
{
|
{
|
||||||
while (is_whspace_octet(*p)) p++;
|
while (is_whspace_octet(*p)) p++;
|
||||||
if (*p == '\0') break;
|
if (*p == '\0') break;
|
||||||
|
|
||||||
/* TODO: return error if protocol is 0.9.
|
/* TODO: return error if protocol is 0.9.
|
||||||
* HTTP/0.9 must not get headers... */
|
* HTTP/0.9 must not get headers... */
|
||||||
|
|
||||||
p = parse_header_field (
|
p = parse_header_field (
|
||||||
htrd, p,
|
htrd, p,
|
||||||
((htrd->option & QSE_HTRD_TRAILERS)? &htrd->re.trailers: &htrd->re.hdrtab)
|
((htrd->option & QSE_HTRD_TRAILERS)? &htrd->re.trailers: &htrd->re.hdrtab)
|
||||||
@ -1107,7 +1112,14 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len)
|
|||||||
|
|
||||||
QSE_ASSERT (len > 0);
|
QSE_ASSERT (len > 0);
|
||||||
|
|
||||||
if (htrd->option & QSE_HTRD_DUMMY)
|
if (htrd->flags & FEEDING_SUSPENDED)
|
||||||
|
{
|
||||||
|
htrd->errnum = QSE_HTRD_ESUSPENDED;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (htrd->option & QSE_HTRD_DUMMY)*/
|
||||||
|
if (htrd->flags & FEEDING_DUMMIFIED)
|
||||||
{
|
{
|
||||||
/* treat everything as contents.
|
/* treat everything as contents.
|
||||||
* i don't care about headers or whatsoever. */
|
* i don't care about headers or whatsoever. */
|
||||||
@ -1159,13 +1171,13 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len)
|
|||||||
|
|
||||||
switch (b)
|
switch (b)
|
||||||
{
|
{
|
||||||
case '\0':
|
case QSE_MT('\0'):
|
||||||
/* guarantee that the request does not contain
|
/* guarantee that the request does not contain
|
||||||
* a null character */
|
* a null character */
|
||||||
htrd->errnum = QSE_HTRD_EBADRE;
|
htrd->errnum = QSE_HTRD_EBADRE;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
case '\n':
|
case QSE_MT('\n'):
|
||||||
{
|
{
|
||||||
if (htrd->fed.s.crlf <= 1)
|
if (htrd->fed.s.crlf <= 1)
|
||||||
{
|
{
|
||||||
@ -1302,7 +1314,6 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len)
|
|||||||
{
|
{
|
||||||
htrd->fed.s.need = htrd->re.attr.content_length;
|
htrd->fed.s.need = htrd->re.attr.content_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htrd->fed.s.need > 0)
|
if (htrd->fed.s.need > 0)
|
||||||
@ -1348,7 +1359,7 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len)
|
|||||||
htrd->fed.s.need = 0;
|
htrd->fed.s.need = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htrd->fed.s.chunk.phase == GET_CHUNK_DATA)
|
if (htrd->fed.s.chunk.phase == GET_CHUNK_DATA)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (htrd->fed.s.need == 0);
|
QSE_ASSERT (htrd->fed.s.need == 0);
|
||||||
@ -1358,7 +1369,7 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len)
|
|||||||
while (ptr < end && is_space_octet(*ptr)) ptr++;
|
while (ptr < end && is_space_octet(*ptr)) ptr++;
|
||||||
if (ptr < end)
|
if (ptr < end)
|
||||||
{
|
{
|
||||||
if (*ptr == '\n')
|
if (*ptr == QSE_MT('\n'))
|
||||||
{
|
{
|
||||||
/* end of chunk data. */
|
/* end of chunk data. */
|
||||||
ptr++;
|
ptr++;
|
||||||
@ -1442,10 +1453,17 @@ qse_printf (QSE_T("CONTENT_LENGTH %d, RAW HEADER LENGTH %d\n"),
|
|||||||
clear_feed (htrd);
|
clear_feed (htrd);
|
||||||
if (ptr >= end) return 0; /* no more feeds to handle */
|
if (ptr >= end) return 0; /* no more feeds to handle */
|
||||||
|
|
||||||
if (htrd->option & QSE_HTRD_DUMMY)
|
if (htrd->flags & FEEDING_SUSPENDED)
|
||||||
|
{
|
||||||
|
htrd->errnum = QSE_HTRD_ESUSPENDED;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (htrd->option & QSE_HTRD_DUMMY)*/
|
||||||
|
if (htrd->flags & FEEDING_DUMMIFIED)
|
||||||
{
|
{
|
||||||
/* once the mode changes to RAW in a callback,
|
/* once the mode changes to RAW in a callback,
|
||||||
* left-over is pused as contents */
|
* left-over is pushed as contents */
|
||||||
if (ptr < end)
|
if (ptr < end)
|
||||||
return push_content (htrd, ptr, end - ptr);
|
return push_content (htrd, ptr, end - ptr);
|
||||||
else
|
else
|
||||||
@ -1466,7 +1484,7 @@ qse_printf (QSE_T("CONTENT_LENGTH %d, RAW HEADER LENGTH %d\n"),
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '\r':
|
case QSE_MT('\r'):
|
||||||
if (htrd->fed.s.crlf == 0 || htrd->fed.s.crlf == 2)
|
if (htrd->fed.s.crlf == 0 || htrd->fed.s.crlf == 2)
|
||||||
htrd->fed.s.crlf++;
|
htrd->fed.s.crlf++;
|
||||||
else htrd->fed.s.crlf = 1;
|
else htrd->fed.s.crlf = 1;
|
||||||
@ -1533,6 +1551,26 @@ int qse_htrd_halt (qse_htrd_t* htrd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qse_htrd_suspend (qse_htrd_t* htrd)
|
||||||
|
{
|
||||||
|
htrd->flags |= FEEDING_SUSPENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_htrd_resume (qse_htrd_t* htrd)
|
||||||
|
{
|
||||||
|
htrd->flags &= ~FEEDING_SUSPENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_htrd_dummify (qse_htrd_t* htrd)
|
||||||
|
{
|
||||||
|
htrd->flags |= FEEDING_DUMMIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qse_htrd_undummify (qse_htrd_t* htrd)
|
||||||
|
{
|
||||||
|
htrd->flags &= ~FEEDING_DUMMIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int qse_htrd_scanqparam (qse_htrd_t* htrd, const qse_mcstr_t* cstr)
|
int qse_htrd_scanqparam (qse_htrd_t* htrd, const qse_mcstr_t* cstr)
|
||||||
{
|
{
|
||||||
|
@ -504,4 +504,3 @@ qse_mchar_t* qse_perenchttpstrdup (int opt, const qse_mchar_t* str, qse_mmgr_t*
|
|||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,9 +53,12 @@ struct task_proxy_t
|
|||||||
#define PROXY_URL_PREREWRITTEN (1 << 12) /* URL has been prerewritten in prerewrite(). */
|
#define PROXY_URL_PREREWRITTEN (1 << 12) /* URL has been prerewritten in prerewrite(). */
|
||||||
#define PROXY_URL_REWRITTEN (1 << 13)
|
#define PROXY_URL_REWRITTEN (1 << 13)
|
||||||
#define PROXY_URL_REDIRECTED (1 << 14)
|
#define PROXY_URL_REDIRECTED (1 << 14)
|
||||||
#define PROXY_X_FORWARDED_FOR (1 << 15) /* X-Forwarded-For added */
|
#define PROXY_X_FORWARDED_FOR (1 << 15) /* X-Forwarded-For: added */
|
||||||
#define PROXY_VIA (1 << 16) /* Via added to the request */
|
#define PROXY_VIA (1 << 16) /* Via: added to the request */
|
||||||
#define PROXY_VIA_RETURNING (1 << 17) /* Via added to the response */
|
#define PROXY_VIA_RETURNING (1 << 17) /* Via: added to the response */
|
||||||
|
#define PROXY_UPGRADE_REQUESTED (1 << 18)
|
||||||
|
#define PROXY_PROTOCOL_SWITCHED (1 << 19)
|
||||||
|
#define PROXY_GOT_BAD_REQUEST (1 << 20)
|
||||||
int flags;
|
int flags;
|
||||||
qse_httpd_t* httpd;
|
qse_httpd_t* httpd;
|
||||||
qse_httpd_client_t* client;
|
qse_httpd_client_t* client;
|
||||||
@ -340,8 +343,8 @@ static int proxy_snatch_client_input_raw (
|
|||||||
/* this function is never called with ptr of QSE_NULL
|
/* this function is never called with ptr of QSE_NULL
|
||||||
* because this callback is set manually after the request
|
* because this callback is set manually after the request
|
||||||
* has been discarded or completed in task_init_proxy() and
|
* has been discarded or completed in task_init_proxy() and
|
||||||
* qse_htre_completecontent or qse-htre_discardcontent() is
|
* qse_htre_completecontent() or qse_htre_discardcontent() is
|
||||||
* not called again. Unlinkw proxy_snatch_client_input(),
|
* not called again. Unlike proxy_snatch_client_input(),
|
||||||
* it doesn't care about EOF indicated by ptr of QSE_NULL. */
|
* it doesn't care about EOF indicated by ptr of QSE_NULL. */
|
||||||
if (ptr && !(proxy->reqflags & PROXY_REQ_FWDERR))
|
if (ptr && !(proxy->reqflags & PROXY_REQ_FWDERR))
|
||||||
{
|
{
|
||||||
@ -660,7 +663,6 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res)
|
|||||||
}
|
}
|
||||||
/* end initial line */
|
/* end initial line */
|
||||||
|
|
||||||
|
|
||||||
if (proxy->resflags & PROXY_RES_PEER_LENGTH_FAKE)
|
if (proxy->resflags & PROXY_RES_PEER_LENGTH_FAKE)
|
||||||
{
|
{
|
||||||
/* length should be added by force.
|
/* length should be added by force.
|
||||||
@ -778,6 +780,37 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (proxy->flags & PROXY_UPGRADE_REQUESTED)
|
||||||
|
{
|
||||||
|
QSE_ASSERT (proxy->req != QSE_NULL);
|
||||||
|
|
||||||
|
if (qse_htre_getscodeval(res) == 101)
|
||||||
|
{
|
||||||
|
/* Unlike raw proxying entasked for CONNECT for which disconnection
|
||||||
|
* is supposed to be scheduled by the caller, protocol upgrade
|
||||||
|
* can be requested over a normal http stream. A stream whose
|
||||||
|
* protocol has been switched must not be sustained after the
|
||||||
|
* task is over. */
|
||||||
|
if (qse_httpd_entaskdisconnect (httpd, proxy->client, xtn->task) == QSE_NULL) return -1;
|
||||||
|
proxy->flags |= PROXY_PROTOCOL_SWITCHED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* the update request is not granted. restore the reader
|
||||||
|
* to the original state so that HTTP packets can be handled
|
||||||
|
* later on. */
|
||||||
|
qse_htrd_undummify (proxy->client->htrd);
|
||||||
|
qse_htre_unsetconcb (proxy->req);
|
||||||
|
proxy->req = QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* let the reader accept data to be fed */
|
||||||
|
qse_htrd_resume (proxy->client->htrd);
|
||||||
|
|
||||||
|
/*task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;*/ /* peer */
|
||||||
|
proxy->task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_READ; /* client-side */
|
||||||
|
}
|
||||||
|
|
||||||
proxy->res_pending = QSE_MBS_LEN(proxy->res) - proxy->res_consumed;
|
proxy->res_pending = QSE_MBS_LEN(proxy->res) - proxy->res_consumed;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -815,11 +848,6 @@ static void proxy_forward_client_input_to_peer (qse_httpd_t* httpd, qse_httpd_ta
|
|||||||
/* normal forwarding */
|
/* normal forwarding */
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
|
|
||||||
#if 0
|
|
||||||
qse_printf (QSE_T("PROXY FORWARD: @@@@@@@@@@WRITING[%.*hs]\n"),
|
|
||||||
(int)QSE_MBS_LEN(proxy->reqfwdbuf),
|
|
||||||
QSE_MBS_PTR(proxy->reqfwdbuf));
|
|
||||||
#endif
|
|
||||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||||
n = httpd->opt.scb.peer.send (
|
n = httpd->opt.scb.peer.send (
|
||||||
httpd, &proxy->peer,
|
httpd, &proxy->peer,
|
||||||
@ -854,13 +882,15 @@ to the head all the time.. grow the buffer to a certain limit. */
|
|||||||
qse_mbs_del (proxy->reqfwdbuf, 0, n);
|
qse_mbs_del (proxy->reqfwdbuf, 0, n);
|
||||||
if (QSE_MBS_LEN(proxy->reqfwdbuf) <= 0)
|
if (QSE_MBS_LEN(proxy->reqfwdbuf) <= 0)
|
||||||
{
|
{
|
||||||
if (proxy->req == QSE_NULL) goto done;
|
/* the forwarding buffer is emptied after sending. */
|
||||||
else task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
if (!proxy->req) goto done;
|
||||||
|
task->trigger.v[0].mask &= ~QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (proxy->req == QSE_NULL)
|
else if (!proxy->req)
|
||||||
{
|
{
|
||||||
done:
|
done:
|
||||||
/* there is nothing to read from the client side and
|
/* there is nothing to read from the client side and
|
||||||
@ -1011,7 +1041,7 @@ static int task_init_proxy (
|
|||||||
/* the caller must make sure that the actual content is discarded or completed
|
/* the caller must make sure that the actual content is discarded or completed
|
||||||
* and the following data is treated as contents */
|
* and the following data is treated as contents */
|
||||||
QSE_ASSERT (arg->req->state & (QSE_HTRE_DISCARDED | QSE_HTRE_COMPLETED));
|
QSE_ASSERT (arg->req->state & (QSE_HTRE_DISCARDED | QSE_HTRE_COMPLETED));
|
||||||
QSE_ASSERT (qse_htrd_getoption(client->htrd) & QSE_HTRD_DUMMY);
|
/*QSE_ASSERT (qse_htrd_getoption(client->htrd) & QSE_HTRD_DUMMY);*/
|
||||||
|
|
||||||
proxy->req = arg->req;
|
proxy->req = arg->req;
|
||||||
qse_htre_setconcb (proxy->req, proxy_snatch_client_input_raw, task);
|
qse_htre_setconcb (proxy->req, proxy_snatch_client_input_raw, task);
|
||||||
@ -1228,13 +1258,55 @@ qse_mbs_ncat (proxy->reqfwdbuf, spc, QSE_COUNTOF(spc));
|
|||||||
snatch_needed = 1;
|
snatch_needed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snatch_needed)
|
if (qse_htre_getheaderval(arg->req, QSE_MT("Upgrade")))
|
||||||
{
|
{
|
||||||
/* set up a callback to be called when the request content
|
/* Upgrade: is found in the request header */
|
||||||
* is fed to the htrd reader. qse_htre_addcontent() that
|
const qse_htre_hdrval_t* hv;
|
||||||
* htrd calls invokes this callback. */
|
hv = qse_htre_getheaderval(arg->req, QSE_MT("Connection"));
|
||||||
|
while (hv)
|
||||||
|
{
|
||||||
|
if (qse_mbscaseword (hv->ptr, QSE_MT("Upgrade"), QSE_MT(','))) break;
|
||||||
|
hv = hv->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hv) goto no_upgrade;
|
||||||
|
|
||||||
|
if (snatch_needed)
|
||||||
|
{
|
||||||
|
/* The upgrade request can't have contents.
|
||||||
|
* Not allowing contents makes implementation easier. */
|
||||||
|
httpd->errnum = QSE_HTTPD_EBADREQ;
|
||||||
|
proxy->flags |= PROXY_GOT_BAD_REQUEST;
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cause feeding of client data to fail. i do this because
|
||||||
|
* it's unknown if upgrade will get granted or not.
|
||||||
|
* if it's granted, the client input should be treated
|
||||||
|
* as an octet string. If not, it should still be handled
|
||||||
|
* as HTTP. */
|
||||||
|
qse_htrd_suspend (client->htrd);
|
||||||
|
|
||||||
|
/* prearrange to not parse client input when feeding is resumed */
|
||||||
|
qse_htrd_dummify (client->htrd);
|
||||||
|
|
||||||
|
proxy->flags |= PROXY_UPGRADE_REQUESTED;
|
||||||
proxy->req = arg->req;
|
proxy->req = arg->req;
|
||||||
qse_htre_setconcb (proxy->req, proxy_snatch_client_input, task);
|
|
||||||
|
/* prearrange to capature client input when feeding is resumed */
|
||||||
|
qse_htre_setconcb (proxy->req, proxy_snatch_client_input_raw, proxy->task);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
no_upgrade:
|
||||||
|
if (snatch_needed)
|
||||||
|
{
|
||||||
|
/* set up a callback to be called when the request content
|
||||||
|
* is fed to the htrd reader. qse_htre_addcontent() that
|
||||||
|
* htrd calls invokes this callback. */
|
||||||
|
proxy->req = arg->req;
|
||||||
|
qse_htre_setconcb (proxy->req, proxy_snatch_client_input, task);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1253,9 +1325,6 @@ nomem_oops:
|
|||||||
/* goto oops */
|
/* goto oops */
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
|
|
||||||
printf ("init_proxy failed...........................................\n");
|
|
||||||
|
|
||||||
/* since a new task can't be added in the initializer,
|
/* since a new task can't be added in the initializer,
|
||||||
* i mark that initialization failed and let task_main_proxy()
|
* i mark that initialization failed and let task_main_proxy()
|
||||||
* add an error task */
|
* add an error task */
|
||||||
@ -1276,7 +1345,6 @@ printf ("init_proxy failed...........................................\n");
|
|||||||
proxy->flags |= PROXY_INIT_FAILED;
|
proxy->flags |= PROXY_INIT_FAILED;
|
||||||
task->ctx = proxy;
|
task->ctx = proxy;
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1290,6 +1358,16 @@ static void task_fini_proxy (
|
|||||||
if (proxy->peer_status & PROXY_PEER_OPEN)
|
if (proxy->peer_status & PROXY_PEER_OPEN)
|
||||||
httpd->opt.scb.peer.close (httpd, &proxy->peer);
|
httpd->opt.scb.peer.close (httpd, &proxy->peer);
|
||||||
|
|
||||||
|
if ((proxy->flags & (PROXY_UPGRADE_REQUESTED | PROXY_PROTOCOL_SWITCHED)) == PROXY_UPGRADE_REQUESTED)
|
||||||
|
{
|
||||||
|
/* upgrade requested but protocol switching not completed yet.
|
||||||
|
* this can happen because dummification is performed before
|
||||||
|
* the 101 response is received. */
|
||||||
|
|
||||||
|
/* no harm to call this multiple times */
|
||||||
|
qse_htrd_undummify (proxy->client->htrd);
|
||||||
|
}
|
||||||
|
|
||||||
if (proxy->res) qse_mbs_close (proxy->res);
|
if (proxy->res) qse_mbs_close (proxy->res);
|
||||||
if (proxy->peer_htrd) qse_htrd_close (proxy->peer_htrd);
|
if (proxy->peer_htrd) qse_htrd_close (proxy->peer_htrd);
|
||||||
if (proxy->reqfwdbuf) qse_mbs_close (proxy->reqfwdbuf);
|
if (proxy->reqfwdbuf) qse_mbs_close (proxy->reqfwdbuf);
|
||||||
@ -1311,24 +1389,12 @@ printf ("task_main_proxy_5 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
|||||||
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
|
||||||
{
|
|
||||||
/* if the client side is readable */
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
|
||||||
}
|
|
||||||
else if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
|
||||||
{
|
|
||||||
/* if the peer side is writable while the client side is not readable*/
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task);
|
proxy_forward_client_input_to_peer (httpd, task);
|
||||||
|
|
||||||
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ proxy->buflen > 0)
|
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ proxy->buflen > 0)
|
||||||
{
|
{
|
||||||
/* wrote to the client socket as long as there's something to
|
/* write to the client socket as long as there's something.
|
||||||
* write. it's safe to do so as the socket is non-blocking.
|
* it's safe to do so as the socket is non-blocking.
|
||||||
* i commented out the check in the 'if' condition above */
|
* i commented out the check in the 'if' condition above */
|
||||||
|
|
||||||
/* TODO: check if proxy outputs more than content-length if it is set... */
|
/* TODO: check if proxy outputs more than content-length if it is set... */
|
||||||
@ -1352,7 +1418,7 @@ printf ("task_main_proxy_5 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* if forwarding didn't finish, something is not really right...
|
/* if forwarding didn't finish, something is not really right...
|
||||||
* so long as the output from CGI is finished, no more forwarding
|
* so long as the output from peer is finished, no more forwarding
|
||||||
* is performed */
|
* is performed */
|
||||||
return (proxy->buflen > 0 || proxy->req ||
|
return (proxy->buflen > 0 || proxy->req ||
|
||||||
(proxy->reqfwdbuf && QSE_MBS_LEN(proxy->reqfwdbuf) > 0))? 1: 0;
|
(proxy->reqfwdbuf && QSE_MBS_LEN(proxy->reqfwdbuf) > 0))? 1: 0;
|
||||||
@ -1362,23 +1428,13 @@ static int task_main_proxy_4 (
|
|||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
||||||
{
|
{
|
||||||
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n",
|
printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger.cmask=%d\n",
|
||||||
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task);
|
proxy_forward_client_input_to_peer (httpd, task);
|
||||||
/*
|
|
||||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
|
||||||
{
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
|
||||||
}
|
|
||||||
else if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
|
||||||
{
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE) &&
|
if ((task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_READABLE) &&
|
||||||
proxy->buflen < QSE_SIZEOF(proxy->buf))
|
proxy->buflen < QSE_SIZEOF(proxy->buf))
|
||||||
@ -1436,6 +1492,12 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
|||||||
qse_htre_unsetconcb (proxy->req);
|
qse_htre_unsetconcb (proxy->req);
|
||||||
proxy->req = QSE_NULL;
|
proxy->req = QSE_NULL;
|
||||||
}
|
}
|
||||||
|
else if (proxy->flags & PROXY_PROTOCOL_SWITCHED)
|
||||||
|
{
|
||||||
|
qse_htrd_undummify (proxy->client->htrd);
|
||||||
|
qse_htre_unsetconcb (proxy->req);
|
||||||
|
proxy->req = QSE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1443,7 +1505,7 @@ printf ("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask
|
|||||||
{
|
{
|
||||||
proxy->buflen += n;
|
proxy->buflen += n;
|
||||||
proxy->peer_output_received += n;
|
proxy->peer_output_received += n;
|
||||||
|
|
||||||
if (proxy->resflags & PROXY_RES_PEER_LENGTH)
|
if (proxy->resflags & PROXY_RES_PEER_LENGTH)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (!(proxy->flags & PROXY_RAW));
|
QSE_ASSERT (!(proxy->flags & PROXY_RAW));
|
||||||
@ -1507,22 +1569,12 @@ static int task_main_proxy_3 (
|
|||||||
|
|
||||||
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
qse_printf (QSE_T("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n"),
|
printf ("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigger[2].mask=%d\n",
|
||||||
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task);
|
proxy_forward_client_input_to_peer (httpd, task);
|
||||||
/*
|
|
||||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
|
||||||
{
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
|
||||||
}
|
|
||||||
else if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
|
||||||
{
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) &&*/ proxy->res_pending > 0)
|
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) &&*/ proxy->res_pending > 0)
|
||||||
{
|
{
|
||||||
@ -1566,6 +1618,12 @@ qse_printf (QSE_T("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigg
|
|||||||
qse_mbs_clear (proxy->res);
|
qse_mbs_clear (proxy->res);
|
||||||
proxy->res_consumed = 0;
|
proxy->res_consumed = 0;
|
||||||
|
|
||||||
|
if (proxy->flags & PROXY_PROTOCOL_SWITCHED)
|
||||||
|
{
|
||||||
|
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
|
goto read_more;
|
||||||
|
}
|
||||||
|
|
||||||
if ((proxy->resflags & PROXY_RES_CLIENT_CHUNK) ||
|
if ((proxy->resflags & PROXY_RES_CLIENT_CHUNK) ||
|
||||||
((proxy->resflags & PROXY_RES_PEER_LENGTH) && proxy->peer_output_received >= proxy->peer_output_length))
|
((proxy->resflags & PROXY_RES_PEER_LENGTH) && proxy->peer_output_received >= proxy->peer_output_length))
|
||||||
{
|
{
|
||||||
@ -1575,6 +1633,7 @@ qse_printf (QSE_T("task_main_proxy_3 trigger[0].mask=%d trigger[1].mask=%d trigg
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
read_more:
|
||||||
/* there are still more to read from the peer.
|
/* there are still more to read from the peer.
|
||||||
* arrange to read the remaining contents from the peer */
|
* arrange to read the remaining contents from the peer */
|
||||||
task->main = task_main_proxy_4;
|
task->main = task_main_proxy_4;
|
||||||
@ -1596,24 +1655,7 @@ static int task_main_proxy_2 (
|
|||||||
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||||
int http_errnum = 500;
|
int http_errnum = 500;
|
||||||
|
|
||||||
#if 0
|
|
||||||
printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
|
||||||
task->trigger.v[0].mask, task->trigger.v[1].mask, task->trigger.cmask);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task);
|
proxy_forward_client_input_to_peer (httpd, task);
|
||||||
#if 0
|
|
||||||
if (task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_READABLE)
|
|
||||||
{
|
|
||||||
/* client is readable */
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 0);
|
|
||||||
}
|
|
||||||
else if (task->trigger.v[0].mask & QSE_HTTPD_TASK_TRIGGER_WRITABLE)
|
|
||||||
{
|
|
||||||
/* client is not readable but peer is writable */
|
|
||||||
proxy_forward_client_input_to_peer (httpd, task, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ proxy->res_pending > 0)
|
if (/*(task->trigger.cmask & QSE_HTTPD_TASK_TRIGGER_WRITABLE) && */ proxy->res_pending > 0)
|
||||||
{
|
{
|
||||||
@ -1624,8 +1666,8 @@ printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
|||||||
* '100 Continue' to the client.
|
* '100 Continue' to the client.
|
||||||
*
|
*
|
||||||
* attempt to write to the client regardless of writability of
|
* attempt to write to the client regardless of writability of
|
||||||
* the cleint socket as it is non-blocking. see the check commented
|
* the cleint socket as it is non-blocking. see the check commented
|
||||||
* in the 'if' condition above. */
|
* out in the 'if' condition above. */
|
||||||
|
|
||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
qse_size_t count;
|
qse_size_t count;
|
||||||
@ -1729,14 +1771,6 @@ printf ("task_main_proxy_2 trigger[0].mask=%d trigger[1].mask=%d cmask=%d\n",
|
|||||||
proxy->buflen += n;
|
proxy->buflen += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
qse_printf (QSE_T("#####PROXY FEEDING %d [\n"), (int)proxy->buflen);
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < proxy->buflen; i++) qse_printf (QSE_T("%hc"), proxy->buf[i]);
|
|
||||||
}
|
|
||||||
qse_printf (QSE_T("]\n"));
|
|
||||||
#endif
|
|
||||||
if (proxy->buflen > 0)
|
if (proxy->buflen > 0)
|
||||||
{
|
{
|
||||||
if (qse_htrd_feed (proxy->peer_htrd, proxy->buf, proxy->buflen) <= -1)
|
if (qse_htrd_feed (proxy->peer_htrd, proxy->buf, proxy->buflen) <= -1)
|
||||||
@ -1749,7 +1783,13 @@ qse_printf (QSE_T("]\n"));
|
|||||||
proxy->buflen = 0;
|
proxy->buflen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QSE_MBS_LEN(proxy->res) > 0)
|
if (proxy->flags & PROXY_PROTOCOL_SWITCHED)
|
||||||
|
{
|
||||||
|
task->trigger.cmask = QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
|
if (QSE_MBS_LEN(proxy->res) > 0) task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
|
task->main = task_main_proxy_3;
|
||||||
|
}
|
||||||
|
else if (QSE_MBS_LEN(proxy->res) > 0)
|
||||||
{
|
{
|
||||||
if (proxy->resflags & PROXY_RES_RECEIVED_RESCON)
|
if (proxy->resflags & PROXY_RES_RECEIVED_RESCON)
|
||||||
{
|
{
|
||||||
@ -1842,10 +1882,17 @@ static int task_main_proxy_1 (
|
|||||||
{
|
{
|
||||||
/* connected to the peer now */
|
/* connected to the peer now */
|
||||||
proxy->peer_status |= PROXY_PEER_CONNECTED;
|
proxy->peer_status |= PROXY_PEER_CONNECTED;
|
||||||
if (proxy->req)
|
if (!(proxy->flags & PROXY_UPGRADE_REQUESTED) && proxy->req)
|
||||||
{
|
{
|
||||||
/* need to read from the client-side as
|
/* need to read from the client-side as
|
||||||
* the content has not been received in full. */
|
* the content has not been received in full.
|
||||||
|
*
|
||||||
|
* proxy->req is set to the original request when snatching is
|
||||||
|
* required. it's also set to the original request when protocol
|
||||||
|
* upgrade is requested. however, a upgrade request containing
|
||||||
|
* contents is treated as a bad request. so i don't arrange
|
||||||
|
* to read from the client side when PROXY_UPGRADE_REQUESTED
|
||||||
|
* is on. */
|
||||||
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_READ;
|
task->trigger.cmask |= QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2124,7 +2171,12 @@ static int task_main_proxy (
|
|||||||
|
|
||||||
if (proxy->flags & PROXY_INIT_FAILED)
|
if (proxy->flags & PROXY_INIT_FAILED)
|
||||||
{
|
{
|
||||||
if (proxy->flags & PROXY_PEER_NAME_UNRESOLVED) http_errnum = 404; /* 404 Not Found */
|
if (proxy->flags & PROXY_GOT_BAD_REQUEST)
|
||||||
|
{
|
||||||
|
http_errnum = 400; /* 400 Bad Request */
|
||||||
|
proxy->keepalive = 0; /* force Connect: close in the response */
|
||||||
|
}
|
||||||
|
else if (proxy->flags & PROXY_PEER_NAME_UNRESOLVED) http_errnum = 404; /* 404 Not Found */
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2194,7 +2246,7 @@ static int task_main_proxy (
|
|||||||
* for a socket descriptor into 1 event.
|
* for a socket descriptor into 1 event.
|
||||||
*
|
*
|
||||||
* if this happens, qse_http_resolvename() can be called
|
* if this happens, qse_http_resolvename() can be called
|
||||||
* multiple times.
|
* multiple times. set this flag to prevent double resolution.
|
||||||
*/
|
*/
|
||||||
proxy->flags |= PROXY_PEER_NAME_RESOLVING;
|
proxy->flags |= PROXY_PEER_NAME_RESOLVING;
|
||||||
|
|
||||||
@ -2268,10 +2320,18 @@ static int task_main_proxy (
|
|||||||
{
|
{
|
||||||
/* peer connected already */
|
/* peer connected already */
|
||||||
proxy->peer_status |= PROXY_PEER_CONNECTED;
|
proxy->peer_status |= PROXY_PEER_CONNECTED;
|
||||||
if (proxy->req)
|
if (!(proxy->flags & PROXY_UPGRADE_REQUESTED) && proxy->req)
|
||||||
{
|
{
|
||||||
/* need to read from the client-side as
|
/* need to read from the client-side as
|
||||||
* the content has not been received in full. */
|
* the content has not been received in full.
|
||||||
|
*
|
||||||
|
* proxy->req is set to the original request when snatching is
|
||||||
|
* required. it's also set to the original request when protocol
|
||||||
|
* upgrade is requested. however, a upgrade request containing
|
||||||
|
* contents is treated as a bad request. so i don't arrange
|
||||||
|
* to read from the client side when PROXY_UPGRADE_REQUESTED
|
||||||
|
* is on.
|
||||||
|
*/
|
||||||
task->trigger.cmask = QSE_HTTPD_TASK_TRIGGER_READ;
|
task->trigger.cmask = QSE_HTTPD_TASK_TRIGGER_READ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,9 +792,6 @@ resolved:
|
|||||||
static void tmr_dns_tmout_update (qse_tmr_t* tmr, qse_tmr_index_t old_index, qse_tmr_index_t new_index, void* ctx)
|
static void tmr_dns_tmout_update (qse_tmr_t* tmr, qse_tmr_index_t old_index, qse_tmr_index_t new_index, void* ctx)
|
||||||
{
|
{
|
||||||
dns_req_t* req = (dns_req_t*)ctx;
|
dns_req_t* req = (dns_req_t*)ctx;
|
||||||
|
|
||||||
printf (">>tmr_dns_tmout_updated req->>%p\n", req);
|
|
||||||
printf (">>tmr_dns_tmout_updated existing->%d, old->%d new->%d\n", (int)req->tmr_tmout, (int)old_index, (int)new_index);
|
|
||||||
QSE_ASSERT (req->tmr_tmout == old_index);
|
QSE_ASSERT (req->tmr_tmout == old_index);
|
||||||
req->tmr_tmout = new_index;
|
req->tmr_tmout = new_index;
|
||||||
}
|
}
|
||||||
|
@ -347,7 +347,6 @@ static void tmr_urs_tmout_update (qse_tmr_t* tmr, qse_tmr_index_t old_index, qse
|
|||||||
{
|
{
|
||||||
urs_req_t* req = (urs_req_t*)ctx;
|
urs_req_t* req = (urs_req_t*)ctx;
|
||||||
|
|
||||||
printf (">>tmr_urs_tmout_updated existing=%d old=%d new=%d\n", (int)req->tmr_tmout, (int)old_index, (int)new_index);
|
|
||||||
QSE_ASSERT (req->tmr_tmout == old_index);
|
QSE_ASSERT (req->tmr_tmout == old_index);
|
||||||
req->tmr_tmout = new_index;
|
req->tmr_tmout = new_index;
|
||||||
}
|
}
|
||||||
|
@ -2242,7 +2242,7 @@ printf ("SWITCHING HTRD TO DUMMY.... %s\n", qse_htre_getqpath(req));
|
|||||||
/* Switch the http read to a dummy mode so that the subsqeuent
|
/* Switch the http read to a dummy mode so that the subsqeuent
|
||||||
* input(request) is just treated as data to the request just
|
* input(request) is just treated as data to the request just
|
||||||
* completed */
|
* completed */
|
||||||
qse_htrd_setoption (client->htrd, qse_htrd_getoption(client->htrd) | QSE_HTRD_DUMMY);
|
qse_htrd_dummify (client->htrd);
|
||||||
|
|
||||||
if (server_xtn->makersrc (httpd, client, req, &rsrc) <= -1)
|
if (server_xtn->makersrc (httpd, client, req, &rsrc) <= -1)
|
||||||
{
|
{
|
||||||
|
@ -711,7 +711,6 @@ qse_printf (QSE_T("failed to accept from server [%s] [%d]\n"), tmp, server->hand
|
|||||||
static void tmr_idle_update (qse_tmr_t* tmr, qse_tmr_index_t old_index, qse_tmr_index_t new_index, void* ctx)
|
static void tmr_idle_update (qse_tmr_t* tmr, qse_tmr_index_t old_index, qse_tmr_index_t new_index, void* ctx)
|
||||||
{
|
{
|
||||||
qse_httpd_client_t* client = (qse_httpd_client_t*)ctx;
|
qse_httpd_client_t* client = (qse_httpd_client_t*)ctx;
|
||||||
printf ("tmr_idle updated old_index %d new_index %d tmr_idle %d\n", (int)old_index, (int)new_index, (int)client->tmr_idle);
|
|
||||||
QSE_ASSERT (client->tmr_idle == old_index);
|
QSE_ASSERT (client->tmr_idle == old_index);
|
||||||
client->tmr_idle = new_index;
|
client->tmr_idle = new_index;
|
||||||
}
|
}
|
||||||
@ -720,7 +719,6 @@ static void tmr_idle_handle (qse_tmr_t* tmr, const qse_ntime_t* now, void* ctx)
|
|||||||
{
|
{
|
||||||
qse_httpd_client_t* client = (qse_httpd_client_t*)ctx;
|
qse_httpd_client_t* client = (qse_httpd_client_t*)ctx;
|
||||||
|
|
||||||
printf ("check if client is idle...\n");
|
|
||||||
if (qse_cmptime(now, &client->last_active) >= 0)
|
if (qse_cmptime(now, &client->last_active) >= 0)
|
||||||
{
|
{
|
||||||
qse_ntime_t diff;
|
qse_ntime_t diff;
|
||||||
@ -728,14 +726,12 @@ printf ("check if client is idle...\n");
|
|||||||
if (qse_cmptime(&diff, &client->server->httpd->opt.idle_limit) >= 0)
|
if (qse_cmptime(&diff, &client->server->httpd->opt.idle_limit) >= 0)
|
||||||
{
|
{
|
||||||
/* this client is idle */
|
/* this client is idle */
|
||||||
printf ("client is idle purging....\n");
|
|
||||||
purge_client (client->server->httpd, client);
|
purge_client (client->server->httpd, client);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qse_tmr_event_t idle_event;
|
qse_tmr_event_t idle_event;
|
||||||
|
|
||||||
printf ("client is NOT idle....\n");
|
|
||||||
QSE_ASSERT (client->server->httpd->tmr == tmr);
|
QSE_ASSERT (client->server->httpd->tmr == tmr);
|
||||||
|
|
||||||
/*qse_gettime (&idle_event.when);*/
|
/*qse_gettime (&idle_event.when);*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user