diff --git a/include/znc/HTTPSock.h b/include/znc/HTTPSock.h
index 65da6fdb..2c3cc872 100644
--- a/include/znc/HTTPSock.h
+++ b/include/znc/HTTPSock.h
@@ -25,8 +25,8 @@ class CModule;
class CHTTPSock : public CSocket {
public:
- CHTTPSock(CModule *pMod);
- CHTTPSock(CModule *pMod, const CString& sHostname, unsigned short uPort, int iTimeout = 60);
+ CHTTPSock(CModule *pMod, const CString& sURIPrefix);
+ CHTTPSock(CModule *pMod, const CString& sURIPrefix, const CString& sHostname, unsigned short uPort, int iTimeout = 60);
virtual ~CHTTPSock();
// Csocket derived members
@@ -76,6 +76,7 @@ public:
const CString& GetPass() const;
const CString& GetParamString() const;
const CString& GetContentType() const;
+ const CString& GetURIPrefix() const;
bool IsPost() const;
// !Getters
@@ -121,6 +122,7 @@ protected:
bool m_bAcceptGzip;
MCString m_msRequestCookies;
MCString m_msResponseCookies;
+ CString m_sURIPrefix;
};
#endif // !_HTTPSOCK_H
diff --git a/include/znc/Listener.h b/include/znc/Listener.h
index 224cecb4..0f39887d 100644
--- a/include/znc/Listener.h
+++ b/include/znc/Listener.h
@@ -32,11 +32,12 @@ public:
ACCEPT_ALL
} EAcceptType;
- CListener(unsigned short uPort, const CString& sBindHost, bool bSSL, EAddrType eAddr, EAcceptType eAccept) {
+ CListener(unsigned short uPort, const CString& sBindHost, const CString& sURIPrefix, bool bSSL, EAddrType eAddr, EAcceptType eAccept) {
m_uPort = uPort;
m_sBindHost = sBindHost;
m_bSSL = bSSL;
m_eAddr = eAddr;
+ m_sURIPrefix = sURIPrefix;
m_pListener = NULL;
m_eAcceptType = eAccept;
}
@@ -49,6 +50,7 @@ public:
unsigned short GetPort() const { return m_uPort; }
const CString& GetBindHost() const { return m_sBindHost; }
CRealListener* GetRealListener() const { return m_pListener; }
+ const CString& GetURIPrefix() const { return m_sURIPrefix; }
EAcceptType GetAcceptType() const { return m_eAcceptType; }
// !Getters
@@ -65,6 +67,7 @@ protected:
EAddrType m_eAddr;
unsigned short m_uPort;
CString m_sBindHost;
+ CString m_sURIPrefix;
CRealListener* m_pListener;
EAcceptType m_eAcceptType;
};
@@ -84,13 +87,14 @@ private:
class CIncomingConnection : public CZNCSock {
public:
- CIncomingConnection(const CString& sHostname, unsigned short uPort, CListener::EAcceptType eAcceptType);
+ CIncomingConnection(const CString& sHostname, unsigned short uPort, CListener::EAcceptType eAcceptType, const CString& sURIPrefix);
virtual ~CIncomingConnection() {}
virtual void ReadLine(const CString& sData);
virtual void ReachedMaxBuffer();
private:
CListener::EAcceptType m_eAcceptType;
+ const CString m_sURIPrefix;
};
#endif // !_LISTENER_H
diff --git a/include/znc/WebModules.h b/include/znc/WebModules.h
index 3c04ddfd..44e477e5 100644
--- a/include/znc/WebModules.h
+++ b/include/znc/WebModules.h
@@ -117,7 +117,7 @@ public:
PAGE_DONE // all stuff has been done
};
- CWebSock();
+ CWebSock(const CString& sURIPrefix);
virtual ~CWebSock();
virtual bool ForceLogin();
diff --git a/include/znc/znc.h b/include/znc/znc.h
index 99c10cb2..2ec5e57a 100644
--- a/include/znc/znc.h
+++ b/include/znc/znc.h
@@ -152,7 +152,8 @@ public:
// Listener yummy
CListener* FindListener(u_short uPort, const CString& BindHost, EAddrType eAddr);
bool AddListener(CListener*);
- bool AddListener(unsigned short uPort, const CString& sBindHost, bool bSSL,
+ bool AddListener(unsigned short uPort, const CString& sBindHost,
+ const CString& sURIPrefix, bool bSSL,
EAddrType eAddr, CListener::EAcceptType eAccept, CString& sError);
bool DelListener(CListener*);
diff --git a/modules/data/webadmin/tmpl/settings.tmpl b/modules/data/webadmin/tmpl/settings.tmpl
index 9c958442..66879fe1 100644
--- a/modules/data/webadmin/tmpl/settings.tmpl
+++ b/modules/data/webadmin/tmpl/settings.tmpl
@@ -16,6 +16,7 @@
IPv6 |
IRC |
Web |
+ URIPrefix |
@@ -38,6 +39,7 @@
checked="checked" ENDIF ?>/>
|
+ VAR URIPrefix ?> |
IF SuggestDeletion ?>
diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp
index ec675080..5f72721e 100644
--- a/modules/webadmin.cpp
+++ b/modules/webadmin.cpp
@@ -101,6 +101,7 @@ public:
CString sArgs(sArgStr);
CString sPort;
CString sListenHost;
+ CString sURIPrefix;
while (sArgs.Left(1) == "-") {
CString sOpt = sArgs.Token(0);
@@ -150,7 +151,7 @@ public:
}
// Now turn that into a listener instance
- CListener *pListener = new CListener(uPort, sListenHost, bSSL,
+ CListener *pListener = new CListener(uPort, sListenHost, sURIPrefix, bSSL,
(!bIPv6 ? ADDR_IPV4ONLY : ADDR_ALL), CListener::ACCEPT_HTTP);
if (!pListener->Listen()) {
@@ -1420,6 +1421,7 @@ public:
bool AddListener(CWebSock& WebSock, CTemplate& Tmpl) {
unsigned short uPort = WebSock.GetParam("port").ToUShort();
CString sHost = WebSock.GetParam("host");
+ CString sURIPrefix = WebSock.GetParam("uriprefix");
if (sHost == "*") sHost = "";
bool bSSL = WebSock.GetParam("ssl").ToBool();
bool bIPv4 = WebSock.GetParam("ipv4").ToBool();
@@ -1460,7 +1462,7 @@ public:
}
CString sMessage;
- if (CZNC::Get().AddListener(uPort, sHost, bSSL, eAddr, eAccept, sMessage)) {
+ if (CZNC::Get().AddListener(uPort, sHost, sURIPrefix, bSSL, eAddr, eAccept, sMessage)) {
if (!sMessage.empty()) {
WebSock.GetSession()->AddSuccess(sMessage);
}
@@ -1545,6 +1547,8 @@ public:
l["IsWeb"] = CString(pListener->GetAcceptType() != CListener::ACCEPT_IRC);
l["IsIRC"] = CString(pListener->GetAcceptType() != CListener::ACCEPT_HTTP);
+ l["URIPrefix"] = pListener->GetURIPrefix() + "/";
+
// simple protection for user from shooting his own foot
// TODO check also for hosts/families
// such check is only here, user still can forge HTTP request to delete web port
diff --git a/src/ClientCommand.cpp b/src/ClientCommand.cpp
index 1d42ec91..38b8a491 100644
--- a/src/ClientCommand.cpp
+++ b/src/ClientCommand.cpp
@@ -1430,6 +1430,7 @@ void CClient::UserPortCommand(CString& sLine) {
Table.AddColumn("SSL");
Table.AddColumn("Proto");
Table.AddColumn("IRC/Web");
+ Table.AddColumn("URIPrefix");
vector::const_iterator it;
const vector& vpListeners = CZNC::Get().GetListeners();
@@ -1445,6 +1446,7 @@ void CClient::UserPortCommand(CString& sLine) {
CListener::EAcceptType eAccept = (*it)->GetAcceptType();
Table.SetCell("IRC/Web", (eAccept == CListener::ACCEPT_ALL ? "All" : (eAccept == CListener::ACCEPT_IRC ? "IRC" : "Web")));
+ Table.SetCell("URIPrefix", (*it)->GetURIPrefix() + "/");
}
PutStatus(Table);
@@ -1483,12 +1485,13 @@ void CClient::UserPortCommand(CString& sLine) {
}
if (sPort.empty() || sAddr.empty() || sAccept.empty()) {
- PutStatus("Usage: AddPort <[+]port> [bindhost]");
+ PutStatus("Usage: AddPort <[+]port> [bindhost [uriprefix]]");
} else {
bool bSSL = (sPort.Left(1).Equals("+"));
const CString sBindHost = sLine.Token(4);
+ const CString sURIPrefix = sLine.Token(5);
- CListener* pListener = new CListener(uPort, sBindHost, bSSL, eAddr, eAccept);
+ CListener* pListener = new CListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept);
if (!pListener->Listen()) {
delete pListener;
diff --git a/src/HTTPSock.cpp b/src/HTTPSock.cpp
index 9ce157eb..d3da712e 100644
--- a/src/HTTPSock.cpp
+++ b/src/HTTPSock.cpp
@@ -28,11 +28,11 @@ using std::set;
#define MAX_POST_SIZE 1024 * 1024
-CHTTPSock::CHTTPSock(CModule *pMod) : CSocket(pMod) {
+CHTTPSock::CHTTPSock(CModule *pMod, const CString& sURIPrefix) : CSocket(pMod), m_sURIPrefix(sURIPrefix) {
Init();
}
-CHTTPSock::CHTTPSock(CModule *pMod, const CString& sHostname, unsigned short uPort, int iTimeout) : CSocket(pMod, sHostname, uPort, iTimeout) {
+CHTTPSock::CHTTPSock(CModule *pMod, const CString& sURIPrefix, const CString& sHostname, unsigned short uPort, int iTimeout) : CSocket(pMod, sHostname, uPort, iTimeout), m_sURIPrefix(sURIPrefix) {
Init();
}
@@ -495,6 +495,10 @@ const CString& CHTTPSock::GetParamString() const {
return m_sPostData;
}
+const CString& CHTTPSock::GetURIPrefix() const {
+ return m_sURIPrefix;
+}
+
bool CHTTPSock::HasParam(const CString& sName, bool bPost) const {
if (bPost)
return (m_msvsPOSTParams.find(sName) != m_msvsPOSTParams.end());
diff --git a/src/Listener.cpp b/src/Listener.cpp
index 9950cd2d..6e0e34eb 100644
--- a/src/Listener.cpp
+++ b/src/Listener.cpp
@@ -60,7 +60,9 @@ bool CRealListener::ConnectionFrom(const CString& sHost, unsigned short uPort) {
}
Csock* CRealListener::GetSockObj(const CString& sHost, unsigned short uPort) {
- CIncomingConnection *pClient = new CIncomingConnection(sHost, uPort, m_Listener.GetAcceptType());
+ CIncomingConnection *pClient = new CIncomingConnection(sHost, uPort,
+ m_Listener.GetAcceptType(),
+ m_Listener.GetURIPrefix());
if (CZNC::Get().AllowConnectionFrom(sHost)) {
GLOBALMODULECALL(OnClientConnect(pClient, sHost, uPort), NOTHING);
} else {
@@ -83,7 +85,7 @@ void CRealListener::SockError(int iErrno, const CString& sDescription) {
}
}
-CIncomingConnection::CIncomingConnection(const CString& sHostname, unsigned short uPort, CListener::EAcceptType eAcceptType) : CZNCSock(sHostname, uPort) {
+CIncomingConnection::CIncomingConnection(const CString& sHostname, unsigned short uPort, CListener::EAcceptType eAcceptType, const CString& sURIPrefix) : CZNCSock(sHostname, uPort), m_sURIPrefix(sURIPrefix) {
m_eAcceptType = eAcceptType;
// The socket will time out in 120 secs, no matter what.
// This has to be fixed up later, if desired.
@@ -141,7 +143,7 @@ void CIncomingConnection::ReadLine(const CString& sLine) {
return;
}
- pSock = new CWebSock();
+ pSock = new CWebSock(m_sURIPrefix);
CZNC::Get().GetManager().SwapSockByAddr(pSock, this);
// And don't forget to give it some sane name / timeout
diff --git a/src/WebModules.cpp b/src/WebModules.cpp
index c8f1c655..e6e689d2 100644
--- a/src/WebModules.cpp
+++ b/src/WebModules.cpp
@@ -185,7 +185,7 @@ void CWebAuth::Invalidate() {
m_pWebSock = NULL;
}
-CWebSock::CWebSock() : CHTTPSock(NULL) {
+CWebSock::CWebSock(const CString& sURIPrefix) : CHTTPSock(NULL, sURIPrefix) {
m_bPathsSet = false;
m_Template.AddTagHandler(new CZNCTagHandler(*this));
diff --git a/src/znc.cpp b/src/znc.cpp
index 9022fe68..fe799cf0 100644
--- a/src/znc.cpp
+++ b/src/znc.cpp
@@ -454,6 +454,7 @@ bool CZNC::WriteConfig() {
CConfig listenerConfig;
listenerConfig.AddKeyValuePair("Host", pListener->GetBindHost());
+ listenerConfig.AddKeyValuePair("URIPrefix", pListener->GetURIPrefix() + "/");
listenerConfig.AddKeyValuePair("Port", CString(pListener->GetPort()));
listenerConfig.AddKeyValuePair("IPv4", CString(pListener->GetAddrType() != ADDR_IPV6ONLY));
@@ -582,6 +583,7 @@ bool CZNC::WriteNewConfig(const CString& sConfigFile) {
bool b6 = false;
#endif
CString sListenHost;
+ CString sURIPrefix;
bool bListenSSL = false;
unsigned int uListenPort = 0;
bool bSuccess;
@@ -610,7 +612,7 @@ bool CZNC::WriteNewConfig(const CString& sConfigFile) {
CUtils::GetInput("Listen Host", sListenHost, sListenHost, "Blank for all ips");
CUtils::PrintAction("Verifying the listener");
- CListener* pListener = new CListener((unsigned short int)uListenPort, sListenHost, bListenSSL,
+ CListener* pListener = new CListener((unsigned short int)uListenPort, sListenHost, sURIPrefix, bListenSSL,
b6 ? ADDR_ALL : ADDR_IPV4ONLY, CListener::ACCEPT_ALL);
if (!pListener->Listen()) {
CUtils::PrintStatus(false, FormatBindError());
@@ -1695,12 +1697,15 @@ bool CZNC::AddListener(const CString& sLine, CString& sError) {
bSSL = true;
}
+ // No support for URIPrefix for old-style configs.
+ CString sURIPrefix;
unsigned short uPort = sPort.ToUShort();
- return AddListener(uPort, sBindHost, bSSL, eAddr, eAccept, sError);
+ return AddListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept, sError);
}
-bool CZNC::AddListener(unsigned short uPort, const CString& sBindHost, bool bSSL,
- EAddrType eAddr, CListener::EAcceptType eAccept, CString& sError) {
+bool CZNC::AddListener(unsigned short uPort, const CString& sBindHost,
+ const CString& sURIPrefixRaw, bool bSSL,
+ EAddrType eAddr, CListener::EAcceptType eAccept, CString& sError) {
CString sHostComment;
if (!sBindHost.empty()) {
@@ -1761,7 +1766,18 @@ bool CZNC::AddListener(unsigned short uPort, const CString& sBindHost, bool bSSL
return false;
}
- CListener* pListener = new CListener(uPort, sBindHost, bSSL, eAddr, eAccept);
+ // URIPrefix must start with a slash and end without one.
+ CString sURIPrefix = CString(sURIPrefixRaw);
+ if(!sURIPrefix.empty()) {
+ if (!sURIPrefix.StartsWith("/")) {
+ sURIPrefix = "/" + sURIPrefix;
+ }
+ if (sURIPrefix.EndsWith("/")) {
+ sURIPrefix.TrimRight("/");
+ }
+ }
+
+ CListener* pListener = new CListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept);
if (!pListener->Listen()) {
sError = FormatBindError();
@@ -1778,6 +1794,7 @@ bool CZNC::AddListener(unsigned short uPort, const CString& sBindHost, bool bSSL
bool CZNC::AddListener(CConfig* pConfig, CString& sError) {
CString sBindHost;
+ CString sURIPrefix;
bool bSSL;
bool b4;
#ifdef HAVE_IPV6
@@ -1799,6 +1816,7 @@ bool CZNC::AddListener(CConfig* pConfig, CString& sError) {
pConfig->FindBoolEntry("ipv6", b6, b6);
pConfig->FindBoolEntry("allowirc", bIRC, true);
pConfig->FindBoolEntry("allowweb", bWeb, true);
+ pConfig->FindStringEntry("uriprefix", sURIPrefix);
EAddrType eAddr;
if (b4 && b6) {
@@ -1826,7 +1844,7 @@ bool CZNC::AddListener(CConfig* pConfig, CString& sError) {
return false;
}
- return AddListener(uPort, sBindHost, bSSL, eAddr, eAccept, sError);
+ return AddListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept, sError);
}
bool CZNC::AddListener(CListener* pListener) {
|