mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-09-28 19:05:55 +08:00
fix+sync
This commit is contained in:
parent
57371985d5
commit
b66e456d46
|
@ -219,8 +219,5 @@ extern U_EXPORT void runDynamicPage_ir_web(int param);
|
|||
);
|
||||
|
||||
UHTTP::putDataSession();
|
||||
|
||||
UClientImage_Base::setRequestNoCache();
|
||||
|
||||
|
||||
|
||||
} }
|
|
@ -109,7 +109,5 @@ extern U_EXPORT void runDynamicPage_wi_auth(int param);
|
|||
|
||||
if (U_http_info.nResponseCode == 0) (void) UClientImage_Base::environment->append(U_CONSTANT_TO_PARAM("HTTP_RESPONSE_CODE=0\n"));
|
||||
|
||||
UClientImage_Base::setRequestNoCache();
|
||||
|
||||
|
||||
} }
|
|
@ -749,7 +749,6 @@ protected:
|
|||
{
|
||||
U_TRACE_NO_PARAM(0, "USocket::setReusePort()")
|
||||
|
||||
U_ASSERT_EQUALS(isUDP(), false)
|
||||
U_ASSERT_EQUALS(isIPC(), false)
|
||||
|
||||
/**
|
||||
|
@ -768,6 +767,19 @@ protected:
|
|||
# endif
|
||||
}
|
||||
|
||||
bool listen()
|
||||
{
|
||||
U_TRACE_NO_PARAM(0, "USocket::listen()")
|
||||
|
||||
if (isUDP() ||
|
||||
U_SYSCALL(listen, "%d,%d", iSockDesc, iBackLog) == 0)
|
||||
{
|
||||
U_RETURN(true);
|
||||
}
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
void close_socket();
|
||||
void _close_socket();
|
||||
|
||||
|
|
|
@ -250,7 +250,11 @@ public:
|
|||
static UString substitute(const UString& s, const char* a, uint32_t n1, char b) { return substitute(U_STRING_TO_PARAM(s), a, n1, &b, 1); }
|
||||
static UString substitute(const UString& s, const char* a, uint32_t n1, const char* b, uint32_t n2) { return substitute(U_STRING_TO_PARAM(s), a, n1, b, n2); }
|
||||
|
||||
static UString substitute(const UString& s, const UString& a, const UString& b) { return substitute(U_STRING_TO_PARAM(s), U_STRING_TO_PARAM(a), U_STRING_TO_PARAM(b)); }
|
||||
static UString substitute(const char* s, uint32_t n, const UString& a, const UString& b) { return substitute(s, n, U_STRING_TO_PARAM(a), U_STRING_TO_PARAM(b)); }
|
||||
static UString substitute(const UString& s, const UString& a, const UString& b) { return substitute(U_STRING_TO_PARAM(s), U_STRING_TO_PARAM(a), U_STRING_TO_PARAM(b)); }
|
||||
|
||||
static UString substitute(const char* s, uint32_t n, UVector<UString>& vec);
|
||||
static UString substitute(const UString& s, UVector<UString>& vec) { return substitute(U_STRING_TO_PARAM(s), vec); }
|
||||
|
||||
// ERASE
|
||||
|
||||
|
|
|
@ -86,7 +86,11 @@ void UVector<void*>::insert(uint32_t pos, const void* elem) // add elem before p
|
|||
U_INTERNAL_ASSERT(pos <= _length)
|
||||
U_INTERNAL_ASSERT(_length <= _capacity)
|
||||
|
||||
if (_length == _capacity)
|
||||
if (_length != _capacity)
|
||||
{
|
||||
(void) U_SYSCALL(memmove, "%p,%p,%u", vec + pos + 1, vec + pos, (_length - pos) * sizeof(void*));
|
||||
}
|
||||
else
|
||||
{
|
||||
const void** old_vec = vec;
|
||||
uint32_t old_capacity = _capacity;
|
||||
|
@ -100,14 +104,6 @@ void UVector<void*>::insert(uint32_t pos, const void* elem) // add elem before p
|
|||
|
||||
UMemoryPool::_free(old_vec, old_capacity, sizeof(void*));
|
||||
}
|
||||
else
|
||||
{
|
||||
# ifdef U_APEX_ENABLE
|
||||
(void) U_SYSCALL(apex_memmove, "%p,%p,%u", vec + pos + 1, vec + pos, (_length - pos) * sizeof(void*));
|
||||
# else
|
||||
(void) U_SYSCALL( memmove, "%p,%p,%u", vec + pos + 1, vec + pos, (_length - pos) * sizeof(void*));
|
||||
# endif
|
||||
}
|
||||
|
||||
vec[pos] = elem;
|
||||
|
||||
|
@ -126,7 +122,11 @@ void UVector<void*>::insert(uint32_t pos, uint32_t n, const void* elem) // add n
|
|||
|
||||
uint32_t new_length = _length + n;
|
||||
|
||||
if (new_length > _capacity)
|
||||
if (new_length <= _capacity)
|
||||
{
|
||||
(void) U_SYSCALL(memmove, "%p,%p,%u", vec + pos + n, vec + pos, (_length - pos) * sizeof(void*));
|
||||
}
|
||||
else
|
||||
{
|
||||
const void** old_vec = vec;
|
||||
uint32_t old_capacity = _capacity;
|
||||
|
@ -140,14 +140,6 @@ void UVector<void*>::insert(uint32_t pos, uint32_t n, const void* elem) // add n
|
|||
|
||||
UMemoryPool::_free(old_vec, old_capacity, sizeof(void*));
|
||||
}
|
||||
else
|
||||
{
|
||||
# ifdef U_APEX_ENABLE
|
||||
(void) U_SYSCALL(apex_memmove, "%p,%p,%u", vec + pos + n, vec + pos, (_length - pos) * sizeof(void*));
|
||||
# else
|
||||
(void) U_SYSCALL( memmove, "%p,%p,%u", vec + pos + n, vec + pos, (_length - pos) * sizeof(void*));
|
||||
# endif
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < n; ++i) vec[pos++] = elem;
|
||||
|
||||
|
|
|
@ -280,8 +280,6 @@ void ULog::updateDate2()
|
|||
*/
|
||||
|
||||
#if defined(U_LINUX) && defined(ENABLE_THREAD)
|
||||
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||
|
||||
# ifndef U_SERVER_CAPTIVE_PORTAL
|
||||
(void) U_SYSCALL(pthread_rwlock_rdlock, "%p", prwlock);
|
||||
# endif
|
||||
|
@ -314,8 +312,6 @@ void ULog::updateDate2()
|
|||
(void) U_SYSCALL(pthread_rwlock_unlock, "%p", prwlock);
|
||||
# endif
|
||||
#else
|
||||
U_INTERNAL_ASSERT_EQUALS(u_pthread_time, U_NULLPTR)
|
||||
|
||||
u_gettimenow();
|
||||
|
||||
if (tv_sec_old_2 != u_now->tv_sec)
|
||||
|
@ -354,8 +350,6 @@ void ULog::updateDate3(char* ptr_date)
|
|||
*/
|
||||
|
||||
#if defined(U_LINUX) && defined(ENABLE_THREAD)
|
||||
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||
|
||||
# ifndef U_SERVER_CAPTIVE_PORTAL
|
||||
(void) U_SYSCALL(pthread_rwlock_rdlock, "%p", prwlock);
|
||||
# endif
|
||||
|
@ -400,8 +394,6 @@ void ULog::updateDate3(char* ptr_date)
|
|||
(void) U_SYSCALL(pthread_rwlock_unlock, "%p", prwlock);
|
||||
# endif
|
||||
#else
|
||||
U_INTERNAL_ASSERT_EQUALS(u_pthread_time, U_NULLPTR)
|
||||
|
||||
u_gettimenow();
|
||||
|
||||
if (tv_sec_old_3 != u_now->tv_sec)
|
||||
|
|
|
@ -980,6 +980,10 @@ void UClientImage_Base::prepareForRead()
|
|||
|
||||
u_clientimage_info.flag.u = 0; // NB: U_ClientImage_parallelization is reset by this...
|
||||
|
||||
#ifdef USERVER_UDP
|
||||
if (UServer_Base::budp == false)
|
||||
#endif
|
||||
{
|
||||
#ifdef U_CLASSIC_SUPPORT
|
||||
if (UServer_Base::isClassic())
|
||||
{
|
||||
|
@ -1053,6 +1057,7 @@ void UClientImage_Base::prepareForRead()
|
|||
#ifdef U_THROTTLING_SUPPORT
|
||||
UServer_Base::initThrottlingClient();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool UClientImage_Base::genericRead()
|
||||
|
@ -1175,9 +1180,6 @@ int UClientImage_Base::handlerRead() // Connection-wide hooks
|
|||
int result;
|
||||
uint32_t sz;
|
||||
|
||||
# ifdef USERVER_UDP
|
||||
if (UServer_Base::budp == false)
|
||||
# endif
|
||||
prepareForRead();
|
||||
|
||||
start:
|
||||
|
@ -1653,7 +1655,6 @@ bool UClientImage_Base::writeResponse()
|
|||
U_INTERNAL_ASSERT_MAJOR(iov_sav[0].iov_len, 0)
|
||||
|
||||
# if defined(U_LINUX) && defined(ENABLE_THREAD)
|
||||
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||
U_INTERNAL_ASSERT_EQUALS(iov_vec[1].iov_base, ULog::ptr_shared_date->date3)
|
||||
# else
|
||||
U_INTERNAL_ASSERT_EQUALS(iov_vec[1].iov_base, ULog::date.date3)
|
||||
|
|
|
@ -534,7 +534,6 @@ int UHttpPlugIn::handlerRun() // NB: we use this method instead of handlerInit()
|
|||
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\nConnection: close\r\n
|
||||
|
||||
#if defined(U_LINUX) && defined(ENABLE_THREAD)
|
||||
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||
U_INTERNAL_ASSERT_POINTER(UServer_Base::ptr_shared_data)
|
||||
|
||||
# ifndef U_SERVER_CAPTIVE_PORTAL
|
||||
|
|
2
src/ulib/net/server/plugin/usp/test.usp
Normal file
2
src/ulib/net/server/plugin/usp/test.usp
Normal file
|
@ -0,0 +1,2 @@
|
|||
<!--#define HEADER plaintext.usp -->
|
||||
<!--#include HEADER -->
|
File diff suppressed because it is too large
Load Diff
|
@ -640,7 +640,7 @@ void UServer_Base::initThrottlingServer()
|
|||
UString pattern, number;
|
||||
UVector<UString> vec(*throttling_mask);
|
||||
|
||||
U_SRV_LOG("db initialization of BandWidthThrottling success: size(%u)", db_throttling->size());
|
||||
U_SRV_LOG("db BandWidthThrottling initialization success: size(%u)", db_throttling->size());
|
||||
|
||||
db_throttling->reset(); // Initialize the db to contain no entries
|
||||
|
||||
|
@ -1116,22 +1116,27 @@ public:
|
|||
|
||||
if (*UServer_Base::ifname)
|
||||
{
|
||||
srv_addr.psaIP4Addr.sin_family = PF_INET;
|
||||
udp_sock._socket();
|
||||
udp_sock.setReuseAddress();
|
||||
|
||||
fd_sock = udp_sock.getFd();
|
||||
|
||||
srv_addr.psaIP4Addr.sin_port = htons(UServer_Base::port);
|
||||
srv_addr.psaIP4Addr.sin_family = PF_INET;
|
||||
srv_addr.psaIP4Addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (udp_sock.setServer(UServer_Base::port, &srv_addr) == false) U_ERROR("Can't bind on udp socket");
|
||||
if (U_SYSCALL(bind, "%d,%p,%d", fd_sock, &(srv_addr.psaGeneric), sizeof(uusockaddr))) U_ERROR("bind on udp socket failed");
|
||||
|
||||
if (UIPAddress::setBroadcastAddress(srv_addr, *UServer_Base::ifname) == false)
|
||||
{
|
||||
U_ERROR("Can't get broadcast address on interface %V", UServer_Base::ifname->rep);
|
||||
U_ERROR("set broadcast address on interface %V failed", UServer_Base::ifname->rep);
|
||||
}
|
||||
|
||||
if (udp_sock.setSockOpt(SOL_SOCKET, SO_BROADCAST, (const int[]){ 1 }) == false) U_ERROR("Can't enable SO_BROADCAST on udp socket");
|
||||
if (udp_sock.setSockOpt(SOL_SOCKET, SO_BROADCAST, (const int[]){ 1 }) == false) U_ERROR("setting SO_BROADCAST on udp socket failed");
|
||||
|
||||
udp_sock.setNonBlocking();
|
||||
|
||||
addr = UServer_Base::socket->cLocalAddress.get_addr();
|
||||
fd_sock = udp_sock.getFd();
|
||||
addr = UServer_Base::socket->cLocalAddress.get_addr();
|
||||
|
||||
U_DUMP("addr = %V", UIPAddress::toString(addr).rep)
|
||||
|
||||
|
@ -1196,8 +1201,10 @@ public:
|
|||
|
||||
if (iBytesTransferred == 1)
|
||||
{
|
||||
if ((cli_addr.psaIP4Addr.sin_addr.s_addr == addr && ntohs(cli_addr.psaIP4Addr.sin_port) == UServer_Base::port) ||
|
||||
(UServer_Base::vallow_cluster && UIPAllow::isAllowed(cli_addr.psaIP4Addr.sin_addr.s_addr, *UServer_Base::vallow_cluster) == false))
|
||||
if (( cli_addr.psaIP4Addr.sin_addr.s_addr == addr &&
|
||||
ntohs(cli_addr.psaIP4Addr.sin_port) == UServer_Base::port) ||
|
||||
(UServer_Base::vallow_cluster &&
|
||||
UIPAllow::isAllowed(cli_addr.psaIP4Addr.sin_addr.s_addr, *UServer_Base::vallow_cluster) == false))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1421,11 +1428,12 @@ UServer_Base::~UServer_Base()
|
|||
# endif
|
||||
|
||||
# ifdef U_LINUX
|
||||
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||
if (u_pthread_time)
|
||||
{
|
||||
delete (UTimeThread*)u_pthread_time;
|
||||
|
||||
delete (UTimeThread*)u_pthread_time;
|
||||
|
||||
(void) pthread_rwlock_destroy(ULog::prwlock);
|
||||
(void) pthread_rwlock_destroy(ULog::prwlock);
|
||||
}
|
||||
|
||||
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
||||
if (bssl)
|
||||
|
@ -2621,11 +2629,9 @@ void UServer_Base::init()
|
|||
#ifdef USERVER_UDP
|
||||
if (budp)
|
||||
{
|
||||
uusockaddr srv_addr;
|
||||
|
||||
U_ASSERT(socket->isUDP())
|
||||
|
||||
if (socket->setServer(port, &srv_addr) == false)
|
||||
if (socket->setServer(port, U_NULLPTR) == false)
|
||||
{
|
||||
U_ERROR("Run as server UDP with port '%u' failed", port);
|
||||
}
|
||||
|
@ -2916,11 +2922,17 @@ next:
|
|||
U_INTERNAL_ASSERT_EQUALS(ULog::prwlock, U_NULLPTR)
|
||||
U_INTERNAL_ASSERT_EQUALS(u_pthread_time, U_NULLPTR)
|
||||
|
||||
# ifdef USERVER_UDP
|
||||
if (budp == false ||
|
||||
UServer_Base::update_date)
|
||||
# endif
|
||||
{
|
||||
U_NEW_ULIB_OBJECT(UTimeThread, u_pthread_time, UTimeThread);
|
||||
|
||||
(void) UThread::initRwLock((ULog::prwlock = &(ptr_shared_data->rwlock)));
|
||||
|
||||
((UTimeThread*)u_pthread_time)->start(50);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(U_LOG_DISABLE) && defined(USE_LIBZ)
|
||||
|
@ -3130,9 +3142,7 @@ void UServer_Base::sendSignalToAllChildren(int signo, sighandler_t handler)
|
|||
U_INTERNAL_ASSERT(proc->parent())
|
||||
|
||||
#if defined(U_LINUX) && defined(ENABLE_THREAD)
|
||||
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||
|
||||
((UTimeThread*)u_pthread_time)->suspend();
|
||||
if (u_pthread_time) ((UTimeThread*)u_pthread_time)->suspend();
|
||||
|
||||
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
||||
if (pthread_ocsp) pthread_ocsp->suspend();
|
||||
|
@ -3154,9 +3164,7 @@ void UServer_Base::sendSignalToAllChildren(int signo, sighandler_t handler)
|
|||
#endif
|
||||
|
||||
#if defined(U_LINUX) && defined(ENABLE_THREAD)
|
||||
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||
|
||||
((UTimeThread*)u_pthread_time)->resume();
|
||||
if (u_pthread_time) ((UTimeThread*)u_pthread_time)->resume();
|
||||
|
||||
# if defined(USE_LIBSSL) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB)
|
||||
if (pthread_ocsp) pthread_ocsp->resume();
|
||||
|
@ -3244,9 +3252,7 @@ RETSIGTYPE UServer_Base::handlerForSigTERM(int signo)
|
|||
if (proc->parent())
|
||||
{
|
||||
# if defined(U_LINUX) && defined(ENABLE_THREAD)
|
||||
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||
|
||||
((UTimeThread*)u_pthread_time)->suspend();
|
||||
if (u_pthread_time) ((UTimeThread*)u_pthread_time)->suspend();
|
||||
# endif
|
||||
|
||||
// NB: we can't use UInterrupt::erase() because it restore the old action (UInterrupt::init)...
|
||||
|
@ -4057,6 +4063,15 @@ void UServer_Base::runLoop(const char* user)
|
|||
while (flag_loop)
|
||||
{
|
||||
if (pClientImage->handlerRead() == U_NOTIFIER_DELETE) break;
|
||||
|
||||
# ifndef U_LOG_DISABLE
|
||||
if (isLog())
|
||||
{
|
||||
pClientImage->logbuf->setEmpty();
|
||||
|
||||
log->log(U_CONSTANT_TO_PARAM("Waiting for connection on port %u"), port);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
if (runDynamicPage_udp)
|
||||
|
|
|
@ -182,12 +182,12 @@ bool USocket::checkTime(long time_limit, long& timeout)
|
|||
U_RETURN(true);
|
||||
}
|
||||
|
||||
void USocket::setLocalInfo(USocket* p, SocketAddress* cLocal)
|
||||
void USocket::setLocalInfo(USocket* p, SocketAddress* pLocal)
|
||||
{
|
||||
U_TRACE(0, "USocket::setLocalInfo(%p,%p)", p, cLocal)
|
||||
U_TRACE(0, "USocket::setLocalInfo(%p,%p)", p, pLocal)
|
||||
|
||||
p->iLocalPort = cLocal->getPortNumber();
|
||||
cLocal->getIPAddress(p->cLocalAddress);
|
||||
p->iLocalPort = pLocal->getPortNumber();
|
||||
pLocal->getIPAddress(p->cLocalAddress);
|
||||
}
|
||||
|
||||
void USocket::setRemoteInfo(USocket* p, SocketAddress* cRemote)
|
||||
|
@ -204,12 +204,12 @@ void USocket::setLocal()
|
|||
|
||||
U_CHECK_MEMORY
|
||||
|
||||
SocketAddress cLocal;
|
||||
socklen_t slDummy = cLocal.sizeOf();
|
||||
SocketAddress local;
|
||||
socklen_t slDummy = local.sizeOf();
|
||||
|
||||
if (U_SYSCALL(getsockname, "%d,%p,%p", getFd(), (sockaddr*)cLocal, &slDummy) == 0)
|
||||
if (U_SYSCALL(getsockname, "%d,%p,%p", getFd(), (sockaddr*)local, &slDummy) == 0)
|
||||
{
|
||||
setLocalInfo(this, &cLocal);
|
||||
setLocalInfo(this, &local);
|
||||
|
||||
U_socket_LocalSet(this) = true;
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ bool USocket::bind()
|
|||
int result, counter = 0;
|
||||
|
||||
loop:
|
||||
result = U_SYSCALL(bind, "%d,%p,%d", getFd(), (sockaddr*)&(cLocal->addr.psaGeneric), cLocal->sizeOf());
|
||||
result = U_SYSCALL(bind, "%d,%p,%d", getFd(), (sockaddr*)(*cLocal), cLocal->sizeOf());
|
||||
|
||||
if (result == -1 &&
|
||||
errno == EADDRINUSE &&
|
||||
|
@ -416,25 +416,6 @@ bool USocket::setServer(unsigned int port, void* localAddress)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (isUDP())
|
||||
{
|
||||
U_INTERNAL_ASSERT_POINTER(localAddress)
|
||||
|
||||
((uusockaddr*)localAddress)->psaIP4Addr.sin_port = htons(port);
|
||||
|
||||
if (U_SYSCALL(bind, "%d,%p,%d", iSockDesc, &(((uusockaddr*)localAddress)->psaGeneric), sizeof(uusockaddr)) == 0)
|
||||
{
|
||||
iLocalPort =
|
||||
iRemotePort = port;
|
||||
|
||||
U_socket_LocalSet(this) = true;
|
||||
|
||||
U_RETURN(true);
|
||||
}
|
||||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
setReusePort();
|
||||
|
||||
U_INTERNAL_DUMP("cLocal = %p", cLocal)
|
||||
|
@ -504,8 +485,7 @@ bool USocket::setServer(unsigned int port, void* localAddress)
|
|||
U_INTERNAL_DUMP("breuseport = %b", breuseport)
|
||||
|
||||
if (breuseport ||
|
||||
(bind() &&
|
||||
U_SYSCALL(listen, "%d,%d", iSockDesc, iBackLog) == 0))
|
||||
(bind() && listen()))
|
||||
{
|
||||
U_RETURN(true);
|
||||
}
|
||||
|
@ -526,7 +506,6 @@ void USocket::reusePort(int _flags)
|
|||
|
||||
if (breuseport)
|
||||
{
|
||||
U_ASSERT_EQUALS(isUDP(), false)
|
||||
U_ASSERT_EQUALS(isIPC(), false)
|
||||
|
||||
int old = iSockDesc,
|
||||
|
@ -547,7 +526,7 @@ void USocket::reusePort(int _flags)
|
|||
if (isClosed() ||
|
||||
(setReuseAddress(), setReusePort(),
|
||||
cLocal->setIPAddressWildCard(U_socket_IPv6(this)), bind()) == false ||
|
||||
U_SYSCALL(listen, "%d,%d", iSockDesc, iBackLog) != 0)
|
||||
listen() == false)
|
||||
{
|
||||
U_ERROR("SO_REUSEPORT failed, port %d", iLocalPort);
|
||||
}
|
||||
|
|
|
@ -2679,7 +2679,6 @@ void UHTTP2::handlerResponse()
|
|||
if (dyntbl->num_entries == 0)
|
||||
{
|
||||
# if defined(U_LINUX) && defined(ENABLE_THREAD)
|
||||
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||
U_INTERNAL_ASSERT_EQUALS(UClientImage_Base::iov_vec[1].iov_base, ULog::ptr_shared_date->date3)
|
||||
# else
|
||||
U_INTERNAL_ASSERT_EQUALS(UClientImage_Base::iov_vec[1].iov_base, ULog::date.date3)
|
||||
|
@ -2709,7 +2708,6 @@ void UHTTP2::handlerResponse()
|
|||
char* ptr_date = entry->value->data();
|
||||
|
||||
# if defined(U_LINUX) && defined(ENABLE_THREAD)
|
||||
U_INTERNAL_ASSERT_POINTER(u_pthread_time)
|
||||
U_INTERNAL_ASSERT_EQUALS(UClientImage_Base::iov_vec[1].iov_base, ULog::ptr_shared_date->date3)
|
||||
# else
|
||||
U_INTERNAL_ASSERT_EQUALS(UClientImage_Base::iov_vec[1].iov_base, ULog::date.date3)
|
||||
|
|
|
@ -223,47 +223,237 @@ UString UStringExt::substitute(const char* s, uint32_t n, const char* a, uint32_
|
|||
{
|
||||
U_TRACE(1, "UStringExt::substitute(%.*S,%u,%.*S,%u,%.*S,%u)", n, s, n, n1, a, n1, n2, b, n2)
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR(n, 0)
|
||||
U_INTERNAL_ASSERT_MAJOR(n1, 0)
|
||||
|
||||
void* p;
|
||||
uint32_t start = 0, len, capacity = (n / n1);
|
||||
uint32_t capacity;
|
||||
bool breserve = false;
|
||||
|
||||
if (capacity == 0) capacity = 22U;
|
||||
if (n2) capacity *= n2;
|
||||
if (capacity > (256U * 1024U * 1024U)) capacity = (256U * 1024U * 1024U); // worst case...
|
||||
|
||||
UString x(capacity);
|
||||
|
||||
while ((p = u_find(s + start, n - start, a, n1)))
|
||||
if (n2 <= n1) capacity = n;
|
||||
else
|
||||
{
|
||||
uint32_t _end = (const char*)p - s;
|
||||
capacity = n2*((n+n1)/n1);
|
||||
|
||||
len = (_end > start ? _end - start : 0);
|
||||
if (capacity > (256U * 1024U * 1024U)) capacity = (breserve = true, (256U * 1024U * 1024U)); // worst case...
|
||||
}
|
||||
|
||||
U_INTERNAL_DUMP("start = %u _end = %u len = %u", start, _end, len)
|
||||
uint32_t len1;
|
||||
const char* p1;
|
||||
UString x(capacity);
|
||||
char* p2 = x.data();
|
||||
|
||||
(void) x.reserve(len + n2);
|
||||
while ((p1 = (const char*)u_find(s, n, a, n1)))
|
||||
{
|
||||
len1 = (p1-s);
|
||||
|
||||
if (len)
|
||||
U_INTERNAL_DUMP("len1 = %u", len1)
|
||||
|
||||
if (breserve)
|
||||
{
|
||||
U_MEMCPY(x.pend(), s + start, len);
|
||||
uint32_t len2 = len1 + n2;
|
||||
|
||||
x.rep->_length += len;
|
||||
x.rep->_length = x.distance(p2);
|
||||
|
||||
if (x.space() < len2)
|
||||
{
|
||||
UString::_reserve(x, len2);
|
||||
|
||||
p2 = x.pend();
|
||||
}
|
||||
}
|
||||
|
||||
if (len1)
|
||||
{
|
||||
U_MEMCPY(p2, s, len1);
|
||||
p2 += len1;
|
||||
|
||||
s = p1;
|
||||
n -= len1;
|
||||
}
|
||||
|
||||
n -= n1;
|
||||
s += n1;
|
||||
|
||||
if (n2)
|
||||
{
|
||||
U_MEMCPY(x.pend(), b, n2);
|
||||
|
||||
x.rep->_length += n2;
|
||||
U_MEMCPY(p2, b, n2);
|
||||
p2 += n2;
|
||||
}
|
||||
|
||||
start = _end + n1;
|
||||
}
|
||||
|
||||
len = n - start;
|
||||
x.rep->_length = x.distance(p2);
|
||||
|
||||
if (len) (void) x.append(s + start, len);
|
||||
U_INTERNAL_DUMP("n = %u", n)
|
||||
|
||||
if (n)
|
||||
{
|
||||
if (breserve &&
|
||||
x.space() < n)
|
||||
{
|
||||
UString::_reserve(x, n);
|
||||
|
||||
p2 = x.pend();
|
||||
}
|
||||
|
||||
U_MEMCPY(p2, s, n);
|
||||
|
||||
x.rep->_length += n;
|
||||
}
|
||||
|
||||
U_INTERNAL_ASSERT(x.invariant())
|
||||
|
||||
U_RETURN_STRING(x);
|
||||
}
|
||||
|
||||
UString UStringExt::substitute(const char* s, uint32_t len, UVector<UString>& vec)
|
||||
{
|
||||
U_TRACE(1, "UStringExt::substitute(%.*S,%u,%p)", len, s, len, &vec)
|
||||
|
||||
U_INTERNAL_ASSERT_MAJOR(len, 0)
|
||||
|
||||
uint32_t n = vec.size();
|
||||
|
||||
if (n == 2) return substitute(s, len, U_STRING_TO_PARAM(vec[0]), U_STRING_TO_PARAM(vec[1]));
|
||||
|
||||
char c;
|
||||
int32_t i;
|
||||
UString item;
|
||||
bool breserve = false, bdigit = false, bspace = false;
|
||||
uint32_t n1 = 0, n2 = 0, capacity, mask_lower = 0, mask_upper = 0;
|
||||
|
||||
uint32_t maskFirstChar[] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
|
||||
0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
|
||||
0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
|
||||
0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
|
||||
0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
|
||||
0x02000000 };
|
||||
|
||||
for (i = 0; i < (int32_t)n; i += 2)
|
||||
{
|
||||
item = vec[i];
|
||||
|
||||
n1 += item.size();
|
||||
n2 += vec[i+1].size();
|
||||
|
||||
c = item.first_char();
|
||||
|
||||
if (u__islower(c)) mask_lower |= maskFirstChar[c-'a'];
|
||||
else if (u__isupper(c)) mask_upper |= maskFirstChar[c-'A'];
|
||||
else if (u__isdigit(c)) bdigit = true;
|
||||
else if (u__isspace(c)) bspace = true;
|
||||
}
|
||||
|
||||
U_INTERNAL_DUMP("n1 = %u n2 = %u mask_lower = %B mask_upper = %B bdigit = %b bspace = %b", n1, n2, mask_lower, mask_upper, bdigit, bspace)
|
||||
|
||||
if (n2 <= n1) capacity = len;
|
||||
else
|
||||
{
|
||||
capacity = n2*((len+n1)/n1);
|
||||
|
||||
if (capacity > (256U * 1024U * 1024U)) capacity = (breserve = true, (256U * 1024U * 1024U)); // worst case...
|
||||
}
|
||||
|
||||
uint32_t len1;
|
||||
const char* p1;
|
||||
UString x(capacity);
|
||||
char* p2 = x.data();
|
||||
const char* end = s + len;
|
||||
|
||||
loop:
|
||||
for (p1 = s; p1 < end; ++p1)
|
||||
{
|
||||
c = *p1;
|
||||
|
||||
if ((u__islower(c) &&
|
||||
(mask_lower & maskFirstChar[c-'a']) == 0) ||
|
||||
(u__isupper(c) &&
|
||||
(mask_upper & maskFirstChar[c-'A']) == 0) ||
|
||||
(u__isdigit(c) &&
|
||||
bdigit == false) ||
|
||||
(u__isspace(c) &&
|
||||
bspace == false))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int32_t)n; i += 2)
|
||||
{
|
||||
item = vec[i];
|
||||
|
||||
if (memcmp(p1, U_STRING_TO_PARAM(item)) == 0)
|
||||
{
|
||||
n1 = item.size();
|
||||
n2 = (item = vec[i+1]).size();
|
||||
|
||||
U_INTERNAL_DUMP("n1 = %u item(%u) = %V", n1, n2, item.rep)
|
||||
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p1 < end)
|
||||
{
|
||||
found:
|
||||
len1 = (p1-s);
|
||||
|
||||
U_INTERNAL_DUMP("len1 = %u", len1)
|
||||
|
||||
if (breserve)
|
||||
{
|
||||
uint32_t len2 = len1 + n2;
|
||||
|
||||
x.rep->_length = x.distance(p2);
|
||||
|
||||
if (x.space() < len2)
|
||||
{
|
||||
UString::_reserve(x, len2);
|
||||
|
||||
p2 = x.pend();
|
||||
}
|
||||
}
|
||||
|
||||
if (len1)
|
||||
{
|
||||
U_MEMCPY(p2, s, len1);
|
||||
p2 += len1;
|
||||
|
||||
s = p1;
|
||||
len -= len1;
|
||||
}
|
||||
|
||||
len -= n1;
|
||||
s += n1;
|
||||
|
||||
if (n2)
|
||||
{
|
||||
U_MEMCPY(p2, item.data(), n2);
|
||||
p2 += n2;
|
||||
}
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
x.rep->_length = x.distance(p2);
|
||||
|
||||
U_INTERNAL_DUMP("len = %u", len)
|
||||
|
||||
if (len)
|
||||
{
|
||||
if (breserve &&
|
||||
x.space() < len)
|
||||
{
|
||||
UString::_reserve(x, len);
|
||||
|
||||
p2 = x.pend();
|
||||
}
|
||||
|
||||
U_MEMCPY(p2, s, len);
|
||||
|
||||
x.rep->_length += len;
|
||||
}
|
||||
|
||||
U_INTERNAL_ASSERT(x.invariant())
|
||||
|
||||
U_RETURN_STRING(x);
|
||||
}
|
||||
|
|
|
@ -5537,14 +5537,14 @@ void UHTTP::initSession()
|
|||
|
||||
if (db_session->open(8 * U_1M, false, true, true, U_SRV_LOCK_DATA_SESSION)) // NB: we don't want truncate (we have only the journal)...
|
||||
{
|
||||
U_SRV_LOG("db initialization of HTTP session success");
|
||||
U_SRV_LOG("db HTTP session initialization success");
|
||||
|
||||
if (data_session) db_session->setPointerToDataStorage(data_session);
|
||||
else if (data_storage) db_session->setPointerToDataStorage(data_storage);
|
||||
}
|
||||
else
|
||||
{
|
||||
U_SRV_LOG("WARNING: db initialization of HTTP session failed");
|
||||
U_SRV_LOG("WARNING: db HTTP session initialization failed");
|
||||
|
||||
delete db_session;
|
||||
db_session = U_NULLPTR;
|
||||
|
@ -5580,7 +5580,7 @@ void UHTTP::initSessionSSL()
|
|||
|
||||
if (db_session_ssl->open(8 * U_1M, false, true, true, U_SRV_LOCK_SSL_SESSION)) // NB: we don't want truncate (we have only the journal)...
|
||||
{
|
||||
U_SRV_LOG("db initialization of SSL session success");
|
||||
U_SRV_LOG("db SSL session initialization success");
|
||||
|
||||
db_session_ssl->reset(); // Initialize the cache to contain no entries
|
||||
|
||||
|
@ -5623,7 +5623,7 @@ void UHTTP::initSessionSSL()
|
|||
}
|
||||
else
|
||||
{
|
||||
U_SRV_LOG("WARNING: db initialization of SSL session failed");
|
||||
U_SRV_LOG("WARNING: db SSL session initialization failed");
|
||||
|
||||
delete db_session_ssl;
|
||||
db_session_ssl = U_NULLPTR;
|
||||
|
@ -6612,6 +6612,8 @@ void UHTTP::handlerResponse()
|
|||
{
|
||||
UClientImage_Base::setHeaderForResponse(6+29+2+12+2); // Date: Wed, 20 Jun 2012 11:43:17 GMT\r\nServer: ULib\r\n
|
||||
|
||||
setStatusDescription();
|
||||
|
||||
// NB: all other responses must include an entity body or a Content-Length header field defined with a value of zero (0)
|
||||
|
||||
char* ptr;
|
||||
|
@ -6619,32 +6621,7 @@ void UHTTP::handlerResponse()
|
|||
const char* ptr2;
|
||||
uint32_t sz1 = set_cookie->size(), sz2 = ext->size();
|
||||
|
||||
if (sz2) ptr2 = ext->data();
|
||||
else
|
||||
{
|
||||
ptr2 = "Content-Length: 0\r\n\r\n";
|
||||
sz2 = U_CONSTANT_SIZE("Content-Length: 0\r\n\r\n");
|
||||
|
||||
if (U_http_info.nResponseCode == HTTP_OK)
|
||||
{
|
||||
if (isGETorHEAD()) U_http_info.nResponseCode = HTTP_NO_CONTENT;
|
||||
|
||||
// A server implements an HSTS policy by supplying a header over an HTTPS connection (HSTS headers over HTTP are ignored)
|
||||
|
||||
# if defined(USE_LIBSSL) && defined(U_HTTP_STRICT_TRANSPORT_SECURITY)
|
||||
if (UServer_Base::bssl &&
|
||||
uri_strict_transport_security_mask == (void*)1L)
|
||||
{
|
||||
ptr2 = "Strict-Transport-Security: max-age=31536000; includeSubDomains; preload\r\nContent-Length: 0\r\n\r\n";
|
||||
sz2 = U_CONSTANT_SIZE("Strict-Transport-Security: max-age=31536000; includeSubDomains; preload\r\nContent-Length: 0\r\n\r\n");
|
||||
}
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
setStatusDescription();
|
||||
|
||||
UClientImage_Base::wbuffer->setBuffer(200U + sz1 + sz2);
|
||||
UClientImage_Base::wbuffer->setBuffer(300U + sz1 + sz2);
|
||||
|
||||
ptr =
|
||||
base = UClientImage_Base::wbuffer->data();
|
||||
|
@ -6718,9 +6695,53 @@ void UHTTP::handlerResponse()
|
|||
}
|
||||
}
|
||||
|
||||
sz1 = ptr-base;
|
||||
|
||||
U_INTERNAL_DUMP("sz1 = %u", sz1)
|
||||
|
||||
if (sz2)
|
||||
{
|
||||
U_INTERNAL_DUMP("ext(%u) = %V", sz2, ext->rep)
|
||||
|
||||
// U_INTERNAL_ASSERT(u_endsWith(U_STRING_TO_PARAM(*ext), U_CONSTANT_TO_PARAM(U_CRLF2)))
|
||||
|
||||
if (sz1 == 0)
|
||||
{
|
||||
UClientImage_Base::wbuffer->swap(*ext);
|
||||
|
||||
U_INTERNAL_DUMP("UClientImage_Base::wbuffer(%u) = %#V", UClientImage_Base::wbuffer->size(), UClientImage_Base::wbuffer->rep)
|
||||
U_INTERNAL_DUMP("UClientImage_Base::body(%u) = %V", UClientImage_Base::body->size(), UClientImage_Base::body->rep)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ptr2 = ext->data();
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr2 = "Content-Length: 0\r\n\r\n";
|
||||
sz2 = U_CONSTANT_SIZE("Content-Length: 0\r\n\r\n");
|
||||
|
||||
if (U_http_info.nResponseCode == HTTP_OK)
|
||||
{
|
||||
if (isGETorHEAD()) U_http_info.nResponseCode = HTTP_NO_CONTENT;
|
||||
|
||||
// A server implements an HSTS policy by supplying a header over an HTTPS connection (HSTS headers over HTTP are ignored)
|
||||
|
||||
# if defined(USE_LIBSSL) && defined(U_HTTP_STRICT_TRANSPORT_SECURITY)
|
||||
if (UServer_Base::bssl &&
|
||||
uri_strict_transport_security_mask == (void*)1L)
|
||||
{
|
||||
ptr2 = "Strict-Transport-Security: max-age=31536000; includeSubDomains; preload\r\nContent-Length: 0\r\n\r\n";
|
||||
sz2 = U_CONSTANT_SIZE("Strict-Transport-Security: max-age=31536000; includeSubDomains; preload\r\nContent-Length: 0\r\n\r\n");
|
||||
}
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
U_MEMCPY(ptr, ptr2, sz2);
|
||||
|
||||
UClientImage_Base::wbuffer->size_adjust((ptr - base) + sz2);
|
||||
UClientImage_Base::wbuffer->size_adjust(sz1 + sz2);
|
||||
}
|
||||
|
||||
U_INTERNAL_DUMP("UClientImage_Base::wbuffer(%u) = %#V", UClientImage_Base::wbuffer->size(), UClientImage_Base::wbuffer->rep)
|
||||
|
@ -7194,12 +7215,7 @@ next:
|
|||
|
||||
ptr = u_num2str32(clength, ptr + U_CONSTANT_SIZE("Content-Length: "));
|
||||
|
||||
if (pEndHeader == U_NULLPTR)
|
||||
{
|
||||
u_put_unalignedp32(ptr, U_MULTICHAR_CONSTANT32('\r','\n','\r','\n'));
|
||||
ptr += U_CONSTANT_SIZE(U_CRLF2);
|
||||
}
|
||||
else
|
||||
if (pEndHeader)
|
||||
{
|
||||
u_put_unalignedp16(ptr, U_MULTICHAR_CONSTANT16('\r','\n'));
|
||||
ptr += U_CONSTANT_SIZE(U_CRLF);
|
||||
|
@ -7209,6 +7225,11 @@ next:
|
|||
U_MEMCPY(ptr, pEndHeader, U_http_info.endHeader);
|
||||
ptr += U_http_info.endHeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
u_put_unalignedp32(ptr, U_MULTICHAR_CONSTANT32('\r','\n','\r','\n'));
|
||||
ptr += U_CONSTANT_SIZE(U_CRLF2);
|
||||
}
|
||||
|
||||
ext->size_adjust(ptr);
|
||||
|
||||
|
@ -8113,7 +8134,9 @@ U_NO_EXPORT void UHTTP::putDataInCache(const UString& fmt, UString& content)
|
|||
|
||||
U_INTERNAL_ASSERT_EQUALS(file_data->size, content.size())
|
||||
|
||||
#ifndef U_LOG_DISABLE
|
||||
uint32_t ratio1 = 100, ratio2 = 100;
|
||||
#endif
|
||||
|
||||
if (u_is_img(mime_index))
|
||||
{
|
||||
|
@ -8214,7 +8237,9 @@ next:
|
|||
|
||||
if (content1)
|
||||
{
|
||||
# ifndef U_LOG_DISABLE
|
||||
ratio1 = UStringExt::ratio;
|
||||
# endif
|
||||
|
||||
setDataInCache(fmt, content1, U_CONSTANT_TO_PARAM("Content-Encoding: gzip\r\n"));
|
||||
}
|
||||
|
@ -8225,7 +8250,9 @@ next:
|
|||
|
||||
if (content2)
|
||||
{
|
||||
# ifndef U_LOG_DISABLE
|
||||
ratio2 = UStringExt::ratio;
|
||||
# endif
|
||||
|
||||
checkArrayCompressData(file_data);
|
||||
|
||||
|
@ -11155,7 +11182,11 @@ U_NO_EXPORT bool UHTTP::UServletPage::load()
|
|||
// NB: dlopen() fail if the module name is not prefixed with "./"...
|
||||
|
||||
char buffer[U_PATH_MAX];
|
||||
#ifndef U_LOG_DISABLE
|
||||
uint32_t sz = u__snprintf(buffer, sizeof(buffer), U_CONSTANT_TO_PARAM("./%v.%s"), path.rep, U_LIB_SUFFIX);
|
||||
#else
|
||||
(void) u__snprintf(buffer, sizeof(buffer), U_CONSTANT_TO_PARAM("./%v.%s"), path.rep, U_LIB_SUFFIX);
|
||||
#endif
|
||||
|
||||
if (UDynamic::load(buffer) == false)
|
||||
{
|
||||
|
@ -11385,8 +11416,6 @@ next: if (*ptr1 == '?')
|
|||
|
||||
setDynamicResponse();
|
||||
|
||||
ext->clear();
|
||||
|
||||
(void) UServer_Base::pClientImage->writeResponse();
|
||||
|
||||
U_RETURN(true);
|
||||
|
|
|
@ -22,7 +22,7 @@ cat <<EOF >inp/webserver.cfg
|
|||
userver {
|
||||
PORT 8080
|
||||
RUN_AS_USER nobody
|
||||
LOG_FILE /tmp/userver_udp.log
|
||||
#LOG_FILE /tmp/userver_udp.log
|
||||
LOG_FILE_SZ 10M
|
||||
PID_FILE /var/run/userver_udp.pid
|
||||
PREFORK_CHILD 0
|
||||
|
|
|
@ -263,7 +263,6 @@ static void UDPEchoServer(unsigned int iPortNumber, bool bIPv6)
|
|||
{
|
||||
U_TRACE(5, "::UDPEchoServer(%u,%b)", iPortNumber, bIPv6)
|
||||
|
||||
uusockaddr addr;
|
||||
char pcBuffer[65535];
|
||||
UIPAddress cIPSource;
|
||||
int iBytesTransferred;
|
||||
|
@ -271,12 +270,7 @@ static void UDPEchoServer(unsigned int iPortNumber, bool bIPv6)
|
|||
|
||||
UUDPSocket cServerSocket(bIPv6);
|
||||
|
||||
(void) memset(&addr, 0, sizeof(addr));
|
||||
|
||||
addr.psaIP4Addr.sin_family = PF_INET;
|
||||
addr.psaIP4Addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
cServerSocket.setServer(iPortNumber, &addr);
|
||||
cServerSocket.setServer(iPortNumber, U_NULLPTR);
|
||||
cServerSocket.reusePort(O_RDWR | O_CLOEXEC);
|
||||
cServerSocket.setLocal();
|
||||
|
||||
|
|
|
@ -1956,6 +1956,36 @@ U_EXPORT main(int argc, char* argv[])
|
|||
|
||||
U_ASSERT( z == "############################################################################################################################ellllo")
|
||||
|
||||
y = U_STRING_FROM_CONSTANT(" uno due tre quattro cinque \n"
|
||||
" uno due tre quattro cinque \n"
|
||||
" uno due tre quattro cinque \n"
|
||||
" uno due tre quattro cinque \n"
|
||||
" uno due tre quattro cinque \n");
|
||||
|
||||
z = UStringExt::substitute(y, U_CONSTANT_TO_PARAM("uno"), U_CONSTANT_TO_PARAM("primo"));
|
||||
|
||||
U_ASSERT( z == " primo due tre quattro cinque \n"
|
||||
" primo due tre quattro cinque \n"
|
||||
" primo due tre quattro cinque \n"
|
||||
" primo due tre quattro cinque \n"
|
||||
" primo due tre quattro cinque \n")
|
||||
|
||||
z = U_STRING_FROM_CONSTANT("uno primo due secondo tre terzo quattro quarto cinque quinto");
|
||||
|
||||
vec.clear();
|
||||
|
||||
(void) vec.split(z);
|
||||
|
||||
y = UStringExt::substitute(y, vec);
|
||||
|
||||
vec.clear();
|
||||
|
||||
U_ASSERT( y == " primo secondo terzo quarto quinto \n"
|
||||
" primo secondo terzo quarto quinto \n"
|
||||
" primo secondo terzo quarto quinto \n"
|
||||
" primo secondo terzo quarto quinto \n"
|
||||
" primo secondo terzo quarto quinto \n")
|
||||
|
||||
y = U_STRING_FROM_CONSTANT("Hello\n\n");
|
||||
|
||||
z = UStringExt::dos2unix(y, true);
|
||||
|
|
Loading…
Reference in New Issue
Block a user