Fix some bugs

This commit is contained in:
David
2018-07-20 16:47:07 -04:00
parent 714c5d7e37
commit c39181f575
46 changed files with 1918 additions and 2669 deletions
+3 -1
View File
@@ -18,6 +18,7 @@ link_directories( ${PROJECT_SOURCE_DIR}/../thirdparty/lib/)
SET (CMAKE_C_COMPILER "/usr/bin/clang")
SET (CMAKE_CXX_COMPILER "/usr/bin/clang++")
## thread sanitizer
#set (TSAN "1")
IF(TSAN)
@@ -27,6 +28,7 @@ ELSE(TSAN)
set(MY_CMAKE_TSAN_FLAG " ")
ENDIF(TSAN)
## address sanitizer
IF(ASAN)
set(MY_CMAKE_ASAN_FLAG " -fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer")
@@ -71,7 +73,7 @@ set(libUnitTest libUnitTest++.a)
set(BSSL_ADD_LIB libdecrepit.a)
##########################################################################################
#If you want to use Brotli Compression, just un-comment out the following commands
set(BROTLI_ADD_LIB libbrotlidec.a libbrotlienc.a libbrotlicommon.a)
set(BROTLI_ADD_LIB libbrotlidec-static.a libbrotlienc-static.a libbrotlicommon-static.a)
add_definitions(-DUSE_BROTLI)
##########################################################################################
#If you want to use IP2Location, just un-comment out the following commands
+1 -1
View File
@@ -1,2 +1,2 @@
About installation, please read below article
https://openlitespeed.org/#install
https://openlitespeed.org/#install
Vendored
-29
View File
@@ -9277,35 +9277,6 @@ else
fi
])
# -*- Autoconf -*-
# Obsolete and "removed" macros, that must however still report explicit
# error messages when used, to smooth transition.
#
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
AC_DEFUN([AM_CONFIG_HEADER],
[AC_DIAGNOSE([obsolete],
['$0': this macro is obsolete.
You should use the 'AC][_CONFIG_HEADERS' macro instead.])dnl
AC_CONFIG_HEADERS($@)])
AC_DEFUN([AM_PROG_CC_STDC],
[AC_PROG_CC
am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc
AC_DIAGNOSE([obsolete],
['$0': this macro is obsolete.
You should simply use the 'AC][_PROG_CC' macro instead.
Also, your code should no longer depend upon 'am_cv_prog_cc_stdc',
but upon 'ac_cv_prog_cc_stdc'.])])
AC_DEFUN([AM_C_PROTOTYPES],
[AC_FATAL([automatic de-ANSI-fication support has been removed])])
AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+2 -2
View File
@@ -383,8 +383,8 @@ static int check_resp_misc(const lsi_session_t *session)
if (!g_api->is_resp_buffer_available(session))
LSM_DBGH((&MNAME), session, "resp buffer not available\n");
else if(!g_api->is_resp_buffer_gzippped(session))
LSM_DBGH((&MNAME), session, "resp buffer not gzipped\n");
else if(g_api->get_resp_buffer_compress_method(session) == 0)
LSM_DBGH((&MNAME), session, "resp buffer not compressed\n");
LSM_DBGH((&MNAME), session, "resp buffer avail and gzipped\n");
if (g_api->is_suspended(session) <= 0)
+1 -1
View File
@@ -334,7 +334,7 @@ static void displayInfo(session_list_t_ *psession_list)
g_api->get_req_query_string(psession_list->m_plsi_session,&queryLength),
chUriFilePath,
g_api->get_status_code(psession_list->m_plsi_session),
g_api->is_resp_buffer_gzippped(psession_list->m_plsi_session),
g_api->get_resp_buffer_compress_method(psession_list->m_plsi_session),
g_api->get_resp_headers_count(psession_list->m_plsi_session),
g_api->is_resp_headers_sent(psession_list->m_plsi_session)
);
+1 -1
View File
@@ -244,7 +244,7 @@ static int process_req(const lsi_session_t *session)
if (LS_FAIL == g_api->set_resp_wait_full_body(session))
LSM_ERR((&MNAME), session, "Failed to set resp wait full body\n");
if (LS_FAIL == g_api->set_resp_buffer_gzip_flag(session, 0))
if (LS_FAIL == g_api->set_resp_buffer_compress_method(session, 0))
LSM_ERR((&MNAME), session, "Failed to set no gzip\n");
if (LS_FAIL == g_api->set_force_mime_type(session, NULL))
+8 -3
View File
@@ -73,16 +73,21 @@ else
AC_MSG_RESULT([$PCRE_LIBS])
m4_ifval($1,$1)
else
PCRE_LDFLAGS="-L$with_pcre/$OPENLSWS_LIBDIR"
pcrevalue=$with_pcre
if test "$pcrevalue" = "yes" ; then
pcrevalue=/usr/local
fi
PCRE_LDFLAGS="-L$pcrevalue/$OPENLSWS_LIBDIR"
OLDLDFLAGS="$LDFLAGS" ; LDFLAGS="$LDFLAGS $PCRE_LDFLAGS"
OLDCPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS -I$with_pcre/include"
OLDCPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS -I$pcrevalue/include"
AC_CHECK_LIB(pcre, pcre_compile)
CPPFLAGS="$OLDCPPFLAGS"
LDFLAGS="$OLDLDFLAGS"
if test "$ac_cv_lib_pcre_pcre_compile" = "yes" ; then
AC_MSG_RESULT(.setting PCRE_LIBS $PCRE_LDFLAGS -lpcre)
PCRE_LIBS="$PCRE_LDFLAGS -lpcre"
test -d "$with_pcre/include" && PCRE_CFLAGS="-I$with_pcre/include"
test -d "$pcrevalue/include" && PCRE_CFLAGS="-I$pcrevalue/include"
AC_MSG_CHECKING([$OPENLSWS_LIBDIR pcre])
AC_MSG_RESULT([$PCRE_LIBS])
m4_ifval($1,$1)
Vendored
+9 -3
View File
@@ -16738,9 +16738,14 @@ $as_echo_n "checking $OPENLSWS_LIBDIR pcre... " >&6; }
$as_echo "$PCRE_LIBS" >&6; }
else
PCRE_LDFLAGS="-L$with_pcre/$OPENLSWS_LIBDIR"
pcrevalue=$with_pcre
if test "$pcrevalue" = "yes" ; then
pcrevalue=/usr/local
fi
PCRE_LDFLAGS="-L$pcrevalue/$OPENLSWS_LIBDIR"
OLDLDFLAGS="$LDFLAGS" ; LDFLAGS="$LDFLAGS $PCRE_LDFLAGS"
OLDCPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS -I$with_pcre/include"
OLDCPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS -I$pcrevalue/include"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre_compile in -lpcre" >&5
$as_echo_n "checking for pcre_compile in -lpcre... " >&6; }
if ${ac_cv_lib_pcre_pcre_compile+:} false; then :
@@ -16792,7 +16797,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: .setting PCRE_LIBS $PCRE_LDFLAGS -lpcre" >&5
$as_echo ".setting PCRE_LIBS $PCRE_LDFLAGS -lpcre" >&6; }
PCRE_LIBS="$PCRE_LDFLAGS -lpcre"
test -d "$with_pcre/include" && PCRE_CFLAGS="-I$with_pcre/include"
test -d "$pcrevalue/include" && PCRE_CFLAGS="-I$pcrevalue/include"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $OPENLSWS_LIBDIR pcre" >&5
$as_echo_n "checking $OPENLSWS_LIBDIR pcre... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PCRE_LIBS" >&5
@@ -18447,6 +18452,7 @@ DEFS=-DHAVE_CONFIG_H
ac_libobjs=
ac_ltlibobjs=
U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
# 1. Remove the extension, and $U if already installed.
ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+2 -2
View File
@@ -11,7 +11,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT([openlitespeed],[1.5.0],[info@litespeedtech.com],[openlitespeed],[http://www.litespeedtech.com/])
AM_INIT_AUTOMAKE([1.0 foreign no-define ])
AC_CONFIG_HEADERS([src/config.h:src/config.h.in])
AC_CONFIG_HEADERS(src/config.h:src/config.h.in)
dnl NOW change the default installation directory!
AC_PREFIX_DEFAULT('/usr/local/lsws')
@@ -364,7 +364,7 @@ AM_CONDITIONAL([HAVE_IP2LOCATION], [test x$need_ip2location = xyes])
echo "IP2Location include = $IP2LOCATION_INCLUDES, need_ip2location = $need_ip2location"
AC_ARG_ENABLE([rpath],
[AS_HELP_STRING([--disable-rpath],
[AS_HELP_STRING([--disable-rpath],
[Disable rpath (It is 'no' by default)])],
[OPENLSWS_DISABLE_RPATH=yes
echo "OPENLSWS_DISABLE_RPATH=yes"], [OPENLSWS_DISABLE_RPATH=no])
+3 -1
View File
@@ -124,7 +124,7 @@ class DInfo
$this->_allActions = array(
'a' => array(DMsg::UIStr('btn_add'), 'fa-plus'),
'v' => array(DMsg::UIStr('btn_view'), 'fa-search-plus'),
'E' => array(DMsg::UIStr('btn_edit'), 'fa-edit'),
'E' => array(DMsg::UIStr('btn_edit'), 'fa-edit'),
's' => array(DMsg::UIStr('btn_save'), 'fa-save'),
'B' => array(DMsg::UIStr('btn_back'), 'fa-reply'), //'fa-level-up'
'n' => array(DMsg::UIStr('btn_next'), 'fa-step-forward'),
@@ -316,6 +316,8 @@ class DInfo
} else {
$r = $editref;
}
$t = addslashes($t);
$r = addslashes($r);
//$t = '&t=' . $t;
//$r = '&r=' . urlencode($r);
+1
View File
@@ -1,5 +1,6 @@
<?php
/* $Id: blowfish.php,v 1.3 2008/02/20 23:24:59 gwang Exp $ */
// vim: expandtab sw=4 ts=4 sts=4:
/**
+6 -7
View File
@@ -4,6 +4,9 @@
# Or,
# Use your pre-built boringSSL
#For openssl, always use the latest officially released version
VERSION=OpenSSL_1_1_1-pre8
if [ "x$1" = "xuse_bssl" ] ; then
if [ "x$2" != "x" ] ; then
@@ -22,13 +25,8 @@ if [ "x$1" = "xuse_bssl" ] ; then
exit 0;
fi
VERSION=OpenSSL_1_0_2-stable
#a bug fix of openssl 1.0.2
fixbug()
{
sed -i -e "s/], s->s3->wpend_tot/], len - tot/" ssl/s3_pkt.c
}
cd `dirname "$0"`
@@ -36,16 +34,17 @@ echo "Checking openssl ..."
if [ ! -f ssl/libcrypto.a ] ; then
echo -e "\033[38;5;148mDownload openssl $VERSION and building, it will take several minutes ...\033[39m"
echo -e "\033[38;5;148mThe url is https://github.com/openssl/openssl/archive/$VERSION.tar.gz\033[39m"
DL=`which curl`
DLCMD="$DL -k -L -o ossl.tar.gz"
$DLCMD https://github.com/openssl/openssl/archive/$VERSION.tar.gz
tar xf ossl.tar.gz
rm -rf ssl
mv openssl-$VERSION ssl
rm ossl.tar.gz
cd ssl
fixbug
./config
make depend
make
+1 -5
View File
@@ -77,8 +77,6 @@ SET(unittest_STAT_SRCS
../test/util/objarraytest.cpp
../test/util/objpooltest.cpp
../test/util/radixtreetest.cpp
../test/spdy/huffmantest.cpp
../test/spdy/hpacktest.cpp
../test/spdy/spdyzlibfiltertest.cpp
../test/spdy/spdyconnectiontest.cpp
../test/spdy/dummiostream.cpp
@@ -115,8 +113,6 @@ SET(unittest_STAT_SRCS
../test/shm/shmxtest.cpp
)
link_directories(${PROJECT_SOURCE_DIR}/ssl/ /usr/local/lib ${PROJECT_SOURCE_DIR}/src/test/unittest-cpp/UnitTest++)
add_executable(openlitespeed ${openlitespeed_SRCS}
${unittest_STAT_SRCS}
)
@@ -147,7 +143,7 @@ add_executable(ls_shmhashstat
SET( litespeedlib
modgzip lsiapi main http lsiapi spdy ssi
registry cgi fcgi jk extensions lsapi proxy
edio socket sslpp lsshm thread log4cxx adns
edio socket sslpp lsshm thread log4cxx adns
-Wl,--whole-archive util lsr -Wl,--no-whole-archive sslpp GeoIP ${MMDB_LIB} udns
pthread rt ${CMAKE_DL_LIBS} ${libUnitTest} libssl.a libcrypto.a
${BSSL_ADD_LIB} ${BROTLI_ADD_LIB} ${IP2LOC_ADD_LIB})
+1 -1
View File
@@ -71,7 +71,7 @@ public:
void schedule(evtcbnode_s *pObj, bool nowait = true);
evtcbnode_s *schedule(evtcb_pf cb, const evtcbtail_t *session,
long lParam, void *pParam, bool nowait = true);
long lParam, void *pParam, bool nowait);
int removeSessionCb(evtcbtail_t * pSession);
static evtcbtail_t **getSessionRefPtr(evtcbnode_s *nodeObj);
+19 -4
View File
@@ -40,6 +40,8 @@ static char s_achForwardHttps[] = "X-Forwarded-Proto: https\r\n";
static char s_achForwardHost[] = "X-Forwarded-Host: ";
ProxyConn::ProxyConn()
: m_iSsl(0)
, m_flag(0)
{
strcpy(m_extraHeader, "Accept-Encoding: gzip\r\nX-Forwarded-For: ");
memset(&m_iTotalPending, 0,
@@ -518,7 +520,7 @@ int ProxyConn::doRead()
return ret;
return doWrite();
}
m_flag |= PCF_IN_DO_READ;
ret = processResp();
if (getState() == ABORT)
{
@@ -528,6 +530,7 @@ int ProxyConn::doRead()
getConnector()->endResponse(0, 0);
}
}
m_flag &= ~PCF_IN_DO_READ;
return ret;
}
@@ -640,13 +643,16 @@ int ProxyConn::readRespBody()
if (ret > 1024 || (ret < (int)bufLen))
pHEC->flushResp();
}
if (m_pChunkIS->eos())
if (!m_pChunkIS || m_pChunkIS->eos())
{
ret = 0;
break;
}
pHEC->flushResp();
return ret;
else if (ret == 0 || m_iSsl == 0)
{
pHEC->flushResp();
return 0;
}
}
else
{
@@ -913,4 +919,13 @@ void ProxyConn::dump()
}
void ProxyConn::continueRead()
{
LS_DBG_L(getLogger(), "[%s] ProxyConn::continueRead(), fd: %d", getLogId(), getfd());
EdStream::continueRead();
if (!isInDoRead() && m_ssl.isConnected())
{
doRead();
}
}
+9 -5
View File
@@ -24,6 +24,8 @@
#include <extensions/httpextprocessor.h>
#include <sslpp/sslconnection.h>
#define PCF_IN_DO_READ 1
class ChunkInputStream;
class ProxyConn : public ExtConn
, public HttpExtProcessor
@@ -48,8 +50,9 @@ class ProxyConn : public ExtConn
ChunkInputStream *m_pChunkIS;
int m_iSsl;
SslConnection m_ssl;
short m_iSsl;
short m_flag;
SslConnection m_ssl;
char m_extraHeader[256]; //X-Forwarded-For
@@ -75,6 +78,7 @@ protected:
public:
virtual int removeRequest(ExtRequest *pReq);
void continueRead();
public:
ProxyConn();
@@ -99,9 +103,9 @@ public:
virtual int close();
void reset();
void setUseSsl(int s) { m_iSsl = s; }
int isUseSsl() const { return m_iSsl; }
void setUseSsl(int s) { m_iSsl = s; }
short isUseSsl() const { return m_iSsl; }
short isInDoRead() const { return m_flag & PCF_IN_DO_READ; }
LS_NO_COPY_ASSIGN(ProxyConn);
};
+1
View File
@@ -157,6 +157,7 @@ int CustomFormat::parseFormat(const char *psFormat)
itemId = REF_REQ_TIME_MS;
break;
case 'e':
case 'x':
if (!pBegin)
break;
itemId = REF_ENV;
+6 -5
View File
@@ -1126,7 +1126,7 @@ void HttpSession::extCmdDone()
EvtcbQue::getInstance().schedule(m_cbExtCmd,
this,
m_lExtCmdParam,
m_pExtCmdParam);
m_pExtCmdParam, false);
}
@@ -2128,7 +2128,7 @@ int HttpSession::sendHttpError(const char *pAdditional)
{
if (statusCode < SC_500)
SsiEngine::printError(this, NULL);
markComplete();
markComplete(true);
getStream()->wantWrite(1);
return 0;
}
@@ -3706,7 +3706,7 @@ int HttpSession::call_nextRequest(evtcbtail_t *p, long , void *)
}
inline void HttpSession::markComplete()
inline void HttpSession::markComplete(bool nowait)
{
LS_DBG_L(getLogSession(), "mark HSS_COMPLETE.");
@@ -3726,7 +3726,7 @@ inline void HttpSession::markComplete()
EvtcbQue::getInstance().schedule(call_nextRequest,
this,
getSn(),
NULL);
NULL, nowait);
}
@@ -3798,7 +3798,8 @@ int HttpSession::flush()
| HSF_SEND_RESP_BUFFERED) == HSF_HANDLER_DONE)
{
LS_DBG_L(getLogSession(), "Set the HSS_COMPLETE flag.");
markComplete();
if (getState() != HSS_COMPLETE)
markComplete(false);
return ret;
}
else
+1 -1
View File
@@ -278,7 +278,7 @@ class HttpSession
}
static int call_nextRequest(lsi_session_t *p, long , void *);
void markComplete();
void markComplete(bool nowait);
void releaseResources();
void releaseReqParser();
+8 -8
View File
@@ -752,11 +752,10 @@ int HttpVHost::configBasics(const XmlNode *pVhConfNode, int iChrootLen)
enableBr((HttpServerConfig::getInstance().getBrCompress()) ?
ConfigCtx::getCurConfigCtx()->getLongValue(pVhConfNode, "enableBr", 0, 1,
1) : 0);
m_rootContext.setGeoIP((
HttpServer::getInstance().getServerContext().isGeoIpOn()) ?
ConfigCtx::getCurConfigCtx()->getLongValue(pVhConfNode, "enableIpGeo", 0,
1,
0) : 0);
int val = ConfigCtx::getCurConfigCtx()->getLongValue(pVhConfNode, "enableIpGeo", -1, 1, -1);
if (val == -1)
val = HttpServer::getInstance().getServerContext().isGeoIpOn();
m_rootContext.setGeoIP(val);
m_rootContext.setIpToLoc(HttpServer::getInstance().getServerContext().isIpToLocOn());
@@ -1710,9 +1709,10 @@ int HttpVHost::configContext(const XmlNode *pContextNode)
{
if (configContextAuth(pContext, pContextNode) == -1)
return LS_FAIL;
pContext->setGeoIP((m_rootContext.isGeoIpOn()) ?
ConfigCtx::getCurConfigCtx()->getLongValue(pContextNode,
"enableIpGeo", 0, 1, 0) : 0);
int val = ConfigCtx::getCurConfigCtx()->getLongValue(pContextNode,
"enableIpGeo", -1, 1, -1);
if (val != -1)
pContext->setGeoIP(val);
pContext->setIpToLoc(m_rootContext.isIpToLocOn());
return pContext->config(getRewriteMaps(), pContextNode, type,
getRootContext());
+152 -57
View File
@@ -36,6 +36,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/errno.h>
#define MAX_KEY_LENGTH 256
@@ -516,6 +517,7 @@ IpToGeo2::IpToGeo2()
: m_ndbs(0)
, m_dbs(NULL)
, m_did_add_env(0)
, m_did_add_env_default(0)
{
}
@@ -554,6 +556,7 @@ void IpToGeo2::release_all()
ls_pfree(m_dbs);
m_dbs = NULL;
m_did_add_env = 0;
m_did_add_env_default = 0;
}
@@ -576,7 +579,7 @@ void IpToGeo2::normalize_address(in6_addr addr, struct sockaddr_in6 *sa)
int IpToGeo2::loadGeoIpDbFile(const char *pFile, const char *pDbLogical)
{
int ret;
LS_DBG("[GEO] loadGeoIpDbFile: %s\n", pFile);
LS_DBG("[GEO] loadGeoIpDbFile: %s, total dbs: %d\n", pFile, m_ndbs + 1);
void *arr = ls_prealloc(m_dbs, ((m_ndbs + 1) * sizeof(dbs_t)));
if (!arr)
{
@@ -621,13 +624,17 @@ int IpToGeo2::loadGeoIpDbFile(const char *pFile, const char *pDbLogical)
int IpToGeo2::testGeoIpDbFile(const char *pFile)
{
pid_t pid = fork();
if (pid < 0)
return -1;
if (pid == 0)
{
// Was done in a fork, but did not work reliably that way.
//pid_t pid = fork();
//if (pid < 0)
//{
// LS_ERROR("[GEO] testGeoIpDbFile fork failed, errno: %d\n", errno);
// return -1;
//}
//if (pid == 0)
//{
MMDB_s mmdb;
int ret = MMDB_open(pFile, MMDB_MODE_MMAP, &mmdb);
int ret = MMDB_open(pFile, 0/*MMDB_MODE_MMAP*/, &mmdb);
if (ret == 0)
{
unsigned char addr[4] = { 88, 252, 206, 167 };
@@ -637,25 +644,33 @@ int IpToGeo2::testGeoIpDbFile(const char *pFile)
normalize_address(*(int32_t *)addr, &sa);
res = MMDB_lookup_sockaddr(&mmdb, (struct sockaddr *)&sa, &dberr);
if (dberr != 0)
{
ret = dberr;
}
else if (!res.found_entry)
{
ret = 0xff;
}
else
{
// Found
}
MMDB_close(&mmdb);
}
exit(ret != 0);
}
else
{
int status;
int wpid = waitpid(pid, &status, 0);
if (wpid == pid && WIFEXITED(status) && WEXITSTATUS(status) == 0)
// exit(ret);
//}
//else
//{
// int status;
// int wpid = waitpid(pid, &status, 0);
// if (wpid == pid && WIFEXITED(status) && WEXITSTATUS(status) == 0)
if (!ret)
return 0;
LS_ERROR("[GEO] GeoIP DB file test failed: '%s'.", pFile);
}
LS_ERROR("[GEO] GeoIP DB file test failed: '%s'. ret: %d\n", pFile, ret);
// LS_ERROR("[GEO] GeoIP DB file test failed: '%s'. Exited: %d, Status: %d\n",
// pFile, WIFEXITED(status), WEXITSTATUS(status));
//}
return -1;
}
@@ -690,58 +705,129 @@ int IpToGeo2::setGeoIpDbFile(const char *pFile, const char *pDbLogical)
}
const char *IpToGeo2::getDefaultLogicalName(const char *fileName)
{
int dblen = strlen(fileName);
for (int i = 0; i < (int)(sizeof(s_db_default) / sizeof(dbs_t)); ++i)
{
int defDbLen = strlen(s_db_default[i].m_file);
if ((dblen > defDbLen) &&
(!(strcmp(s_db_default[i].m_file,
&fileName[dblen - defDbLen]))))
{
return s_db_default[i].m_logical;
}
}
return NULL;
}
/**
* config: With XmlNodeList
* "GeoIP DB": Allows you a user to specify a NEW DB name in the OLD form.
* We have to validate the name and then try to apply a logical
* name. Not easy, but we'll give it a shot.
* User interface nests environment variables within the XML
* definition. Process the name, then the nested stuff and then
* do the defaults so that they will NOT overwrite the user's
* specifications.
*/
int IpToGeo2::config(const XmlNodeList *pList)
{
XmlNodeList::const_iterator iter;
int succ = 0;
const char *logicalName = NULL;
for (iter = pList->begin(); iter != pList->end(); ++iter)
{
XmlNode *p = *iter;
const char *pFile = p->getValue();
char achBufFile[MAX_PATH_LEN];
if ((!pFile) ||
(ConfigCtx::getCurConfigCtx()->getValidFile(achBufFile, pFile,
"GeoIP DB") != 0))
continue;
// This is a compatibility mode so we'll validate some things and try
// to use it.
int dblen = strlen(achBufFile);
for (int i = 0; i < (int)(sizeof(s_db_default) / sizeof(dbs_t)); ++i)
LS_DBG_M("[GEO] config test pList: name: %s, value: %s, has child: %d\n",
p->getName(), p->getValue(), p->hasChild());
if (!(strcasecmp(p->getName(), "maxminddbenable")))
{
int defDbLen = strlen(s_db_default[i].m_file);
if ((dblen > defDbLen) &&
(!(strcmp(s_db_default[i].m_file,
&achBufFile[dblen - defDbLen]))))
if (strcasecmp(p->getValue(), "off"))
{
if (setGeoIpDbFile(achBufFile, s_db_default[i].m_logical) == 0)
LS_NOTICE("[GEO] Geolocation disabled by configuration\n");
return -1;
}
}
else if (!strcasecmp(p->getName(), "maxminddbfile"))
{
if (configSetFile(p->getValue()) == -1)
return -1;
succ = 1;
}
else if (!strcasecmp(p->getName(), "geoipdb"))
{
int hasEnv = 0;
if (!pFile)
{
LS_ERROR("[GEO] for %s you must specify a valid file name\n",
p->getName());
return -1;
}
LS_DBG_M("[GEO] geoipdb found, hasChild: %d\n", p->hasChild());
if (p->hasChild())
{
XmlNodeList children;
p->getAllChildren(children);
XmlNodeList::const_iterator iterChild;
for (iterChild = children.begin(); iterChild != children.end();
++iterChild)
{
succ = 1;
for (int e = 0; e < s_db_default[i].m_nenv; ++e)
XmlNode *parm = *iterChild;
LS_DBG_M("[GEO] check child name: %s, value: %s\n",
parm->getName(), parm->getValue());
if (!strcasecmp(parm->getName(), "geoipdbname"))
{
char env[MAX_PATH_LEN * 3];
snprintf(env, sizeof(env), "%s %s%s",
s_db_default[i].m_env[e].m_var,
s_db_default[i].m_logical,
s_db_default[i].m_env[e].m_key);
if (configSetEnv(env) != 0)
{
succ = 0;
break;
}
logicalName = parm->getValue();
LS_DBG_M("[GEO] geoipdb found logical name: %s\n",
logicalName);
}
else if (!strcasecmp(parm->getName(),"maxminddbenv"))
{
hasEnv = 1;
LS_DBG_M("[GEO] geoipdb found env var for later\n");
}
if (!succ)
return -1; // Already reported
}
}
if (!logicalName)
{
// Use a default logical name?
if (!(logicalName = getDefaultLogicalName(pFile)))
LS_ERROR("[GEO] no logical name specified for unknown "
"database %s\n", pFile);
return -1;
}
if (setGeoIpDbFile(pFile, logicalName) == -1)
return -1;
if (hasEnv)
{
XmlNodeList children;
p->getAllChildren(children);
XmlNodeList::const_iterator iterChild;
for (iterChild = children.begin(); iterChild != children.end();
++iterChild)
{
XmlNode *parm = *iterChild;
LS_DBG_M("[GEO] check child name for env: %s, value: %s\n",
parm->getName(), parm->getValue());
if (!strcasecmp(parm->getName(),"maxminddbenv"))
{
LS_DBG_M("[GEO] process env override now\n");
if (configSetEnv(parm->getValue()))
return -1;
}
}
}
succ = 1;
}
else if (!strcasecmp(p->getName(), "maxminddbenv"))
{
if (configSetEnv(p->getValue()))
return -1;
}
}
if (succ)
@@ -902,9 +988,11 @@ int IpToGeo2::parseEnvLine(const char *pEnvAliasMap,
int IpToGeo2::validateEnv(const char *pEnvAliasMap, const char *variable,
const char *database, const char *map, int *db)
const char *database, const char *map, int *db,
int *found)
{
const char *env_title = "MaxMindDBEnv";
*found = 0;
for (int i = 0; i < m_ndbs; ++i)
{
if (!(strcasecmp(database, m_dbs[i].m_logical)))
@@ -921,9 +1009,10 @@ int IpToGeo2::validateEnv(const char *pEnvAliasMap, const char *variable,
{
if (strcasecmp(variable, m_dbs[i].m_env[e].m_var) == 0)
{
LS_ERROR("[GEO] In %s Environment variable %s can not be "
"defined twice", env_title, variable);
return -1;
LS_DBG_M("[GEO] In %s Environment variable %s 2nd definition"
"being ignored", env_title, variable);
*found = 1;
break;
}
}
LS_DBG("[GEO] Env FOUND! %s=%s%s DB #%d\n", variable, database,
@@ -983,21 +1072,27 @@ int IpToGeo2::configSetEnv(const char *pEnvAliasMap)
char database[MAX_PATH_LEN];
char map[MAX_PATH_LEN];
int db;
int found;
if (parseEnvLine(pEnvAliasMap, variable, sizeof(variable),
database, sizeof(database), map, sizeof(map)) == -1)
return -1;
if (validateEnv(pEnvAliasMap, variable, database, map, &db) == -1)
if (validateEnv(pEnvAliasMap, variable, database, map, &db, &found) == -1)
return -1;
if (addEnv(pEnvAliasMap, variable, database, map, db) == -1)
return -1;
m_did_add_env = 1;
if (!found)
{
if (addEnv(pEnvAliasMap, variable, database, map, db) == -1)
return -1;
m_did_add_env = 1;
}
return 0;
}
int IpToGeo2::defaultEnv()
{
LS_DBG("[GEO] defaultEnv\n");
LS_DBG("[GEO] defaultEnv %d DBs, default DBs: %d\n", m_ndbs,
(int)(sizeof(s_db_default) / sizeof(dbs_t)));
m_did_add_env_default = 1;
for (int i = 0; i < m_ndbs; ++i)
{
for (int defDb = 0; defDb < (int)(sizeof(s_db_default) / sizeof(dbs_t));
@@ -1050,7 +1145,7 @@ GeoInfo * IpToGeo2::lookUpSA(struct sockaddr *sa)
"file\n");
return NULL;
}
if ((m_ndbs) && (!m_did_add_env))
if ((m_ndbs) && (!m_did_add_env_default))
if (defaultEnv() == -1)
{
LS_ERROR("[GEO] Error setting default ENV\n");
+3 -1
View File
@@ -108,12 +108,13 @@ private:
void normalize_address(in6_addr addr, struct sockaddr_in6 *sa);
int loadGeoIpDbFile(const char *pFile, const char *pDbLogical);
int testGeoIpDbFile(const char *pFile);
const char *getDefaultLogicalName(const char *fileName);
int parseEnvLine(const char *pEnvAliasMap,
char *variable, int var_len,
char *database, int database_len,
char *map, int map_len);
int validateEnv(const char *pEnvAliasMap, const char *variable,
const char *database, const char *map, int *db);
const char *database, const char *map, int *db, int *found);
int addEnv(const char *pEnvAliasMap, const char *variable,
const char *database, const char *map, const int db);
int defaultEnv();
@@ -126,6 +127,7 @@ private:
int m_ndbs;
dbs_t *m_dbs;
int m_did_add_env;
int m_did_add_env_default;
static IpToGeo2 *s_pIpToGeo2;
LS_NO_COPY_ASSIGN(IpToGeo2);
};
+22 -9
View File
@@ -806,12 +806,15 @@ int StaticFileCacheData::compressHelper(AutoStr2 &path, FileCacheDataEx *&pData,
int StaticFileCacheData::readyCompressed(char compressMode)
{
LS_DBG_H("readyCompressed() compressMode %d", compressMode);
time_t tm = time(NULL);
if (tm == getLastMod())
return LS_FAIL;
if (tm == m_tmLastCheck)
return setReadiedCompressData(compressMode);
int statBr = -1, retGz = -1, statGz = -1;
struct stat stGzip;
struct stat stBr;
@@ -820,18 +823,25 @@ int StaticFileCacheData::readyCompressed(char compressMode)
if (!m_bredPath.c_str() || !*m_bredPath.c_str())
{
if (buildCompressedPaths() == -1)
{
LS_ERROR("readyCompressed() buildCompressedPaths error.");
return LS_FAIL;
}
}
if (compressMode & SFCD_MODE_BROTLI)
{
statBr = ls_fio_stat(m_bredPath.c_str(), &stBr);
LS_DBG_H("readyCompressed() path %s statBr %d",
m_bredPath.c_str(), statBr);
}
if (compressMode & SFCD_MODE_GZIP)
{
statGz = ls_fio_stat(m_gzippedPath.c_str(), &stGzip);
retGz = ((statGz == -1)
|| (stGzip.st_mtime != getLastMod()));
LS_DBG_H("readyCompressed() path %s statGz %d retGz %d",
m_gzippedPath.c_str(), statGz, retGz);
}
if (compressMode & SFCD_MODE_BROTLI) // brotli active AND not valid
@@ -839,35 +849,38 @@ int StaticFileCacheData::readyCompressed(char compressMode)
if ((statBr != -1) && (stBr.st_mtime == getLastMod()))
{
// use br
}
if (!(compressMode & SFCD_MODE_GZIP) || retGz)
{
// update br
if ((statBr = compressHelper(m_bredPath, m_pBrotli, stBr, statBr, 1)))
{
LS_ERROR("readyCompressed compress br error %s.",
m_bredPath.c_str());
return LS_FAIL;
}
}
else
{
compressMode &= ~SFCD_MODE_BROTLI;
}
}
else if ((compressMode & SFCD_MODE_GZIP) && retGz)
{
// update gz
if ((statGz = compressHelper(m_gzippedPath, m_pGzip, stGzip, statGz, 0)))
return LS_FAIL;
}
else if (compressMode & SFCD_MODE_GZIP)
{
// use gz
if (retGz && (statGz = compressHelper(m_gzippedPath, m_pGzip, stGzip, statGz, 0)))
{
LS_DBG_H("readyCompressed() compress gzip error %s or file size not suitable for gzip.",
m_gzippedPath.c_str());
return LS_FAIL;
}
// else use gz
}
else
{
LS_ERROR("Compress with both Brotli and Gzip turned off.");
return LS_FAIL;
}
if ((compressMode & SFCD_MODE_BROTLI)
&& (statBr != -1) && ((!m_pBrotli) || (m_pBrotli->isDirty(stBr))))
buildCompressedCache(m_pBrotli, stBr);
+4 -2
View File
@@ -508,11 +508,13 @@ int StaticFileHandler::process(HttpSession *pSession,
& LSI_FLAG_DECOMPRESS_REQUIRED) == 0);
char mode = (pReq->brAcceptable() == BR_REQUIRED ? SFCD_MODE_BROTLI : 0);
if (pReq->gzipAcceptable() == GZIP_REQUIRED && !pReq->brAcceptable())
if (pReq->gzipAcceptable() == GZIP_REQUIRED &&
pReq->brAcceptable() != BR_REQUIRED)
mode |= SFCD_MODE_GZIP;
ret = pInfo->readyCacheData(compressed, mode);
LS_DBG_L(pReq->getLogSession(), "readyCacheData() return %d", ret);
LS_DBG_L(pReq->getLogSession(), "readyCacheData(%d, %d) return %d",
compressed, mode, ret);
FileCacheDataEx *pECache = pInfo->getECache();
+3 -3
View File
@@ -1027,12 +1027,12 @@ static long create_event(evtcb_pf cb,
const lsi_session_t *session, long lParam, void *pParam)
{
return (long)EvtcbQue::getInstance().schedule(cb, session,
lParam, pParam);
lParam, pParam, false);
}
*/
static long create_event(evtcb_pf cb,
const lsi_session_t *session, long lParam, void *pParam, int nowait)
static long create_event(evtcb_pf cb, const lsi_session_t *session,
long lParam, void *pParam, int nowait)
{
return (long)EvtcbQue::getInstance().schedule(cb, session,
lParam, pParam, nowait);
+6 -8
View File
@@ -2426,8 +2426,6 @@ int HttpServerImpl::configServerBasic2(const XmlNode *pRoot,
" in the response header.");
}
HttpServer::getInstance().getServerContext().setGeoIP(
ConfigCtx::getCurConfigCtx()->getLongValue(pRoot, "enableIpGeo", 0, 1, 0));
HttpServerConfig::getInstance().setUseProxyHeader(
ConfigCtx::getCurConfigCtx()->getLongValue(pRoot,
@@ -3222,12 +3220,12 @@ int HttpServerImpl::configServer(int reconfig, XmlNode *pRoot)
HttpMime::configScriptHandler(pList, NULL, NULL);
}
if (m_serverContext.isGeoIpOn())
{
configIpToGeo(pRoot);
configIpToLoc(pRoot);
}
int val = ConfigCtx::getCurConfigCtx()->getLongValue(pRoot, "enableIpGeo", -1, 1, -1);
configIpToGeo(pRoot);
configIpToLoc(pRoot);
if (val == -1)
val = ClientCache::getIp2Geo() != NULL;
HttpServer::getInstance().getServerContext().setGeoIP(val);
const char *pVal = pRoot->getChildValue("suspendedVhosts");
if (pVal)
+63 -59
View File
@@ -47,6 +47,7 @@
#define UNKNOWN_KEYWORDS "unknownkeywords"
//All the keywords are lower case
//TODO: !! means the item marked need to be rempved in later version
//Look at the bottom for items out of alphabetical order.
plainconfKeywords plainconf::sKeywords[] =
{
{"accesscontrol", NULL},
@@ -84,8 +85,8 @@ plainconfKeywords plainconf::sKeywords[] =
{"cacertpath", NULL},
{"certchain", NULL},
{"certfile", NULL},
{"certfile2", NULL},
{"certfile3", NULL},
{"certfile2", NULL},
{"certfile3", NULL},
{"cgidsock", NULL},
{"cgirlimit", NULL},
{"checksymbollink", NULL},
@@ -157,6 +158,7 @@ plainconfKeywords plainconf::sKeywords[] =
{"geoipdb", NULL},
{"geoipdbcache", NULL},
{"geoipdbfile", NULL},
{"geoipdbname", NULL},
{"graceperiod", NULL},
{"group", NULL},
{"groupdb", NULL},
@@ -178,7 +180,7 @@ plainconfKeywords plainconf::sKeywords[] =
{"inherit", NULL},
{"indexfiles", NULL},
{"inittimeout", NULL},
{"internal", NULL},
{"internal", NULL},
{"inmembufsize", NULL},
{"instances", NULL},
{"iptogeo", NULL},
@@ -188,8 +190,8 @@ plainconfKeywords plainconf::sKeywords[] =
{"keepalivetimeout", NULL},
{"keepdays", NULL},
{"keyfile", NULL},
{"keyfile2", NULL},
{"keyfile3", NULL},
{"keyfile2", NULL},
{"keyfile3", NULL},
{"listener", NULL},
{"listenerlist", NULL}, //!!
{"listeners", NULL},
@@ -211,6 +213,8 @@ plainconfKeywords plainconf::sKeywords[] =
{"maxdynrespheadersize", NULL},
{"maxdynrespsize", NULL},
{"maxkeepalivereq", NULL},
{"maxminddbenable", NULL},
{"maxminddbenv", NULL},
{"maxmmapfilesize", NULL},
{"maxreqbodysize", NULL},
{"maxreqheadersize", NULL},
@@ -320,11 +324,11 @@ plainconfKeywords plainconf::sKeywords[] =
{"vhtemplatelist", NULL},//!!
{"virtualhost", NULL},
{"virtualhostconfig", NULL},
{"virtualhostlist", NULL},//!!
{"virtualhostlist", NULL},//!!
{"virtualhosttemplate", NULL},
{"websocket", NULL},
{"websocketlist", NULL},//!!
{"workers", NULL},
{"websocketlist", NULL},//!!
{"workers", NULL},
{"workingdir", NULL},
{"zconfadclist", NULL},
{"zconfauth", NULL},
@@ -335,66 +339,66 @@ plainconfKeywords plainconf::sKeywords[] =
{"zconfsend", NULL},
{"disableinitlogrotation", NULL},
{"fileetag", NULL},
{"gracefulrestarttimeout", NULL},
{"renegprotection", NULL},
{"sessiontimeout", NULL},
{"suspendedvhosts", NULL},
{"restricteddirpermissionmask", NULL},
{"restrictedscriptpermissionmask", NULL},
{"disableinitlogrotation", NULL},
{"fileetag", NULL},
{"gracefulrestarttimeout", NULL},
{"renegprotection", NULL},
{"sessiontimeout", NULL},
{"suspendedvhosts", NULL},
{"restricteddirpermissionmask", NULL},
{"restrictedscriptpermissionmask", NULL},
{"phpsuexec", NULL},
{"phpsuexec", NULL},
{"phpsuexecmaxconn", NULL},
{"useaio", NULL},
{"phpsuexecmaxconn", NULL},
{"useaio", NULL},
{"aioblocksize", NULL},
{"forcestrictownership", NULL},
{"accessfilename", NULL},
{"allowoverride", NULL},
{"cachetimeout", NULL},
{"general", NULL},
{"enablecontextac", NULL},
{"aioblocksize", NULL},
{"forcestrictownership", NULL},
{"accessfilename", NULL},
{"allowoverride", NULL},
{"cachetimeout", NULL},
{"general", NULL},
{"enablecontextac", NULL},
//Hooks name here
{"l4_beginsession", NULL},
{"l4_endsession", NULL},
{"l4_recving", NULL},
{"l4_sending", NULL},
{"http_begin", NULL},
{"recv_req_header", NULL},
{"uri_map", NULL},
{"http_auth", NULL},
{"recv_req_body", NULL},
{"rcvd_req_body", NULL},
{"recv_resp_header", NULL},
{"recv_resp_body", NULL},
{"rcvd_resp_body", NULL},
{"handler_restart", NULL},
{"send_resp_header", NULL},
{"send_resp_body", NULL},
{"http_end", NULL},
{"main_inited", NULL},
{"main_prefork", NULL},
{"main_postfork", NULL},
{"worker_postfork", NULL},
{"worker_atexit", NULL},
{"main_atexit", NULL},
{"l4_beginsession", NULL},
{"l4_endsession", NULL},
{"l4_recving", NULL},
{"l4_sending", NULL},
{"http_begin", NULL},
{"recv_req_header", NULL},
{"uri_map", NULL},
{"http_auth", NULL},
{"recv_req_body", NULL},
{"rcvd_req_body", NULL},
{"recv_resp_header", NULL},
{"recv_resp_body", NULL},
{"rcvd_resp_body", NULL},
{"handler_restart", NULL},
{"send_resp_header", NULL},
{"send_resp_body", NULL},
{"http_end", NULL},
{"main_inited", NULL},
{"main_prefork", NULL},
{"main_postfork", NULL},
{"worker_postfork", NULL},
{"worker_atexit", NULL},
{"main_atexit", NULL},
{"umask", NULL},
{"blockbadreq", NULL}, //Add to avoid error notice in errorlog
{"umask", NULL},
{"blockbadreq", NULL}, //Add to avoid error notice in errorlog
{"uploadpassbypath", NULL},
{"uploadtmpdir", NULL},
{"uploadtmpfilepermission", NULL},
{"uploadpassbypath", NULL},
{"uploadtmpdir", NULL},
{"uploadtmpfilepermission", NULL},
{"phpinioverride", NULL},
{"php_value", NULL},
{"php_flag", NULL},
{"php_admin_value", NULL},
{"php_admin_flag", NULL},
{"phpinioverride", NULL},
{"php_value", NULL},
{"php_flag", NULL},
{"php_admin_value", NULL},
{"php_admin_flag", NULL},
};
+1
View File
@@ -10,3 +10,4 @@ add_subdirectory(uploadprogress)
add_subdirectory(mod_lsphp)
add_subdirectory(modsecurity-ls)
+1 -1
View File
@@ -13,7 +13,7 @@ spdydebug.cpp
h2connection.cpp
h2protocol.cpp
h2stream.cpp
hpack.cpp
lshpack.c
)
add_library(spdy STATIC ${spdy_STAT_SRCS})
+1 -1
View File
@@ -4,6 +4,6 @@ libspdy_a_METASOURCES = AUTO
libspdy_a_SOURCES = spdyprotocol.cpp spdyconnection.cpp spdystream.cpp \
spdyzlibfilter.cpp spdystreampool.cpp h2connection.cpp \
h2protocol.cpp h2stream.cpp hpack.cpp
h2protocol.cpp h2stream.cpp lshpack.c
noinst_HEADERS =
+45 -6
View File
@@ -107,7 +107,7 @@ libspdy_a_LIBADD =
am_libspdy_a_OBJECTS = spdyprotocol.$(OBJEXT) spdyconnection.$(OBJEXT) \
spdystream.$(OBJEXT) spdyzlibfilter.$(OBJEXT) \
spdystreampool.$(OBJEXT) h2connection.$(OBJEXT) \
h2protocol.$(OBJEXT) h2stream.$(OBJEXT) hpack.$(OBJEXT)
h2protocol.$(OBJEXT) h2stream.$(OBJEXT) lshpack.$(OBJEXT)
libspdy_a_OBJECTS = $(am_libspdy_a_OBJECTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -125,12 +125,30 @@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
@@ -334,13 +352,13 @@ AM_CPPFLAGS = -I$(top_srcdir)/openssl/include/ -I$(top_srcdir)/include -I$(top_s
libspdy_a_METASOURCES = AUTO
libspdy_a_SOURCES = spdyprotocol.cpp spdyconnection.cpp spdystream.cpp \
spdyzlibfilter.cpp spdystreampool.cpp h2connection.cpp \
h2protocol.cpp h2stream.cpp hpack.cpp
h2protocol.cpp h2stream.cpp lshpack.c
noinst_HEADERS =
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
.SUFFIXES: .c .cpp .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -389,13 +407,34 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h2connection.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h2protocol.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/h2stream.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hpack.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lshpack.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spdyconnection.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spdyprotocol.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spdystream.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spdystreampool.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spdyzlibfilter.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+47 -33
View File
@@ -86,27 +86,16 @@ H2Connection::H2Connection()
HioHandler *H2Connection::get()
{
H2Connection *pConn = new H2Connection();
//pConn->init();
if (0 != lshpack_enc_init(&pConn->m_hpack_enc))
{
delete pConn;
return NULL;
}
lshpack_dec_init(&pConn->m_hpack_dec);
return pConn;
}
int H2Connection::init()
{
m_iCurDataOutWindow = H2_FCW_INIT_SIZE;
m_uiLastStreamId = 0;
m_iStreamOutInitWindowSize = H2_FCW_INIT_SIZE;
m_iServerMaxStreams = 100;
m_iMaxPushStreams = 100;
m_tmIdleBegin = 0;
m_uiShutdownStreams = 0;
m_iCurPushStreams = 0;
m_iCurrentFrameRemain = -H2_FRAME_HEADER_SIZE;
m_pCurH2Header = (H2FrameHeader *)m_iaH2HeaderMem;
return 0;
}
int H2Connection::onInitConnected()
{
m_iState = HIOS_CONNECTED;
@@ -118,6 +107,8 @@ int H2Connection::onInitConnected()
H2Connection::~H2Connection()
{
lshpack_enc_cleanup(&m_hpack_enc);
lshpack_dec_cleanup(&m_hpack_dec);
}
@@ -125,10 +116,12 @@ int H2Connection::onReadEx()
{
int ret;
m_iFlag &= ~H2_CONN_FLAG_WAIT_PROCESS;
m_iFlag |= H2_CONN_FLAG_IN_EVENT;
ret = onReadEx2();
if ((m_iFlag & H2_CONN_FLAG_WAIT_PROCESS) != 0)
onWriteEx();
if (getBuf()->size() > 1024)
m_iFlag &= ~H2_CONN_FLAG_IN_EVENT;
if (getBuf()->size() > 1024 || m_iFlag & H2_CONN_FLAG_WANT_FLUSH)
flush();
return ret;
}
@@ -434,7 +427,7 @@ int H2Connection::processSettingFrame(H2FrameHeader *pHeader)
iEntryValue);
return LS_FAIL;
}
m_hpack.getReqDynTbl().updateMaxCapacity(iEntryValue);
lshpack_dec_set_max_capacity(&m_hpack_dec, iEntryValue);
break;
case H2_SETTINGS_MAX_FRAME_SIZE:
if ((iEntryValue < H2_DEFAULT_DATAFRAME_SIZE) ||
@@ -918,9 +911,9 @@ int H2Connection::processHeadersFrame(H2FrameHeader *pHeader)
}
int H2Connection::decodeData(unsigned char *pSrc, unsigned char *bufEnd,
char *method, int *methodLen, char **uri,
int *uriLen)
int H2Connection::decodeData(const unsigned char *pSrc,
const unsigned char *bufEnd, char *method, int *methodLen,
char **uri, int *uriLen)
{
int rc, n = 0;
m_bufInflate.clear();
@@ -934,8 +927,9 @@ int H2Connection::decodeData(unsigned char *pSrc, unsigned char *bufEnd,
bool authority = false;
bool scheme = false;
bool error = false;
while ((rc = m_hpack.decHeader(pSrc, bufEnd, out, out + sizeof(out),
name_len, val_len)) > 0)
while (pSrc < bufEnd &&
(0 == (rc = lshpack_dec_decode(&m_hpack_dec, &pSrc, bufEnd, out,
out + sizeof(out), &name_len, &val_len))))
{
char *name = out;
char *val = name + name_len;
@@ -1313,11 +1307,23 @@ int H2Connection::flush()
BufferedOS::flush();
if (!isEmpty())
getStream()->continueWrite();
else
m_iFlag &= ~H2_CONN_FLAG_WANT_FLUSH;
getStream()->flush();
return LS_DONE;
}
void H2Connection::wantFlush()
{
if (m_iFlag & H2_CONN_FLAG_WANT_FLUSH)
return;
flush();
if (m_iFlag & H2_CONN_FLAG_IN_EVENT)
m_iFlag |= H2_CONN_FLAG_WANT_FLUSH;
}
int H2Connection::onCloseEx()
{
if (getStream()->isReadyToRelease())
@@ -1470,7 +1476,7 @@ int H2Connection::encodeHeaders(HttpRespHeaders *pRespHeaders,
char *p = (char *)HttpStatusCode::getInstance().getCodeString(
pRespHeaders->getHttpCode()) + 1;
pCur = m_hpack.encHeader(pCur, pBufEnd, (char *)":status", 7, p, 3, 0);
pCur = lshpack_enc_encode(&m_hpack_enc, pCur, pBufEnd, ":status", 7, p, 3, 0);
pRespHeaders->dropConnectionHeaders();
@@ -1512,7 +1518,7 @@ int H2Connection::encodeHeaders(HttpRespHeaders *pRespHeaders,
str.append((char *)pIov->iov_base, pIov->iov_len);
str.append("\r\n", 2);
}
pCur = m_hpack.encHeader(pCur, pBufEnd, key, keyLen,
pCur = lshpack_enc_encode(&m_hpack_enc, pCur, pBufEnd, key, keyLen,
(char *)pIov->iov_base, pIov->iov_len, 0);
}
}
@@ -1578,12 +1584,14 @@ int H2Connection::sendPushPromise(uint32_t streamId, uint32_t promise_streamId,
uint32_t sid = htonl(promise_streamId);
memcpy(pCur, &sid, 4);
pCur += 4;
pCur = m_hpack.encHeader(pCur, pBufEnd, ":method", 7, "GET", 3, 0);
pCur = m_hpack.encHeader(pCur, pBufEnd, ":path", 5, pUrl->ptr,
pUrl->len, 0);
pCur = m_hpack.encHeader(pCur, pBufEnd, ":authority", 10, pHost->ptr,
pHost->len, 0);
pCur = m_hpack.encHeader(pCur, pBufEnd, ":scheme", 7, "https", 5, 0);
pCur = lshpack_enc_encode(&m_hpack_enc, pCur, pBufEnd, ":method", 7,
"GET", 3, 0);
pCur = lshpack_enc_encode(&m_hpack_enc, pCur, pBufEnd, ":path", 5,
pUrl->ptr, pUrl->len, 0);
pCur = lshpack_enc_encode(&m_hpack_enc, pCur, pBufEnd, ":authority", 10,
pHost->ptr, pHost->len, 0);
pCur = lshpack_enc_encode(&m_hpack_enc, pCur, pBufEnd, ":scheme", 7,
"https", 5, 0);
// if (etag)
// pCur = m_hpack.encHeader(pCur, pBufEnd, "if-match", 8, etag->ptr,
@@ -1595,7 +1603,7 @@ int H2Connection::sendPushPromise(uint32_t streamId, uint32_t promise_streamId,
{
while(headers->key.ptr)
{
pCur = m_hpack.encHeader(pCur, pBufEnd,
pCur = lshpack_enc_encode(&m_hpack_enc, pCur, pBufEnd,
headers->key.ptr,
headers->key.len,
headers->val.ptr,
@@ -1713,6 +1721,7 @@ int H2Connection::onWriteEx()
TDLinkQueue<H2Stream> *pQue = &m_priQue[0];
TDLinkQueue<H2Stream> *pEnd = &m_priQue[H2_STREAM_PRIORITYS];
m_iFlag |= H2_CONN_FLAG_IN_EVENT;
for (; pQue < pEnd && m_iCurDataOutWindow > 0; ++pQue)
{
@@ -1741,10 +1750,15 @@ int H2Connection::onWriteEx()
recycleStream(pH2Stream->getStreamID());
}
if (getStream()->canWrite() & HIO_FLAG_BUFF_FULL)
{
m_iFlag &= ~H2_CONN_FLAG_IN_EVENT;
flush();
return 0;
}
if (wantWrite > 0)
break;
}
m_iFlag &= ~H2_CONN_FLAG_IN_EVENT;
if (!isEmpty())
flush();
+10 -5
View File
@@ -21,7 +21,6 @@
#include <edio/bufferedos.h>
#include <http/hiostream.h>
#include <spdy/h2protocol.h>
#include <spdy/hpack.h>
#include <util/autobuf.h>
#include <util/dlinkqueue.h>
#include <util/ghash.h>
@@ -31,6 +30,8 @@
#include <sys/time.h>
#include <limits.h>
#include "lshpack.h"
#define H2_CONN_FLAG_GOAWAY (1<<0)
#define H2_CONN_FLAG_PREFACE (1<<1)
@@ -41,6 +42,8 @@
#define H2_CONN_HEADERS_START (1<<6)
#define H2_CONN_FLAG_WAIT_PROCESS (1<<7)
#define H2_CONN_FLAG_NO_PUSH (1<<8)
#define H2_CONN_FLAG_WANT_FLUSH (1<<9)
#define H2_CONN_FLAG_IN_EVENT (1<<10)
#define H2_STREAM_PRIORITYS (8)
@@ -49,8 +52,9 @@ class H2Stream;
class H2Connection: public HioHandler, public BufferedOS
{
public:
private:
H2Connection();
public:
virtual ~H2Connection();
LogSession *getLogSession() const
@@ -85,7 +89,6 @@ public:
//Following functions are just placeholder
//Placeholder
int init();
int onInitConnected();
int onTimerEx();
@@ -153,6 +156,7 @@ public:
void decShutdownStream() { --m_uiShutdownStreams; }
int pushPromise(uint32_t streamId, ls_str_t* pUrl, ls_str_t* pHost,
ls_strpair_t *headers);
void wantFlush();
private:
typedef THash< H2Stream * > StreamMap;
@@ -212,7 +216,7 @@ private:
int appendReqHeaders(H2Stream *arg1, char *method = NULL,
int methodLen = 0,
char *uri = NULL, int uriLen = 0);
int decodeData(unsigned char *pSrc, unsigned char *bufEnd,
int decodeData(const unsigned char *pSrc, const unsigned char *bufEnd,
char *method, int *methodLen, char **uri, int *uriLen);
void skipRemainData();
int encodeHeaders(HttpRespHeaders *pRespHeaders, unsigned char *buf,
@@ -262,7 +266,8 @@ private:
H2FrameHeader *m_pCurH2Header;
private:
Hpack m_hpack;
struct lshpack_enc m_hpack_enc;
struct lshpack_dec m_hpack_dec;
LS_NO_COPY_ASSIGN(H2Connection);
};
+1 -1
View File
@@ -195,7 +195,7 @@ int H2Stream::shutdown()
LS_DBG_L(this, "H2Stream::shutdown()");
m_pH2Conn->sendFinFrame(m_uiStreamId);
setActiveTime(DateTime::s_curTime);
m_pH2Conn->flush();
m_pH2Conn->wantFlush();
return 0;
}
-276
View File
@@ -1,276 +0,0 @@
/*****************************************************************************
* Open LiteSpeed is an open source HTTP server. *
* Copyright (C) 2013 - 2018 LiteSpeed Technologies, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see http://www.gnu.org/licenses/. *
*****************************************************************************/
#ifndef HPACK_H
#define HPACK_H
#include <lsdef.h>
#include <util/loopbuf.h>
#include <util/ghash.h>
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#define INITIAL_DYNAMIC_TABLE_SIZE 4096
#define HPACK_STATIC_TABLE_SIZE 61
enum
{
HPACK_HUFFMAN_FLAG_ACCEPTED = 0x01,
HPACK_HUFFMAN_FLAG_SYM = 0x02,
HPACK_HUFFMAN_FLAG_FAIL = 0x04,
};
//static table
struct HpackHdrTbl_t
{
const char *name;
uint16_t name_len;
const char *val;
uint16_t val_len;
};
struct HpackHuffEncode_t
{
uint32_t code;
int bits;
};
struct HpackHuffDecode_t
{
uint8_t state;
uint8_t flags;
uint8_t sym;
};
struct HpackHuffDecodeStatus_t
{
uint8_t state;
uint8_t eos;
};
class DynTblEntry
{
public:
DynTblEntry(const char *name, uint32_t name_len,
const char *val, uint32_t val_len, uint8_t stxTabId)
{
reset();
init(name, name_len, val, val_len, stxTabId);
}
~DynTblEntry()
{
if (m_valLen && m_val)
delete []m_val;
//only when name in static table, use a pointer to it, otherwise new one
if (m_nameLen && m_nameId == 0 && m_name)
delete []m_name;
reset();
};
uint32_t getEntrySize() const { return m_valLen + m_nameLen + 32; }
char *getName() const { return m_name; }
uint16_t getNameLen() const { return m_nameLen; }
char *getValue() const { return m_val; }
uint16_t getValueLen() { return m_valLen; }
void init(const char *name, uint32_t name_len,
const char *val, uint32_t val_len,
uint8_t stxTabId);
private:
char *m_name;
uint8_t m_nameId; // < 64, if in StxTab, is 1~61; other 0.
uint16_t m_nameLen; // < 8192
uint16_t m_valLen; // < 8192
char *m_val;
void reset()
{
memset(&m_name, 0, (char *)&m_val + sizeof(char *) - (char *)&m_name);
}
LS_NO_COPY_ASSIGN(DynTblEntry);
};
#define ENTRYPSIZE (sizeof(DynTblEntry *))
class HpackDynTbl
{
public:
HpackDynTbl();
~HpackDynTbl();
size_t getTotalTableSize() { return m_curCapacity; }
size_t getEntryCount() { return (uint32_t)(m_loopbuf.size()) / ENTRYPSIZE; }
void updateMaxCapacity(size_t maxCapacity)
{
m_maxCapacity = maxCapacity;
updateCurMaxCapacity(maxCapacity);
}
void updateCurMaxCapacity(size_t maxCapacity)
{
m_curMaxCapacity = maxCapacity;
removeOverflowEntries();
}
size_t getMaxCapacity() const
{ return m_maxCapacity; }
void reset();
int getDynTabId(const char *name, uint16_t name_len,
const char *value, uint16_t value_len,
int &val_matched, uint8_t stxTabId);
DynTblEntry *getEntry(uint32_t dynTblId)
{
if (dynTblId < HPACK_STATIC_TABLE_SIZE + 1
|| dynTblId > HPACK_STATIC_TABLE_SIZE + getEntryCount())
return NULL;
return getEntryInternal(dynTblIdToInternalIndex(dynTblId));
}
void removeNameValueHashTEntry(DynTblEntry *pEntry);
void removeNameHashTEntry(DynTblEntry *pEntry);
void popEntry();
void pushEntry(const char *name, uint16_t name_len,
const char *val, uint16_t val_len,
uint32_t nameIndex);
public:
static hash_key_t hfName(const void *__s);
static hash_key_t hfNameVal(const void *__s);
static int cmpName(const void *pVal1, const void *pVal2);
static int cmpNameVal(const void *pVal1, const void *pVal2);
protected:
void removeOverflowEntries();
DynTblEntry *getEntryInternal(int index)
{
// if (index < 0 || index * (int)ENTRYPSIZE >= m_loopbuf.size())
// return NULL;
DynTblEntry **pEntry =
(DynTblEntry **)(m_loopbuf.getPointer(index * ENTRYPSIZE));
return *pEntry;
}
int dynTblIdToInternalIndex(uint32_t dynTblId)
{
assert(dynTblId >= HPACK_STATIC_TABLE_SIZE + 1
&& dynTblId <= HPACK_STATIC_TABLE_SIZE + getEntryCount());
return getEntryCount() - (dynTblId - HPACK_STATIC_TABLE_SIZE);
}
protected:
size_t m_maxCapacity; //set by SETTINGS_HEADER_TABLE_SIZE
size_t m_curMaxCapacity;
size_t m_curCapacity;
uint32_t m_nextFlowId;
//It contains DynamicTableEntry * as each chars
LoopBuf m_loopbuf;
GHash *m_pNameHashT;
GHash *m_pNameValueHashT;
LS_NO_COPY_ASSIGN(HpackDynTbl);
};
/*******************************************************************************************
* Comments about huffman encode and decode
* The encoding compression ratio is in the range of (0.625, 3.75), so that it is safe to
* malloc the buffer
* 1, times 4 of the original clear text buffer when encoding
* 2, times 2 of the encoded text buffer when decoding
*
*******************************************************************************************/
class HuffmanCode
{
public:
HuffmanCode() {};
~HuffmanCode() {};
static size_t calcHuffmanEncBufSize(const unsigned char *src,
const unsigned char *src_end);
static int huffmanEnc(const unsigned char *src,
const unsigned char *src_end,
unsigned char *dst, int dst_len);
static unsigned char *huffmanDec4bits(uint8_t src_4bits,
unsigned char *dst,
HpackHuffDecodeStatus_t &status,
bool lowerCase);
static int huffmanDec(unsigned char *src, int src_len, unsigned char *dst,
int dst_len, bool lowerCase);
static HpackHuffEncode_t m_HpackHuffEncode_t[257];
static HpackHuffDecode_t m_HpackHuffDecode_t[256][16];
LS_NO_COPY_ASSIGN(HuffmanCode);
};
class Hpack
{
public:
Hpack() {};
~Hpack() {};
HpackDynTbl &getReqDynTbl() { return m_reqDynTbl; }
HpackDynTbl &getRespDynTbl() { return m_respDynTbl; }
static uint8_t getStxTabId(const char *name, uint16_t name_len,
const char *val, uint16_t val_len,
int &val_matched);
unsigned char *encInt(unsigned char *dst, uint32_t value,
uint32_t prefix_bits);
int decInt(unsigned char *&src, const unsigned char *src_end,
uint32_t prefix_bits, uint32_t &value);
int encStr(unsigned char *dst, size_t dst_len,
const unsigned char *str, uint16_t str_len);
int decStr(unsigned char *dst, size_t dst_len, unsigned char *&src,
const unsigned char *src_end, bool lowerCase);
//indexedType: 0, Add, 1,: without, 2: never
unsigned char *encHeader(unsigned char *dst, unsigned char *dstEnd,
const char *name, uint16_t nameLen,
const char *value, uint16_t valueLen,
int indexedType = 0);
int decHeader(unsigned char *&src, unsigned char *srcEnd,
char *dst, char *const dstEnd,
uint16_t &name_len, uint16_t &val_len);
private:
HpackDynTbl m_reqDynTbl;
HpackDynTbl m_respDynTbl;
LS_NO_COPY_ASSIGN(Hpack);
};
#endif // HPACK_H
File diff suppressed because it is too large Load Diff
+162
View File
@@ -0,0 +1,162 @@
/*
MIT License
Copyright (c) 2018 LiteSpeed Technologies Inc
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef LITESPEED_HPACK_H
#define LITESPEED_HPACK_H 1
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* Strings up to 65535 characters in length are supported.
*/
typedef uint16_t lshpack_strlen_t;
/** Maximum length is defined for convenience */
#define LSHPACK_MAX_STRLEN UINT16_MAX
struct lshpack_enc;
struct lshpack_dec;
/**
* Initialization routine allocates memory. -1 is returned if memory
* could not be allocated. 0 is returned on success.
*/
int
lshpack_enc_init (struct lshpack_enc *);
/**
* Clean up HPACK encoder, freeing all allocated memory.
*/
void
lshpack_enc_cleanup (struct lshpack_enc *);
/**
* @brief Encode one name/value pair
*
* @param[in,out] henc - A pointer to a valid HPACK API struct
* @param[out] dst - A pointer to destination buffer
* @param[out] dst_end - A pointer to end of destination buffer
* @param[in] name - A pointer to the item name
* @param[in] name_len - The item name's length
* @param[in] value - A pointer to the item value
* @param[in] value_len - The item value's length
* @param[in] indexed_type - 0, Add, 1,: without, 2: never
*
* @return The (possibly advanced) dst pointer. If the destination
* pointer was not advanced, an error must have occurred.
*/
unsigned char *
lshpack_enc_encode (struct lshpack_enc *henc, unsigned char *dst,
unsigned char *dst_end, const char *name, lshpack_strlen_t name_len,
const char *value, lshpack_strlen_t value_len, int indexed_type);
void
lshpack_enc_set_max_capacity (struct lshpack_enc *, unsigned);
/**
* Initialize HPACK decoder structure.
*/
void
lshpack_dec_init (struct lshpack_dec *);
/**
* Clean up HPACK decoder structure, freeing all allocated memory.
*/
void
lshpack_dec_cleanup (struct lshpack_dec *);
/*
* Returns 0 on success, a negative value on failure.
*
* If 0 is returned, `src' is advanced. Calling with a zero-length input
* buffer results in an error.
*/
int
lshpack_dec_decode (struct lshpack_dec *dec,
const unsigned char **src, const unsigned char *src_end,
char *dst, char *const dst_end, lshpack_strlen_t *name_len,
lshpack_strlen_t *val_len);
void
lshpack_dec_set_max_capacity (struct lshpack_dec *, unsigned);
/* Some internals follow. Struct definitions are exposed to save a malloc.
* These structures are not very complicated.
*/
#include <sys/queue.h>
struct lshpack_enc_table_entry;
STAILQ_HEAD(lshpack_enc_head, lshpack_enc_table_entry);
struct lshpack_double_enc_head;
struct lshpack_enc
{
unsigned hpe_cur_capacity;
unsigned hpe_max_capacity;
/* Each new dynamic table entry gets the next number. It is used to
* calculate the entry's position in the decoder table without having
* to maintain an actual array.
*/
unsigned hpe_next_id;
/* Dynamic table entries (struct enc_table_entry) live in two hash
* tables: name/value hash table and name hash table. These tables
* are the same size.
*/
unsigned hpe_nelem;
unsigned hpe_nbits;
struct lshpack_enc_head
hpe_all_entries;
struct lshpack_double_enc_head
*hpe_buckets;
};
struct lshpack_arr
{
unsigned nalloc,
nelem,
off;
uintptr_t *els;
};
struct lshpack_dec
{
unsigned hpd_max_capacity; /* Maximum set by caller */
unsigned hpd_cur_max_capacity; /* Adjusted at runtime */
unsigned hpd_cur_capacity;
struct lshpack_arr hpd_dyn_table;
};
#ifdef __cplusplus
}
#endif
#endif
+1 -1
View File
@@ -276,11 +276,11 @@ void SslConnection::restoreRbio()
#else
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
SSL_set0_rbio(m_ssl,m_saved_rbio);
BIO_free(m_saved_rbio);
#else
BIO_free_all(m_ssl->rbio);
m_ssl->rbio = m_saved_rbio;
#endif
m_saved_rbio = NULL;
#endif
ls_pfree(m_rbioBuf);
m_rbioBuf = NULL;
+1 -1
View File
@@ -120,7 +120,7 @@ static int newSessionCb(SSL *pSSL, SSL_SESSION *pSess)
pObj->x_iExpireTime = DateTime::s_curTime + cache.getExpireSec();
unsigned int len;
const unsigned char *id = SSL_SESSION_get_id((const SSL_SESSION *)pSSL, &len);
const unsigned char *id = SSL_SESSION_get_id((const SSL_SESSION *)pSess, &len);
cache.addSession((unsigned char *)id, (int)len,
data, iDataLen + sizeof(*pObj));
+4 -2
View File
@@ -197,6 +197,7 @@ int SslTicket::init(const char *pFileName, long int timeout)
if (pFileName != NULL)
m_pFile = new AutoStr2(pFileName);
m_iLifetime = timeout;
m_pKeyStore->lock();
if ((m_iOff = m_pKeyStore->find(s_pSTTickets, strlen(s_pSTTickets),
&iValLen)) == 0)
{
@@ -215,14 +216,16 @@ int SslTicket::init(const char *pFileName, long int timeout)
else
{
if (loadKeyFromFile(pFileName, &m_aKeys[0]) == LS_FAIL)
{
m_pKeyStore->unlock();
return LS_FAIL;
}
m_aKeys[0].expireSec = DateTime::s_curTime + m_iLifetime;
m_idxCur = 0;
m_idxNext = 1;
m_idxPrev = SSLTICKET_NUMKEYS - 1;
}
m_pKeyStore->lock();
if ((m_iOff = m_pKeyStore->insert(s_pSTTickets, strlen(s_pSTTickets),
NULL, sizeof(STShmData_t))) == 0)
{
@@ -237,7 +240,6 @@ int SslTicket::init(const char *pFileName, long int timeout)
m_pKeyStore->unlock();
return LS_OK;
}
m_pKeyStore->lock();
pShmData = (STShmData_t *)m_pKeyStore->offset2ptr(m_iOff);
memmove(m_aKeys, pShmData->m_aKeys,
(sizeof(STKey_t) + sizeof(short)) * SSLTICKET_NUMKEYS);
+5 -5
View File
@@ -657,7 +657,11 @@ static void SslConnection_ssl_info_cb(const SSL *pSSL, int where, int ret)
{
SslConnection *pConnection = (SslConnection *)SSL_get_ex_data(pSSL,
SslConnection::getConnIdx());
if ((where & SSL_CB_HANDSHAKE_START) && pConnection->getFlag() == 1)
if ((where & SSL_CB_HANDSHAKE_START) && pConnection->getFlag() == 1
#if OPENSSL_VERSION_NUMBER > 0x10101000L
&& SSL_version(pSSL) != TLS1_3_VERSION
#endif
)
{
close(SSL_get_fd(pSSL));
#ifndef OPENSSL_IS_BORINGSSL
@@ -828,11 +832,7 @@ void SslUtil::updateProtocol(SSL_CTX *pCtx, int method)
#ifdef TLS1_3_VERSION
if (method & SslContext::SSL_TLSv13)
#ifdef OPENSSL_IS_BORINGSSL
SSL_CTX_set_max_proto_version(pCtx, TLS1_3_VERSION);
#else
SSL_CTX_set_max_version(pCtx, TLS1_3_VERSION);
#endif
#endif
#ifdef SSL_OP_NO_TLSv1_3
+3 -4
View File
@@ -62,8 +62,6 @@ SET(unittest_STAT_SRCS
util/objpooltest.cpp
util/radixtreetest.cpp
spdy/pushtest.cpp
spdy/huffmantest.cpp
spdy/hpacktest.cpp
spdy/spdyzlibfiltertest.cpp
spdy/spdyconnectiontest.cpp
spdy/dummiostream.cpp
@@ -164,10 +162,11 @@ add_executable(ols_unittest
SET( unittestlib
modgzip lsiapi main http lsiapi ssi
registry cgi fcgi jk extensions lsapi proxy
edio socket sslpp lsshm thread log4cxx GeoIP maxminddb adns
edio socket sslpp lsshm thread log4cxx GeoIP adns
-Wl,--whole-archive util lsr -Wl,--no-whole-archive
udns pthread rt ${CMAKE_DL_LIBS} ${libUnitTest} ${BSSL_ADD_LIB}
${BROTLI_ADD_LIB} ${IP2LOC_ADD_LIB} spdy libssl.a libcrypto.a
${BROTLI_ADD_LIB} ${IP2LOC_ADD_LIB} ${MMDB_LIB}
spdy libssl.a libcrypto.a
-Wl,-Map=ols_unittest.map)
target_link_libraries(ols_unittest ${unittestlib} )
File diff suppressed because it is too large Load Diff
-89
View File
@@ -1,89 +0,0 @@
/*****************************************************************************
* Open LiteSpeed is an open source HTTP server. *
* Copyright (C) 2013 - 2018 LiteSpeed Technologies, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see http://www.gnu.org/licenses/. *
*****************************************************************************/
#ifndef HPACK_TEST_H
#define HPACK_TEST_H
#include "spdy/hpack.h"
class HpackDynTbl_Forloop : public HpackDynTbl
{
public:
void popEntry()
{
DynTblEntry *pEntry = getEntryInternal(0);
m_loopbuf.pop_front(ENTRYPSIZE);
m_curCapacity -= pEntry->getEntrySize();
delete pEntry;
}
void pushEntry(char *name, uint16_t name_len, char *val, uint16_t val_len,
uint32_t nameIndex)
{
DynTblEntry *pEntry = new DynTblEntry(name, name_len, val,
val_len, nameIndex);
m_loopbuf.append((char *)(&pEntry), ENTRYPSIZE);
m_curCapacity += pEntry->getEntrySize();
++m_nextFlowId;
removeOverflowEntries();
}
void reset()
{
int count = getEntryCount();
for (int i = count - 1; i >= 0; --i)
delete getEntryInternal(i);
m_loopbuf.clear();
m_curCapacity = 0;
m_maxCapacity = INITIAL_DYNAMIC_TABLE_SIZE;
m_nextFlowId = 0;
}
int getDynTabId(char *name, uint16_t name_len, char *value,
uint16_t value_len, int &val_matched, uint8_t stxTabId)
{
int id = 0 ;
DynTblEntry *pEntry;
int count = getEntryCount();
for (int i = 0; i < count; ++i)
{
pEntry = getEntryInternal(i);
if (value_len == pEntry->getValueLen()
&& memcmp(value, pEntry->getValue(), value_len) == 0
&& name_len == pEntry->getNameLen()
&& memcmp(name, pEntry->getName(), name_len) == 0)
{
val_matched = 1;
id = i + 1 + HPACK_STATIC_TABLE_SIZE;
break;
}
else if (stxTabId == 0) //If have stxTabId, so needn't go further
{
if (name_len == pEntry->getNameLen()
&& memcmp(name, pEntry->getName(), name_len) == 0)
{
id = i + 1 + HPACK_STATIC_TABLE_SIZE;
break;
}
}
}
return id;
};
};
#endif
-89
View File
@@ -1,89 +0,0 @@
/*****************************************************************************
* Open LiteSpeed is an open source HTTP server. *
* Copyright (C) 2013 - 2018 LiteSpeed Technologies, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see http://www.gnu.org/licenses/. *
*****************************************************************************/
#ifdef RUN_TEST
#include "unittest-cpp/UnitTest++.h"
#include "spdy/hpack.h"
#include <stdlib.h>
void testBothEncAndDec(uint8_t *src, size_t src_len = 0);
void testBothEncAndDec(uint8_t *src, size_t src_len)
{
if (src_len == 0)
src_len = strlen((char *)src);
size_t dst_len = HuffmanCode::calcHuffmanEncBufSize(src,
src + src_len) + 1;
unsigned char *dst = (unsigned char *)malloc(dst_len);
int real_dst_len = HuffmanCode::huffmanEnc(src, src + src_len, dst,
dst_len);
CHECK(real_dst_len == (int)(dst_len - 1));
size_t src_len2 = real_dst_len * 4 +
1; //at most 30 bit each char, so at most times 4.
unsigned char *src2 = (unsigned char *)malloc(src_len2);
int real_src_len2 = HuffmanCode::huffmanDec(dst, real_dst_len, src2,
src_len2, false);
CHECK(real_src_len2 == (int)src_len);
CHECK(memcmp(src, src2, src_len) == 0);
free(dst);
free(src2);
}
TEST(huffman_test)
{
size_t src_len, i;
uint8_t *src = (uint8_t *)"1234567890ABC1232p58456l;gfn./";
testBothEncAndDec(src);
src = (uint8_t *)
"ABCslf90-4895lkjhcv][[67/..n jhkufdyfldhfyherewlr pouirtl;k";
testBothEncAndDec(src);
src = (uint8_t *)"!@#$%^&*()_+=-=-';?><,.{}[][~1iOIGBV<PO";
testBothEncAndDec(src);
src_len = 8195;
src = (uint8_t *)malloc(src_len);
for (i = 0; i < src_len; ++i)
src[i] = rand() % 256;
testBothEncAndDec(src, src_len);
src_len = 4096;
for (i = 0; i < src_len; ++i)
src[i] = rand() % 256;
testBothEncAndDec(src, src_len);
src_len = 1023;
for (i = 0; i < src_len; ++i)
src[i] = rand() % 256;
testBothEncAndDec(src, src_len);
src_len = 513;
for (i = 0; i < src_len; ++i)
src[i] = rand() % 256;
testBothEncAndDec(src, src_len);
free(src);
}
#endif
-23
View File
@@ -1,23 +0,0 @@
/*****************************************************************************
* Open LiteSpeed is an open source HTTP server. *
* Copyright (C) 2013 - 2018 LiteSpeed Technologies, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see http://www.gnu.org/licenses/. *
*****************************************************************************/
#ifndef HPACK_HuFFMAN_TEST_H
#define HPACK_HuFFMAN_TEST_H
#endif