From 390b93bfb8def34e8a1dfd18a920802fff0167b8 Mon Sep 17 00:00:00 2001 From: cxl Date: Wed, 14 May 2014 09:22:30 +0000 Subject: [PATCH] POP3: HTTP CONNECT proxy support git-svn-id: svn://ultimatepp.org/upp/trunk@7372 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/Http.cpp | 7 ++--- uppsrc/Core/Inet.h | 8 ++++-- uppsrc/Core/POP3/POP3.cpp | 38 +++++++++++++++++++++++++ uppsrc/Core/POP3/POP3.h | 17 ++++++++--- uppsrc/Core/POP3/src.tpp/Pop3$en-us.tpp | 17 +++++++++++ uppsrc/CtrlLib/ToolTip.cpp | 2 +- 6 files changed, 77 insertions(+), 12 deletions(-) diff --git a/uppsrc/Core/Http.cpp b/uppsrc/Core/Http.cpp index a3dc5d6dd..20c2dad0d 100644 --- a/uppsrc/Core/Http.cpp +++ b/uppsrc/Core/Http.cpp @@ -106,8 +106,7 @@ HttpRequest& HttpRequest::Url(const char *u) return *this; } -static -void sParseProxyUrl(const char *p, String& proxy_host, int& proxy_port) +void ParseProxyUrl(const char *p, String& proxy_host, int& proxy_port) { const char *t = p; while(*p && *p != ':') @@ -120,14 +119,14 @@ void sParseProxyUrl(const char *p, String& proxy_host, int& proxy_port) HttpRequest& HttpRequest::Proxy(const char *url) { proxy_port = 80; - sParseProxyUrl(url, proxy_host, proxy_port); + ParseProxyUrl(url, proxy_host, proxy_port); return *this; } HttpRequest& HttpRequest::SSLProxy(const char *url) { ssl_proxy_port = 8080; - sParseProxyUrl(url, ssl_proxy_host, ssl_proxy_port); + ParseProxyUrl(url, ssl_proxy_host, ssl_proxy_port); return *this; } diff --git a/uppsrc/Core/Inet.h b/uppsrc/Core/Inet.h index 49a38b339..81a72b2ed 100644 --- a/uppsrc/Core/Inet.h +++ b/uppsrc/Core/Inet.h @@ -472,11 +472,11 @@ public: HttpRequest& ContentType(const String& a) { contenttype = a; return *this; } HttpRequest& KeepAlive(bool ka = true) { keep_alive = ka; return *this;} - HttpRequest& Proxy(const String& host, int port) { proxy_host = host; proxy_port = port; return *this; } + HttpRequest& Proxy(const String& host, int port) { proxy_host = host; proxy_port = port; return *this; } HttpRequest& Proxy(const char *p); - HttpRequest& ProxyAuth(const String& u, const String& p) { proxy_username = u; proxy_password = p; return *this; } + HttpRequest& ProxyAuth(const String& u, const String& p) { proxy_username = u; proxy_password = p; return *this; } - HttpRequest& SSLProxy(const String& host, int port) { ssl_proxy_host = host; ssl_proxy_port = port; return *this; } + HttpRequest& SSLProxy(const String& host, int port) { ssl_proxy_host = host; ssl_proxy_port = port; return *this; } HttpRequest& SSLProxy(const char *p); HttpRequest& SSLProxyAuth(const String& u, const String& p) { ssl_proxy_username = u; ssl_proxy_password = p; return *this; } @@ -595,3 +595,5 @@ public: WebSocket() { Reset(); } }; + +void ParseProxyUrl(const char *p, String& proxy_host, int& proxy_port); diff --git a/uppsrc/Core/POP3/POP3.cpp b/uppsrc/Core/POP3/POP3.cpp index 18b5ebf9e..43c62b5f1 100644 --- a/uppsrc/Core/POP3/POP3.cpp +++ b/uppsrc/Core/POP3/POP3.cpp @@ -8,6 +8,13 @@ void Pop3::Trace(bool b) sPop3Trace = b; } +Pop3& Pop3::Proxy(const char *p) +{ + proxy_port = 8080; + ParseProxyUrl(p, proxy_host, proxy_port); + return *this; +} + String Pop3::GetTimeStamp() { int begin = data.Find('<'); @@ -169,6 +176,37 @@ bool Pop3::Login() throw Exc(t_("Username is not specified.")); if(pass.IsEmpty()) throw Exc(t_("Password is nor specified.")); + if(proxy_host.GetCount()) { + String host_port = host; + host_port << ':' << Nvl(port, ssl ? 995 : 110); + String data; + data << "CONNECT " << host_port << " HTTP/1.1\r\n" + << "Host: " << host_port << "\r\n"; + if(!IsNull(proxy_username)) + data << "Proxy-Authorization: Basic " + << Base64Encode(proxy_username + ':' + proxy_password) << "\r\n"; + data << "\r\n"; + LLOG("Trying to connect proxy " << proxy_host << ":" << proxy_port); + if(!Connect(proxy_host, proxy_port)) + throw Exc("Unable to connect the proxy"); + LLOG("About to send proxy request:\n" << data); + if(!PutAll(data)) + throw Exc("Unable to send request to the proxy"); + String response; + for(;;) { + String l = GetLine(); + if(l.GetCount() == 0) + break; + LLOG("< " << l); + if(response.GetCount() == 0) + response = l; + } + LLOG("Proxy response: " << response); + if(!response.StartsWith("HTTP") || response.Find(" 2") < 0) + throw Exc("Invalid proxy reply: " + response); + LLOG("Connected via proxy"); + } + else if(!Connect(host, Nvl(port, ssl ? 995 : 110))) throw Exc(GetErrorDesc()); LLOG(Format(t_("Opening connection to %s:%d."), host, port)); diff --git a/uppsrc/Core/POP3/POP3.h b/uppsrc/Core/POP3/POP3.h index a012719b2..fcf500c8e 100644 --- a/uppsrc/Core/POP3/POP3.h +++ b/uppsrc/Core/POP3/POP3.h @@ -7,6 +7,11 @@ using namespace Upp; class Pop3 : public TcpSocket { + String proxy_host; + int proxy_port; + String proxy_username; + String proxy_password; + String host; String user; String pass; @@ -16,16 +21,20 @@ class Pop3 : public TcpSocket bool ssl; bool online; - bool GetListItems(ValueMap& list, dword type1, dword type2); - String GetTimeStamp(); + bool GetListItems(ValueMap& list, dword type1, dword type2); + String GetTimeStamp(); bool Authenticate(); - bool PutGet(const String& s, bool multiline = false, bool nolog = false); - + bool PutGet(const String& s, bool multiline = false, bool nolog = false); + public: Pop3& Host(const String& h) { host = h; return *this; } Pop3& Port(int p) { port = p; return *this; } Pop3& User(const String& u, const String& p) { user = u; pass = p; return *this; } Pop3& SSL(bool b = true) { ssl = b; return *this; } + + Pop3& Proxy(const String& host, int port) { proxy_host = host; proxy_port = port; return *this; } + Pop3& Proxy(const char *p); + Pop3& ProxyAuth(const String& u, const String& p) { proxy_username = u; proxy_password = p; return *this; } int GetMessageCount(); String GetMessage(int index); diff --git a/uppsrc/Core/POP3/src.tpp/Pop3$en-us.tpp b/uppsrc/Core/POP3/src.tpp/Pop3$en-us.tpp index 252b36b0b..3ddcc0559 100644 --- a/uppsrc/Core/POP3/src.tpp/Pop3$en-us.tpp +++ b/uppsrc/Core/POP3/src.tpp/Pop3$en-us.tpp @@ -47,6 +47,23 @@ rue])&] Returns `*this for method chaining.&] [s3;%% &] [s4; &] +[s5;:Pop3`:`:Proxy`(const String`&`,int`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* Proxy]([@(0.0.255) c +onst]_[_^String^ String][@(0.0.255) `&]_[*@3 host], [@(0.0.255) int]_[*@3 port])&] +[s2;%% Sets HTTP CONNECT proxy for connection.&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:Proxy`(const char`*`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* Proxy]([@(0.0.255) const +]_[@(0.0.255) char]_`*[*@3 p])&] +[s2;%% Sets HTTP CONNECT proxy for connection, parameter contains +host and port separated by `':`'.&] +[s3;%% &] +[s4; &] +[s5;:Pop3`:`:ProxyAuth`(const String`&`,const String`&`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* P +roxyAuth]([@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 u], +[@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 p])&] +[s2;%% Sets the username and password for proxy..&] +[s3;%% &] +[s4; &] [s5;:Pop3`:`:GetMessageCount`(`): [@(0.0.255) int]_[* GetMessageCount]()&] [s2;%% Returns the number of currently available messages in the POP3 mailbox. Returns `-1 on failure.&] diff --git a/uppsrc/CtrlLib/ToolTip.cpp b/uppsrc/CtrlLib/ToolTip.cpp index 925b940e5..e0f3906df 100644 --- a/uppsrc/CtrlLib/ToolTip.cpp +++ b/uppsrc/CtrlLib/ToolTip.cpp @@ -2,7 +2,7 @@ NAMESPACE_UPP -#define LLOG(x) DLOG(x) +#define LLOG(x) // DLOG(x) ToolTip::ToolTip() {