wxURL implementation using WinInet functions under Win32 (patch 839305)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@25562 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -309,6 +309,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
|
|||||||
|
|
||||||
<set var="NET_WIN32_SRC" hints="files">
|
<set var="NET_WIN32_SRC" hints="files">
|
||||||
src/msw/gsocket.c
|
src/msw/gsocket.c
|
||||||
|
src/msw/urlmsw.cpp
|
||||||
</set>
|
</set>
|
||||||
<set var="NET_WIN32_HDR" hints="files">
|
<set var="NET_WIN32_HDR" hints="files">
|
||||||
wx/msw/gsockmsw.h
|
wx/msw/gsockmsw.h
|
||||||
|
@@ -34,6 +34,7 @@ INCOMPATIBLE CHANGES SINCE 2.4.x
|
|||||||
- wxTabView::GetLayers() changed return type from wxList& to wxTabLayerList&
|
- wxTabView::GetLayers() changed return type from wxList& to wxTabLayerList&
|
||||||
(when WXWIN_COMPATIBILITY_2_4 == 0)
|
(when WXWIN_COMPATIBILITY_2_4 == 0)
|
||||||
- wxID_SEPARATOR (id used for the menu separators) value changed from -1 to -2
|
- wxID_SEPARATOR (id used for the menu separators) value changed from -1 to -2
|
||||||
|
- wxGetNumberFromUser() is now in separate wx/numdlg.h, not wx/textdlg.h
|
||||||
|
|
||||||
|
|
||||||
DEPRECATED METHODS SINCE 2.4.x
|
DEPRECATED METHODS SINCE 2.4.x
|
||||||
@@ -146,6 +147,7 @@ wxMSW:
|
|||||||
wxEVT_COMMAND_COMBOBOX_SELECTED changed the selection
|
wxEVT_COMMAND_COMBOBOX_SELECTED changed the selection
|
||||||
- wxFileDialog now returns correct filter index for multiple-file dialogs
|
- wxFileDialog now returns correct filter index for multiple-file dialogs
|
||||||
- added wxTextCtrl::HitTest()
|
- added wxTextCtrl::HitTest()
|
||||||
|
- experimental wxURL implementation using WinInet functions (Hajo Kirchhoff)
|
||||||
|
|
||||||
wxGTK:
|
wxGTK:
|
||||||
|
|
||||||
|
@@ -435,6 +435,16 @@
|
|||||||
// Define this to use wxURL class.
|
// Define this to use wxURL class.
|
||||||
#define wxUSE_URL 1
|
#define wxUSE_URL 1
|
||||||
|
|
||||||
|
// Define this to use native platform url and protocol support.
|
||||||
|
// Currently valid only for MS-Windows.
|
||||||
|
// Note: if you set this to 1, you can open ftp/http/gopher sites
|
||||||
|
// and obtain a valid input stream for these sites
|
||||||
|
// even when you set wxUSE_PROTOCOL_FTP/HTTP to 0.
|
||||||
|
// Doing so reduces the code size.
|
||||||
|
//
|
||||||
|
// This code is experimental and subject to change.
|
||||||
|
#define wxUSE_URL_NATIVE 0
|
||||||
|
|
||||||
// Support for regular expression matching via wxRegEx class: enable this to
|
// Support for regular expression matching via wxRegEx class: enable this to
|
||||||
// use POSIX regular expressions in your code. You need to compile regex
|
// use POSIX regular expressions in your code. You need to compile regex
|
||||||
// library from src/regex to use it under Windows.
|
// library from src/regex to use it under Windows.
|
||||||
|
@@ -37,6 +37,17 @@ typedef enum {
|
|||||||
wxURL_PROTOERR
|
wxURL_PROTOERR
|
||||||
} wxURLError;
|
} wxURLError;
|
||||||
|
|
||||||
|
#if wxUSE_URL_NATIVE
|
||||||
|
class WXDLLIMPEXP_NET wxURL;
|
||||||
|
|
||||||
|
class WXDLLIMPEXP_NET wxURLNativeImp : public wxObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~wxURLNativeImp() { }
|
||||||
|
virtual wxInputStream *GetInputStream(wxURL *owner) = 0;
|
||||||
|
};
|
||||||
|
#endif // wxUSE_URL_NATIVE
|
||||||
|
|
||||||
class WXDLLIMPEXP_NET wxURL : public wxObject
|
class WXDLLIMPEXP_NET wxURL : public wxObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -72,6 +83,14 @@ protected:
|
|||||||
wxHTTP *m_proxy;
|
wxHTTP *m_proxy;
|
||||||
#endif // wxUSE_SOCKETS
|
#endif // wxUSE_SOCKETS
|
||||||
|
|
||||||
|
#if wxUSE_URL_NATIVE
|
||||||
|
friend class wxURLNativeImp;
|
||||||
|
// pointer to a native URL implementation object
|
||||||
|
wxURLNativeImp *m_nativeImp;
|
||||||
|
// Creates on the heap and returns a native
|
||||||
|
// implementation object for the current platform.
|
||||||
|
static wxURLNativeImp *CreateNativeImpObject();
|
||||||
|
#endif
|
||||||
wxProtoInfo *m_protoinfo;
|
wxProtoInfo *m_protoinfo;
|
||||||
wxProtocol *m_protocol;
|
wxProtocol *m_protocol;
|
||||||
|
|
||||||
|
@@ -61,6 +61,9 @@ wxURL::wxURL(const wxString& url)
|
|||||||
m_protocol = NULL;
|
m_protocol = NULL;
|
||||||
m_error = wxURL_NOERR;
|
m_error = wxURL_NOERR;
|
||||||
m_url = url;
|
m_url = url;
|
||||||
|
#if wxUSE_URL_NATIVE
|
||||||
|
m_nativeImp = CreateNativeImpObject();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if wxUSE_SOCKETS
|
#if wxUSE_SOCKETS
|
||||||
if ( ms_useDefaultProxy && !ms_proxyDefault )
|
if ( ms_useDefaultProxy && !ms_proxyDefault )
|
||||||
@@ -162,6 +165,9 @@ wxURL::~wxURL()
|
|||||||
if (m_proxy && m_proxy != ms_proxyDefault)
|
if (m_proxy && m_proxy != ms_proxyDefault)
|
||||||
delete m_proxy;
|
delete m_proxy;
|
||||||
#endif
|
#endif
|
||||||
|
#if wxUSE_URL_NATIVE
|
||||||
|
delete m_nativeImp;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
@@ -285,6 +291,19 @@ wxInputStream *wxURL::GetInputStream()
|
|||||||
m_protocol->SetPassword(m_password);
|
m_protocol->SetPassword(m_password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_URL_NATIVE
|
||||||
|
// give the native implementation to return a better stream
|
||||||
|
// such as the native WinINet functionality under MS-Windows
|
||||||
|
if (m_nativeImp)
|
||||||
|
{
|
||||||
|
wxInputStream *rc;
|
||||||
|
rc = m_nativeImp->GetInputStream(this);
|
||||||
|
if (rc != 0)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
// else use the standard behaviour
|
||||||
|
#endif // wxUSE_URL_NATIVE
|
||||||
|
|
||||||
#if wxUSE_SOCKETS
|
#if wxUSE_SOCKETS
|
||||||
wxIPV4address addr;
|
wxIPV4address addr;
|
||||||
|
|
||||||
|
233
src/msw/urlmsw.cpp
Normal file
233
src/msw/urlmsw.cpp
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: msw/urlmsw.cpp
|
||||||
|
// Purpose: MS-Windows native URL support based on WinINet
|
||||||
|
// Author: Hajo Kirchhoff
|
||||||
|
// Modified by:
|
||||||
|
// Created: 06/11/2003
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 2003 Hajo Kirchhoff
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// For compilers that support precompilation, includes "wx.h".
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if wxUSE_URL_NATIVE
|
||||||
|
|
||||||
|
#if !wxUSE_PROTOCOL_HTTP
|
||||||
|
#include <wx/protocol/protocol.h>
|
||||||
|
|
||||||
|
// empty http protocol replacement (for now)
|
||||||
|
// so that wxUSE_URL_NATIVE can be used with
|
||||||
|
// wxSOCKETS==0 and wxUSE_PROTOCOL_HTTP==0
|
||||||
|
class wxHTTPDummyProto : public wxProtocol
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxHTTPDummyProto() : wxProtocol() { }
|
||||||
|
|
||||||
|
wxProtocolError GetError() { return m_error; }
|
||||||
|
|
||||||
|
virtual bool Abort() { return TRUE; }
|
||||||
|
|
||||||
|
wxInputStream *GetInputStream(const wxString& WXUNUSED(path))
|
||||||
|
{
|
||||||
|
return 0; // input stream is returned by wxURLNativeImp
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxProtocolError m_error;
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_CLASS_NO_COPY(wxHTTPDummyProto)
|
||||||
|
DECLARE_PROTOCOL(wxHTTPDummyProto)
|
||||||
|
};
|
||||||
|
|
||||||
|
// the only "reason for being" for this class is to tell
|
||||||
|
// wxURL that there is someone dealing with the http protocol
|
||||||
|
IMPLEMENT_DYNAMIC_CLASS(wxHTTPDummyProto, wxProtocol)
|
||||||
|
IMPLEMENT_PROTOCOL(wxHTTPDummyProto, wxT("http"), NULL, FALSE)
|
||||||
|
USE_PROTOCOL(wxHTTPDummyProto)
|
||||||
|
|
||||||
|
#endif // !wxUSE_PROTOCOL_HTTP
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __VISUALC__ // be conservative about this pragma
|
||||||
|
// tell the linker to include wininet.lib automatically
|
||||||
|
#pragma comment(lib, "wininet.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/string.h"
|
||||||
|
#include "wx/list.h"
|
||||||
|
#include "wx/utils.h"
|
||||||
|
#include "wx/module.h"
|
||||||
|
#include "wx/url.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <wininet.h>
|
||||||
|
|
||||||
|
// this class needn't be exported
|
||||||
|
class wxWinINetURL:public wxURLNativeImp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxInputStream *GetInputStream(wxURL *owner);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// return the WinINet session handle
|
||||||
|
static HINTERNET GetSessionHandle();
|
||||||
|
};
|
||||||
|
|
||||||
|
HINTERNET wxWinINetURL::GetSessionHandle()
|
||||||
|
{
|
||||||
|
// this struct ensures that the session is opened when the
|
||||||
|
// first call to GetSessionHandle is made
|
||||||
|
// it also ensures that the session is closed when the program
|
||||||
|
// terminates
|
||||||
|
static struct INetSession
|
||||||
|
{
|
||||||
|
INetSession()
|
||||||
|
{
|
||||||
|
DWORD rc = InternetAttemptConnect(0);
|
||||||
|
|
||||||
|
m_handle = InternetOpen
|
||||||
|
(
|
||||||
|
wxVERSION_STRING,
|
||||||
|
INTERNET_OPEN_TYPE_PRECONFIG,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
rc == ERROR_SUCCESS ? 0 : INTERNET_FLAG_OFFLINE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
~INetSession()
|
||||||
|
{
|
||||||
|
InternetCloseHandle(m_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
HINTERNET m_handle;
|
||||||
|
} session;
|
||||||
|
|
||||||
|
return session.m_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this class needn't be exported
|
||||||
|
class /*WXDLLIMPEXP_NET */ wxWinINetInputStream : public wxInputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxWinINetInputStream(HINTERNET hFile=0);
|
||||||
|
~wxWinINetInputStream();
|
||||||
|
|
||||||
|
void Attach(HINTERNET hFile);
|
||||||
|
|
||||||
|
off_t SeekI( off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode) )
|
||||||
|
{ return -1; }
|
||||||
|
off_t TellI() const
|
||||||
|
{ return -1; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void SetError(wxStreamError err) { m_lasterror=err; }
|
||||||
|
HINTERNET m_hFile;
|
||||||
|
size_t OnSysRead(void *buffer, size_t bufsize);
|
||||||
|
|
||||||
|
DECLARE_NO_COPY_CLASS(wxWinINetInputStream)
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t wxWinINetInputStream::OnSysRead(void *buffer, size_t bufsize)
|
||||||
|
{
|
||||||
|
DWORD bytesread = 0;
|
||||||
|
if ( !InternetReadFile(m_hFile, buffer, bufsize, &bytesread) )
|
||||||
|
{
|
||||||
|
DWORD lError = ::GetLastError();
|
||||||
|
if ( lError != ERROR_SUCCESS )
|
||||||
|
SetError(wxSTREAM_READ_ERROR);
|
||||||
|
|
||||||
|
DWORD iError, bLength;
|
||||||
|
InternetGetLastResponseInfo(&iError, NULL, &bLength);
|
||||||
|
if ( bLength > 0 )
|
||||||
|
{
|
||||||
|
wxString errorString;
|
||||||
|
InternetGetLastResponseInfo
|
||||||
|
(
|
||||||
|
&iError,
|
||||||
|
wxStringBuffer(errorString, bLength),
|
||||||
|
&bLength
|
||||||
|
);
|
||||||
|
|
||||||
|
wxLogError(wxT("Read failed with error %d: %s"),
|
||||||
|
iError, errorString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bytesread == 0 )
|
||||||
|
{
|
||||||
|
SetError(wxSTREAM_EOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytesread;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxWinINetInputStream::wxWinINetInputStream(HINTERNET hFile)
|
||||||
|
: m_hFile(hFile)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWinINetInputStream::Attach(HINTERNET newHFile)
|
||||||
|
{
|
||||||
|
wxCHECK_RET(m_hFile==NULL,
|
||||||
|
wxT("cannot attach new stream when stream already exists"));
|
||||||
|
m_hFile=newHFile;
|
||||||
|
SetError(m_hFile!=NULL ? wxSTREAM_NO_ERROR : wxSTREAM_READ_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxWinINetInputStream::~wxWinINetInputStream()
|
||||||
|
{
|
||||||
|
if ( m_hFile )
|
||||||
|
{
|
||||||
|
InternetCloseHandle(m_hFile);
|
||||||
|
m_hFile=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wxURLNativeImp *wxURL::CreateNativeImpObject()
|
||||||
|
{
|
||||||
|
return new wxWinINetURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxInputStream *wxWinINetURL::GetInputStream(wxURL *owner)
|
||||||
|
{
|
||||||
|
DWORD service;
|
||||||
|
if ( owner->GetProtocolName() == wxT("http") )
|
||||||
|
{
|
||||||
|
service = INTERNET_SERVICE_HTTP;
|
||||||
|
}
|
||||||
|
else if ( owner->GetProtocolName() == wxT("ftp") )
|
||||||
|
{
|
||||||
|
service = INTERNET_SERVICE_FTP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// unknown protocol. Let wxURL try another method.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxWinINetInputStream *newStream = new wxWinINetInputStream;
|
||||||
|
HINTERNET newStreamHandle = InternetOpenUrl
|
||||||
|
(
|
||||||
|
GetSessionHandle(),
|
||||||
|
owner->GetURL(),
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
INTERNET_FLAG_KEEP_CONNECTION |
|
||||||
|
INTERNET_FLAG_PASSIVE,
|
||||||
|
(DWORD_PTR)newStream
|
||||||
|
);
|
||||||
|
newStream->Attach(newStreamHandle);
|
||||||
|
|
||||||
|
return newStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_URL_NATIVE
|
||||||
|
|
Reference in New Issue
Block a user