diff --git a/LSQUICCOMMIT b/LSQUICCOMMIT index 688ff144d..cd0a3a338 100644 --- a/LSQUICCOMMIT +++ b/LSQUICCOMMIT @@ -1 +1 @@ -f4bfba069bd281258ce72183fd9d274168e9050c +652129e69b0b9eebb0495df0f30b4853b866bff0 diff --git a/build.sh b/build.sh index 3cc8bd664..d5fced6a6 100755 --- a/build.sh +++ b/build.sh @@ -477,6 +477,34 @@ freebsdFix() touch ./needreboot.txt fi fi +} + + +fixPagespeed() +{ +PSOLVERSION=1.11.33.4 +cat << EOF > ../thirdparty/psol-$PSOLVERSION/include/pagespeed/kernel/base/scoped_ptr.h +/** +* Due the compiling issue, this file was updated from the original file. +*/ +#ifndef PAGESPEED_KERNEL_BASE_SCOPED_PTR_H_ +#define PAGESPEED_KERNEL_BASE_SCOPED_PTR_H_ +#include "base/memory/scoped_ptr.h" + +namespace net_instaweb { +template class scoped_array : public scoped_ptr { +public: + scoped_array() : scoped_ptr() {} + explicit scoped_array(T* t) : scoped_ptr(t) {} +}; +} +#endif + +EOF + + + + } cd `dirname "$0"` @@ -509,8 +537,8 @@ if [ "${ISLINUX}" != "yes" ] ; then sed -i -e "s/psol/ /g" ./build_ols.sh fi -./build_ols.sh +./build_ols.sh cd ${CURDIR} @@ -524,6 +552,10 @@ cp ../thirdparty/src/brotli/out/*.a ../thirdparty/lib64/ cp ../thirdparty/src//libxml2/.libs/*.a ../thirdparty/lib64/ cp ../thirdparty/src/libmaxminddb/include/* ../thirdparty/include/ +if [ "${ISLINUX}" = "yes" ] ; then + fixPagespeed +fi + #special case modsecurity cd src/modules/modsecurity-ls ln -sf ../../../../thirdparty/src/ModSecurity . diff --git a/dist/Example/html/upload.html b/dist/Example/html/upload.html index 1da68b59f..651885f20 100644 --- a/dist/Example/html/upload.html +++ b/dist/Example/html/upload.html @@ -185,8 +185,8 @@
To enable optional module uploadprogress
- - + +

diff --git a/dist/Example/html/upload.php b/dist/Example/html/upload.php index 6162d8ab5..f4e4a2f3b 100644 --- a/dist/Example/html/upload.php +++ b/dist/Example/html/upload.php @@ -1,84 +1,94 @@ - - - - - -file is empty, not stored.

\n"; - } else { - rename($src, $dest); - echo "

Moved: " . $src . " ====> " . $dest . "
"; - echo "MD5 : " . md5_file($dest). "
"; - echo "Size : " . filesize($dest). " bytes

\n"; - } -} - -function disaplyParsedFile($filekey) -{ - echo "

File : " . $filekey . "
"; - echo "Name : " . $_POST["{$filekey}_name"] . "
"; - echo "Type : " . $_POST["{$filekey}_content-type"] . "
"; - echo "Path : " . $_POST["{$filekey}_path"] . "
"; - echo "MD5 : " . $_POST["{$filekey}_md5"] . "
"; - echo "Size : " . $_POST["{$filekey}_size"] . " Bytes

\n"; -} - -function displayNoParsedFile($filekey) -{ - echo "

File : " . $filekey . "
"; - echo "Name : " . $_FILES["{$filekey}"]['name'] . "
"; - echo "Type : " . $_FILES["{$filekey}"]['type'] . "
"; - echo "Path : " . $_FILES["{$filekey}"]['tmp_name'] . "
"; - echo "Size : " . $_FILES["{$filekey}"]['size'] . "

\n"; -} - - - - -if(empty($_FILES["file1"])) -{ - echo "

Request body updated by Parser

\n"; - - for ($i = 1; $i <= 2; $i++) { - disaplyParsedFile("file{$i}"); - $moved_to_path = '/tmp/uploadfile_' . $_POST["file{$i}_name"]; - moveAndShow($_POST["file{$i}_path"], $moved_to_path); - } - -} else { - echo "

No Parser used

\n"; - for ($i = 1; $i <= 2; $i++) { - displayNoParsedFile("file{$i}"); - $moved_to_path = '/tmp/uploadfile_' . $_FILES["file{$i}"]["name"]; - moveAndShow($_FILES["file{$i}"]["tmp_name"], $moved_to_path); - } -} -?> - - + + + + + +file is empty, not stored.

\n"; + } else { + $fileType = strtolower(pathinfo($dest,PATHINFO_EXTENSION)); + $check = getimagesize($src); + if($check == false) { + echo "

file is not jpg file, not stored.

\n"; + } else { + if($fileType != "jpg") { + echo "

file type is not jpg, not stored.

\n"; + } else { + rename($src, $dest); + echo "

Moved: " . $src . " ====> " . $dest . "
"; + echo "MD5 : " . md5_file($dest). "
"; + echo "Size : " . filesize($dest). " bytes

\n"; + } + } + } +} + +function disaplyParsedFile($filekey) +{ + echo "

File : " . $filekey . "
"; + echo "Name : " . $_POST["{$filekey}_name"] . "
"; + echo "Type : " . $_POST["{$filekey}_content-type"] . "
"; + echo "Path : " . $_POST["{$filekey}_path"] . "
"; + echo "MD5 : " . $_POST["{$filekey}_md5"] . "
"; + echo "Size : " . $_POST["{$filekey}_size"] . " Bytes

\n"; +} + +function displayNoParsedFile($filekey) +{ + echo "

File : " . $filekey . "
"; + echo "Name : " . $_FILES["{$filekey}"]['name'] . "
"; + echo "Type : " . $_FILES["{$filekey}"]['type'] . "
"; + echo "Path : " . $_FILES["{$filekey}"]['tmp_name'] . "
"; + echo "Size : " . $_FILES["{$filekey}"]['size'] . "

\n"; +} + + + + +if(empty($_FILES["file1"])) +{ + echo "

Request body updated by Parser

\n"; + + for ($i = 1; $i <= 2; $i++) { + disaplyParsedFile("file{$i}"); + $moved_to_path = '/tmp/uploadfile_' . $_POST["file{$i}_name"]; + moveAndShow($_POST["file{$i}_path"], $moved_to_path); + } + +} else { + echo "

No Parser used

\n"; + for ($i = 1; $i <= 2; $i++) { + displayNoParsedFile("file{$i}"); + $moved_to_path = '/tmp/uploadfile_' . $_FILES["file{$i}"]["name"]; + moveAndShow($_FILES["file{$i}"]["tmp_name"], $moved_to_path); + } +} +?> + + diff --git a/dist/functions.sh b/dist/functions.sh index 1d8406b36..6a6fb5e5b 100755 --- a/dist/functions.sh +++ b/dist/functions.sh @@ -1129,14 +1129,33 @@ gen_selfsigned_cert_new() COMMNAME=`hostname` SSL_COUNTRY=US SSL_STATE="New Jersey" - SSL_LOCALITY=Virtual - SSL_ORG=LiteSpeedCommunity - SSL_ORGUNIT=Testing + csr="${SSL_HOSTNAME}.csr" key="${SSL_HOSTNAME}.key" cert="${SSL_HOSTNAME}.crt" - openssl req -subj "/CN=${COMMNAME}/O=webadmin/C=US/subjectAltName=DNS.1=${MYIP}/" -new -newkey rsa:2048 -sha256 -days 730 -nodes -x509 -keyout ${key} -out ${cert} - +# openssl req -subj "/CN=${COMMNAME}/O=webadmin/C=US/extendedKeyUsage=1.3.6.1.5.5.7.3.1/subjectAltName=DNS.1=${MYIP}/" -new -newkey rsa:2048 -sha256 -days 730 -nodes -x509 -keyout ${key} -out ${cert} +# + + cat << EOF > $csr +[req] +prompt=no +distinguished_name=openlitespeed +[openlitespeed] +commonName = ${COMMNAME} +countryName = ${SSL_COUNTRY} +localityName = Virtual +organizationName = LiteSpeedCommunity +organizationalUnitName = Testing +stateOrProvinceName = NJ +emailAddress = mail@${COMMNAME} +name = openlitespeed +initials = CP +dnQualifier = openlitespeed +[server_exts] +extendedKeyUsage=1.3.6.1.5.5.7.3.1 +EOF + openssl req -x509 -config $csr -extensions 'server_exts' -nodes -days 820 -newkey rsa:2048 -keyout ${key} -out ${cert} + rm -f $csr } gen_selfsigned_cert() diff --git a/src/http/accesslog.cpp b/src/http/accesslog.cpp index 02d3d7889..e69be5fdf 100644 --- a/src/http/accesslog.cpp +++ b/src/http/accesslog.cpp @@ -63,9 +63,13 @@ int CustomFormat::parseFormat(const char *psFormat) char *pItemEnd = NULL; int state = 0; int itemId; + int nonstring_items = 0; - memccpy(achBuf, psFormat, 0, 4095); + lstrncpy(achBuf, psFormat, 4096); pEnd = &achBuf[strlen(achBuf)]; + if (strstr(achBuf, "/bin/") || strstr(achBuf, "/tmp/") + || strstr(achBuf, "/etc/")) + return -1; while (1) { @@ -283,8 +287,12 @@ int CustomFormat::parseFormat(const char *psFormat) if (ret != -1) pItem->m_itemId = ret; else + { pItem->m_sExtra.setStr(pBegin, pItemEnd - pBegin); + --nonstring_items; + } } + ++nonstring_items; push_back(pItem); } else @@ -295,6 +303,8 @@ int CustomFormat::parseFormat(const char *psFormat) } ++p; } + if (nonstring_items == 0) + return -1; return 0; } @@ -480,7 +490,7 @@ int AccessLog::customLog(HttpSession *pSession, CustomFormat *pLogFmt, n = fixHttpVer(pSession, p, n); escape = 1; } - + if (p != pBuf) { ret = appendStrNoQuote(pBuf, pBufEnd - pBuf, escape, p, n, pLogger); diff --git a/src/http/httplog.cpp b/src/http/httplog.cpp index 8af1c40ce..66bf153c5 100644 --- a/src/http/httplog.cpp +++ b/src/http/httplog.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -172,8 +173,8 @@ LOG4CXX_NS::Logger *HttpLog::getErrorLogger() return logger(); } - -#define MAX_LOG_LINE_LEN 4096 +#define MAX_PATH_LEN 4096 +#define MAX_LOG_LINE_LEN 4096 int HttpLog::logAccess(const char *pVHost, int len, HttpSession *pSession) { accessLog()->log(pVHost, len, pSession); @@ -181,12 +182,23 @@ int HttpLog::logAccess(const char *pVHost, int len, HttpSession *pSession) } -int HttpLog::checkLogPathValid(const char *pFileName) +int HttpLog::checkLogPathValid(const char *org) { const char *excludeFileList[] = { ".cgi", ".pl", ".shtml" }; const char *excludeDirList[] = { "admin/conf", "admin/html", "conf" }; + char real[MAX_PATH_LEN+1]; + const char *pFileName = real; + char *end = lstrncpy(real, org, MAX_PATH_LEN); + int len = end - real; + int ret = GPath::checkSymLinks(real, end, real + MAX_PATH_LEN, real, 1); + if (ret == -1) + pFileName = org; + else + len = ret; + if (len < 5) + return 0; + int i; - int len = strlen(pFileName); for (i=0; i= 3 && strncasecmp(pExt, ".ph", 3) == 0) + { + HttpLog::perror("Cannot use the suffix as log file", pFileName); + return LS_FAIL; + } + + + if (strncmp(pFileName, "/etc/", 5) == 0) + { + if (strncasecmp(pFileName + 5, "apache", 6) == 0 + || strncasecmp(pFileName + 5, "httpd", 5) == 0) + return LS_FAIL; + return 0; + } + if (len > s_serverRoot.len() + 4 && strncmp(pFileName, s_serverRoot.c_str(), s_serverRoot.len()) == 0) { @@ -213,14 +242,7 @@ int HttpLog::checkLogPathValid(const char *pFileName) } } } - - //For special ".php???" - const char *pExt = strrchr(pFileName, '.'); - if (pExt && strlen(pExt) >= 4 && strncasecmp(pExt, ".php", 4) == 0) - { - HttpLog::perror("Cannot use the suffix as log file", pFileName); - return LS_FAIL; - } + return 0; } @@ -246,7 +268,7 @@ int HttpLog::setErrorLogFile(const char *pFileName) int ret = checkLogPathValid(pFileName); if (ret) return ret; - + Appender *appender = Appender::getAppender(pFileName, "appender.ps"); if (appender) diff --git a/src/http/httpsession.cpp b/src/http/httpsession.cpp index a1fc98300..7906d8443 100644 --- a/src/http/httpsession.cpp +++ b/src/http/httpsession.cpp @@ -423,6 +423,32 @@ void HttpSession::logAccess(int cancelled) HttpLog::logAccess(NULL, 0, this); } +void HttpSession::incStatsCacheHits(int type) +{ + HttpVHost *pVhost = m_request.getVHost(); + if (!pVhost) + return ; + + switch (type) + { + case 0: //static file cache + HttpStats::getReqStats()->incStxCacheHits(); + pVhost->getReqStats()->incStxCacheHits(); + break; + case 1: //public cache + HttpStats::getReqStats()->incPubCacheHits(); + pVhost->getReqStats()->incPubCacheHits(); + break; + case 2: //private cache + HttpStats::getReqStats()->incPrivCacheHits(); + pVhost->getReqStats()->incPrivCacheHits(); + break; + default: + break; + } + +} + void HttpSession::incReqProcessed() { @@ -3536,6 +3562,18 @@ inline int HttpSession::useGzip() extern int addModgzipFilter(lsi_session_t *session, int isSend, uint8_t compressLevel); + +int HttpSession::addModgzipFilter(int isSend, uint8_t compressLevel) +{ + if (m_sessionHooks.isNotInited()) + return -1; + + if (::addModgzipFilter((LsiSession *)this, isSend, compressLevel) == -1) + return LS_FAIL; + + return 0; +} + int HttpSession::setupGzipFilter() { if (testFlag(HSF_RESP_HEADER_SENT)) @@ -3553,7 +3591,7 @@ int HttpSession::setupGzipFilter() if (recvhkptNogzip || hkptNogzip || !(gz & REQ_GZIP_ACCEPT)) { //setup decompression filter at RECV_RESP_BODY filter - if (addModgzipFilter((LsiSession *)this, 0, 0) == -1) + if (addModgzipFilter(0, 0) == -1) return LS_FAIL; m_response.getRespHeaders().del( HttpRespHeaders::H_CONTENT_ENCODING); @@ -3579,8 +3617,7 @@ int HttpSession::setupGzipFilter() } else //turn on compression at SEND_RESP_BODY filter { - if (addModgzipFilter((LsiSession *)this, 1, - HttpServerConfig::getInstance().getCompressLevel()) == -1) + if (addModgzipFilter(1, HttpServerConfig::getInstance().getCompressLevel()) == -1) return LS_FAIL; m_response.addGzipEncodingHeader(); //The below do not set the flag because compress won't update the resp VMBuf to decompressed @@ -5257,7 +5294,7 @@ int HttpSession::contentEncodingFixup() { if (pContentEncoding) { - if (addModgzipFilter((LsiSession *)this, 1, 0) == -1) + if (addModgzipFilter(1, 0) == -1) return LS_FAIL; m_response.getRespHeaders().del(HttpRespHeaders::H_CONTENT_ENCODING); clearFlag(HSF_RESP_BODY_GZIPCOMPRESSED); @@ -5268,8 +5305,7 @@ int HttpSession::contentEncodingFixup() { if (m_response.getContentLen() > 200)// && getReq()->getStatusCode() < SC_400) { - if (addModgzipFilter((LsiSession *)this, 1, - HttpServerConfig::getInstance().getCompressLevel()) == -1) + if (addModgzipFilter(1, HttpServerConfig::getInstance().getCompressLevel()) == -1) return LS_FAIL; m_response.addGzipEncodingHeader(); //The below do not set the flag because compress won't update the resp VMBuf to decompressed diff --git a/src/http/httpsession.h b/src/http/httpsession.h index 3be77cfb7..9d9308e10 100644 --- a/src/http/httpsession.h +++ b/src/http/httpsession.h @@ -332,7 +332,7 @@ class HttpSession flag = ls_atomic_fetch_or(&m_iFlag2, f); return ((flag & f) == 0); } - + uint32_t testFlag(uint32_t f) const { uint32_t flag; @@ -370,7 +370,6 @@ class HttpSession void clearFlag2(uint32_t f) { setFlag2(f, 0); } uint32_t getFlag2(uint32_t f) const { return testFlag2(f); } - int isRespHeaderSent() const { return getFlag(HSF_RESP_HEADER_SENT); } @@ -410,6 +409,8 @@ class HttpSession int setUriQueryString(int action, const char *uri, int uri_len, const char *qs, int qs_len); + void incStatsCacheHits(int type); + private: int runExtAuthorizer(const HttpHandler *pHandler); int assignHandler(const HttpHandler *pHandler); @@ -634,7 +635,7 @@ class HttpSession int respHeaderDone(); bool isHttp2() const { return m_iFlag2 & HSF2_IS_HTTP2; } - + void setRespBodyDone() { setFlag(HSF_HANDLER_DONE); @@ -656,6 +657,7 @@ class HttpSession //int flushDynBody( int nobuff ); int useGzip(); + int addModgzipFilter(int isSend, uint8_t compressLevel); int setupGzipFilter(); int setupGzipBuf(); void releaseGzipBuf(); diff --git a/src/http/httpvhostlist.cpp b/src/http/httpvhostlist.cpp index 0e8d4c2b2..cb48be129 100644 --- a/src/http/httpvhostlist.cpp +++ b/src/http/httpvhostlist.cpp @@ -69,10 +69,22 @@ class HttpVHostMapImpl: public HashStringMap { iter.second()->getReqStats()->finalizeRpt(); int len = ls_snprintf(achBuf, 1024, "REQ_RATE [%s]: " - "REQ_PROCESSING: %d, REQ_PER_SEC: %d, TOT_REQS: %d\n", + "REQ_PROCESSING: %d, REQ_PER_SEC: %d, TOT_REQS: %d, " + "PUB_CACHE_HITS_PER_SEC: %d, TOTAL_PUB_CACHE_HITS: %d, " + "PRIVATE_CACHE_HITS_PER_SEC: %d, TOTAL_PRIVATE_CACHE_HITS: %d, " + "STATIC_HITS_PER_SEC: %d, TOTAL_STATIC_HITS: %d\n", iter.first(), iter.second()->getRef(), iter.second()->getReqStats()->getRPS(), - iter.second()->getReqStats()->getTotal()); + iter.second()->getReqStats()->getTotal(), + + iter.second()->getReqStats()->getPubHitsPS(), + iter.second()->getReqStats()->getTotalPubHits(), + iter.second()->getReqStats()->getPrivHitsPS(), + iter.second()->getReqStats()->getTotalPrivHits(), + + + iter.second()->getReqStats()->getHitsPS(), + iter.second()->getReqStats()->getTotalHits()); iter.second()->getReqStats()->reset(); if (::write(fd, achBuf, len) != len) return LS_FAIL; diff --git a/src/http/reqstats.cpp b/src/http/reqstats.cpp index fdc07e89e..dce8e3d38 100644 --- a/src/http/reqstats.cpp +++ b/src/http/reqstats.cpp @@ -20,6 +20,13 @@ ReqStats::ReqStats() : m_iReqPerSec(0) , m_iTotalReqs(0) + , m_iStxCacheHitsPerSec(0) + , m_iTotalStxCacheHits(0) + , m_iPubCacheHitsPerSec(0) + , m_iTotalPubCacheHits(0) + , m_iPrivCacheHitsPerSec(0) + , m_iTotalPrivCacheHits(0) + { } @@ -30,6 +37,10 @@ ReqStats::~ReqStats() void ReqStats::finalizeRpt() { m_iTotalReqs += m_iReqPerSec; + m_iTotalStxCacheHits += m_iStxCacheHitsPerSec; + m_iTotalPubCacheHits += m_iPubCacheHitsPerSec; + m_iTotalPrivCacheHits += m_iPrivCacheHitsPerSec; + } diff --git a/src/http/reqstats.h b/src/http/reqstats.h index 1724c49f9..ab7fe5a24 100644 --- a/src/http/reqstats.h +++ b/src/http/reqstats.h @@ -24,6 +24,13 @@ class ReqStats { int m_iReqPerSec; int m_iTotalReqs; + int m_iStxCacheHitsPerSec; + int m_iTotalStxCacheHits; + + int m_iPubCacheHitsPerSec; + int m_iTotalPubCacheHits; + int m_iPrivCacheHitsPerSec; + int m_iTotalPrivCacheHits; ReqStats(const ReqStats &rhs); @@ -32,12 +39,39 @@ class ReqStats ReqStats(); ~ReqStats(); void incReqProcessed() { ++m_iReqPerSec; } + void incStxCacheHits() { ++m_iStxCacheHitsPerSec; } + void incPubCacheHits() { ++m_iPubCacheHitsPerSec; } + void incPrivCacheHits() { ++m_iPrivCacheHitsPerSec; } + int getRPS() const { return m_iReqPerSec; } int getTotal() const { return m_iTotalReqs; } - void reset() { m_iReqPerSec = 0; } - void resetTotal() { m_iTotalReqs = 0; } - void finalizeRpt(); + int getHitsPS() const { return m_iStxCacheHitsPerSec; } + int getTotalHits() const { return m_iTotalStxCacheHits; } + + int getPubHitsPS() const { return m_iPubCacheHitsPerSec; } + int getTotalPubHits() const { return m_iTotalPubCacheHits; } + int getPrivHitsPS() const { return m_iPrivCacheHitsPerSec; } + int getTotalPrivHits() const { return m_iTotalPrivCacheHits; } + + + void reset() + { + m_iReqPerSec = 0; + m_iStxCacheHitsPerSec = 0; + m_iPubCacheHitsPerSec = 0; + m_iPrivCacheHitsPerSec = 0; + } + + void resetTotal() + { + m_iTotalReqs = 0; + m_iTotalStxCacheHits = 0; + m_iTotalPubCacheHits = 0; + m_iTotalPrivCacheHits = 0; + } + + void finalizeRpt(); }; #endif diff --git a/src/http/staticfilehandler.cpp b/src/http/staticfilehandler.cpp index 989f466e8..1fa1e9bf0 100644 --- a/src/http/staticfilehandler.cpp +++ b/src/http/staticfilehandler.cpp @@ -46,6 +46,7 @@ #include #include #include +#include "httpstats.h" RedirectHandler::RedirectHandler() @@ -448,6 +449,8 @@ int StaticFileHandler::process(HttpSession *pSession, } } + pSession->incStatsCacheHits(0); + //if ( code == SC_200 ) if ((!isSSI) && (code == SC_200)) { @@ -609,7 +612,7 @@ int StaticFileHandler::process(HttpSession *pSession, else { /** - * Serving not done, add flag to save to static file cache when + * Serving not done, add flag to save to static file cache when * response is done */ pSession->setFlag(HSF_SAVE_STX_FILE_CACHE); diff --git a/src/main/httpserver.cpp b/src/main/httpserver.cpp index 8c4e5a195..dc20dfba2 100644 --- a/src/main/httpserver.cpp +++ b/src/main/httpserver.cpp @@ -590,7 +590,11 @@ int generateConnReport(int fd) "SSL_BPS_IN: %ld, SSL_BPS_OUT: %ld\n" "MAXCONN: %d, MAXSSL_CONN: %d, PLAINCONN: %d, " "AVAILCONN: %d, IDLECONN: %d, SSLCONN: %d, AVAILSSL: %d\n" - "REQ_RATE []: REQ_PROCESSING: %d, REQ_PER_SEC: %d, TOT_REQS: %d\n", + "REQ_RATE []: REQ_PROCESSING: %d, REQ_PER_SEC: %d, TOT_REQS: %d, " + "PUB_CACHE_HITS_PER_SEC: %d, TOTAL_PUB_CACHE_HITS: %d, " + "PRIVATE_CACHE_HITS_PER_SEC: %d, TOTAL_PRIVATE_CACHE_HITS: %d, " + "STATIC_HITS_PER_SEC: %d, TOTAL_STATIC_HITS: %d\n", + HttpStats::getBytesRead() / 1024, HttpStats::getBytesWritten() / 1024, HttpStats::getSSLBytesRead() / 1024, @@ -602,7 +606,15 @@ int generateConnReport(int fd) ctrl.getMaxConns() - ctrl.availConn() - HttpStats::getIdleConns(), HttpStats::getReqStats()->getRPS(), - HttpStats::getReqStats()->getTotal()); + HttpStats::getReqStats()->getTotal(), + + HttpStats::getReqStats()->getPubHitsPS(), + HttpStats::getReqStats()->getTotalPubHits(), + HttpStats::getReqStats()->getPrivHitsPS(), + HttpStats::getReqStats()->getTotalPrivHits(), + HttpStats::getReqStats()->getHitsPS(), + HttpStats::getReqStats()->getTotalHits()); + write(fd, achBuf, n); HttpStats::setBytesRead(0); @@ -3225,6 +3237,21 @@ int HttpServerImpl::configServerBasics(int reconfig, const XmlNode *pRoot) else testAndFixDirs("conf", pw->pw_uid, procConf.getGid(), 0750); + char syscmd[1024] = {0}; +#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__gnu_linux__) + snprintf(syscmd, 1024, "usermod -a -G %s lsadm", MainServerConfigObj.getGroup()); +#endif + +#if defined(__FreeBSD__ ) || defined(__NetBSD__) || defined(__OpenBSD__) + snprintf(syscmd, 1024, "pw usermod lsadm -G %s", MainServerConfigObj.getGroup()); +#endif + +#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + snprintf(syscmd, 1024, "dseditgroup -o edit -a lsadm -t user %s", MainServerConfigObj.getGroup()); +#endif + if (*syscmd) + ::system(syscmd); + return 0; } diff --git a/src/main/lshttpdmain.cpp b/src/main/lshttpdmain.cpp index f38eb64d5..aa756dfee 100644 --- a/src/main/lshttpdmain.cpp +++ b/src/main/lshttpdmain.cpp @@ -82,7 +82,7 @@ /*** * Do not change the below format, it will be set correctly while packing the code */ -#define BUILDTIME " (built: Thu Apr 16 21:39:11 UTC 2020)" +#define BUILDTIME " (built: Thu Apr 30 13:36:22 UTC 2020)" #define GlobalServerSessionHooks (LsiApiHooks::getServerSessionHooks()) diff --git a/src/main/plainconf.cpp b/src/main/plainconf.cpp index 2c9b38284..6464119b4 100644 --- a/src/main/plainconf.cpp +++ b/src/main/plainconf.cpp @@ -679,6 +679,7 @@ void plainconf::saveUnknownItems(const char *fileName, int lineNumber, if (strcasecmp(pCurNode->getName(), "module") != 0 && strstr(name, "::") == NULL && strcasecmp(pCurNode->getName(), "rewrite") != 0 + && strcasecmp(pCurNode->getName(), "context") != 0 && strcasecmp(pCurNode->getName(), "urlFilter") != 0) { logToMem(LOG_LEVEL_ERR, "Not support [%s %s] in file %s:%d", name, value, @@ -782,6 +783,8 @@ void plainconf::handleSpecialCase(XmlNode *pNode) if (strcasecmp(pNode->getName(), "module") == 0) appendValueToKey(pNode, "param", value); + if (strcasecmp(pNode->getName(), "context") == 0) + appendValueToKey(pNode, "param", value); else if (strcasecmp(pNode->getName(), "rewrite") == 0) appendValueToKey(pNode, "rules", value); else if (strcasecmp(pNode->getName(), "urlFilter") == 0) diff --git a/src/modules/cache/cache.cpp b/src/modules/cache/cache.cpp index 50ea5a23c..c7a68ddbf 100644 --- a/src/modules/cache/cache.cpp +++ b/src/modules/cache/cache.cpp @@ -294,10 +294,10 @@ static int parseStoragePath(CacheConfig *pConfig, const char *pValStr, if (pValStr[0] != '/') lstrncpy(cachePath, g_api->get_server_root(), max_file_len); - + /** * Since pValStr is not null terminated, so do a length checking here - * + * */ if (valLen + 1 > max_file_len - strlen(cachePath)) { @@ -309,7 +309,7 @@ static int parseStoragePath(CacheConfig *pConfig, const char *pValStr, delete []pBak; return -1; } - + strncat(cachePath, pValStr, valLen); strncat(cachePath, "/", 1); @@ -327,7 +327,7 @@ static int parseStoragePath(CacheConfig *pConfig, const char *pValStr, pConfig->getStore()->initManager(); pConfig->setOwnStore(1); g_api->set_timer(10*1000, 1, house_keeping_cb, pConfig->getStore()); - + g_api->log(NULL, LSI_LOG_DEBUG, "[%s]parseConfig setStoragePath [%s] for level %d[name: %s].\n", ModuleNameStr, cachePath, level, name); @@ -686,7 +686,7 @@ static void uriToTag(const lsi_session_t *session, char url[maxUrlLength] = { 0 }; int urlLen = 0; char httpstr[4] = {0}; - + int len = g_api->get_req_var_by_id(session, LSI_VAR_HTTPS, httpstr, 4); if (len == 2 && httpstr[1] == 'n') @@ -698,19 +698,19 @@ static void uriToTag(const lsi_session_t *session, { memcpy(url + urlLen, "http://", 7); urlLen += 7; - } - + } + len = g_api->get_req_var_by_id(session, LSI_VAR_SERVER_NAME, url + urlLen, maxUrlLength - urlLen); urlLen += len; - + memcpy(url + urlLen, ":", 1); ++urlLen; - + len = g_api->get_req_var_by_id(session, LSI_VAR_SERVER_PORT, url + urlLen, maxUrlLength - urlLen); urlLen += len; - + if (maxUrlLength - urlLen > uriLen) { /** @@ -1372,7 +1372,7 @@ short lookUpCache(lsi_param_t *rec, MyMData *myData, int no_vary, ModuleNameStr); } } - + if (!(*pEntry)->isUnderConstruct()) return CE_STATE_HAS_PUBLIC_CACHE; else @@ -1587,7 +1587,7 @@ static int deflateBufAndWriteToFile(MyMData *myData, unsigned char *pBuf, ret = -1; break; } - + } } while (myData->zstream->avail_out == 0); } @@ -1634,7 +1634,7 @@ static int endCache(lsi_param_t *rec) ModuleNameStr); return cancelCache(rec); } - + deflateBufAndWriteToFile(myData, NULL, 0, 1, fd); if (myData->pConfig->getAddEtagType() == 2) @@ -1931,7 +1931,7 @@ int cacheHeader(lsi_param_t *rec, MyMData *myData) { myData->pEntry->setMaxStale(myData->pConfig->getMaxStale()); int fd = myData->pEntry->getFdStore(); - g_api->log(rec->session, + g_api->log(rec->session, (fd != -1 ? LSI_LOG_DEBUG : LSI_LOG_ERROR), "[%s]save to %s cachestore by cacheHeader(), uri:%s\n", ModuleNameStr, ((myData->cacheCtrl.isPrivateCacheable()) ? "private" : "public"), @@ -1939,7 +1939,7 @@ int cacheHeader(lsi_param_t *rec, MyMData *myData) if (fd == -1) return LS_FAIL; - + char *sLastMod = NULL; char *sETag = NULL; int nLastModLen = 0; @@ -2021,12 +2021,12 @@ int cacheHeader(lsi_param_t *rec, MyMData *myData) memcpy(tag + keyLen, ",", 1); offset = keyLen + 1; } - - + + int uri_len = 0; const char *uri = g_api->get_req_uri(rec->session, &uri_len); uriToTag(rec->session, uri, uri_len, 1, tag + offset); - + myData->pEntry->setTag(tag, offset + 16); delete []tag; @@ -2160,13 +2160,13 @@ int cacheHeader(lsi_param_t *rec, MyMData *myData) { continue; } - + //if it is lsc-cookie, then change to Set-Cookie if (iov_key[i].iov_len == 10 && strncasecmp(pKey, "lsc-cookie", 10) == 0) pKey = "Set-Cookie"; } - + #ifdef CACHE_RESP_HEADER headersBufSize += writeHttpHeader(fd, &(myData->m_pEntry->m_sRespHeader), pKey, iov_key[i].iov_len, @@ -2257,7 +2257,7 @@ int cacheTofile(lsi_param_t *rec) "[%s:cacheTofile] Failed due to write file error!\n", ModuleNameStr); endCache(rec); - + return 0; } @@ -2956,7 +2956,7 @@ static void processPurge2(const lsi_session_t *session, key.m_pIP = g_api->get_client_ip(session, &ipLen); key.m_ipLen = ipLen; key.m_iCookieVary = 0; - + HttpSession *pSession = (HttpSession *)session; HttpReq *pReq = pSession->getReq(); key.m_iCookiePrivate = getPrivateCacheCookie(pReq, @@ -2972,8 +2972,8 @@ static void processPurge2(const lsi_session_t *session, if (strncmp(pValue, "public,", 7) == 0) pValue += 7; } - - + + while (isspace(*pValue)) ++pValue; @@ -2983,12 +2983,12 @@ static void processPurge2(const lsi_session_t *session, stale = 1; pValue += 6; } - + while (isspace(*pValue)) ++pValue; valLen = pValueEnd - pValue; - + char tag[17] = {0}; if (*pValue == '/') { @@ -2996,7 +2996,7 @@ static void processPurge2(const lsi_session_t *session, pValue = tag; valLen = 16; } - + if (isPriv) { pStore->getManager()->processPrivatePurgeCmd(&key, @@ -3012,7 +3012,7 @@ static void processPurge2(const lsi_session_t *session, g_api->log(session, LSI_LOG_DEBUG, "PURGE public cache: %.*s\n", valLen, pValue); } - + } @@ -3230,7 +3230,7 @@ static int handlerProcess(const lsi_session_t *session) //Disable RECV_RESP header here, to avoid cache myself disableRcvdRespHeaderFilter(session); - + if (myData->iMethod == HTTP_PURGE || myData->iMethod == HTTP_REFRESH) { /** @@ -3241,7 +3241,7 @@ static int handlerProcess(const lsi_session_t *session) * 4, else purge all the entry with a tag which is caculated from the * url, no matter the qs, cookie and vary and so on. */ - + //Comments: REFRESH is stale purge int stale = myData->iMethod == HTTP_REFRESH ? 1 : 0; char httpAuthEnv[3] = {0}; @@ -3266,10 +3266,10 @@ static int handlerProcess(const lsi_session_t *session) char *pConfUri = myData->pConfig->getPurgeUri(); int uri_len = 0; const char *uri = g_api->get_req_uri(session, &uri_len); - + if (pConfUri && strcasecmp(pConfUri, uri) == 0) bPurgeTags = true; - + if (bPurgeTags) { int valLen = 0; @@ -3294,7 +3294,7 @@ static int handlerProcess(const lsi_session_t *session) /** * Now, will puge all cache with this URL */ - + char tag[17] = {0}; uriToTag(session, uri, uri_len, 1, tag); purgeAllByTag(session, myData, tag, 16, stale); @@ -3304,15 +3304,15 @@ static int handlerProcess(const lsi_session_t *session) g_api->append_resp_body(session, stale ? "REFRESH" : "PURGE", stale ? 7 : 5); - + g_api->append_resp_body(session, " by \"", 5); - g_api->append_resp_body(session, myData->pOrgUri, + g_api->append_resp_body(session, myData->pOrgUri, strlen(myData->pOrgUri)); g_api->append_resp_body(session, "\".\r\n", 4); } g_api->log(NULL, LSI_LOG_DEBUG, - "[%s]Did %s %s with tag: %d.\n", ModuleNameStr, + "[%s]Did %s %s with tag: %d.\n", ModuleNameStr, stale ? "REFRESH" : "PURGE", myData->pOrgUri, bPurgeTags); @@ -3323,7 +3323,7 @@ static int handlerProcess(const lsi_session_t *session) myData->pEntry->incRef(); myData->pEntry->setLastAccess(DateTime::s_curTime); - + char tmBuf[RFC_1123_TIME_LEN + 1]; int len; int fd = myData->pEntry->getFdStore(); @@ -3332,6 +3332,8 @@ static int handlerProcess(const lsi_session_t *session) int hitIdx = (myData->iCacheState == CE_STATE_HAS_PRIVATE_CACHE) ? 1 : 0; + ((HttpSession *)session)->incStatsCacheHits(1 + hitIdx); + char *buff = NULL; char *pBuffOrg = NULL; int part1offset = myData->pEntry->getPart1Offset(); @@ -3432,19 +3434,19 @@ static int handlerProcess(const lsi_session_t *session) g_api->remove_resp_header(session, LSI_RSPHDR_LITESPEED_PURGE, NULL, 0); g_api->remove_resp_header(session, -1, "X-LiteSpeed-Purge2", 18); - + struct iovec iov[1] = {{NULL, 0}}; int count = g_api->get_resp_header(session, -1, "lsc-cookie", 10, iov, 1); if (iov[0].iov_len > 0 && count == 1) { g_api->remove_resp_header(session, -1, "lsc-cookie", 10); - + g_api->set_resp_header(session, LSI_RSPHDR_UNKNOWN, "Set-Cookie", 10, (char *)iov[0].iov_base, iov[0].iov_len, LSI_HEADEROP_SET); - + } } }