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:
Vadim Zeitlin 2004-02-07 15:28:06 +00:00
parent ba1e9d6ced
commit 25959b956d
6 changed files with 287 additions and 3 deletions

View File

@ -309,6 +309,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
<set var="NET_WIN32_SRC" hints="files">
src/msw/gsocket.c
src/msw/urlmsw.cpp
</set>
<set var="NET_WIN32_HDR" hints="files">
wx/msw/gsockmsw.h

View File

@ -34,6 +34,7 @@ INCOMPATIBLE CHANGES SINCE 2.4.x
- wxTabView::GetLayers() changed return type from wxList& to wxTabLayerList&
(when WXWIN_COMPATIBILITY_2_4 == 0)
- 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
@ -146,6 +147,7 @@ wxMSW:
wxEVT_COMMAND_COMBOBOX_SELECTED changed the selection
- wxFileDialog now returns correct filter index for multiple-file dialogs
- added wxTextCtrl::HitTest()
- experimental wxURL implementation using WinInet functions (Hajo Kirchhoff)
wxGTK:

View File

@ -435,6 +435,16 @@
// Define this to use wxURL class.
#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
// use POSIX regular expressions in your code. You need to compile regex
// library from src/regex to use it under Windows.

View File

@ -37,6 +37,17 @@ typedef enum {
wxURL_PROTOERR
} 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
{
public:
@ -72,6 +83,14 @@ protected:
wxHTTP *m_proxy;
#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;
wxProtocol *m_protocol;

View File

@ -61,6 +61,9 @@ wxURL::wxURL(const wxString& url)
m_protocol = NULL;
m_error = wxURL_NOERR;
m_url = url;
#if wxUSE_URL_NATIVE
m_nativeImp = CreateNativeImpObject();
#endif
#if wxUSE_SOCKETS
if ( ms_useDefaultProxy && !ms_proxyDefault )
@ -157,10 +160,13 @@ void wxURL::CleanData()
wxURL::~wxURL()
{
CleanData();
CleanData();
#if wxUSE_SOCKETS
if (m_proxy && m_proxy != ms_proxyDefault)
delete m_proxy;
if (m_proxy && m_proxy != ms_proxyDefault)
delete m_proxy;
#endif
#if wxUSE_URL_NATIVE
delete m_nativeImp;
#endif
}
@ -285,6 +291,19 @@ wxInputStream *wxURL::GetInputStream()
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
wxIPV4address addr;

233
src/msw/urlmsw.cpp Normal file
View 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