mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-09-28 19:05:55 +08:00
bug fixing
This commit is contained in:
parent
9ac5de60a3
commit
8f3c28a7e7
5
configure
vendored
5
configure
vendored
|
@ -24472,7 +24472,10 @@ $as_echo "$msg" >&6; }
|
||||||
|
|
||||||
$as_echo "#define USE_LIBEXPAT 1" >>confdefs.h
|
$as_echo "#define USE_LIBEXPAT 1" >>confdefs.h
|
||||||
|
|
||||||
expat_version=$(strings $expatdir/lib*/libexpat.* 2>/dev/null | grep "^expat_[0-9]" | head -n1 | cut -d'_' -f2)
|
expat_version=$(strings $expatdir/lib*/libexpat.* 2>/dev/null | grep "^expat_[0-9]*" | head -n1 | cut -d'_' -f2)
|
||||||
|
if test -z "${expat_version}"; then
|
||||||
|
expat_version=$(ls $expatdir/libexpat.so.*.* 2>/dev/null | head -n 1 | awk -F'.so.' '{n=2; print $n}' 2>/dev/null)
|
||||||
|
fi
|
||||||
if test -z "${expat_version}"; then
|
if test -z "${expat_version}"; then
|
||||||
expat_version="unknown"
|
expat_version="unknown"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -142,7 +142,7 @@ U_EXPORT void u_printSize(char* restrict buffer, uint64_t bytes); /* prin
|
||||||
U_EXPORT char* u_getPathRelativ(const char* restrict path, uint32_t* restrict path_len);
|
U_EXPORT char* u_getPathRelativ(const char* restrict path, uint32_t* restrict path_len);
|
||||||
U_EXPORT bool u_rmatch(const char* restrict haystack, uint32_t haystack_len, const char* restrict needle, uint32_t needle_len) __pure;
|
U_EXPORT bool u_rmatch(const char* restrict haystack, uint32_t haystack_len, const char* restrict needle, uint32_t needle_len) __pure;
|
||||||
U_EXPORT double u_calcRate(uint64_t bytes, uint32_t msecs, int* restrict units); /* Calculate the transfert rate */
|
U_EXPORT double u_calcRate(uint64_t bytes, uint32_t msecs, int* restrict units); /* Calculate the transfert rate */
|
||||||
U_EXPORT uint32_t u_findEndHeader( const char* restrict s, uint32_t n); /* find sequence of U_CRLF2 or U_LF2 */
|
U_EXPORT uint32_t u_findEndHeader( const char* restrict s, uint32_t n) __pure; /* find sequence of U_CRLF2 or U_LF2 */
|
||||||
U_EXPORT uint32_t u_findEndHeader1(const char* restrict s, uint32_t n) __pure; /* find sequence of U_CRLF2 */
|
U_EXPORT uint32_t u_findEndHeader1(const char* restrict s, uint32_t n) __pure; /* find sequence of U_CRLF2 */
|
||||||
U_EXPORT const char* u_get_mimetype(const char* restrict suffix, int* pmime_index);
|
U_EXPORT const char* u_get_mimetype(const char* restrict suffix, int* pmime_index);
|
||||||
|
|
||||||
|
|
|
@ -1129,7 +1129,7 @@ public:
|
||||||
|
|
||||||
// Check equality with string at pos
|
// Check equality with string at pos
|
||||||
|
|
||||||
bool isEqual(uint32_t pos, const UString& str, bool ignore_case = false);
|
bool isEqual(uint32_t pos, const UString& str, bool ignore_case = false) __pure;
|
||||||
|
|
||||||
// Check equality with an existing vector object
|
// Check equality with an existing vector object
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ public:
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UTimeDate::updateTime(%.5S)", ptr)
|
U_TRACE(0, "UTimeDate::updateTime(%.5S)", ptr)
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_DIFFERS(u_now->tv_sec % U_ONE_HOUR_IN_SECOND, 0)
|
U_INTERNAL_ASSERT(u_now->tv_sec % U_ONE_HOUR_IN_SECOND)
|
||||||
|
|
||||||
U_NUM2STR16(ptr, (u_now->tv_sec / 60) % 60);
|
U_NUM2STR16(ptr, (u_now->tv_sec / 60) % 60);
|
||||||
U_NUM2STR16(ptr+3,u_now->tv_sec % 60);
|
U_NUM2STR16(ptr+3,u_now->tv_sec % 60);
|
||||||
|
|
|
@ -1706,6 +1706,7 @@ static void usp_init_wi_auth()
|
||||||
file_RECOVERY = U_NEW(UFile(dir + U_STRING_FROM_CONSTANT("/wifi-recovery")));
|
file_RECOVERY = U_NEW(UFile(dir + U_STRING_FROM_CONSTANT("/wifi-recovery")));
|
||||||
file_UTILIZZO = U_NEW(UFile(dir + U_STRING_FROM_CONSTANT("/wifi-utilizzo")));
|
file_UTILIZZO = U_NEW(UFile(dir + U_STRING_FROM_CONSTANT("/wifi-utilizzo")));
|
||||||
|
|
||||||
|
UServer_Base::update_date =
|
||||||
UServer_Base::update_date1 = true;
|
UServer_Base::update_date1 = true;
|
||||||
|
|
||||||
(void) UServer_Base::addLog(file_LOG);
|
(void) UServer_Base::addLog(file_LOG);
|
||||||
|
|
|
@ -35,15 +35,11 @@ class UClientImage_Base;
|
||||||
class U_EXPORT ULog : public UFile {
|
class U_EXPORT ULog : public UFile {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef struct static_date {
|
typedef struct log_date {
|
||||||
struct timeval _timeval; // => u_now
|
|
||||||
char spinlock1[1];
|
|
||||||
char date1[17+1]; // 18/06/12 18:45:56
|
char date1[17+1]; // 18/06/12 18:45:56
|
||||||
char spinlock2[1];
|
|
||||||
char date2[26+1]; // 04/Jun/2012:18:18:37 +0200
|
char date2[26+1]; // 04/Jun/2012:18:18:37 +0200
|
||||||
char spinlock3[1];
|
|
||||||
char date3[6+29+2+12+2+19+1]; // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\nConnection: close\r\n
|
char date3[6+29+2+12+2+19+1]; // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\nConnection: close\r\n
|
||||||
} static_date;
|
} log_date;
|
||||||
|
|
||||||
typedef struct log_data {
|
typedef struct log_data {
|
||||||
uint32_t file_ptr;
|
uint32_t file_ptr;
|
||||||
|
@ -55,9 +51,13 @@ public:
|
||||||
} log_data;
|
} log_data;
|
||||||
|
|
||||||
static ULog* pthis;
|
static ULog* pthis;
|
||||||
|
static log_date date;
|
||||||
static const char* prefix;
|
static const char* prefix;
|
||||||
static struct iovec iov_vec[5];
|
static struct iovec iov_vec[5];
|
||||||
static static_date* ptr_static_date;
|
static log_date* ptr_shared_date;
|
||||||
|
#ifdef ENABLE_THREAD
|
||||||
|
static pthread_rwlock_t* prwlock;
|
||||||
|
#endif
|
||||||
|
|
||||||
// COSTRUTTORI
|
// COSTRUTTORI
|
||||||
|
|
||||||
|
@ -137,6 +137,8 @@ protected:
|
||||||
bool checkForLogRotateDataToWrite();
|
bool checkForLogRotateDataToWrite();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static long tv_sec_old_1, tv_sec_old_2, tv_sec_old_3;
|
||||||
|
|
||||||
void write(const struct iovec* iov, int n);
|
void write(const struct iovec* iov, int n);
|
||||||
|
|
||||||
#ifdef USE_LIBZ
|
#ifdef USE_LIBZ
|
||||||
|
@ -145,27 +147,13 @@ protected:
|
||||||
|
|
||||||
static void close();
|
static void close();
|
||||||
static void startup();
|
static void startup();
|
||||||
static void initStaticDate();
|
static void initDate();
|
||||||
static void _updateStaticDate(char* ptr, int which);
|
static void updateDate1();
|
||||||
|
static void updateDate2();
|
||||||
|
static void updateDate3();
|
||||||
static void logResponse(const UString& data, const char* name, const char* format, ...);
|
static void logResponse(const UString& data, const char* name, const char* format, ...);
|
||||||
static void log(const struct iovec* iov, const char* name, const char* type, int ncount, const char* msg, uint32_t msg_len, const char* format, ...);
|
static void log(const struct iovec* iov, const char* name, const char* type, int ncount, const char* msg, uint32_t msg_len, const char* format, ...);
|
||||||
|
|
||||||
static void updateStaticDate(char* ptr, int which)
|
|
||||||
{
|
|
||||||
U_TRACE(0, "ULog::updateStaticDate(%p,%d)", ptr, which)
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_POINTER(ptr)
|
|
||||||
U_INTERNAL_ASSERT_DIFFERS(ptr[0], '\0')
|
|
||||||
|
|
||||||
# ifdef ENABLE_THREAD
|
|
||||||
if (u_pthread_time == 0)
|
|
||||||
# endif
|
|
||||||
_updateStaticDate(ptr, which);
|
|
||||||
|
|
||||||
U_INTERNAL_DUMP("ptr_static_date->date1 = %.17S ptr_static_date->date2 = %.26S ptr_static_date->date3+6 = %.29S",
|
|
||||||
ptr_static_date->date1, ptr_static_date->date2, ptr_static_date->date3+6)
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int decode(const char* name, uint32_t len, bool bfacility) __pure U_NO_EXPORT;
|
static int decode(const char* name, uint32_t len, bool bfacility) __pure U_NO_EXPORT;
|
||||||
|
|
||||||
|
|
|
@ -268,40 +268,27 @@ public:
|
||||||
sem_t lock_user1;
|
sem_t lock_user1;
|
||||||
sem_t lock_user2;
|
sem_t lock_user2;
|
||||||
sem_t lock_rdb_server;
|
sem_t lock_rdb_server;
|
||||||
# ifdef USE_LIBSSL
|
|
||||||
sem_t lock_ssl_session;
|
|
||||||
# if defined(ENABLE_THREAD) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
|
||||||
sem_t lock_ocsp_staple;
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
sem_t lock_static_date;
|
|
||||||
sem_t lock_data_session;
|
sem_t lock_data_session;
|
||||||
sem_t lock_db_not_found;
|
sem_t lock_db_not_found;
|
||||||
char spinlock_user1[1];
|
char spinlock_user1[1];
|
||||||
char spinlock_user2[1];
|
char spinlock_user2[1];
|
||||||
char spinlock_rdb_server[1];
|
char spinlock_rdb_server[1];
|
||||||
|
char spinlock_data_session[1];
|
||||||
|
char spinlock_db_not_found[1];
|
||||||
# ifdef USE_LIBSSL
|
# ifdef USE_LIBSSL
|
||||||
|
sem_t lock_ssl_session;
|
||||||
char spinlock_ssl_session[1];
|
char spinlock_ssl_session[1];
|
||||||
# if defined(ENABLE_THREAD) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
# if defined(ENABLE_THREAD) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
||||||
|
sem_t lock_ocsp_staple;
|
||||||
char spinlock_ocsp_staple[1];
|
char spinlock_ocsp_staple[1];
|
||||||
# endif
|
# endif
|
||||||
# endif
|
|
||||||
char spinlock_static_date[1];
|
|
||||||
char spinlock_data_session[1];
|
|
||||||
char spinlock_db_not_found[1];
|
|
||||||
# ifdef ENABLE_THREAD
|
|
||||||
/* typedef struct static_date {
|
|
||||||
struct timeval _timeval; // => u_now
|
|
||||||
char spinlock1[1];
|
|
||||||
char date1[17+1]; // 18/06/12 18:45:56
|
|
||||||
char spinlock2[1];
|
|
||||||
char date2[26+1]; // 04/Jun/2012:18:18:37 +0200
|
|
||||||
char spinlock3[1];
|
|
||||||
char date3[6+29+2+12+2+19+1]; // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\nConnection: close\r\n
|
|
||||||
} static_date; */
|
|
||||||
ULog::static_date static_date;
|
|
||||||
# endif
|
# endif
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
|
# ifdef ENABLE_THREAD
|
||||||
|
pthread_rwlock_t rwlock;
|
||||||
|
struct timeval now_shared; // => u_now
|
||||||
|
ULog::log_date log_date_shared;
|
||||||
|
# endif
|
||||||
ULog::log_data log_data_shared;
|
ULog::log_data log_data_shared;
|
||||||
// -> maybe unnamed array of char for gzip compression (log rotate)
|
// -> maybe unnamed array of char for gzip compression (log rotate)
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
|
@ -316,33 +303,23 @@ public:
|
||||||
#define U_LOCK_USER1 &(UServer_Base::ptr_shared_data->lock_user1)
|
#define U_LOCK_USER1 &(UServer_Base::ptr_shared_data->lock_user1)
|
||||||
#define U_LOCK_USER2 &(UServer_Base::ptr_shared_data->lock_user2)
|
#define U_LOCK_USER2 &(UServer_Base::ptr_shared_data->lock_user2)
|
||||||
#define U_LOCK_RDB_SERVER &(UServer_Base::ptr_shared_data->lock_rdb_server)
|
#define U_LOCK_RDB_SERVER &(UServer_Base::ptr_shared_data->lock_rdb_server)
|
||||||
#define U_LOCK_STATIC_DATE &(UServer_Base::ptr_shared_data->lock_static_date)
|
|
||||||
#define U_LOCK_SSL_SESSION &(UServer_Base::ptr_shared_data->lock_ssl_session)
|
#define U_LOCK_SSL_SESSION &(UServer_Base::ptr_shared_data->lock_ssl_session)
|
||||||
#define U_LOCK_DATA_SESSION &(UServer_Base::ptr_shared_data->lock_data_session)
|
#define U_LOCK_DATA_SESSION &(UServer_Base::ptr_shared_data->lock_data_session)
|
||||||
#define U_LOCK_DB_NOT_FOUND &(UServer_Base::ptr_shared_data->lock_db_not_found)
|
#define U_LOCK_DB_NOT_FOUND &(UServer_Base::ptr_shared_data->lock_db_not_found)
|
||||||
#define U_SPINLOCK_USER1 UServer_Base::ptr_shared_data->spinlock_user1
|
#define U_SPINLOCK_USER1 UServer_Base::ptr_shared_data->spinlock_user1
|
||||||
#define U_SPINLOCK_USER2 UServer_Base::ptr_shared_data->spinlock_user2
|
#define U_SPINLOCK_USER2 UServer_Base::ptr_shared_data->spinlock_user2
|
||||||
#define U_SPINLOCK_RDB_SERVER UServer_Base::ptr_shared_data->spinlock_rdb_server
|
#define U_SPINLOCK_RDB_SERVER UServer_Base::ptr_shared_data->spinlock_rdb_server
|
||||||
#define U_SPINLOCK_STATIC_DATE UServer_Base::ptr_shared_data->spinlock_static_date
|
|
||||||
#define U_SPINLOCK_SSL_SESSION UServer_Base::ptr_shared_data->spinlock_ssl_session
|
#define U_SPINLOCK_SSL_SESSION UServer_Base::ptr_shared_data->spinlock_ssl_session
|
||||||
#define U_SPINLOCK_DATA_SESSION UServer_Base::ptr_shared_data->spinlock_data_session
|
#define U_SPINLOCK_DATA_SESSION UServer_Base::ptr_shared_data->spinlock_data_session
|
||||||
#define U_SPINLOCK_DB_NOT_FOUND UServer_Base::ptr_shared_data->spinlock_db_not_found
|
#define U_SPINLOCK_DB_NOT_FOUND UServer_Base::ptr_shared_data->spinlock_db_not_found
|
||||||
#define U_HTTP_DATE1_SPINLOCK UServer_Base::ptr_static_date->spinlock1
|
|
||||||
#define U_HTTP_DATE1 ((char*)&(UServer_Base::ptr_static_date->date1[0]))
|
|
||||||
#define U_HTTP_DATE2_SPINLOCK UServer_Base::ptr_static_date->spinlock2
|
|
||||||
#define U_HTTP_DATE2 ((char*)&(UServer_Base::ptr_static_date->date2[0]))
|
|
||||||
#define U_HTTP_DATE3_SPINLOCK UServer_Base::ptr_static_date->spinlock3
|
|
||||||
#define U_HTTP_DATE3 ((char*)&(UServer_Base::ptr_static_date->date3[6]))
|
|
||||||
#define U_LOG_DATA_SHARED &(UServer_Base::ptr_shared_data->log_data_shared)
|
|
||||||
|
|
||||||
static pid_t pid;
|
static pid_t pid;
|
||||||
static ULock* lock_user1;
|
static ULock* lock_user1;
|
||||||
static ULock* lock_user2;
|
static ULock* lock_user2;
|
||||||
static int preforked_num_kids; // keeping a pool of children and that they accept connections themselves
|
static int preforked_num_kids; // keeping a pool of children and that they accept connections themselves
|
||||||
static shared_data* ptr_shared_data;
|
static shared_data* ptr_shared_data;
|
||||||
static ULog::static_date* ptr_static_date;
|
|
||||||
static uint32_t shared_data_add, map_size;
|
static uint32_t shared_data_add, map_size;
|
||||||
static bool update_date1, update_date2, update_date3;
|
static bool update_date, update_date1, update_date2, update_date3;
|
||||||
|
|
||||||
static void setLockUser1()
|
static void setLockUser1()
|
||||||
{
|
{
|
||||||
|
|
|
@ -191,7 +191,7 @@ public:
|
||||||
U_RETURN(0);
|
U_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t remain(const char* ptr) const
|
ptrdiff_t remain(const char* ptr) const
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UStringRep::remain(%p)", ptr)
|
U_TRACE(0, "UStringRep::remain(%p)", ptr)
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ public:
|
||||||
bool equal(const UStringRep* rep) const { return equal(rep->str, rep->_length); }
|
bool equal(const UStringRep* rep) const { return equal(rep->str, rep->_length); }
|
||||||
__pure bool equal(const char* s, uint32_t n) const
|
__pure bool equal(const char* s, uint32_t n) const
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UStringRep::equal(%#.*S,%u)", n, s, n) // problem with sanitize address
|
U_TRACE(0, "UStringRep::equal(%#.*S,%u)", n, s, n)
|
||||||
|
|
||||||
U_CHECK_MEMORY
|
U_CHECK_MEMORY
|
||||||
|
|
||||||
|
@ -1109,7 +1109,7 @@ public:
|
||||||
|
|
||||||
explicit UString(uint32_t n)
|
explicit UString(uint32_t n)
|
||||||
{
|
{
|
||||||
U_TRACE_REGISTER_OBJECT_WITHOUT_CHECK_MEMORY(0, UString, "%u", n) // problem with sanitize address
|
U_TRACE_REGISTER_OBJECT_WITHOUT_CHECK_MEMORY(0, UString, "%u", n)
|
||||||
|
|
||||||
rep = UStringRep::create(0U, n, 0);
|
rep = UStringRep::create(0U, n, 0);
|
||||||
|
|
||||||
|
@ -1379,7 +1379,7 @@ public:
|
||||||
|
|
||||||
UString& append(const char* s, uint32_t n)
|
UString& append(const char* s, uint32_t n)
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UString::append(%.*S,%u)", n, s, n) // problem with sanitize address
|
U_TRACE(0, "UString::append(%.*S,%u)", n, s, n)
|
||||||
|
|
||||||
if (n)
|
if (n)
|
||||||
{
|
{
|
||||||
|
@ -1656,7 +1656,7 @@ public:
|
||||||
char c_char(uint32_t pos) const { return rep->at(pos); }
|
char c_char(uint32_t pos) const { return rep->at(pos); }
|
||||||
char* c_pointer(uint32_t pos) const { return (char*)rep->c_pointer(pos); }
|
char* c_pointer(uint32_t pos) const { return (char*)rep->c_pointer(pos); }
|
||||||
|
|
||||||
uint32_t remain( const char* ptr) const { return rep->remain(ptr); }
|
ptrdiff_t remain( const char* ptr) const { return rep->remain(ptr); }
|
||||||
__pure uint32_t distance(const char* ptr) const { return rep->distance(ptr); }
|
__pure uint32_t distance(const char* ptr) const { return rep->distance(ptr); }
|
||||||
|
|
||||||
void setFromInode(uint64_t* p) { (void) replace((const char*)p, sizeof(uint64_t)); }
|
void setFromInode(uint64_t* p) { (void) replace((const char*)p, sizeof(uint64_t)); }
|
||||||
|
|
|
@ -69,6 +69,22 @@ public:
|
||||||
(void) U_SYSCALL(pthread_mutex_unlock, "%p", mutex);
|
(void) U_SYSCALL(pthread_mutex_unlock, "%p", mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool initRwLock(pthread_rwlock_t* rwlock)
|
||||||
|
{
|
||||||
|
U_TRACE(1, "UThread::initRwLock(%p)", rwlock)
|
||||||
|
|
||||||
|
pthread_rwlockattr_t rwlockattr;
|
||||||
|
|
||||||
|
if (U_SYSCALL(pthread_rwlockattr_init, "%p", &rwlockattr) != 0 ||
|
||||||
|
U_SYSCALL(pthread_rwlockattr_setpshared, "%p,%d", &rwlockattr, PTHREAD_PROCESS_SHARED) != 0 ||
|
||||||
|
U_SYSCALL(pthread_rwlock_init, "%p,%p", rwlock, &rwlockattr) != 0)
|
||||||
|
{
|
||||||
|
U_RETURN(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
U_RETURN(true);
|
||||||
|
}
|
||||||
|
|
||||||
static bool initIPC(pthread_mutex_t* mutex, pthread_cond_t* cond);
|
static bool initIPC(pthread_mutex_t* mutex, pthread_cond_t* cond);
|
||||||
static void doIPC(pthread_mutex_t* mutex, pthread_cond_t* cond, vPF function, bool wait);
|
static void doIPC(pthread_mutex_t* mutex, pthread_cond_t* cond, vPF function, bool wait);
|
||||||
|
|
||||||
|
@ -179,7 +195,14 @@ protected:
|
||||||
|
|
||||||
static void sigHandler(int signo);
|
static void sigHandler(int signo);
|
||||||
static void execHandler(UThread* th);
|
static void execHandler(UThread* th);
|
||||||
static void threadCleanup(UThread* th);
|
|
||||||
|
static void threadCleanup(UThread* th)
|
||||||
|
{
|
||||||
|
U_TRACE(0, "UThread::threadCleanup(%p)", th)
|
||||||
|
|
||||||
|
th->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// A special global function, getThread(), is provided to identify the thread object that represents the current
|
// A special global function, getThread(), is provided to identify the thread object that represents the current
|
||||||
// execution context you are running under. This is sometimes needed to deliver signals to the correct thread
|
// execution context you are running under. This is sometimes needed to deliver signals to the correct thread
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// source: https://github.com/tatsuhiro-t/nghttp2/ @ 76b3ba2, under the following license
|
// source: https://github.com/tatsuhiro-t/nghttp2/ @ 76b3ba2, under the following license
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* nghttp2 - HTTP/2 C Library
|
* nghttp2 - HTTP/2 C Library
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013 Tatsuhiro Tsujikawa
|
* Copyright (c) 2013 Tatsuhiro Tsujikawa
|
||||||
|
|
|
@ -17,11 +17,6 @@
|
||||||
#include <ulib/net/ipaddress.h>
|
#include <ulib/net/ipaddress.h>
|
||||||
#include <ulib/container/hash_map.h>
|
#include <ulib/container/hash_map.h>
|
||||||
|
|
||||||
#define HTTP2_CONNECTION_UPGRADE \
|
|
||||||
"HTTP/1.1 101 Switching Protocols\r\n" \
|
|
||||||
"Connection: Upgrade\r\n" \
|
|
||||||
"Upgrade: h2c\r\n\r\n"
|
|
||||||
|
|
||||||
#define HTTP2_CONNECTION_PREFACE "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" // (24 bytes)
|
#define HTTP2_CONNECTION_PREFACE "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" // (24 bytes)
|
||||||
|
|
||||||
class UHTTP;
|
class UHTTP;
|
||||||
|
@ -119,14 +114,11 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
enum StreamState {
|
enum StreamState {
|
||||||
STREAM_STATE_RECV_PSUEDO_HEADERS = 0x001,
|
STREAM_STATE_IDLE = 0x000,
|
||||||
STREAM_STATE_RECV_HEADERS = 0x002,
|
STREAM_STATE_RESERVED = 0x001,
|
||||||
STREAM_STATE_RECV_BODY = 0x004,
|
STREAM_STATE_OPEN = 0x002,
|
||||||
STREAM_STATE_REQ_PENDING = 0x008,
|
STREAM_STATE_HALF_CLOSED = 0x004,
|
||||||
STREAM_STATE_SEND_HEADERS = 0x010,
|
STREAM_STATE_CLOSED = 0x008
|
||||||
STREAM_STATE_SEND_BODY = 0x020,
|
|
||||||
STREAM_STATE_END_STREAM = 0x040,
|
|
||||||
STREAM_STATE_HALF_CLOSED = 0x080
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ConnectionState {
|
enum ConnectionState {
|
||||||
|
@ -146,22 +138,18 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Connection {
|
struct Connection {
|
||||||
// headers
|
ConnectionState state; // state
|
||||||
UHashMap<UString>* itable;
|
Settings peer_settings; // settings
|
||||||
UHashMap<UString>* otable;
|
UHashMap<UString> itable; // headers request
|
||||||
// streams
|
// internal
|
||||||
Stream open_streams[100];
|
uint32_t input_window;
|
||||||
// settings
|
uint32_t output_window;
|
||||||
Settings peer_settings;
|
int32_t hpack_max_capacity; // the value set by SETTINGS_HEADER_TABLE_SIZE
|
||||||
// streams
|
// streams
|
||||||
int max_open_stream_id;
|
int max_open_stream_id;
|
||||||
uint32_t num_responding_streams;
|
uint32_t num_responding_streams;
|
||||||
uint32_t max_processed_stream_id;
|
uint32_t max_processed_stream_id;
|
||||||
// internal
|
Stream streams[100];
|
||||||
ConnectionState state;
|
|
||||||
uint32_t input_window;
|
|
||||||
uint32_t output_window;
|
|
||||||
int32_t hpack_max_capacity; // the value set by SETTINGS_HEADER_TABLE_SIZE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HpackHeaderTableEntry {
|
struct HpackHeaderTableEntry {
|
||||||
|
@ -238,32 +226,25 @@ protected:
|
||||||
|
|
||||||
static int nerror;
|
static int nerror;
|
||||||
static Stream* pStream;
|
static Stream* pStream;
|
||||||
|
static bool settings_ack;
|
||||||
static FrameHeader frame;
|
static FrameHeader frame;
|
||||||
static void* pConnectionEnd;
|
static void* pConnectionEnd;
|
||||||
static Connection* pConnection;
|
static Connection* pConnection;
|
||||||
|
static const Settings settings;
|
||||||
static const char* upgrade_settings;
|
static const char* upgrade_settings;
|
||||||
static const Settings SETTINGS_HOST;
|
|
||||||
static const Settings SETTINGS_DEFAULT;
|
|
||||||
|
|
||||||
static uint32_t hash_static_table[61];
|
static uint32_t hash_static_table[61];
|
||||||
static HpackHeaderTableEntry hpack_static_table[61];
|
static HpackHeaderTableEntry hpack_static_table[61];
|
||||||
|
|
||||||
// SERVICES
|
// SERVICES
|
||||||
|
|
||||||
static void readFrame();
|
static void readFrame();
|
||||||
static void decodeFrame();
|
static void sendError();
|
||||||
|
|
||||||
static void manageData();
|
static void manageData();
|
||||||
static void managePriority();
|
static void manageHeaders();
|
||||||
static void manageWindowUpdate();
|
static bool readBodyRequest();
|
||||||
|
|
||||||
static void setStream();
|
|
||||||
static void setConnection();
|
|
||||||
static void sendError(int err);
|
|
||||||
static void resetReadBuffer(uint32_t length);
|
|
||||||
static bool updateSetting(const char* ptr, uint32_t len);
|
static bool updateSetting(const char* ptr, uint32_t len);
|
||||||
static void decodeHeaders(const char* ptr, const char* endptr);
|
static void decodeHeaders(const char* ptr, const char* endptr);
|
||||||
static bool manageHeaders(const char** ptr, const char** endptr);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static const char* getFrameTypeDescription();
|
static const char* getFrameTypeDescription();
|
||||||
|
@ -317,8 +298,11 @@ protected:
|
||||||
static const HuffSym huff_sym_table[];
|
static const HuffSym huff_sym_table[];
|
||||||
static const HuffDecode huff_decode_table[][16];
|
static const HuffDecode huff_decode_table[][16];
|
||||||
|
|
||||||
static uint32_t hpackDecodeInt( const unsigned char* src, const unsigned char* src_end, int32_t* pvalue, uint8_t prefix_max);
|
static uint32_t hpackDecodeString(const unsigned char* src, const unsigned char* src_end, UString* pvalue);
|
||||||
static uint32_t hpackDecodeString(const unsigned char* src, const unsigned char* src_end, UString* pvalue);
|
static uint32_t hpackEncodeString( unsigned char* dst, const char* src, uint32_t len);
|
||||||
|
|
||||||
|
static unsigned char* hpackEncodeInt( unsigned char* dst, uint32_t value, uint8_t prefix_max);
|
||||||
|
static uint32_t hpackDecodeInt( const unsigned char* src, const unsigned char* src_end, int32_t* pvalue, uint8_t prefix_max);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class UHTTP;
|
friend class UHTTP;
|
||||||
|
|
|
@ -30,10 +30,6 @@ typedef int (*verify_cb)(int,X509_STORE_CTX*); /* error callback */
|
||||||
# define U_STORE_FLAGS (X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL)
|
# define U_STORE_FLAGS (X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_LIBUUID
|
|
||||||
# include <uuid/uuid.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef FNM_CASEFOLD
|
#ifndef FNM_CASEFOLD
|
||||||
#define FNM_CASEFOLD FNM_IGNORECASE
|
#define FNM_CASEFOLD FNM_IGNORECASE
|
||||||
#endif
|
#endif
|
||||||
|
@ -44,7 +40,7 @@ typedef int (*verify_cb)(int,X509_STORE_CTX*); /* error callback */
|
||||||
|
|
||||||
struct U_EXPORT UServices {
|
struct U_EXPORT UServices {
|
||||||
|
|
||||||
static bool isSetuidRoot(); // UID handling: are we setuid-root...
|
static bool isSetuidRoot(); // UID handling: check if we are setuid-root
|
||||||
static void closeStdInputOutput(); // move stdin and stdout to /dev/null
|
static void closeStdInputOutput(); // move stdin and stdout to /dev/null
|
||||||
static int getDevNull(const char* file); // return open(/dev/null)
|
static int getDevNull(const char* file); // return open(/dev/null)
|
||||||
|
|
||||||
|
@ -171,22 +167,18 @@ struct U_EXPORT UServices {
|
||||||
static void generateDigest(int alg, uint32_t keylen, const UString& data, UString& output, int base64 = 0)
|
static void generateDigest(int alg, uint32_t keylen, const UString& data, UString& output, int base64 = 0)
|
||||||
{ generateDigest(alg, keylen, (unsigned char*)U_STRING_TO_PARAM(data), output, base64); }
|
{ generateDigest(alg, keylen, (unsigned char*)U_STRING_TO_PARAM(data), output, base64); }
|
||||||
|
|
||||||
#ifdef USE_LIBUUID
|
|
||||||
// creat a new unique UUID value - 16 bytes (128 bits) long
|
// creat a new unique UUID value - 16 bytes (128 bits) long
|
||||||
// return from the binary representation a 36-byte string (plus tailing '\0') of the form 1b4e28ba-2fa1-11d2-883f-0016d3cca427
|
// return from the binary representation a 36-byte string (plus tailing '\0') of the form 1b4e28ba-2fa1-11d2-883f-0016d3cca427
|
||||||
|
|
||||||
static uuid_t uuid; // typedef unsigned char uuid_t[16];
|
static UString getUUID();
|
||||||
|
static uint64_t getUniqUID(); // creat a new unique UUID value - 8 bytes (64 bits) long
|
||||||
static UString getUUID();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static uint64_t getUniqUID();
|
|
||||||
|
|
||||||
#ifdef USE_LIBSSL
|
#ifdef USE_LIBSSL
|
||||||
/* setup OPENSSL standard certificate directory. The X509_STORE holds the tables etc for verification stuff.
|
/**
|
||||||
A X509_STORE_CTX is used while validating a single certificate. The X509_STORE has X509_LOOKUPs for looking
|
* setup OPENSSL standard certificate directory. The X509_STORE holds the tables etc for verification stuff.
|
||||||
up certs. The X509_STORE then calls a function to actually verify the certificate chain
|
* A X509_STORE_CTX is used while validating a single certificate. The X509_STORE has X509_LOOKUPs for looking
|
||||||
*/
|
* up certs. The X509_STORE then calls a function to actually verify the certificate chain
|
||||||
|
*/
|
||||||
|
|
||||||
static UString* CApath;
|
static UString* CApath;
|
||||||
static X509_STORE* store;
|
static X509_STORE* store;
|
||||||
|
@ -227,8 +219,8 @@ struct U_EXPORT UServices {
|
||||||
* passwd is the corresponsding password for the private key
|
* passwd is the corresponsding password for the private key
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static UString getSignatureValue(int alg, const UString& data, const UString& pkey, const UString& passwd, int base64, ENGINE* e = 0);
|
|
||||||
static bool verifySignature( int alg, const UString& data, const UString& signature, const UString& pkey, ENGINE* e = 0);
|
static bool verifySignature( int alg, const UString& data, const UString& signature, const UString& pkey, ENGINE* e = 0);
|
||||||
|
static UString getSignatureValue(int alg, const UString& data, const UString& pkey, const UString& passwd, int base64, ENGINE* e = 0);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -271,6 +271,7 @@ public:
|
||||||
|
|
||||||
static int handlerREAD();
|
static int handlerREAD();
|
||||||
static bool handlerCache();
|
static bool handlerCache();
|
||||||
|
static int manageRequest();
|
||||||
static int processRequest();
|
static int processRequest();
|
||||||
static void initDbNotFound();
|
static void initDbNotFound();
|
||||||
static void setEndRequestProcessing();
|
static void setEndRequestProcessing();
|
||||||
|
|
|
@ -361,7 +361,10 @@ AC_DEFUN([AC_CHECK_PACKAGE],[
|
||||||
echo "${T_MD}libexpat found in $expatdir${T_ME}"
|
echo "${T_MD}libexpat found in $expatdir${T_ME}"
|
||||||
USE_LIBEXPAT=yes
|
USE_LIBEXPAT=yes
|
||||||
AC_DEFINE(USE_LIBEXPAT, 1, [Define if enable libexpat support])
|
AC_DEFINE(USE_LIBEXPAT, 1, [Define if enable libexpat support])
|
||||||
expat_version=$(strings $expatdir/lib*/libexpat.* 2>/dev/null | grep "^expat_[[0-9]]" | head -n1 | cut -d'_' -f2)
|
expat_version=$(strings $expatdir/lib*/libexpat.* 2>/dev/null | grep "^expat_[[0-9]]*" | head -n1 | cut -d'_' -f2)
|
||||||
|
if test -z "${expat_version}"; then
|
||||||
|
expat_version=$(ls $expatdir/libexpat.so.*.* 2>/dev/null | head -n 1 | awk -F'.so.' '{n=2; print $n}' 2>/dev/null)
|
||||||
|
fi
|
||||||
if test -z "${expat_version}"; then
|
if test -z "${expat_version}"; then
|
||||||
expat_version="unknown"
|
expat_version="unknown"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -58,13 +58,14 @@ void u_debug_at_exit(void);
|
||||||
#ifdef HAVE_ENDIAN_H
|
#ifdef HAVE_ENDIAN_H
|
||||||
# include <endian.h>
|
# include <endian.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SYSCALL_H
|
||||||
|
# include <sys/syscall.h>
|
||||||
|
#endif
|
||||||
#ifndef _MSWINDOWS_
|
#ifndef _MSWINDOWS_
|
||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
# include <sys/uio.h>
|
# include <sys/uio.h>
|
||||||
# include <sys/utsname.h>
|
# include <sys/utsname.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For TIOCGWINSZ and friends: */
|
/* For TIOCGWINSZ and friends: */
|
||||||
#ifdef HAVE_SYS_IOCTL_H
|
#ifdef HAVE_SYS_IOCTL_H
|
||||||
# include <sys/ioctl.h>
|
# include <sys/ioctl.h>
|
||||||
|
@ -386,14 +387,29 @@ bool u_setStartTime(void)
|
||||||
|
|
||||||
(void) gettimeofday(u_now, 0);
|
(void) gettimeofday(u_now, 0);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* The "hash seed" is a feature to perturb the results to avoid "algorithmic complexity attacks"
|
* The "hash seed" is a feature to perturb the results to avoid "algorithmic complexity attacks"
|
||||||
*
|
*
|
||||||
* http://lwn.net/Articles/474365
|
* http://lwn.net/Articles/474365
|
||||||
*/
|
*/
|
||||||
|
|
||||||
u_seed_hash = u_random((uint32_t)u_pid ^ (uint32_t)u_now->tv_usec);
|
u_seed_hash = u_random((uint32_t)u_pid ^ (uint32_t)u_now->tv_usec);
|
||||||
|
|
||||||
|
#ifdef SYS_getrandom
|
||||||
|
if (syscall(SYS_getrandom, &u_seed_hash, sizeof(u_seed_hash), 0) == sizeof(u_seed_hash)) u_seed_hash |= 1;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
int fd = open("/dev/urandom", O_CLOEXEC | O_RDONLY);
|
||||||
|
if (fd < 0) fd = open("/dev/random", O_CLOEXEC | O_RDONLY);
|
||||||
|
if (fd > 0)
|
||||||
|
{
|
||||||
|
if (read(fd, &u_seed_hash, sizeof(u_seed_hash)) == sizeof(u_seed_hash)) u_seed_hash |= 1;
|
||||||
|
|
||||||
|
(void) close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* seed the random generator */
|
/* seed the random generator */
|
||||||
|
|
||||||
u_set_seed_random(u_seed_hash >> 16, u_seed_hash % 4294967296);
|
u_set_seed_random(u_seed_hash >> 16, u_seed_hash % 4294967296);
|
||||||
|
|
|
@ -582,7 +582,7 @@ __pure uint32_t u_findEndHeader1(const char* restrict str, uint32_t n)
|
||||||
|
|
||||||
/* find sequence of U_LF2 or U_CRLF2 */
|
/* find sequence of U_LF2 or U_CRLF2 */
|
||||||
|
|
||||||
uint32_t u_findEndHeader(const char* restrict str, uint32_t n)
|
__pure uint32_t u_findEndHeader(const char* restrict str, uint32_t n)
|
||||||
{
|
{
|
||||||
const char* restrict p;
|
const char* restrict p;
|
||||||
const char* restrict end = str + n;
|
const char* restrict end = str + n;
|
||||||
|
|
|
@ -282,7 +282,7 @@ __pure uint32_t UVector<UString>::find(const UString& str, bool ignore_case)
|
||||||
|
|
||||||
// Check equality with string at pos
|
// Check equality with string at pos
|
||||||
|
|
||||||
bool UVector<UString>::isEqual(uint32_t pos, const UString& str, bool ignore_case)
|
__pure bool UVector<UString>::isEqual(uint32_t pos, const UString& str, bool ignore_case)
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UVector<UString>::isEqual(%u,%V,%b)", pos, str.rep, ignore_case)
|
U_TRACE(0, "UVector<UString>::isEqual(%u,%V,%b)", pos, str.rep, ignore_case)
|
||||||
|
|
||||||
|
|
332
src/ulib/log.cpp
332
src/ulib/log.cpp
|
@ -34,18 +34,26 @@
|
||||||
#define U_MARK_END "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" // 24
|
#define U_MARK_END "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" // 24
|
||||||
#define U_FMT_START_STOP "*** %s %N (%ubit, pid %P) [%U@%H] ***"
|
#define U_FMT_START_STOP "*** %s %N (%ubit, pid %P) [%U@%H] ***"
|
||||||
|
|
||||||
ULog* ULog::pthis;
|
long ULog::tv_sec_old_1;
|
||||||
const char* ULog::prefix;
|
long ULog::tv_sec_old_2;
|
||||||
struct iovec ULog::iov_vec[5];
|
long ULog::tv_sec_old_3;
|
||||||
ULog::static_date* ULog::ptr_static_date;
|
ULog* ULog::pthis;
|
||||||
|
const char* ULog::prefix;
|
||||||
|
struct iovec ULog::iov_vec[5];
|
||||||
|
ULog::log_date ULog::date;
|
||||||
|
ULog::log_date* ULog::ptr_shared_date;
|
||||||
|
#ifdef ENABLE_THREAD
|
||||||
|
pthread_rwlock_t* ULog::prwlock;
|
||||||
|
#endif
|
||||||
|
|
||||||
ULog::ULog(const UString& path, uint32_t _size, const char* dir_log_gz) : UFile(path, 0)
|
ULog::ULog(const UString& path, uint32_t _size, const char* dir_log_gz) : UFile(path, 0)
|
||||||
{
|
{
|
||||||
U_TRACE_REGISTER_OBJECT(0, ULog, "%V,%u,%S", path.rep, _size, dir_log_gz)
|
U_TRACE_REGISTER_OBJECT(0, ULog, "%V,%u,%S", path.rep, _size, dir_log_gz)
|
||||||
|
|
||||||
lock = 0;
|
lock = 0;
|
||||||
log_file_sz = log_gzip_sz = 0;
|
|
||||||
ptr_log_data = 0;
|
ptr_log_data = 0;
|
||||||
|
log_file_sz =
|
||||||
|
log_gzip_sz = 0;
|
||||||
|
|
||||||
U_Log_start_stop_msg(this) = false;
|
U_Log_start_stop_msg(this) = false;
|
||||||
|
|
||||||
|
@ -74,16 +82,16 @@ ULog::ULog(const UString& path, uint32_t _size, const char* dir_log_gz) : UFile(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
typedef struct log_data {
|
* typedef struct log_data {
|
||||||
uint32_t file_ptr;
|
* uint32_t file_ptr;
|
||||||
uint32_t file_page;
|
* uint32_t file_page;
|
||||||
uint32_t gzip_len;
|
* uint32_t gzip_len;
|
||||||
sem_t lock_shared;
|
* sem_t lock_shared;
|
||||||
char spinlock_shared[1];
|
* char spinlock_shared[1];
|
||||||
// --------------> maybe unnamed array of char for gzip compression...
|
* // --------------> maybe unnamed array of char for gzip compression...
|
||||||
} log_data;
|
* } log_data;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ptr_log_data = U_MALLOC_TYPE(log_data);
|
ptr_log_data = U_MALLOC_TYPE(log_data);
|
||||||
|
|
||||||
|
@ -186,38 +194,30 @@ ULog::~ULog()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ULog::initStaticDate()
|
void ULog::initDate()
|
||||||
{
|
{
|
||||||
U_TRACE(1, "ULog::initStaticDate()")
|
U_TRACE(1, "ULog::initDate()")
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(ptr_static_date, 0)
|
|
||||||
|
|
||||||
ptr_static_date = U_MALLOC_TYPE(static_date);
|
|
||||||
|
|
||||||
(void) U_SYSCALL(memset, "%p,%d,%u", ptr_static_date, 0, sizeof(static_date));
|
|
||||||
|
|
||||||
u_now = &(ptr_static_date->_timeval);
|
|
||||||
|
|
||||||
iov_vec[0].iov_len = 17;
|
iov_vec[0].iov_len = 17;
|
||||||
iov_vec[1].iov_len =
|
iov_vec[1].iov_len =
|
||||||
iov_vec[4].iov_len = 1;
|
iov_vec[4].iov_len = 1;
|
||||||
iov_vec[0].iov_base = (caddr_t) ptr_static_date->date1;
|
iov_vec[0].iov_base = (caddr_t)date.date1;
|
||||||
iov_vec[1].iov_base = (caddr_t) " ";
|
iov_vec[1].iov_base = (caddr_t)" ";
|
||||||
iov_vec[2].iov_base = (caddr_t) u_buffer;
|
iov_vec[2].iov_base = (caddr_t)u_buffer;
|
||||||
iov_vec[4].iov_base = (caddr_t) U_LF;
|
iov_vec[4].iov_base = (caddr_t)U_LF;
|
||||||
|
|
||||||
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
||||||
|
|
||||||
(void) u_strftime2(ptr_static_date->date1, 17, "%d/%m/%y %T", u_now->tv_sec + u_now_adjust);
|
(void) u_strftime2(date.date1, 17, "%d/%m/%y %T", u_now->tv_sec + u_now_adjust);
|
||||||
(void) u_strftime2(ptr_static_date->date2, 26, "%d/%b/%Y:%T %z", u_now->tv_sec + u_now_adjust);
|
(void) u_strftime2(date.date2, 26, "%d/%b/%Y:%T %z", u_now->tv_sec + u_now_adjust);
|
||||||
(void) u_strftime2(ptr_static_date->date3, 6+29+2+12+2+17+2, "Date: %a, %d %b %Y %T GMT\r\nServer: ULib\r\nConnection: close\r\n", u_now->tv_sec);
|
(void) u_strftime2(date.date3, 6+29+2+12+2+17+2, "Date: %a, %d %b %Y %T GMT\r\nServer: ULib\r\nConnection: close\r\n", u_now->tv_sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ULog::startup()
|
void ULog::startup()
|
||||||
{
|
{
|
||||||
U_TRACE(1, "ULog::startup()")
|
U_TRACE(1, "ULog::startup()")
|
||||||
|
|
||||||
initStaticDate();
|
initDate();
|
||||||
|
|
||||||
log(U_FMT_START_STOP, "STARTUP", sizeof(void*) * 8);
|
log(U_FMT_START_STOP, "STARTUP", sizeof(void*) * 8);
|
||||||
|
|
||||||
|
@ -267,101 +267,233 @@ void ULog::setPrefix(const char* _prefix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ULog::_updateStaticDate(char* ptr, int which)
|
void ULog::updateDate1()
|
||||||
{
|
{
|
||||||
U_TRACE(1, "ULog::_updateStaticDate(%p,%d)", ptr, which)
|
U_TRACE(1, "ULog::updateDate1()")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 18/06/12 18:45:56
|
||||||
|
* 012345678901234567890123456789
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ENABLE_THREAD
|
||||||
|
if (u_pthread_time)
|
||||||
|
{
|
||||||
|
# if defined(U_LOG_ENABLE) && defined(USE_LIBZ)
|
||||||
|
(void) U_SYSCALL(pthread_rwlock_rdlock, "%p", prwlock);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (tv_sec_old_1 != u_now->tv_sec)
|
||||||
|
{
|
||||||
|
long tv_sec = u_now->tv_sec;
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("tv_sec_old_1 = %lu u_now->tv_sec = %lu", tv_sec_old_1, tv_sec)
|
||||||
|
|
||||||
|
if ((tv_sec - tv_sec_old_1) != 1 ||
|
||||||
|
(tv_sec % U_ONE_HOUR_IN_SECOND) == 0)
|
||||||
|
{
|
||||||
|
tv_sec_old_1 = tv_sec;
|
||||||
|
|
||||||
|
U_MEMCPY(date.date1, ptr_shared_date->date1, 17);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++tv_sec_old_1;
|
||||||
|
|
||||||
|
u_put_unalignedp16(date.date1+12, U_MULTICHAR_CONSTANT16(ptr_shared_date->date1[12],ptr_shared_date->date1[13]));
|
||||||
|
u_put_unalignedp16(date.date1+12+3,U_MULTICHAR_CONSTANT16(ptr_shared_date->date1[15],ptr_shared_date->date1[16]));
|
||||||
|
}
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(tv_sec, tv_sec_old_1)
|
||||||
|
}
|
||||||
|
|
||||||
|
# if defined(U_LOG_ENABLE) && defined(USE_LIBZ)
|
||||||
|
(void) U_SYSCALL(pthread_rwlock_unlock, "%p", prwlock);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
U_INTERNAL_ASSERT_EQUALS(u_pthread_time, 0)
|
U_INTERNAL_ASSERT_EQUALS(u_pthread_time, 0)
|
||||||
|
|
||||||
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
||||||
|
|
||||||
bool bchange = ((u_now->tv_sec % U_ONE_HOUR_IN_SECOND) == 0);
|
if (tv_sec_old_1 != u_now->tv_sec)
|
||||||
|
|
||||||
if (which == 1)
|
|
||||||
{
|
{
|
||||||
static long tv_sec_old_1;
|
long tv_sec = u_now->tv_sec;
|
||||||
|
|
||||||
/**
|
U_INTERNAL_DUMP("tv_sec_old_1 = %lu u_now->tv_sec = %lu", tv_sec_old_1, tv_sec)
|
||||||
* 18/06/12 18:45:56
|
|
||||||
* 012345678901234567890123456789
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (tv_sec_old_1 == u_now->tv_sec) return;
|
if ((tv_sec - tv_sec_old_1) != 1 ||
|
||||||
|
(tv_sec % U_ONE_HOUR_IN_SECOND) == 0)
|
||||||
U_INTERNAL_ASSERT_MINOR(tv_sec_old_1, u_now->tv_sec)
|
|
||||||
|
|
||||||
if (bchange ||
|
|
||||||
(u_now->tv_sec - tv_sec_old_1) != 1)
|
|
||||||
{
|
{
|
||||||
(void) u_strftime2(ptr, 17, "%d/%m/%y %T", (tv_sec_old_1 = u_now->tv_sec) + u_now_adjust);
|
(void) u_strftime2(date.date1, 17, "%d/%m/%y %T", (tv_sec_old_1 = tv_sec) + u_now_adjust);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
++tv_sec_old_1;
|
++tv_sec_old_1;
|
||||||
|
|
||||||
UTimeDate::updateTime(ptr+12);
|
UTimeDate::updateTime(date.date1+12);
|
||||||
}
|
}
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(u_now->tv_sec, tv_sec_old_1)
|
U_INTERNAL_ASSERT_EQUALS(tv_sec, tv_sec_old_1)
|
||||||
}
|
}
|
||||||
else if (which == 3)
|
}
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("date.date1 = %.17S", date.date1)
|
||||||
|
}
|
||||||
|
|
||||||
|
void ULog::updateDate2()
|
||||||
|
{
|
||||||
|
U_TRACE(1, "ULog::updateDate2()")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 04/Jun/2012:18:18:37 +0200
|
||||||
|
* 012345678901234567890123456789
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ENABLE_THREAD
|
||||||
|
if (u_pthread_time)
|
||||||
{
|
{
|
||||||
static long tv_sec_old_3;
|
# if defined(U_LOG_ENABLE) && defined(USE_LIBZ)
|
||||||
|
(void) U_SYSCALL(pthread_rwlock_rdlock, "%p", prwlock);
|
||||||
|
# endif
|
||||||
|
|
||||||
/**
|
if (tv_sec_old_2 != u_now->tv_sec)
|
||||||
* Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\n
|
|
||||||
* 0123456789012345678901234567890123456789
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (tv_sec_old_3 == u_now->tv_sec) return;
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_MINOR(tv_sec_old_3, u_now->tv_sec)
|
|
||||||
|
|
||||||
if (bchange ||
|
|
||||||
(u_now->tv_sec - tv_sec_old_3) != 1)
|
|
||||||
{
|
{
|
||||||
(void) u_strftime2(ptr, 29-4, "%a, %d %b %Y %T", (tv_sec_old_3 = u_now->tv_sec)); // GMT can't change...
|
long tv_sec = u_now->tv_sec;
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("tv_sec_old_2 = %lu u_now->tv_sec = %lu", tv_sec_old_2, tv_sec)
|
||||||
|
|
||||||
|
if ((tv_sec - tv_sec_old_2) != 1 ||
|
||||||
|
(tv_sec % U_ONE_HOUR_IN_SECOND) == 0)
|
||||||
|
{
|
||||||
|
tv_sec_old_2 = tv_sec;
|
||||||
|
|
||||||
|
U_MEMCPY(date.date2, ptr_shared_date->date2, 26);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++tv_sec_old_2;
|
||||||
|
|
||||||
|
u_put_unalignedp16(date.date2+15, U_MULTICHAR_CONSTANT16(ptr_shared_date->date2[15],ptr_shared_date->date2[16]));
|
||||||
|
u_put_unalignedp16(date.date2+15+3,U_MULTICHAR_CONSTANT16(ptr_shared_date->date2[18],ptr_shared_date->date2[19]));
|
||||||
|
}
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(tv_sec, tv_sec_old_2)
|
||||||
|
}
|
||||||
|
|
||||||
|
# if defined(U_LOG_ENABLE) && defined(USE_LIBZ)
|
||||||
|
(void) U_SYSCALL(pthread_rwlock_unlock, "%p", prwlock);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(u_pthread_time, 0)
|
||||||
|
|
||||||
|
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
||||||
|
|
||||||
|
if (tv_sec_old_2 != u_now->tv_sec)
|
||||||
|
{
|
||||||
|
long tv_sec = u_now->tv_sec;
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("tv_sec_old_2 = %lu u_now->tv_sec = %lu", tv_sec_old_2, tv_sec)
|
||||||
|
|
||||||
|
if ((tv_sec - tv_sec_old_2) != 1 ||
|
||||||
|
(tv_sec % U_ONE_HOUR_IN_SECOND) == 0)
|
||||||
|
{
|
||||||
|
(void) u_strftime2(date.date2, 26-6, "%d/%b/%Y:%T", (tv_sec_old_2 = tv_sec) + u_now_adjust);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++tv_sec_old_2;
|
||||||
|
|
||||||
|
UTimeDate::updateTime(date.date2+15);
|
||||||
|
}
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(tv_sec, tv_sec_old_2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("date.date2 = %.26S", date.date2)
|
||||||
|
}
|
||||||
|
|
||||||
|
void ULog::updateDate3()
|
||||||
|
{
|
||||||
|
U_TRACE(1, "ULog::updateDate3()")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\n
|
||||||
|
* 0123456789012345678901234567890123
|
||||||
|
* 0123456789012345678901234567890123456789
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ENABLE_THREAD
|
||||||
|
if (u_pthread_time)
|
||||||
|
{
|
||||||
|
# if defined(U_LOG_ENABLE) && defined(USE_LIBZ)
|
||||||
|
(void) U_SYSCALL(pthread_rwlock_rdlock, "%p", prwlock);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (tv_sec_old_3 != u_now->tv_sec)
|
||||||
|
{
|
||||||
|
long tv_sec = u_now->tv_sec;
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("tv_sec_old_3 = %lu u_now->tv_sec = %lu", tv_sec_old_3, tv_sec)
|
||||||
|
|
||||||
|
if ((tv_sec - tv_sec_old_3) != 1 ||
|
||||||
|
(tv_sec % U_ONE_HOUR_IN_SECOND) == 0)
|
||||||
|
{
|
||||||
|
tv_sec_old_3 = tv_sec;
|
||||||
|
|
||||||
|
U_MEMCPY(date.date3+6, ptr_shared_date->date3+6, 29-4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++tv_sec_old_3;
|
||||||
|
|
||||||
|
u_put_unalignedp16(date.date3+26, U_MULTICHAR_CONSTANT16(ptr_shared_date->date3[26],ptr_shared_date->date3[27]));
|
||||||
|
u_put_unalignedp16(date.date3+26+3,U_MULTICHAR_CONSTANT16(ptr_shared_date->date3[29],ptr_shared_date->date3[30]));
|
||||||
|
}
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(tv_sec, tv_sec_old_3)
|
||||||
|
}
|
||||||
|
|
||||||
|
# if defined(U_LOG_ENABLE) && defined(USE_LIBZ)
|
||||||
|
(void) U_SYSCALL(pthread_rwlock_unlock, "%p", prwlock);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(u_pthread_time, 0)
|
||||||
|
|
||||||
|
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
||||||
|
|
||||||
|
if (tv_sec_old_3 != u_now->tv_sec)
|
||||||
|
{
|
||||||
|
long tv_sec = u_now->tv_sec;
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("tv_sec_old_3 = %lu u_now->tv_sec = %lu", tv_sec_old_3, tv_sec)
|
||||||
|
|
||||||
|
if ((tv_sec - tv_sec_old_3) != 1 ||
|
||||||
|
(tv_sec % U_ONE_HOUR_IN_SECOND) == 0)
|
||||||
|
{
|
||||||
|
(void) u_strftime2(date.date3+6, 29-4, "%a, %d %b %Y %T", (tv_sec_old_3 = tv_sec)); // GMT can't change...
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
++tv_sec_old_3;
|
++tv_sec_old_3;
|
||||||
|
|
||||||
UTimeDate::updateTime(ptr+20);
|
UTimeDate::updateTime(date.date3+26);
|
||||||
}
|
}
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(u_now->tv_sec, tv_sec_old_3)
|
U_INTERNAL_ASSERT_EQUALS(tv_sec, tv_sec_old_3)
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
static long tv_sec_old_2;
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(which, 2)
|
U_INTERNAL_DUMP("date.date3+6 = %.29S", date.date3+6)
|
||||||
|
|
||||||
/**
|
|
||||||
* 04/Jun/2012:18:18:37 +0200
|
|
||||||
* 012345678901234567890123456789
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (tv_sec_old_2 == u_now->tv_sec) return;
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_MINOR(tv_sec_old_2, u_now->tv_sec)
|
|
||||||
|
|
||||||
if (bchange ||
|
|
||||||
(u_now->tv_sec - tv_sec_old_2) != 1)
|
|
||||||
{
|
|
||||||
(void) u_strftime2(ptr, 26-6, "%d/%b/%Y:%T", (tv_sec_old_2 = u_now->tv_sec) + u_now_adjust);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++tv_sec_old_2;
|
|
||||||
|
|
||||||
UTimeDate::updateTime(ptr+15);
|
|
||||||
}
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(u_now->tv_sec, tv_sec_old_2)
|
|
||||||
}
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(ptr_static_date->date1, iov_vec[0].iov_base)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ULog::setShared(log_data* ptr, uint32_t _size, bool breference)
|
void ULog::setShared(log_data* ptr, uint32_t _size, bool breference)
|
||||||
|
@ -559,7 +691,7 @@ void ULog::write(const char* msg, uint32_t len)
|
||||||
iov_vec[3].iov_len = len;
|
iov_vec[3].iov_len = len;
|
||||||
iov_vec[3].iov_base = (caddr_t) msg;
|
iov_vec[3].iov_base = (caddr_t) msg;
|
||||||
|
|
||||||
updateStaticDate(ptr_static_date->date1, 1);
|
updateDate1();
|
||||||
|
|
||||||
pthis->write(iov_vec, 5);
|
pthis->write(iov_vec, 5);
|
||||||
|
|
||||||
|
@ -606,7 +738,7 @@ void ULog::log(int _fd, const char* fmt, ...)
|
||||||
iov_vec[3].iov_len = len;
|
iov_vec[3].iov_len = len;
|
||||||
iov_vec[3].iov_base = (caddr_t)buffer;
|
iov_vec[3].iov_base = (caddr_t)buffer;
|
||||||
|
|
||||||
updateStaticDate(ptr_static_date->date1, 1);
|
updateDate1();
|
||||||
|
|
||||||
(void) U_SYSCALL(writev, "%d,%p,%d", _fd, iov_vec, 5);
|
(void) U_SYSCALL(writev, "%d,%p,%d", _fd, iov_vec, 5);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
# include <ulib/utility/http2.h>
|
# include <ulib/utility/http2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int UClientImage_Base::idx;
|
int UClientImage_Base::idx;
|
||||||
int UClientImage_Base::csfd;
|
int UClientImage_Base::csfd;
|
||||||
int UClientImage_Base::iovcnt;
|
int UClientImage_Base::iovcnt;
|
||||||
iPF UClientImage_Base::callerHandlerRead;
|
iPF UClientImage_Base::callerHandlerRead;
|
||||||
|
@ -129,8 +129,23 @@ UClientImage_Base::UClientImage_Base()
|
||||||
last_event = u_now->tv_sec;
|
last_event = u_now->tv_sec;
|
||||||
pending_close = 0;
|
pending_close = 0;
|
||||||
|
|
||||||
|
// NB: array are not pointers (virtual table can shift the address of 'this')...
|
||||||
|
|
||||||
|
if (UServer_Base::pClientImage == 0)
|
||||||
|
{
|
||||||
|
UServer_Base::pClientImage = this;
|
||||||
|
UServer_Base::eClientImage = this + UNotifier::max_connection;
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("UServer_Base::pClientImage = %p UServer_Base::eClientImage = %p UNotifier::max_connection = %u",
|
||||||
|
UServer_Base::pClientImage, UServer_Base::eClientImage, UNotifier::max_connection)
|
||||||
|
}
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("new T[%u]: elem %u of %u", UNotifier::max_connection, (this - UServer_Base::pClientImage), UNotifier::max_connection)
|
||||||
|
|
||||||
#ifndef U_HTTP2_DISABLE
|
#ifndef U_HTTP2_DISABLE
|
||||||
connection = U_NEW(UHTTP2::Connection);
|
connection = U_NEW(UHTTP2::Connection);
|
||||||
|
|
||||||
|
((UHTTP2::Connection*)connection)->itable.setIndexFunction(UHTTP2::setIndexStaticTable);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,19 +175,6 @@ void UClientImage_Base::set()
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UClientImage_Base::set()")
|
U_TRACE(0, "UClientImage_Base::set()")
|
||||||
|
|
||||||
// NB: array are not pointers (virtual table can shift the address of 'this')...
|
|
||||||
|
|
||||||
if (UServer_Base::pClientImage == 0)
|
|
||||||
{
|
|
||||||
UServer_Base::pClientImage = this;
|
|
||||||
UServer_Base::eClientImage = this + UNotifier::max_connection;
|
|
||||||
|
|
||||||
U_INTERNAL_DUMP("UServer_Base::pClientImage = %p UServer_Base::eClientImage = %p UNotifier::max_connection = %u",
|
|
||||||
UServer_Base::pClientImage, UServer_Base::eClientImage, UNotifier::max_connection)
|
|
||||||
}
|
|
||||||
|
|
||||||
U_INTERNAL_DUMP("new T[%u]: elem %u of %u", UNotifier::max_connection, (this - UServer_Base::pClientImage), UNotifier::max_connection)
|
|
||||||
|
|
||||||
U_INTERNAL_DUMP("this = %p socket = %p UEventFd::fd = %d", this, socket, UEventFd::fd)
|
U_INTERNAL_DUMP("this = %p socket = %p UEventFd::fd = %d", this, socket, UEventFd::fd)
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_POINTER(socket)
|
U_INTERNAL_ASSERT_POINTER(socket)
|
||||||
|
@ -223,7 +225,7 @@ bool UClientImage_Base::check_memory()
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UClientImage_Base::check_memory()")
|
U_TRACE(0, "UClientImage_Base::check_memory()")
|
||||||
|
|
||||||
U_INTERNAL_DUMP("u_check_memory_vector<T>: elem %u of %u", this - UServer_Base::pClientImage, UNotifier::max_connection)
|
U_INTERNAL_DUMP("u_check_memory_vector<T>: elem %u of %u", this-UServer_Base::pClientImage, UNotifier::max_connection)
|
||||||
|
|
||||||
U_INTERNAL_DUMP("this = %p socket = %p UEventFd::fd = %d", this, socket, UEventFd::fd)
|
U_INTERNAL_DUMP("this = %p socket = %p UEventFd::fd = %d", this, socket, UEventFd::fd)
|
||||||
|
|
||||||
|
@ -778,12 +780,27 @@ void UClientImage_Base::manageReadBufferResize(uint32_t n)
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UClientImage_Base::manageReadBufferResize(%u)", n)
|
U_TRACE(0, "UClientImage_Base::manageReadBufferResize(%u)", n)
|
||||||
|
|
||||||
ptrdiff_t diff;
|
|
||||||
const char* ptr;
|
|
||||||
|
|
||||||
U_DUMP("U_ClientImage_pipeline = %b size_request = %u rbuffer->size() = %u rbuffer->capacity() = %u request->size() = %u rstart = %u",
|
U_DUMP("U_ClientImage_pipeline = %b size_request = %u rbuffer->size() = %u rbuffer->capacity() = %u request->size() = %u rstart = %u",
|
||||||
U_ClientImage_pipeline, size_request, rbuffer->size(), rbuffer->capacity(), request->size(), rstart)
|
U_ClientImage_pipeline, size_request, rbuffer->size(), rbuffer->capacity(), request->size(), rstart)
|
||||||
|
|
||||||
|
#ifndef U_HTTP2_DISABLE
|
||||||
|
if (U_http_version == '2')
|
||||||
|
{
|
||||||
|
if (rstart)
|
||||||
|
{
|
||||||
|
rbuffer->moveToBeginDataInBuffer(rstart);
|
||||||
|
rstart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UString::_reserve(*rbuffer, n);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ptrdiff_t diff;
|
||||||
|
const char* ptr;
|
||||||
|
|
||||||
request->clear();
|
request->clear();
|
||||||
|
|
||||||
if (U_ClientImage_pipeline)
|
if (U_ClientImage_pipeline)
|
||||||
|
@ -811,8 +828,7 @@ next1:
|
||||||
|
|
||||||
UString::_reserve(*rbuffer, n);
|
UString::_reserve(*rbuffer, n);
|
||||||
|
|
||||||
if (U_http_method_type &&
|
if (U_http_method_type)
|
||||||
U_http_version != '2')
|
|
||||||
{
|
{
|
||||||
diff = rbuffer->data() - ptr;
|
diff = rbuffer->data() - ptr;
|
||||||
next2:
|
next2:
|
||||||
|
@ -1447,9 +1463,9 @@ bool UClientImage_Base::writeResponse()
|
||||||
msg_len = (U_ClientImage_pipeline ? U_CONSTANT_SIZE("[pipeline] ") : 0);
|
msg_len = (U_ClientImage_pipeline ? U_CONSTANT_SIZE("[pipeline] ") : 0);
|
||||||
|
|
||||||
iov_vec[2].iov_len = sz1;
|
iov_vec[2].iov_len = sz1;
|
||||||
iov_vec[2].iov_base = (caddr_t) wbuffer->data();
|
iov_vec[2].iov_base = (caddr_t)wbuffer->data();
|
||||||
iov_vec[3].iov_len = sz2;
|
iov_vec[3].iov_len = sz2;
|
||||||
iov_vec[3].iov_base = (caddr_t) body->data();
|
iov_vec[3].iov_base = (caddr_t)body->data();
|
||||||
|
|
||||||
ncount = sz1 + sz2;
|
ncount = sz1 + sz2;
|
||||||
|
|
||||||
|
@ -1478,7 +1494,14 @@ bool UClientImage_Base::writeResponse()
|
||||||
|
|
||||||
u__memcpy(iov_sav, iov_vec, U_IOV_TO_SAVE, __PRETTY_FUNCTION__);
|
u__memcpy(iov_sav, iov_vec, U_IOV_TO_SAVE, __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
ULog::updateStaticDate(UServer_Base::ptr_static_date->date3+6, 3);
|
# if defined(ENABLE_THREAD) && !defined(U_LOG_ENABLE) && !defined(USE_LIBZ)
|
||||||
|
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(iov_vec[1].iov_base, UServer_Base::ptr_shared_data->log_date_shared.date3)
|
||||||
|
# else
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(iov_vec[1].iov_base, ULog::date.date3)
|
||||||
|
|
||||||
|
ULog::updateDate3();
|
||||||
|
# endif
|
||||||
|
|
||||||
# ifdef U_LOG_ENABLE
|
# ifdef U_LOG_ENABLE
|
||||||
if (logbuf) ULog::log(iov_vec+idx, UServer_Base::mod_name[0], "response", ncount, "[pipeline] ", msg_len, " to %v", logbuf->rep);
|
if (logbuf) ULog::log(iov_vec+idx, UServer_Base::mod_name[0], "response", ncount, "[pipeline] ", msg_len, " to %v", logbuf->rep);
|
||||||
|
|
|
@ -348,6 +348,7 @@ int UHttpPlugIn::handlerConfig(UFileConfig& cfg)
|
||||||
|
|
||||||
if (x)
|
if (x)
|
||||||
{
|
{
|
||||||
|
UServer_Base::update_date =
|
||||||
UServer_Base::update_date2 = true;
|
UServer_Base::update_date2 = true;
|
||||||
|
|
||||||
uint32_t size = cfg.readLong(*UString::str_LOG_FILE_SZ);
|
uint32_t size = cfg.readLong(*UString::str_LOG_FILE_SZ);
|
||||||
|
@ -446,11 +447,18 @@ int UHttpPlugIn::handlerRun() // NB: we use this method because now we have the
|
||||||
|
|
||||||
if (UServer_Base::vplugin_name->last() == *UString::str_http)
|
if (UServer_Base::vplugin_name->last() == *UString::str_http)
|
||||||
{
|
{
|
||||||
|
UServer_Base::update_date =
|
||||||
UServer_Base::update_date3 = true;
|
UServer_Base::update_date3 = true;
|
||||||
|
|
||||||
UClientImage_Base::iov_vec[1].iov_base = (caddr_t) UServer_Base::ptr_static_date->date3; // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\n...
|
UClientImage_Base::iov_vec[1].iov_base = (caddr_t)ULog::date.date3; // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\n...
|
||||||
UClientImage_Base::iov_vec[1].iov_len = 6+29+2+12+2+17+2;
|
UClientImage_Base::iov_vec[1].iov_len = 6+29+2+12+2+17+2;
|
||||||
|
|
||||||
|
# if defined(ENABLE_THREAD) && !defined(U_LOG_ENABLE) && !defined(USE_LIBZ)
|
||||||
|
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||||
|
|
||||||
|
UClientImage_Base::iov_vec[1].iov_base = (caddr_t)UServer_Base::ptr_shared_data->log_date_shared.date3;
|
||||||
|
# endif
|
||||||
|
|
||||||
U_INTERNAL_DUMP("UClientImage_Base::iov_vec[0] = %.*S UClientImage_Base::iov_vec[1] = %.*S",
|
U_INTERNAL_DUMP("UClientImage_Base::iov_vec[0] = %.*S UClientImage_Base::iov_vec[1] = %.*S",
|
||||||
UClientImage_Base::iov_vec[0].iov_len, UClientImage_Base::iov_vec[0].iov_base,
|
UClientImage_Base::iov_vec[0].iov_len, UClientImage_Base::iov_vec[0].iov_base,
|
||||||
UClientImage_Base::iov_vec[1].iov_len, UClientImage_Base::iov_vec[1].iov_base)
|
UClientImage_Base::iov_vec[1].iov_len, UClientImage_Base::iov_vec[1].iov_base)
|
||||||
|
|
|
@ -89,6 +89,7 @@ bool UServer_Base::public_address;
|
||||||
bool UServer_Base::monitoring_process;
|
bool UServer_Base::monitoring_process;
|
||||||
bool UServer_Base::set_tcp_keep_alive;
|
bool UServer_Base::set_tcp_keep_alive;
|
||||||
bool UServer_Base::set_realtime_priority;
|
bool UServer_Base::set_realtime_priority;
|
||||||
|
bool UServer_Base::update_date;
|
||||||
bool UServer_Base::update_date1;
|
bool UServer_Base::update_date1;
|
||||||
bool UServer_Base::update_date2;
|
bool UServer_Base::update_date2;
|
||||||
bool UServer_Base::update_date3;
|
bool UServer_Base::update_date3;
|
||||||
|
@ -143,7 +144,6 @@ UVector<UString>* UServer_Base::vplugin_name_static;
|
||||||
UClientImage_Base* UServer_Base::pClientImage;
|
UClientImage_Base* UServer_Base::pClientImage;
|
||||||
UClientImage_Base* UServer_Base::vClientImage;
|
UClientImage_Base* UServer_Base::vClientImage;
|
||||||
UClientImage_Base* UServer_Base::eClientImage;
|
UClientImage_Base* UServer_Base::eClientImage;
|
||||||
ULog::static_date* UServer_Base::ptr_static_date;
|
|
||||||
UVector<UServerPlugIn*>* UServer_Base::vplugin;
|
UVector<UServerPlugIn*>* UServer_Base::vplugin;
|
||||||
UServer_Base::shared_data* UServer_Base::ptr_shared_data;
|
UServer_Base::shared_data* UServer_Base::ptr_shared_data;
|
||||||
UVector<UServer_Base::file_LOG*>* UServer_Base::vlog;
|
UVector<UServer_Base::file_LOG*>* UServer_Base::vlog;
|
||||||
|
@ -167,24 +167,14 @@ UVector<UIPAllow*>* UServer_Base::vallow_IP_prv;
|
||||||
class UTimeThread : public UThread {
|
class UTimeThread : public UThread {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
UTimeThread() : UThread(true, false) { watch_counter = 1; }
|
UTimeThread() : UThread(true, false) {}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
UTimeVal before;
|
|
||||||
#endif
|
|
||||||
int watch_counter;
|
|
||||||
|
|
||||||
virtual void run()
|
virtual void run()
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UTimeThread::run()")
|
U_TRACE(0, "UTimeThread::run()")
|
||||||
|
|
||||||
# ifdef DEBUG
|
|
||||||
long delta;
|
|
||||||
UTimeVal after;
|
|
||||||
# endif
|
|
||||||
bool bchange;
|
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
long tv_sec_old = u_now->tv_sec;
|
u_timeval.tv_sec = u_now->tv_sec;
|
||||||
|
|
||||||
U_SRV_LOG("UTimeThread optimization for time resolution of one second activated (pid %u)", UThread::getTID());
|
U_SRV_LOG("UTimeThread optimization for time resolution of one second activated (pid %u)", UThread::getTID());
|
||||||
|
|
||||||
|
@ -196,74 +186,46 @@ public:
|
||||||
(void) U_SYSCALL(nanosleep, "%p,%p", &ts, 0);
|
(void) U_SYSCALL(nanosleep, "%p,%p", &ts, 0);
|
||||||
|
|
||||||
# if defined(U_LOG_ENABLE) && defined(USE_LIBZ)
|
# if defined(U_LOG_ENABLE) && defined(USE_LIBZ)
|
||||||
if ((UServer_Base::log && UServer_Base::log->checkForLogRotateDataToWrite()) ||
|
if (UServer_Base::log) (void) UServer_Base::log->checkForLogRotateDataToWrite();
|
||||||
(UServer_Base::apache_like_log && UServer_Base::apache_like_log->checkForLogRotateDataToWrite()))
|
if (UServer_Base::apache_like_log) (void) UServer_Base::apache_like_log->checkForLogRotateDataToWrite();
|
||||||
{
|
|
||||||
watch_counter = 1;
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
U_INTERNAL_DUMP("watch_counter = %d tv_sec_old = %ld u_now->tv_sec = %ld", watch_counter, tv_sec_old, u_now->tv_sec)
|
U_INTERNAL_DUMP("u_timeval.tv_sec = %ld u_now->tv_sec = %ld", u_timeval.tv_sec, u_now->tv_sec)
|
||||||
|
|
||||||
if (tv_sec_old == u_now->tv_sec)
|
if (u_timeval.tv_sec == u_now->tv_sec)
|
||||||
{
|
{
|
||||||
if (--watch_counter > 0) u_now->tv_sec++;
|
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
||||||
|
|
||||||
|
if (u_timeval.tv_sec == u_now->tv_sec) continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT_DIFFERS(u_now->tv_sec, u_timeval.tv_sec)
|
||||||
|
|
||||||
|
u_timeval.tv_sec = u_now->tv_sec;
|
||||||
|
|
||||||
|
if (UServer_Base::update_date)
|
||||||
|
{
|
||||||
|
# if defined(U_LOG_ENABLE) && defined(USE_LIBZ)
|
||||||
|
(void) U_SYSCALL(pthread_rwlock_wrlock, "%p", ULog::prwlock);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if ((u_timeval.tv_sec % U_ONE_HOUR_IN_SECOND) != 0)
|
||||||
|
{
|
||||||
|
if (UServer_Base::update_date1) UTimeDate::updateTime(ULog::ptr_shared_date->date1 + 12);
|
||||||
|
if (UServer_Base::update_date2) UTimeDate::updateTime(ULog::ptr_shared_date->date2 + 15);
|
||||||
|
if (UServer_Base::update_date3) UTimeDate::updateTime(ULog::ptr_shared_date->date3 + 26);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
# ifdef DEBUG
|
if (UServer_Base::update_date1) (void) u_strftime2(ULog::ptr_shared_date->date1, 17, "%d/%m/%y %T", u_timeval.tv_sec + u_now_adjust);
|
||||||
if (watch_counter == 0)
|
if (UServer_Base::update_date2) (void) u_strftime2(ULog::ptr_shared_date->date2, 26-6, "%d/%b/%Y:%T", u_timeval.tv_sec + u_now_adjust); // %z in general don't change...
|
||||||
{
|
if (UServer_Base::update_date3) (void) u_strftime2(ULog::ptr_shared_date->date3+6, 29-4, "%a, %d %b %Y %T", u_timeval.tv_sec); // GMT can't change...
|
||||||
before.tv_sec = u_now->tv_sec + 1;
|
|
||||||
before.tv_usec = u_now->tv_usec;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
|
||||||
|
|
||||||
# ifdef DEBUG
|
|
||||||
after.set(*u_now);
|
|
||||||
|
|
||||||
after -= before;
|
|
||||||
delta = after.getMilliSecond();
|
|
||||||
|
|
||||||
if (delta >= 1000L ||
|
|
||||||
delta <= -1000L)
|
|
||||||
{
|
|
||||||
U_SRV_LOG("UTimeThread delta time exceed 1 sec: diff(%ld ms)", delta);
|
|
||||||
|
|
||||||
if (delta <= -30000L) U_ERROR("UTimeThread delta time exceed too much - ts = { %ld, %ld }", ts.tv_sec, ts.tv_nsec);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
watch_counter = 30;
|
|
||||||
|
|
||||||
if (tv_sec_old == u_now->tv_sec) continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if defined(U_LOG_ENABLE) && defined(USE_LIBZ)
|
||||||
|
(void) U_SYSCALL(pthread_rwlock_unlock, "%p", ULog::prwlock);
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_DIFFERS(u_now->tv_sec, tv_sec_old)
|
|
||||||
|
|
||||||
bchange = ((u_now->tv_sec % U_ONE_HOUR_IN_SECOND) == 0);
|
|
||||||
|
|
||||||
if (UServer_Base::update_date1)
|
|
||||||
{
|
|
||||||
if (bchange == false) UTimeDate::updateTime(U_HTTP_DATE1 + 12);
|
|
||||||
else (void) u_strftime2(U_HTTP_DATE1, 17, "%d/%m/%y %T", u_now->tv_sec + u_now_adjust);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UServer_Base::update_date2)
|
|
||||||
{
|
|
||||||
if (bchange == false) UTimeDate::updateTime(U_HTTP_DATE2 + 15);
|
|
||||||
else (void) u_strftime2(U_HTTP_DATE2, 26-6, "%d/%b/%Y:%T", u_now->tv_sec + u_now_adjust); // NB: %z in general don't change...
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UServer_Base::update_date3)
|
|
||||||
{
|
|
||||||
if (bchange == false) UTimeDate::updateTime(U_HTTP_DATE3 + 20);
|
|
||||||
else (void) u_strftime2(U_HTTP_DATE3, 29-4, "%a, %d %b %Y %T", u_now->tv_sec); // GMT can't change...
|
|
||||||
}
|
|
||||||
|
|
||||||
tv_sec_old = u_now->tv_sec;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -395,9 +357,11 @@ UServer_Base::~UServer_Base()
|
||||||
((UTimeThread*)u_pthread_time)->suspend();
|
((UTimeThread*)u_pthread_time)->suspend();
|
||||||
|
|
||||||
delete (UTimeThread*)u_pthread_time; // delete to join
|
delete (UTimeThread*)u_pthread_time; // delete to join
|
||||||
|
|
||||||
|
(void) U_SYSCALL(pthread_rwlock_destroy, "%p", ULog::prwlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
||||||
if (bssl)
|
if (bssl)
|
||||||
{
|
{
|
||||||
if (pthread_ocsp)
|
if (pthread_ocsp)
|
||||||
|
@ -411,7 +375,7 @@ UServer_Base::~UServer_Base()
|
||||||
|
|
||||||
if (UServer_Base::lock_ocsp_staple) delete UServer_Base::lock_ocsp_staple;
|
if (UServer_Base::lock_ocsp_staple) delete UServer_Base::lock_ocsp_staple;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UClientImage_Base::clear();
|
UClientImage_Base::clear();
|
||||||
|
@ -876,6 +840,7 @@ void UServer_Base::loadConfigParam()
|
||||||
{
|
{
|
||||||
// open log
|
// open log
|
||||||
|
|
||||||
|
update_date =
|
||||||
update_date1 = true;
|
update_date1 = true;
|
||||||
|
|
||||||
log = U_NEW(ULog(x, cfg->readLong(*UString::str_LOG_FILE_SZ)));
|
log = U_NEW(ULog(x, cfg->readLong(*UString::str_LOG_FILE_SZ)));
|
||||||
|
@ -1394,7 +1359,7 @@ void UServer_Base::init()
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/**
|
/**
|
||||||
* This code does NOT make a connection or send any packets (to 64.233.187.99 which is google).
|
* This code does NOT make a connection or send any packets (to 8.8.8.8 which is google DNS).
|
||||||
* Since UDP is a stateless protocol connect() merely makes a system call which figures out how to
|
* Since UDP is a stateless protocol connect() merely makes a system call which figures out how to
|
||||||
* route the packets based on the address and what interface (and therefore IP address) it should
|
* route the packets based on the address and what interface (and therefore IP address) it should
|
||||||
* bind to. Returns an array containing the family (AF_INET), local port, and local address (which
|
* bind to. Returns an array containing the family (AF_INET), local port, and local address (which
|
||||||
|
@ -1545,7 +1510,7 @@ void UServer_Base::init()
|
||||||
#ifdef U_LOG_ENABLE
|
#ifdef U_LOG_ENABLE
|
||||||
uint32_t log_rotate_size = 0;
|
uint32_t log_rotate_size = 0;
|
||||||
|
|
||||||
# ifdef USE_LIBZ
|
# ifdef USE_LIBZ
|
||||||
if (isLog())
|
if (isLog())
|
||||||
{
|
{
|
||||||
// The zlib documentation states that destination buffer size must be at least 0.1% larger than avail_in plus 12 bytes
|
// The zlib documentation states that destination buffer size must be at least 0.1% larger than avail_in plus 12 bytes
|
||||||
|
@ -1553,7 +1518,7 @@ void UServer_Base::init()
|
||||||
log_rotate_size =
|
log_rotate_size =
|
||||||
shared_data_add = log->UFile::st_size + (log->UFile::st_size / 10) + 12U;
|
shared_data_add = log->UFile::st_size + (log->UFile::st_size / 10) + 12U;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
U_INTERNAL_DUMP("log_rotate_size = %u", log_rotate_size)
|
U_INTERNAL_DUMP("log_rotate_size = %u", log_rotate_size)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1585,61 +1550,56 @@ void UServer_Base::init()
|
||||||
#ifdef U_LOG_ENABLE
|
#ifdef U_LOG_ENABLE
|
||||||
if (isLog() == false)
|
if (isLog() == false)
|
||||||
#endif
|
#endif
|
||||||
ULog::initStaticDate();
|
ULog::initDate();
|
||||||
|
|
||||||
if (bpthread_time == false) ptr_static_date = ULog::ptr_static_date;
|
|
||||||
#ifdef ENABLE_THREAD
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ptr_static_date = &(ptr_shared_data->static_date);
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_POINTER( ULog::ptr_static_date)
|
|
||||||
U_INTERNAL_ASSERT_EQUALS((void*)u_now, (void*)ULog::ptr_static_date)
|
|
||||||
|
|
||||||
U_MEMCPY(ptr_static_date, ULog::ptr_static_date, sizeof(ULog::static_date));
|
|
||||||
|
|
||||||
u_now = &(ptr_static_date->_timeval);
|
|
||||||
ULog::iov_vec[0].iov_base = (caddr_t)ptr_static_date->date1;
|
|
||||||
|
|
||||||
U_FREE_TYPE(ULog::ptr_static_date, ULog::static_date);
|
|
||||||
|
|
||||||
ULog::ptr_static_date = ptr_static_date;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS((void*)u_now, (void*)ptr_static_date)
|
|
||||||
U_INTERNAL_ASSERT_EQUALS((void*)u_now, (void*)ULog::ptr_static_date)
|
|
||||||
|
|
||||||
#if defined(ENABLE_THREAD) && !defined(_MSWINDOWS_)
|
|
||||||
// NB: we block SIGHUP and SIGTERM; the threads created will inherit a copy of the signal mask...
|
|
||||||
# ifdef sigemptyset
|
|
||||||
sigemptyset(&mask);
|
|
||||||
# else
|
|
||||||
(void) U_SYSCALL(sigemptyset, "%p", &mask);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef sigaddset
|
|
||||||
sigaddset(&mask, SIGHUP);
|
|
||||||
sigaddset(&mask, SIGTERM);
|
|
||||||
# else
|
|
||||||
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGHUP);
|
|
||||||
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGTERM);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
(void) U_SYSCALL(pthread_sigmask, "%d,%p,%p", SIG_BLOCK, &mask, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
flag_loop = true; // NB: UTimeThread loop depend on this...
|
|
||||||
|
|
||||||
#ifdef ENABLE_THREAD
|
#ifdef ENABLE_THREAD
|
||||||
if (bpthread_time)
|
if (bpthread_time)
|
||||||
{
|
{
|
||||||
|
U_INTERNAL_ASSERT_POINTER(ptr_shared_data)
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(ULog::ptr_shared_date, 0)
|
||||||
|
|
||||||
|
u_now = &(ptr_shared_data->now_shared);
|
||||||
|
ULog::ptr_shared_date = &(ptr_shared_data->log_date_shared);
|
||||||
|
|
||||||
|
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
||||||
|
|
||||||
|
U_MEMCPY(ULog::ptr_shared_date, &ULog::date, sizeof(ULog::log_date));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_THREAD) && !defined(_MSWINDOWS_)
|
||||||
|
// NB: we block SIGHUP and SIGTERM; the threads created will inherit a copy of the signal mask...
|
||||||
|
# ifdef sigemptyset
|
||||||
|
sigemptyset(&mask);
|
||||||
|
# else
|
||||||
|
(void) U_SYSCALL(sigemptyset, "%p", &mask);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef sigaddset
|
||||||
|
sigaddset(&mask, SIGHUP);
|
||||||
|
sigaddset(&mask, SIGTERM);
|
||||||
|
# else
|
||||||
|
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGHUP);
|
||||||
|
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGTERM);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
(void) U_SYSCALL(pthread_sigmask, "%d,%p,%p", SIG_BLOCK, &mask, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
flag_loop = true; // NB: UTimeThread loop depend on this setting...
|
||||||
|
|
||||||
|
#ifdef ENABLE_THREAD
|
||||||
|
if (bpthread_time)
|
||||||
|
{
|
||||||
|
U_INTERNAL_ASSERT_EQUALS(ULog::prwlock, 0)
|
||||||
U_INTERNAL_ASSERT_EQUALS(u_pthread_time, 0)
|
U_INTERNAL_ASSERT_EQUALS(u_pthread_time, 0)
|
||||||
|
|
||||||
U_NEW_ULIB_OBJECT(u_pthread_time, UTimeThread);
|
U_NEW_ULIB_OBJECT(u_pthread_time, UTimeThread);
|
||||||
|
|
||||||
U_INTERNAL_DUMP("u_pthread_time = %p", u_pthread_time)
|
U_INTERNAL_DUMP("u_pthread_time = %p", u_pthread_time)
|
||||||
|
|
||||||
|
(void) UThread::initRwLock((ULog::prwlock = &(ptr_shared_data->rwlock)));
|
||||||
|
|
||||||
((UTimeThread*)u_pthread_time)->start(50);
|
((UTimeThread*)u_pthread_time)->start(50);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1647,9 +1607,9 @@ void UServer_Base::init()
|
||||||
#ifdef U_LOG_ENABLE
|
#ifdef U_LOG_ENABLE
|
||||||
if (isLog())
|
if (isLog())
|
||||||
{
|
{
|
||||||
// NB: if log is mapped must be always shared cause of possibility of fork() by parallelization
|
// NB: if log is mapped must be always shared because of possibility of fork() by parallelization...
|
||||||
|
|
||||||
if (log->isMemoryMapped()) log->setShared(U_LOG_DATA_SHARED, log_rotate_size);
|
if (log->isMemoryMapped()) log->setShared(&(ptr_shared_data->log_data_shared), log_rotate_size);
|
||||||
|
|
||||||
U_SRV_LOG("Mapped %u bytes (%u KB) of shared memory for %d preforked process", sizeof(shared_data) + shared_data_add, map_size / 1024, preforked_num_kids);
|
U_SRV_LOG("Mapped %u bytes (%u KB) of shared memory for %d preforked process", sizeof(shared_data) + shared_data_add, map_size / 1024, preforked_num_kids);
|
||||||
}
|
}
|
||||||
|
@ -1690,8 +1650,8 @@ void UServer_Base::init()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There may not always be a connection waiting after a SIGIO is delivered or select(2) or poll(2) return a readability
|
* There may not always be a connection waiting after a SIGIO is delivered or select(2) or poll(2) return a readability
|
||||||
* event because the connection might have been removed by an asynchronous network error or another thread before
|
* event because the connection might have been removed by an asynchronous network error or another thread before
|
||||||
* accept() is called. If this happens then the call will block waiting for the next connection to arrive. To ensure
|
* accept() is called. If this happens then the call will block waiting for the next connection to arrive. To ensure
|
||||||
* that accept() never blocks, the passed socket sockfd needs to have the O_NONBLOCK flag set (see socket(7))
|
* that accept() never blocks, the passed socket sockfd needs to have the O_NONBLOCK flag set (see socket(7))
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1874,13 +1834,13 @@ RETSIGTYPE UServer_Base::handlerForSigHUP(int signo)
|
||||||
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
||||||
|
|
||||||
#ifdef ENABLE_THREAD
|
#ifdef ENABLE_THREAD
|
||||||
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
||||||
if (pthread_ocsp) pthread_ocsp->suspend();
|
if (pthread_ocsp) pthread_ocsp->suspend();
|
||||||
# endif
|
# endif
|
||||||
if (u_pthread_time) ((UTimeThread*)u_pthread_time)->suspend();
|
if (u_pthread_time) ((UTimeThread*)u_pthread_time)->suspend();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pthis->handlerSignal(); // manage before regenering preforked pool of children...
|
pthis->handlerSignal(); // manage signal before we regenering the preforked pool of children...
|
||||||
|
|
||||||
// NB: we can't use UInterrupt::erase() because it restore the old action (UInterrupt::init)...
|
// NB: we can't use UInterrupt::erase() because it restore the old action (UInterrupt::init)...
|
||||||
|
|
||||||
|
@ -1896,19 +1856,9 @@ RETSIGTYPE UServer_Base::handlerForSigHUP(int signo)
|
||||||
|
|
||||||
#ifdef ENABLE_THREAD
|
#ifdef ENABLE_THREAD
|
||||||
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
||||||
if (pthread_ocsp) pthread_ocsp->resume();
|
if (pthread_ocsp) pthread_ocsp->resume();
|
||||||
# endif
|
# endif
|
||||||
if (u_pthread_time)
|
if (u_pthread_time) ((UTimeThread*)u_pthread_time)->resume();
|
||||||
{
|
|
||||||
# ifdef DEBUG
|
|
||||||
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
|
||||||
|
|
||||||
((UTimeThread*)u_pthread_time)->before.set(*u_now);
|
|
||||||
# endif
|
|
||||||
((UTimeThread*)u_pthread_time)->watch_counter = 0;
|
|
||||||
|
|
||||||
((UTimeThread*)u_pthread_time)->resume();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef U_LOG_ENABLE
|
#ifdef U_LOG_ENABLE
|
||||||
|
@ -2174,7 +2124,7 @@ try_accept:
|
||||||
# ifdef U_LOG_ENABLE
|
# ifdef U_LOG_ENABLE
|
||||||
if (isLog() &&
|
if (isLog() &&
|
||||||
flag_loop && // NB: we check to avoid SIGTERM event...
|
flag_loop && // NB: we check to avoid SIGTERM event...
|
||||||
CSOCKET->iState != -EINTR && // NB: we check to avoid log spurious EINTR on accept() by timer...
|
CSOCKET->iState != -EINTR && // NB: we check to avoid log spurious EINTR on accept() by any timer...
|
||||||
CSOCKET->iState != -EAGAIN)
|
CSOCKET->iState != -EAGAIN)
|
||||||
{
|
{
|
||||||
CSOCKET->setMsgError();
|
CSOCKET->setMsgError();
|
||||||
|
@ -2772,18 +2722,6 @@ void UServer_Base::run()
|
||||||
if (preforked_num_kids <= 0) pid_to_wait = pid;
|
if (preforked_num_kids <= 0) pid_to_wait = pid;
|
||||||
|
|
||||||
if (set_realtime_priority) u_switch_to_realtime_priority(pid);
|
if (set_realtime_priority) u_switch_to_realtime_priority(pid);
|
||||||
|
|
||||||
# ifdef ENABLE_THREAD
|
|
||||||
if (u_pthread_time)
|
|
||||||
{
|
|
||||||
# ifdef DEBUG
|
|
||||||
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
|
||||||
|
|
||||||
((UTimeThread*)u_pthread_time)->before.set(*u_now);
|
|
||||||
# endif
|
|
||||||
((UTimeThread*)u_pthread_time)->watch_counter = 0;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proc->child())
|
if (proc->child())
|
||||||
|
@ -3069,7 +3007,6 @@ const char* UServer_Base::dump(bool reset) const
|
||||||
<< "last_event " << last_event << '\n'
|
<< "last_event " << last_event << '\n'
|
||||||
<< "verify_mode " << verify_mode << '\n'
|
<< "verify_mode " << verify_mode << '\n'
|
||||||
<< "shared_data_add " << shared_data_add << '\n'
|
<< "shared_data_add " << shared_data_add << '\n'
|
||||||
<< "ptr_static_date " << (void*)ptr_static_date << '\n'
|
|
||||||
<< "ptr_shared_data " << (void*)ptr_shared_data << '\n'
|
<< "ptr_shared_data " << (void*)ptr_shared_data << '\n'
|
||||||
<< "preforked_num_kids " << preforked_num_kids << '\n'
|
<< "preforked_num_kids " << preforked_num_kids << '\n'
|
||||||
<< "log (ULog " << (void*)log << ")\n"
|
<< "log (ULog " << (void*)log << ")\n"
|
||||||
|
|
|
@ -712,7 +712,7 @@ uint32_t UOptions::getopt(int argc, char** argv, int* poptind)
|
||||||
"SSL support..........:%W " LIBSSL_ENABLE "%W\n"
|
"SSL support..........:%W " LIBSSL_ENABLE "%W\n"
|
||||||
"SSH support..........:%W " LIBSSH_ENABLE "%W\n"
|
"SSH support..........:%W " LIBSSH_ENABLE "%W\n"
|
||||||
"LDAP support.........:%W " LIBLDAP_ENABLE "%W\n"
|
"LDAP support.........:%W " LIBLDAP_ENABLE "%W\n"
|
||||||
"LDAP support.........:%W " LIBLDAP_ENABLE "%W\n"
|
"cURL support.........:%W " LIBCURL_ENABLE "%W\n"
|
||||||
"XML support..........:%W " LIBEXPAT_ENABLE "%W\n"
|
"XML support..........:%W " LIBEXPAT_ENABLE "%W\n"
|
||||||
"MAGIC support........:%W " MAGIC_ENABLE "%W\n"
|
"MAGIC support........:%W " MAGIC_ENABLE "%W\n"
|
||||||
"SQLite support.......:%W " SQLITE_ENABLE "%W\n"
|
"SQLite support.......:%W " SQLITE_ENABLE "%W\n"
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
# include <sys/syscall.h>
|
# include <sys/syscall.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void* (*exec_t)(void*);
|
typedef void* (*exec_t) (void*);
|
||||||
typedef void (*cleanup_t)(void*);
|
typedef void (*cleanup_t)(void*);
|
||||||
|
|
||||||
#ifndef HAVE_NANOSLEEP
|
#ifndef HAVE_NANOSLEEP
|
||||||
|
@ -138,15 +138,9 @@ void UThread::stop()
|
||||||
|
|
||||||
(void) U_SYSCALL(pthread_cancel, "%p", priv->_tid);
|
(void) U_SYSCALL(pthread_cancel, "%p", priv->_tid);
|
||||||
|
|
||||||
if (bdetached == false)
|
if (bdetached == false) (void) U_SYSCALL(pthread_join, "%p,%p", priv->_tid, 0);
|
||||||
{
|
|
||||||
(void) U_SYSCALL(pthread_join, "%p,%p", priv->_tid, 0);
|
|
||||||
}
|
|
||||||
#ifdef HAVE_PTHREAD_YIELD
|
#ifdef HAVE_PTHREAD_YIELD
|
||||||
else
|
else (void) U_SYSCALL_NO_PARAM(pthread_yield);
|
||||||
{
|
|
||||||
(void) U_SYSCALL_NO_PARAM(pthread_yield);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,13 +173,6 @@ void UThread::close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UThread::threadCleanup(UThread* th)
|
|
||||||
{
|
|
||||||
U_TRACE(0, "UThread::threadCleanup(%p)", th)
|
|
||||||
|
|
||||||
th->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UThread::yield()
|
void UThread::yield()
|
||||||
{
|
{
|
||||||
U_TRACE(1, "UThread::yield()")
|
U_TRACE(1, "UThread::yield()")
|
||||||
|
@ -202,17 +189,17 @@ void UThread::yield()
|
||||||
|
|
||||||
if (bcancel)
|
if (bcancel)
|
||||||
{
|
{
|
||||||
# ifdef sigemptyset
|
# ifdef sigemptyset
|
||||||
sigemptyset(&cancel);
|
sigemptyset(&cancel);
|
||||||
# else
|
# else
|
||||||
(void) U_SYSCALL(sigemptyset, "%p", &cancel);
|
(void) U_SYSCALL(sigemptyset, "%p", &cancel);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef sigaddset
|
# ifdef sigaddset
|
||||||
sigaddset(&cancel, CCXX_SIG_THREAD_CANCEL);
|
sigaddset(&cancel, CCXX_SIG_THREAD_CANCEL);
|
||||||
# else
|
# else
|
||||||
(void) U_SYSCALL(sigaddset, "%p,%d", &cancel, CCXX_SIG_THREAD_CANCEL);
|
(void) U_SYSCALL(sigaddset, "%p,%d", &cancel, CCXX_SIG_THREAD_CANCEL);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
(void) U_SYSCALL(pthread_sigmask, "%d,%p,%p", SIG_UNBLOCK, &cancel, &old);
|
(void) U_SYSCALL(pthread_sigmask, "%d,%p,%p", SIG_UNBLOCK, &cancel, &old);
|
||||||
}
|
}
|
||||||
|
@ -254,11 +241,11 @@ void UThread::sigInstall(int signo)
|
||||||
|
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
# ifdef sigemptyset
|
#ifdef sigemptyset
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
# else
|
#else
|
||||||
(void) U_SYSCALL(sigemptyset, "%p", &sa.sa_mask);
|
(void) U_SYSCALL(sigemptyset, "%p", &sa.sa_mask);
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
#ifdef SA_RESTART
|
#ifdef SA_RESTART
|
||||||
sa.sa_flags = SA_RESTART;
|
sa.sa_flags = SA_RESTART;
|
||||||
|
@ -364,25 +351,25 @@ void UThread::execHandler(UThread* th)
|
||||||
|
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
|
|
||||||
# ifdef sigemptyset
|
#ifdef sigemptyset
|
||||||
sigemptyset(&mask);
|
sigemptyset(&mask);
|
||||||
# else
|
#else
|
||||||
(void) U_SYSCALL(sigemptyset, "%p", &mask);
|
(void) U_SYSCALL(sigemptyset, "%p", &mask);
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
# ifdef sigaddset
|
#ifdef sigaddset
|
||||||
// sigaddset(&mask, SIGHUP);
|
// sigaddset(&mask, SIGHUP);
|
||||||
sigaddset(&mask, SIGINT);
|
sigaddset(&mask, SIGINT);
|
||||||
sigaddset(&mask, SIGABRT);
|
sigaddset(&mask, SIGABRT);
|
||||||
sigaddset(&mask, SIGPIPE);
|
sigaddset(&mask, SIGPIPE);
|
||||||
sigaddset(&mask, SIGALRM);
|
sigaddset(&mask, SIGALRM);
|
||||||
# else
|
#else
|
||||||
// (void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGHUP);
|
// (void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGHUP);
|
||||||
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGINT);
|
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGINT);
|
||||||
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGABRT);
|
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGABRT);
|
||||||
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGPIPE);
|
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGPIPE);
|
||||||
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGALRM);
|
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, SIGALRM);
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
(void) U_SYSCALL(pthread_sigmask, "%d,%p,%p", SIG_BLOCK, &mask, 0);
|
(void) U_SYSCALL(pthread_sigmask, "%d,%p,%p", SIG_BLOCK, &mask, 0);
|
||||||
|
|
||||||
|
@ -394,19 +381,19 @@ void UThread::execHandler(UThread* th)
|
||||||
// of Linux threads, it was possible to stop a single thread with SIGSTOP, but this behaviour has now been fixed
|
// of Linux threads, it was possible to stop a single thread with SIGSTOP, but this behaviour has now been fixed
|
||||||
// to conform to the Posix standard (so it stops all threads in the process)
|
// to conform to the Posix standard (so it stops all threads in the process)
|
||||||
|
|
||||||
# ifdef sigemptyset
|
# ifdef sigemptyset
|
||||||
sigemptyset(&mask);
|
sigemptyset(&mask);
|
||||||
# else
|
# else
|
||||||
(void) U_SYSCALL(sigemptyset, "%p", &mask);
|
(void) U_SYSCALL(sigemptyset, "%p", &mask);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef sigaddset
|
# ifdef sigaddset
|
||||||
sigaddset(&mask, U_SIGSTOP);
|
sigaddset(&mask, U_SIGSTOP);
|
||||||
sigaddset(&mask, U_SIGCONT);
|
sigaddset(&mask, U_SIGCONT);
|
||||||
# else
|
# else
|
||||||
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, U_SIGSTOP);
|
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, U_SIGSTOP);
|
||||||
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, U_SIGCONT);
|
(void) U_SYSCALL(sigaddset, "%p,%d", &mask, U_SIGCONT);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
(void) U_SYSCALL(pthread_sigmask, "%d,%p,%p", SIG_UNBLOCK, &mask, 0);
|
(void) U_SYSCALL(pthread_sigmask, "%d,%p,%p", SIG_UNBLOCK, &mask, 0);
|
||||||
|
|
||||||
|
@ -575,10 +562,10 @@ bool UThread::initIPC(pthread_mutex_t* mutex, pthread_cond_t* cond)
|
||||||
{
|
{
|
||||||
pthread_mutexattr_t mutexattr;
|
pthread_mutexattr_t mutexattr;
|
||||||
|
|
||||||
if (U_SYSCALL(pthread_mutexattr_init, "%p", &mutexattr) == -1 ||
|
if (U_SYSCALL(pthread_mutexattr_init, "%p", &mutexattr) != 0 ||
|
||||||
U_SYSCALL(pthread_mutexattr_setrobust, "%p,%d", &mutexattr, PTHREAD_MUTEX_ROBUST) == -1 ||
|
U_SYSCALL(pthread_mutexattr_setrobust, "%p,%d", &mutexattr, PTHREAD_MUTEX_ROBUST) != 0 ||
|
||||||
U_SYSCALL(pthread_mutexattr_setpshared, "%p,%d", &mutexattr, PTHREAD_PROCESS_SHARED) == -1 ||
|
U_SYSCALL(pthread_mutexattr_setpshared, "%p,%d", &mutexattr, PTHREAD_PROCESS_SHARED) != 0 ||
|
||||||
U_SYSCALL(pthread_mutex_init, "%p,%p", mutex, &mutexattr) == -1)
|
U_SYSCALL(pthread_mutex_init, "%p,%p", mutex, &mutexattr) != 0)
|
||||||
{
|
{
|
||||||
U_RETURN(false);
|
U_RETURN(false);
|
||||||
}
|
}
|
||||||
|
@ -588,9 +575,9 @@ bool UThread::initIPC(pthread_mutex_t* mutex, pthread_cond_t* cond)
|
||||||
{
|
{
|
||||||
pthread_condattr_t condattr;
|
pthread_condattr_t condattr;
|
||||||
|
|
||||||
if (U_SYSCALL(pthread_condattr_init, "%p", &condattr) == -1 ||
|
if (U_SYSCALL(pthread_condattr_init, "%p", &condattr) != 0 ||
|
||||||
U_SYSCALL(pthread_condattr_setpshared, "%p,%d", &condattr, PTHREAD_PROCESS_SHARED) == -1 ||
|
U_SYSCALL(pthread_condattr_setpshared, "%p,%d", &condattr, PTHREAD_PROCESS_SHARED) != 0 ||
|
||||||
U_SYSCALL(pthread_cond_init, "%p,%p", cond, &condattr) == -1)
|
U_SYSCALL(pthread_cond_init, "%p,%p", cond, &condattr) != 0)
|
||||||
{
|
{
|
||||||
U_RETURN(false);
|
U_RETURN(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,8 +127,14 @@ long UTimeVal::restart()
|
||||||
{
|
{
|
||||||
U_TRACE(1, "UTimeVal::restart()")
|
U_TRACE(1, "UTimeVal::restart()")
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
long tv_sec_old = u_now->tv_sec;
|
||||||
|
#endif
|
||||||
|
|
||||||
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT(tv_sec_old <= u_now->tv_sec)
|
||||||
|
|
||||||
struct timeval time_from_last_start = { u_now->tv_sec - tv_sec, u_now->tv_usec - tv_usec };
|
struct timeval time_from_last_start = { u_now->tv_sec - tv_sec, u_now->tv_usec - tv_usec };
|
||||||
|
|
||||||
tv_sec = u_now->tv_sec;
|
tv_sec = u_now->tv_sec;
|
||||||
|
@ -151,8 +157,14 @@ long UTimeVal::stop()
|
||||||
{
|
{
|
||||||
U_TRACE(1, "UTimeVal::stop()")
|
U_TRACE(1, "UTimeVal::stop()")
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
long tv_sec_old = u_now->tv_sec;
|
||||||
|
#endif
|
||||||
|
|
||||||
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
(void) U_SYSCALL(gettimeofday, "%p,%p", u_now, 0);
|
||||||
|
|
||||||
|
U_INTERNAL_ASSERT(tv_sec_old <= u_now->tv_sec)
|
||||||
|
|
||||||
struct timeval time_elapsed = { u_now->tv_sec - tv_sec, u_now->tv_usec - tv_usec };
|
struct timeval time_elapsed = { u_now->tv_sec - tv_sec, u_now->tv_usec - tv_usec };
|
||||||
|
|
||||||
if (time_elapsed.tv_usec < 0L)
|
if (time_elapsed.tv_usec < 0L)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -55,22 +55,22 @@ void USemaphore::init(sem_t* ptr, int resource)
|
||||||
U_INTERNAL_ASSERT_DIFFERS(first, next)
|
U_INTERNAL_ASSERT_DIFFERS(first, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG
|
||||||
int _value = getValue();
|
int _value = getValue();
|
||||||
|
|
||||||
if (_value != resource) U_ERROR("USemaphore::init(%p,%u) failed - value = %d", ptr, resource, _value);
|
if (_value != resource) U_ERROR("USemaphore::init(%p,%u) failed - value = %d", ptr, resource, _value);
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# ifdef _MSWINDOWS_
|
# ifdef _MSWINDOWS_
|
||||||
psem = (sem_t*) ::CreateSemaphore((LPSECURITY_ATTRIBUTES)NULL, (LONG)resource, 1000000, (LPCTSTR)NULL);
|
psem = (sem_t*) ::CreateSemaphore((LPSECURITY_ATTRIBUTES)NULL, (LONG)resource, 1000000, (LPCTSTR)NULL);
|
||||||
# else
|
# else
|
||||||
if (flock == 0)
|
if (flock == 0)
|
||||||
{
|
{
|
||||||
flock = U_NEW(UFile);
|
flock = U_NEW(UFile);
|
||||||
|
|
||||||
if (flock->mkTemp(0) == false) U_ERROR("USemaphore::init(%p,%u) failed", ptr, resource);
|
if (flock->mkTemp(0) == false) U_ERROR("USemaphore::init(%p,%u) failed", ptr, resource);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,11 +88,11 @@ USemaphore::~USemaphore()
|
||||||
|
|
||||||
(void) sem_destroy(psem); // Free resources associated with semaphore object sem
|
(void) sem_destroy(psem); // Free resources associated with semaphore object sem
|
||||||
#else
|
#else
|
||||||
# ifdef _MSWINDOWS_
|
# ifdef _MSWINDOWS_
|
||||||
::CloseHandle((HANDLE)psem);
|
::CloseHandle((HANDLE)psem);
|
||||||
# else
|
# else
|
||||||
(void) flock->close();
|
(void) flock->close();
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,11 +116,11 @@ void USemaphore::post()
|
||||||
|
|
||||||
U_INTERNAL_DUMP("value = %d", getValue())
|
U_INTERNAL_DUMP("value = %d", getValue())
|
||||||
#else
|
#else
|
||||||
# ifdef _MSWINDOWS_
|
# ifdef _MSWINDOWS_
|
||||||
::ReleaseSemaphore((HANDLE)psem, 1, (LPLONG)NULL);
|
::ReleaseSemaphore((HANDLE)psem, 1, (LPLONG)NULL);
|
||||||
# else
|
# else
|
||||||
(void) flock->unlock();
|
(void) flock->unlock();
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,11 +190,11 @@ bool USemaphore::wait(time_t timeoutMS)
|
||||||
|
|
||||||
if (rc == 0) U_RETURN(true);
|
if (rc == 0) U_RETURN(true);
|
||||||
#else
|
#else
|
||||||
# ifdef _MSWINDOWS_
|
# ifdef _MSWINDOWS_
|
||||||
if (::WaitForSingleObject((HANDLE)psem, timeoutMS) == WAIT_OBJECT_0) U_RETURN(true);
|
if (::WaitForSingleObject((HANDLE)psem, timeoutMS) == WAIT_OBJECT_0) U_RETURN(true);
|
||||||
# else
|
# else
|
||||||
if (flock->unlock()) U_RETURN(true);
|
if (flock->unlock()) U_RETURN(true);
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
U_RETURN(false);
|
U_RETURN(false);
|
||||||
|
@ -234,11 +234,11 @@ wait:
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(rc, 0)
|
U_INTERNAL_ASSERT_EQUALS(rc, 0)
|
||||||
#else
|
#else
|
||||||
# ifdef _MSWINDOWS_
|
# ifdef _MSWINDOWS_
|
||||||
(void) ::WaitForSingleObject((HANDLE)psem, INFINITE);
|
(void) ::WaitForSingleObject((HANDLE)psem, INFINITE);
|
||||||
# else
|
# else
|
||||||
(void) flock->unlock();
|
(void) flock->unlock();
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
#include <ulib/utility/services.h>
|
#include <ulib/utility/services.h>
|
||||||
#include <ulib/net/server/server.h>
|
#include <ulib/net/server/server.h>
|
||||||
|
|
||||||
|
#ifdef USE_LIBUUID
|
||||||
|
# include <uuid/uuid.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned char UServices::key[16];
|
unsigned char UServices::key[16];
|
||||||
|
|
||||||
/* coverity[+alloc] */
|
/* coverity[+alloc] */
|
||||||
|
@ -222,13 +226,15 @@ int UServices::askToLDAP(UString* pinput, UHashMap<UString>* ptable, const char*
|
||||||
U_RETURN(0);
|
U_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// creat a new unique UUID value - 8 bytes (64 bits) long
|
||||||
|
|
||||||
uint64_t UServices::getUniqUID()
|
uint64_t UServices::getUniqUID()
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UServices::getUniqUID()")
|
U_TRACE(0, "UServices::getUniqUID()")
|
||||||
|
|
||||||
static uint64_t unique_num;
|
static uint64_t unique_num;
|
||||||
|
|
||||||
if (unique_num == 0) unique_num = (uint64_t)u_now->tv_usec;
|
if (unique_num == 0) unique_num = (uint64_t)u_seed_hash;
|
||||||
|
|
||||||
uint64_t _uid = (((uint64_t)u_pid) << 56) |
|
uint64_t _uid = (((uint64_t)u_pid) << 56) |
|
||||||
((((uint64_t)u_now->tv_sec) & (0xfffffULL << 20)) << 16) |
|
((((uint64_t)u_now->tv_sec) & (0xfffffULL << 20)) << 16) |
|
||||||
|
@ -237,27 +243,75 @@ uint64_t UServices::getUniqUID()
|
||||||
U_RETURN(_uid);
|
U_RETURN(_uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_LIBUUID
|
|
||||||
// creat a new unique UUID value - 16 bytes (128 bits) long
|
// creat a new unique UUID value - 16 bytes (128 bits) long
|
||||||
// return from the binary representation a 36-byte string (plus tailing '\0') of the form 1b4e28ba-2fa1-11d2-883f-0016d3cca427
|
// return from the binary representation a 36-byte string (plus tailing '\0') of the form 1b4e28ba-2fa1-11d2-883f-0016d3cca427
|
||||||
|
|
||||||
uuid_t UServices::uuid; // typedef unsigned char uuid_t[16];
|
|
||||||
|
|
||||||
UString UServices::getUUID()
|
UString UServices::getUUID()
|
||||||
{
|
{
|
||||||
U_TRACE(1, "UServices::getUUID()")
|
U_TRACE(1, "UServices::getUUID()")
|
||||||
|
|
||||||
UString id(37U);
|
UString buffer(36U);
|
||||||
|
char* id = buffer.data();
|
||||||
|
|
||||||
U_SYSCALL_VOID(uuid_generate, "%p", uuid);
|
#ifdef USE_LIBUUID
|
||||||
U_SYSCALL_VOID(uuid_unparse, "%p", uuid, id.data());
|
uuid_t uuid; // typedef unsigned char uuid_t[16];
|
||||||
|
|
||||||
id.size_adjust(36U);
|
U_SYSCALL_VOID(uuid_generate, "%p", uuid);
|
||||||
|
U_SYSCALL_VOID(uuid_unparse, "%p,%p", uuid, id);
|
||||||
|
#else
|
||||||
|
static unsigned short clock_seq;
|
||||||
|
|
||||||
U_RETURN_STRING(id);
|
unsigned short clock_seq_low = ++clock_seq & 0xff;
|
||||||
}
|
unsigned short clock_seq_hi_variant = (clock_seq >> 8) & 0x3f;
|
||||||
|
|
||||||
|
uint64_t node = getUniqUID(),
|
||||||
|
ossp_time = (((uint64_t)u_now->tv_sec + (141427ULL * 24ULL * 60ULL * 60ULL)) * 10000000ULL) + (u_now->tv_usec > 0 ? u_now->tv_usec * 10 : 0);
|
||||||
|
|
||||||
|
uint32_t time_low = htonl( ossp_time & 0xffffffff),
|
||||||
|
time_mid = htons((ossp_time >> 32) & 0x0000ffff),
|
||||||
|
time_hi_and_version = htons((ossp_time >> 48) & 0x00000fff);
|
||||||
|
|
||||||
|
#define U_APPEND_HEX(value, offset) \
|
||||||
|
*id++ = u_hex_upper[(((char*)&value)[offset] >> 4) & 0x0F]; \
|
||||||
|
*id++ = u_hex_upper[(((char*)&value)[offset] ) & 0x0F];
|
||||||
|
|
||||||
|
U_APPEND_HEX(time_low, 0);
|
||||||
|
U_APPEND_HEX(time_low, 1);
|
||||||
|
U_APPEND_HEX(time_low, 2);
|
||||||
|
U_APPEND_HEX(time_low, 3);
|
||||||
|
|
||||||
|
*id++ = '-';
|
||||||
|
|
||||||
|
U_APPEND_HEX(time_mid, 0);
|
||||||
|
U_APPEND_HEX(time_mid, 1);
|
||||||
|
|
||||||
|
*id++ = '-';
|
||||||
|
|
||||||
|
U_APPEND_HEX(time_hi_and_version, 0);
|
||||||
|
U_APPEND_HEX(time_hi_and_version, 1);
|
||||||
|
|
||||||
|
*id++ = '-';
|
||||||
|
|
||||||
|
U_APPEND_HEX(clock_seq_hi_variant, 0);
|
||||||
|
U_APPEND_HEX(clock_seq_low, 0);
|
||||||
|
|
||||||
|
*id++ = '-';
|
||||||
|
|
||||||
|
U_APPEND_HEX(node, 0);
|
||||||
|
U_APPEND_HEX(node, 1);
|
||||||
|
U_APPEND_HEX(node, 2);
|
||||||
|
U_APPEND_HEX(node, 3);
|
||||||
|
U_APPEND_HEX(node, 4);
|
||||||
|
U_APPEND_HEX(node, 5);
|
||||||
|
|
||||||
|
#undef U_APPEND_HEX(value, offset)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
buffer.size_adjust(36U);
|
||||||
|
|
||||||
|
U_RETURN_STRING(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_LIBSSL
|
#ifdef USE_LIBSSL
|
||||||
# include <openssl/err.h>
|
# include <openssl/err.h>
|
||||||
# include <openssl/engine.h>
|
# include <openssl/engine.h>
|
||||||
|
|
|
@ -956,7 +956,7 @@ void UHTTP::ctor()
|
||||||
/**
|
/**
|
||||||
* Set up static environment variables
|
* Set up static environment variables
|
||||||
* -------------------------------------------------------------------------------------------------------------------------------------------
|
* -------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
* server static variable Description
|
* server static variable Description
|
||||||
* -------------------------------------------------------------------------------------------------------------------------------------------
|
* -------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
* SERVER_PORT
|
* SERVER_PORT
|
||||||
* SERVER_ADDR
|
* SERVER_ADDR
|
||||||
|
@ -966,14 +966,14 @@ void UHTTP::ctor()
|
||||||
* GATEWAY_INTERFACE CGI specification revision with which this server complies. Format: CGI/revision
|
* GATEWAY_INTERFACE CGI specification revision with which this server complies. Format: CGI/revision
|
||||||
* -------------------------------------------------------------------------------------------------------------------------------------------
|
* -------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
* Example:
|
* Example:
|
||||||
* ----------------------------------------------------------------------------------------------------------------------------
|
* -------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
* SERVER_PORT=80
|
* SERVER_PORT=80
|
||||||
* SERVER_ADDR=127.0.0.1
|
* SERVER_ADDR=127.0.0.1
|
||||||
* SERVER_NAME=localhost
|
* SERVER_NAME=localhost
|
||||||
* DOCUMENT_ROOT="/var/www/localhost/htdocs"
|
* DOCUMENT_ROOT="/var/www/localhost/htdocs"
|
||||||
* SERVER_SOFTWARE=Apache
|
* SERVER_SOFTWARE=Apache
|
||||||
* GATEWAY_INTERFACE=CGI/1.1
|
* GATEWAY_INTERFACE=CGI/1.1
|
||||||
* ----------------------------------------------------------------------------------------------------------------------------
|
* -------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_POINTER(UServer_Base::cenvironment)
|
U_INTERNAL_ASSERT_POINTER(UServer_Base::cenvironment)
|
||||||
|
@ -1047,14 +1047,14 @@ next:
|
||||||
cache_file = U_NEW(UHashMap<UHTTP::UFileCacheData*>);
|
cache_file = U_NEW(UHashMap<UHTTP::UFileCacheData*>);
|
||||||
|
|
||||||
#ifdef U_STATIC_ONLY
|
#ifdef U_STATIC_ONLY
|
||||||
# if defined(U_ALIAS) && !defined(U_STATIC_SERVLET_WI_AUTH)
|
# if defined(U_ALIAS) && !defined(U_STATIC_SERVLET_WI_AUTH)
|
||||||
U_INTERNAL_ASSERT_EQUALS(virtual_host, false)
|
U_INTERNAL_ASSERT_EQUALS(virtual_host, false)
|
||||||
# endif
|
# endif
|
||||||
/**
|
/**
|
||||||
* I do know that to include code in the middle of a function is hacky and dirty, but this is the best solution that I could figure out.
|
* I do know that to include code in the middle of a function is hacky and dirty, but this is the best solution that I could figure out.
|
||||||
* If you have some idea to clean it up, please, don't hesitate and let me know
|
* If you have some idea to clean it up, please, don't hesitate and let me know
|
||||||
*/
|
*/
|
||||||
# include "../net/server/plugin/usp/loader.autoconf.cpp"
|
# include "../net/server/plugin/usp/loader.autoconf.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(file_not_in_cache_data, 0)
|
U_INTERNAL_ASSERT_EQUALS(file_not_in_cache_data, 0)
|
||||||
|
@ -1101,7 +1101,7 @@ next:
|
||||||
# ifdef U_STDCPP_ENABLE
|
# ifdef U_STDCPP_ENABLE
|
||||||
if (content_cache)
|
if (content_cache)
|
||||||
{
|
{
|
||||||
n += (content_cache.size() / (1024 + 512)); // NB: we assume as medium file size ~1.5k...
|
n += (content_cache.size() / (1024 + 512)); // NB: we assume as medium file size something like ~1.5k...
|
||||||
|
|
||||||
UString2Object(U_STRING_TO_PARAM(content_cache), *cache_file);
|
UString2Object(U_STRING_TO_PARAM(content_cache), *cache_file);
|
||||||
|
|
||||||
|
@ -1492,7 +1492,15 @@ __pure bool UHTTP::isMobile()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* ---------------------------------------------------------------------------------------------------------------------------
|
||||||
* HTTP message
|
* HTTP message
|
||||||
|
* ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
* There are four parts to an HTTP request:
|
||||||
|
* ---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
* 1) the request line [REQUIRED]: the method, the URL, the version of the protocol
|
||||||
|
* 2) the request headers [OPTIONAL]: a series of lines (one per) in the format of name, colon(:), and the value of the header
|
||||||
|
* 3) a blank line [REQUIRED]: worth mentioning by itself
|
||||||
|
* 4) the request Body [OPTIONAL]: used in POST/PUT/PATCH requests to send content to the server
|
||||||
* ======================================================================================
|
* ======================================================================================
|
||||||
* Read the request line and attached headers. A typical http request will take the form:
|
* Read the request line and attached headers. A typical http request will take the form:
|
||||||
* ======================================================================================
|
* ======================================================================================
|
||||||
|
@ -1641,14 +1649,18 @@ int UHTTP::handlerDataPending()
|
||||||
U_RETURN(-1);
|
U_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: HTTP/2 implementation
|
U_ClientImage_data_missing = false;
|
||||||
|
|
||||||
|
UClientImage_Base::setRequestNeedProcessing();
|
||||||
|
|
||||||
|
(void) manageRequest();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
return 1 // child of parallelization
|
return 1 // child of parallelization
|
||||||
return -1 // parent of parallelization
|
return -1 // parent of parallelization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
U_RETURN(-1);
|
U_RETURN(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -1661,22 +1673,26 @@ bool UHTTP::scanfHeaderRequest(const char* ptr, uint32_t size)
|
||||||
U_TRACE(0, "UHTTP::scanfHeaderRequest(%.*S,%u)", size, ptr, size)
|
U_TRACE(0, "UHTTP::scanfHeaderRequest(%.*S,%u)", size, ptr, size)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ------------------------------------------------------------------
|
* -------------------------------------------------------------------
|
||||||
* Check HTTP request.
|
* Check HTTP request
|
||||||
|
* -------------------------------------------------------------------
|
||||||
* The default is GET for input requests and POST for output requests.
|
* The default is GET for input requests and POST for output requests.
|
||||||
* Other possible alternatives are:
|
* Other possible alternatives are:
|
||||||
* ------------------------------------------------------------------
|
* -------------------------------------------------------------------
|
||||||
* - PUT
|
* - PUT
|
||||||
* - HEAD
|
* - HEAD
|
||||||
* - COPY
|
* - COPY
|
||||||
* - PATCH
|
* - PATCH
|
||||||
* - DELETE
|
* - DELETE
|
||||||
* - OPTIONS
|
* - OPTIONS
|
||||||
* ---------------------- NOT implemented ---------------------------
|
* ---------------------- NOT implemented ----------------------------
|
||||||
* - CONNECT
|
* - CONNECT
|
||||||
* - TRACE (because can send client cookie information, dangerous...)
|
* - TRACE (because can send client cookie information, dangerous...)
|
||||||
* ------------------------------------------------------------------
|
* -------------------------------------------------------------------
|
||||||
* See http://ietf.org/rfc/rfc2616.txt for further information about HTTP request methods
|
* for further information about HTTP request methods see:
|
||||||
|
*
|
||||||
|
* http://ietf.org/rfc/rfc2616.txt
|
||||||
|
* -------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
@ -3169,17 +3185,6 @@ bool UHTTP::callService(const UString& path) // NB: it is used also by server_pl
|
||||||
U_RETURN(true);
|
U_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ---------------------------------------------------------------------------------------------------------------------------
|
|
||||||
* There are four parts to an HTTP request:
|
|
||||||
* ---------------------------------------------------------------------------------------------------------------------------
|
|
||||||
* 1) the request line [REQUIRED]: the method, the URL, the version of the protocol
|
|
||||||
* 2) the request headers [OPTIONAL]: a series of lines (one per) in the format of name, colon(:), and the value of the header
|
|
||||||
* 3) a blank line [REQUIRED]: worth mentioning by itself
|
|
||||||
* 4) the request Body [OPTIONAL]: used in POST/PUT/PATCH requests to send content to the server
|
|
||||||
* ---------------------------------------------------------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool UHTTP::handlerCache()
|
bool UHTTP::handlerCache()
|
||||||
{
|
{
|
||||||
U_TRACE(0, "UHTTP::handlerCache()")
|
U_TRACE(0, "UHTTP::handlerCache()")
|
||||||
|
@ -3338,7 +3343,6 @@ int UHTTP::handlerREAD()
|
||||||
|
|
||||||
U_INTERNAL_ASSERT(*UClientImage_Base::request)
|
U_INTERNAL_ASSERT(*UClientImage_Base::request)
|
||||||
|
|
||||||
const char* ptr;
|
|
||||||
bool result_read_body;
|
bool result_read_body;
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
@ -3452,8 +3456,7 @@ dmiss: UClientImage_Base::setRequestProcessed();
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(U_ClientImage_data_missing, false)
|
U_INTERNAL_ASSERT_EQUALS(U_ClientImage_data_missing, false)
|
||||||
|
|
||||||
if (result_read_body) UClientImage_Base::size_request += U_http_info.clength;
|
if (result_read_body == false)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
U_INTERNAL_DUMP("UServer_Base::csocket->isClosed() = %b UClientImage_Base::wbuffer(%u) = %V",
|
U_INTERNAL_DUMP("UServer_Base::csocket->isClosed() = %b UClientImage_Base::wbuffer(%u) = %V",
|
||||||
UServer_Base::csocket->isClosed(), UClientImage_Base::wbuffer->size(), UClientImage_Base::wbuffer->rep)
|
UServer_Base::csocket->isClosed(), UClientImage_Base::wbuffer->size(), UClientImage_Base::wbuffer->rep)
|
||||||
|
@ -3464,11 +3467,22 @@ dmiss: UClientImage_Base::setRequestProcessed();
|
||||||
|
|
||||||
U_RETURN(U_PLUGIN_HANDLER_FINISHED);
|
U_RETURN(U_PLUGIN_HANDLER_FINISHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UClientImage_Base::size_request += U_http_info.clength;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return manageRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
int UHTTP::manageRequest()
|
||||||
|
{
|
||||||
|
U_TRACE(0, "UHTTP::manageRequest()")
|
||||||
|
|
||||||
// check the HTTP message
|
// check the HTTP message
|
||||||
|
|
||||||
|
U_INTERNAL_DUMP("U_ClientImage_request = %d %B", U_ClientImage_request, U_ClientImage_request)
|
||||||
|
|
||||||
U_ASSERT(UClientImage_Base::isRequestNotFound())
|
U_ASSERT(UClientImage_Base::isRequestNotFound())
|
||||||
|
|
||||||
// manage alias uri
|
// manage alias uri
|
||||||
|
@ -3501,6 +3515,7 @@ dmiss: UClientImage_Base::setRequestProcessed();
|
||||||
if (valias)
|
if (valias)
|
||||||
{
|
{
|
||||||
UString str;
|
UString str;
|
||||||
|
const char* ptr;
|
||||||
int i, n = valias->size();
|
int i, n = valias->size();
|
||||||
|
|
||||||
// Ex: /admin /admin.html
|
// Ex: /admin /admin.html
|
||||||
|
@ -3512,7 +3527,6 @@ dmiss: UClientImage_Base::setRequestProcessed();
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
|
|
||||||
str = (*valias)[i];
|
str = (*valias)[i];
|
||||||
|
|
||||||
ptr = str.data();
|
ptr = str.data();
|
||||||
|
|
||||||
int len = str.size();
|
int len = str.size();
|
||||||
|
@ -3624,7 +3638,7 @@ set_uri: U_http_info.uri = alias->data();
|
||||||
// we check if it is present as shared file (without the virtual host prefix)
|
// we check if it is present as shared file (without the virtual host prefix)
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
# ifndef U_SERVER_CAPTIVE_PORTAL
|
# ifndef U_SERVER_CAPTIVE_PORTAL
|
||||||
ptr = pathname->c_pointer(u_cwd_len);
|
const char* ptr = pathname->c_pointer(u_cwd_len);
|
||||||
|
|
||||||
# ifdef U_ALIAS
|
# ifdef U_ALIAS
|
||||||
U_INTERNAL_DUMP("virtual_host = %b U_http_host_vlen = %u U_http_is_request_nostat = %b", virtual_host, U_http_host_vlen, U_http_is_request_nostat)
|
U_INTERNAL_DUMP("virtual_host = %b U_http_host_vlen = %u U_http_is_request_nostat = %b", virtual_host, U_http_host_vlen, U_http_is_request_nostat)
|
||||||
|
@ -4224,9 +4238,9 @@ void UHTTP::setEndRequestProcessing()
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
U_INTERNAL_ASSERT_EQUALS(U_HTTP_DATE2, iov_vec[2].iov_base)
|
U_INTERNAL_ASSERT_EQUALS(iov_vec[2].iov_base, ULog::date.date2)
|
||||||
|
|
||||||
ULog::updateStaticDate(U_HTTP_DATE2, 2);
|
ULog::updateDate2();
|
||||||
|
|
||||||
UServer_Base::apache_like_log->write(iov_vec, 10);
|
UServer_Base::apache_like_log->write(iov_vec, 10);
|
||||||
|
|
||||||
|
@ -5199,11 +5213,11 @@ uint32_t UHTTP::processForm()
|
||||||
{
|
{
|
||||||
U_ASSERT(isPOST())
|
U_ASSERT(isPOST())
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// POST
|
// POST
|
||||||
// ------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Content-Type: application/x-www-form-urlencoded OR multipart/form-data...
|
// Content-Type: application/x-www-form-urlencoded OR multipart/form-data...
|
||||||
// ------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
if (U_HTTP_CTYPE_MEMEQ("application/x-www-form-urlencoded")) tmp = *UClientImage_Base::body;
|
if (U_HTTP_CTYPE_MEMEQ("application/x-www-form-urlencoded")) tmp = *UClientImage_Base::body;
|
||||||
else
|
else
|
||||||
|
@ -5438,6 +5452,13 @@ UString UHTTP::getHeaderForResponse()
|
||||||
|
|
||||||
UClientImage_Base::setRequestProcessed();
|
UClientImage_Base::setRequestProcessed();
|
||||||
|
|
||||||
|
#ifndef U_HTTP2_DISABLE
|
||||||
|
if (U_http_version == '2')
|
||||||
|
{
|
||||||
|
return UString::getStringNull();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UClientImage_Base::setHeaderForResponse(6+29+2+12+2); // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\n
|
UClientImage_Base::setHeaderForResponse(6+29+2+12+2); // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\n
|
||||||
|
|
||||||
if (U_http_info.nResponseCode == HTTP_NOT_IMPLEMENTED ||
|
if (U_http_info.nResponseCode == HTTP_NOT_IMPLEMENTED ||
|
||||||
|
@ -5665,7 +5686,8 @@ void UHTTP::setResponse(const UString* content_type, UString* pbody)
|
||||||
"<address>ULib Server</address>\r\n" \
|
"<address>ULib Server</address>\r\n" \
|
||||||
"</body></html>\r\n"
|
"</body></html>\r\n"
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------------------------------------
|
/**
|
||||||
|
* ------------------------------------------------------------------------------------------------------------------
|
||||||
* http://sebastians-pamphlets.com/the-anatomy-of-http-redirects-301-302-307/
|
* http://sebastians-pamphlets.com/the-anatomy-of-http-redirects-301-302-307/
|
||||||
* ------------------------------------------------------------------------------------------------------------------
|
* ------------------------------------------------------------------------------------------------------------------
|
||||||
* HTTP/1.0
|
* HTTP/1.0
|
||||||
|
@ -5695,6 +5717,7 @@ void UHTTP::setResponse(const UString* content_type, UString* pbody)
|
||||||
* the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new
|
* the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new
|
||||||
* URI(s), since many pre-HTTP/1.1 user agents do not understand the 307 status. Therefore, the note SHOULD contain the
|
* URI(s), since many pre-HTTP/1.1 user agents do not understand the 307 status. Therefore, the note SHOULD contain the
|
||||||
* information necessary for a user to repeat the original request on the new URI.
|
* information necessary for a user to repeat the original request on the new URI.
|
||||||
|
* ------------------------------------------------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void UHTTP::setRedirectResponse(int mode, const char* ptr_location, uint32_t len_location)
|
void UHTTP::setRedirectResponse(int mode, const char* ptr_location, uint32_t len_location)
|
||||||
|
@ -9598,12 +9621,12 @@ void UHTTP::initApacheLikeLog()
|
||||||
|
|
||||||
iov_vec[1].iov_base = (caddr_t) " - - [";
|
iov_vec[1].iov_base = (caddr_t) " - - [";
|
||||||
iov_vec[1].iov_len = U_CONSTANT_SIZE(" - - [");
|
iov_vec[1].iov_len = U_CONSTANT_SIZE(" - - [");
|
||||||
iov_vec[2].iov_base = (caddr_t) U_HTTP_DATE2; // %d/%b/%Y:%T %z - 21/May/2012:16:29:41 +0200
|
iov_vec[2].iov_base = (caddr_t)ULog::date.date2; // %d/%b/%Y:%T %z - 21/May/2012:16:29:41 +0200
|
||||||
iov_vec[2].iov_len = 26;
|
iov_vec[2].iov_len = 26;
|
||||||
iov_vec[3].iov_base = (caddr_t) "] \"";
|
iov_vec[3].iov_base = (caddr_t) "] \"";
|
||||||
iov_vec[3].iov_len = U_CONSTANT_SIZE("] \"");
|
iov_vec[3].iov_len = U_CONSTANT_SIZE("] \"");
|
||||||
// request
|
// request
|
||||||
iov_vec[5].iov_base = (caddr_t) iov_buffer; // response_code, body_len
|
iov_vec[5].iov_base = (caddr_t)iov_buffer; // response_code, body_len
|
||||||
// referer
|
// referer
|
||||||
iov_vec[7].iov_base = (caddr_t) "\" \"";
|
iov_vec[7].iov_base = (caddr_t) "\" \"";
|
||||||
iov_vec[7].iov_len = U_CONSTANT_SIZE("\" \"");
|
iov_vec[7].iov_len = U_CONSTANT_SIZE("\" \"");
|
||||||
|
|
|
@ -22,9 +22,9 @@ export ORM_DRIVER ORM_OPTION UMEMPOOL
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
# PLAINTEXT
|
# PLAINTEXT
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
UMEMPOOL="982,0,0,36,9846,-24,-23,1727,1151"
|
#UMEMPOOL="982,0,0,36,9846,-24,-23,1727,1151"
|
||||||
sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
#sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
||||||
sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 16384|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
#sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 16384|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
||||||
#sed -i "s|CLIENT_THRESHOLD .*|CLIENT_THRESHOLD 4000|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
#sed -i "s|CLIENT_THRESHOLD .*|CLIENT_THRESHOLD 4000|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
||||||
#sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 8000|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
#sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 8000|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -58,9 +58,9 @@ export ORM_DRIVER ORM_OPTION UMEMPOOL
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
# JSON
|
# JSON
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
#UMEMPOOL="56,0,0,40,150,-24,-13,-20,0"
|
UMEMPOOL="56,0,0,40,150,-24,-13,-20,0"
|
||||||
#sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
||||||
#sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
||||||
#sed -i "s|CLIENT_THRESHOLD .*|CLIENT_THRESHOLD 50|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
#sed -i "s|CLIENT_THRESHOLD .*|CLIENT_THRESHOLD 50|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
||||||
#sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
#sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" benchmark/FrameworkBenchmarks/fbenchmark.cfg
|
||||||
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -3,7 +3,7 @@ userver {
|
||||||
PORT 8080
|
PORT 8080
|
||||||
PREFORK_CHILD 4
|
PREFORK_CHILD 4
|
||||||
TCP_LINGER_SET 0
|
TCP_LINGER_SET 0
|
||||||
LISTEN_BACKLOG 16384
|
LISTEN_BACKLOG 256
|
||||||
DOCUMENT_ROOT benchmark/FrameworkBenchmarks/ULib/www
|
DOCUMENT_ROOT benchmark/FrameworkBenchmarks/ULib/www
|
||||||
PID_FILE benchmark/FrameworkBenchmarks/ULib/userver_tcp.pid
|
PID_FILE benchmark/FrameworkBenchmarks/ULib/userver_tcp.pid
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,11 @@ rm -f $DOC_ROOT/web_server_multiclient.log* \
|
||||||
trace.*userver_*.[0-9]* object.*userver_*.[0-9]* stack.*userver_*.[0-9]* mempool.*userver_*.[0-9]* \
|
trace.*userver_*.[0-9]* object.*userver_*.[0-9]* stack.*userver_*.[0-9]* mempool.*userver_*.[0-9]* \
|
||||||
$DOC_ROOT/trace.*userver_*.[0-9]* $DOC_ROOT/object.*userver_*.[0-9]* $DOC_ROOT/stack.*userver_*.[0-9]* $DOC_ROOT/mempool.*userver_*.[0-9]*
|
$DOC_ROOT/trace.*userver_*.[0-9]* $DOC_ROOT/object.*userver_*.[0-9]* $DOC_ROOT/stack.*userver_*.[0-9]* $DOC_ROOT/mempool.*userver_*.[0-9]*
|
||||||
|
|
||||||
#UTRACE="0 100M 0"
|
#UTRACE="5 100M 0"
|
||||||
|
#UTRACE_SIGNAL="0 100M -1"
|
||||||
#UOBJDUMP="0 10M 100"
|
#UOBJDUMP="0 10M 100"
|
||||||
#USIMERR="error.sim"
|
#USIMERR="error.sim"
|
||||||
export UTRACE UOBJDUMP USIMERR
|
export UTRACE UOBJDUMP USIMERR UTRACE_SIGNAL
|
||||||
|
|
||||||
if [ "$TERM" = "msys" ]; then
|
if [ "$TERM" = "msys" ]; then
|
||||||
export TMPDIR="c:/tmp"
|
export TMPDIR="c:/tmp"
|
||||||
|
|
|
@ -39,11 +39,8 @@ U_EXPORT main (int argc, char* argv[])
|
||||||
|
|
||||||
// U_ASSERT( result1 == U_STRING_FROM_CONSTANT("test_services.cpp\n") )
|
// U_ASSERT( result1 == U_STRING_FROM_CONSTANT("test_services.cpp\n") )
|
||||||
|
|
||||||
#ifdef USE_LIBUUID
|
|
||||||
buffer = UServices::getUUID();
|
buffer = UServices::getUUID();
|
||||||
U_INTERNAL_DUMP("buffer = %#.*S", U_STRING_TO_TRACE(buffer))
|
U_INTERNAL_DUMP("buffer = %#.*S", U_STRING_TO_TRACE(buffer))
|
||||||
U_INTERNAL_DUMP("UServices::uuid = %#.*S", 16, UServices::uuid)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cmd = U_STRING_FROM_CONSTANT("cat test_services.cpp");
|
cmd = U_STRING_FROM_CONSTANT("cat test_services.cpp");
|
||||||
result2 = UCommand::outputCommand(cmd, 0, -1, fd_stderr);
|
result2 = UCommand::outputCommand(cmd, 0, -1, fd_stderr);
|
||||||
|
|
|
@ -53,39 +53,35 @@ U_EXPORT main (int argc, char* argv[])
|
||||||
U_ASSERT( UTimeDate::getSecondFromTime("19030314104248Z", true, "%4u%2u%2u%2u%2u%2uZ") < u_now->tv_sec )
|
U_ASSERT( UTimeDate::getSecondFromTime("19030314104248Z", true, "%4u%2u%2u%2u%2u%2uZ") < u_now->tv_sec )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
typedef struct static_date {
|
typedef struct log_date {
|
||||||
struct timeval _timeval; // => u_now
|
|
||||||
char lock1[1];
|
|
||||||
char date1[17+1]; // 18/06/12 18:45:56
|
char date1[17+1]; // 18/06/12 18:45:56
|
||||||
char lock2[1];
|
|
||||||
char date2[26+1]; // 04/Jun/2012:18:18:37 +0200
|
char date2[26+1]; // 04/Jun/2012:18:18:37 +0200
|
||||||
char lock3[1];
|
|
||||||
char date3[6+29+2+12+2+19+1]; // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\nConnection: close\r\n
|
char date3[6+29+2+12+2+19+1]; // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\nConnection: close\r\n
|
||||||
} static_date;
|
} log_date;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ULog::static_date log_data;
|
ULog::log_date log_date;
|
||||||
|
|
||||||
(void) u_strftime2(log_data.date1, 17, "%d/%m/%y %T", u_now->tv_sec + u_now_adjust);
|
(void) u_strftime2(log_date.date1, 17, "%d/%m/%y %T", u_now->tv_sec + u_now_adjust);
|
||||||
(void) u_strftime2(log_data.date2, 26, "%d/%b/%Y:%T %z", u_now->tv_sec + u_now_adjust);
|
(void) u_strftime2(log_date.date2, 26, "%d/%b/%Y:%T %z", u_now->tv_sec + u_now_adjust);
|
||||||
(void) u_strftime2(log_data.date3, 6+29+2+12+2+17+2, "Date: %a, %d %b %Y %T GMT\r\nServer: ULib\r\nConnection: close\r\n", u_now->tv_sec);
|
(void) u_strftime2(log_date.date3, 6+29+2+12+2+17+2, "Date: %a, %d %b %Y %T GMT\r\nServer: ULib\r\nConnection: close\r\n", u_now->tv_sec);
|
||||||
|
|
||||||
U_INTERNAL_DUMP("date1 = %.17S date2 = %.26S date3+6 = %.29S", log_data.date1, log_data.date2, log_data.date3+6)
|
U_INTERNAL_DUMP("date1 = %.17S date2 = %.26S date3+6 = %.29S", log_date.date1, log_date.date2, log_date.date3+6)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
for (int i = 0; i < 360; ++i)
|
for (int i = 0; i < 360; ++i)
|
||||||
{
|
{
|
||||||
u_now->tv_sec++;
|
u_now->tv_sec++;
|
||||||
|
|
||||||
UTimeDate::updateTime(log_data.date1 + 12);
|
UTimeDate::updateTime(log_date.date1 + 12);
|
||||||
UTimeDate::updateTime(log_data.date2 + 15);
|
UTimeDate::updateTime(log_date.date2 + 15);
|
||||||
UTimeDate::updateTime(log_data.date3+6 + 20);
|
UTimeDate::updateTime(log_date.date3+6 + 20);
|
||||||
|
|
||||||
cout.write(log_data.date1, 17);
|
cout.write(log_date.date1, 17);
|
||||||
cout.write(" - ", 3);
|
cout.write(" - ", 3);
|
||||||
cout.write(log_data.date2, 26);
|
cout.write(log_date.date2, 26);
|
||||||
cout.write(" - ", 3);
|
cout.write(" - ", 3);
|
||||||
cout.write(log_data.date3+6, 29);
|
cout.write(log_date.date3+6, 29);
|
||||||
cout.put('\n');
|
cout.put('\n');
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -39,11 +39,8 @@ U_EXPORT main (int argc, char* argv[])
|
||||||
|
|
||||||
// U_ASSERT( result1 == U_STRING_FROM_CONSTANT("test_services.cpp\n") )
|
// U_ASSERT( result1 == U_STRING_FROM_CONSTANT("test_services.cpp\n") )
|
||||||
|
|
||||||
#ifdef USE_LIBUUID
|
|
||||||
buffer = UServices::getUUID();
|
buffer = UServices::getUUID();
|
||||||
U_INTERNAL_DUMP("buffer = %#.*S", U_STRING_TO_TRACE(buffer))
|
U_INTERNAL_DUMP("buffer = %#.*S", U_STRING_TO_TRACE(buffer))
|
||||||
U_INTERNAL_DUMP("UServices::uuid = %#.*S", 16, UServices::uuid)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cmd = U_STRING_FROM_CONSTANT("cat test_services.cpp");
|
cmd = U_STRING_FROM_CONSTANT("cat test_services.cpp");
|
||||||
result2 = UCommand::outputCommand(cmd, 0, -1, fd_stderr);
|
result2 = UCommand::outputCommand(cmd, 0, -1, fd_stderr);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user