]> git.saurik.com Git - wxWidgets.git/commitdiff
wxURL implementation using WinInet functions under Win32 (patch 839305)
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 7 Feb 2004 15:28:06 +0000 (15:28 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 7 Feb 2004 15:28:06 +0000 (15:28 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@25562 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

build/bakefiles/files.bkl
docs/changes.txt
include/wx/msw/setup0.h
include/wx/url.h
src/common/url.cpp
src/msw/urlmsw.cpp [new file with mode: 0644]

index 00e8232608f44cc45d1cf312d207d45748f7ed14..b27840a1fd6e87ca863aad434aa81b61c6cd8a5a 100644 (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
index 93bda7d04d857d96c4a781e5e2899ece718ddc73..c203cedc2d3999d3f5e69fe16e91b05d48a59163 100644 (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:
 
index 1efd582ebe4cd553eae91d5d2c6078827e793ec0..c094148dd71029a4e8716a883b88ff748042e44c 100644 (file)
 // 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.
index dc220b8a5faa653ffbc6dac948135a09e756fd64..59d8428060fdcaa038e872d5b85bf82d09d473e1 100644 (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;
 
index e265e0c5f3c729019b71647eeb7a6435cac11578..6c0da6ee2921fbbee52720e73a2ff240b7b36b68 100644 (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;
 
diff --git a/src/msw/urlmsw.cpp b/src/msw/urlmsw.cpp
new file mode 100644 (file)
index 0000000..404da29
--- /dev/null
@@ -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
+