mirror of
https://github.com/litespeedtech/openlitespeed.git
synced 2026-06-19 07:37:10 +00:00
Fix some bugs
This commit is contained in:
+3
-1
@@ -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,2 +1,2 @@
|
||||
About installation, please read below article
|
||||
https://openlitespeed.org/#install
|
||||
https://openlitespeed.org/#install
|
||||
Vendored
-29
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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])
|
||||
|
||||
Vendored
+3
-1
@@ -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
@@ -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:
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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},
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -10,3 +10,4 @@ add_subdirectory(uploadprogress)
|
||||
add_subdirectory(mod_lsphp)
|
||||
add_subdirectory(modsecurity-ls)
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ spdydebug.cpp
|
||||
h2connection.cpp
|
||||
h2protocol.cpp
|
||||
h2stream.cpp
|
||||
hpack.cpp
|
||||
lshpack.c
|
||||
)
|
||||
|
||||
add_library(spdy STATIC ${spdy_STAT_SRCS})
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
+1300
-896
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user