First version of HttpsClient (using SSL)

git-svn-id: svn://ultimatepp.org/upp/trunk@2042 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
rylek 2010-02-09 19:19:06 +00:00
parent c0dea5dff1
commit 04b10ecca1
6 changed files with 98 additions and 20 deletions

View file

@ -31,6 +31,7 @@ link(WIN32 MT MSC71) /nodefaultlib:libc;
file
WebSSL.h,
util.cpp,
httpscli.cpp,
src.tpp,
srcimp.tpp,
srcdoc.tpp,

View file

@ -6,6 +6,7 @@
#include <Web/Web.h>
#include <openssl/ssl.h>
#include <openssl/conf.h>
#include <openssl/err.h>
NAMESPACE_UPP
@ -19,7 +20,7 @@ String SSLToString(X509_NAME *name);
String ASN1ToString(ASN1_STRING *time);
Date ASN1ToDate(ASN1_STRING *time);
void SSLInit();
//void SSLInit();
class SSLBuffer
{
@ -124,7 +125,7 @@ private:
class SSLContext
{
public:
SSLContext(SSL_CTX *c = NULL) : ssl_ctx(c) { SSLInit(); }
SSLContext(SSL_CTX *c = NULL) : ssl_ctx(c) { /*SSLInit();*/ }
~SSLContext() { Clear(); }
bool IsEmpty() const { return !ssl_ctx; }
@ -159,6 +160,20 @@ inline String SSLInfoCertNotAfter() { return "SSL_CERT_NOT_AFTER"; } //
inline String SSLInfoCertVersion() { return "SSL_CERT_VERSION"; } // int
inline String SSLInfoCertSerialNumber() { return "SSL_CERT_SERIAL_NUMBER"; } // String
class HttpsClient : public HttpClient {
public:
HttpsClient();
void Secure(bool s) { secure = s; }
virtual bool CreateClientSocket();
public:
One<SSLContext> ssl_context;
bool secure;
};
END_UPP_NAMESPACE
#endif//flagNOSSL

View file

@ -0,0 +1,33 @@
#ifndef flagNOSSL
#include "WebSSL.h"
NAMESPACE_UPP
HttpsClient::HttpsClient()
{
secure = true;
}
bool HttpsClient::CreateClientSocket()
{
if(!secure)
return HttpClient::CreateClientSocket();
if(!ssl_context) {
ssl_context = new SSLContext;
if(!ssl_context->Create(SSLv3_client_method())) {
error = t_("Error creating SSL context.");
return false;
}
}
if(!SSLClientSocket(socket, *ssl_context, socket_host, socket_port, true, NULL, 0, false)) {
error = Socket::GetErrorText();
return false;
}
socket.Linger(0);
return true;
}
END_UPP_NAMESPACE
#endif

View file

@ -5,7 +5,7 @@
NAMESPACE_UPP
#define LOG_UPP_SSL_MALLOC 0
#define LOG_UPP_SSL_MALLOC 1
#if LOG_UPP_SSL_MALLOC
static int UPP_SSL_alloc = 0;
@ -25,7 +25,7 @@ void *SSLAlloc(size_t size)
*aptr++ = alloc;
#if LOG_UPP_SSL_MALLOC
UPP_SSL_alloc += alloc;
RLOG("UPP_SSL_MALLOC(" << (int)size << ", alloc " << alloc << ") -> " << aptr << ", total = " << UPP_SSL_alloc);
RLOG("UPP_SSL_MALLOC(" << (int)size << ", alloc " << alloc << ") -> " << FormatIntHex(aptr) << ", total = " << UPP_SSL_alloc);
#endif
return aptr;
}
@ -67,13 +67,31 @@ void *SSLRealloc(void *ptr, size_t size)
memcpy(newaptr, ptr, min<int>(*aptr - sizeof(int), size));
#if LOG_UPP_SSL_MALLOC
UPP_SSL_alloc += newalloc - *aptr;
RLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int)size << ", alloc " << newalloc << ") -> " << newaptr
<< ", total = " << UPP_SSL_alloc);
RLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int)size << ", alloc " << newalloc << ") -> "
<< FormatIntHex(newaptr) << ", total = " << UPP_SSL_alloc);
#endif
MemoryFree(aptr);
return newaptr;
}
INITBLOCK {
Socket::Init();
CRYPTO_set_mem_functions(SSLAlloc, SSLRealloc, SSLFree);
SSL_load_error_strings();
SSL_library_init();
}
EXITBLOCK {
CONF_modules_unload(1);
// destroy_ui_method();
EVP_cleanup();
// ENGINE_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_remove_state(0);
ERR_free_strings();
}
/*
void SSLInit()
{
static bool inited = false;
@ -86,6 +104,7 @@ void SSLInit()
SSL_library_init();
}
}
*/
String SSLGetLastError()
{
@ -415,7 +434,7 @@ int SSLSocketData::Write(const void *buf, int amount)
bool SSLSocketData::OpenClient(const char *host, int port, bool nodelay, dword *my_addr, int timeout, bool blocking)
{
if(!Data::OpenClient(host, port, nodelay, my_addr, timeout, blocking))
if(!Data::OpenClient(host, port, nodelay, my_addr, timeout, /*blocking*/true))
return false;
if(!(ssl = SSL_new(ssl_context)))
{
@ -479,8 +498,7 @@ bool SSLSocketData::Close(int timeout_msec)
if(ssl)
SSL_shutdown(ssl);
bool res = Data::Close(timeout_msec);
if(ssl)
{
if(ssl) {
SSL_free(ssl);
ssl = NULL;
}

View file

@ -246,21 +246,16 @@ String HttpClient::Execute(Gate2<int, int> progress)
Close();
error = Null;
bool use_proxy = !IsNull(proxy_host);
String sock_host = (use_proxy ? proxy_host : host);
int sock_port = (use_proxy ? proxy_port : port);
socket_host = (use_proxy ? proxy_host : host);
socket_port = (use_proxy ? proxy_port : port);
LLOG("socket host = " << sock_host << ":" << sock_port);
if(!socket.IsOpen()) {
if(!ClientSocket(socket, sock_host, sock_port, true, NULL, 0, false)) {
error = Socket::GetErrorText();
return String::GetVoid();
}
socket.Linger(0);
}
LLOG("socket host = " << socket_host << ":" << socket_port);
if(!socket.IsOpen() && !CreateClientSocket())
return String::GetVoid();
while(!socket.PeekWrite(1000)) {
int time = msecs();
if(time >= end_time) {
error = NFormat(t_("%s:%d: connecting to host timed out"), sock_host, sock_port);
error = NFormat(t_("%s:%d: connecting to host timed out"), socket_host, socket_port);
return String::GetVoid();
}
if(progress(time - start_time, end_time - start_time)) {
@ -534,6 +529,16 @@ EXIT:
return body;
}
bool HttpClient::CreateClientSocket()
{
if(!ClientSocket(socket, socket_host, socket_port, true, NULL, 0, false)) {
error = Socket::GetErrorText();
return false;
}
socket.Linger(0);
return true;
}
String HttpClientGet(String url, String proxy, String username, String password,
String *server_headers, String *error, Gate2<int, int> progress,
int timeout, int num_redirect, int retries)

View file

@ -67,7 +67,10 @@ public:
void Close() { socket.Close(); }
static void Trace(bool b = true);
virtual bool CreateClientSocket();
public:
Socket socket;
bool keepalive;
@ -107,6 +110,9 @@ public:
String redirect_url;
String authenticate;
String socket_host;
int socket_port;
enum {
DEFAULT_PORT = 80,