protected:
wxProtocolError m_perr;
wxList m_headers;
- bool m_read;
+ bool m_read, m_proxy_mode;
wxSockAddress *m_addr;
public:
wxHTTP();
void SetHeader(const wxString& header, const wxString& h_data);
wxString GetHeader(const wxString& header);
+ void SetProxyMode(bool on);
+
protected:
typedef enum {
wxHTTP_GET,
static wxHTTP *g_proxy;
wxProtoInfo *m_protoinfo;
wxProtocol *m_protocol;
- wxHTTP m_proxy;
+ wxHTTP *m_proxy;
wxURLError m_error;
wxString m_protoname, m_hostname, m_servname, m_path, m_url;
wxString m_user, m_password;
+ bool m_useProxy;
bool PrepProto(wxString& url);
bool PrepHost(wxString& url);
inline wxString GetProtocolName() const
{ return m_protoinfo->m_protoname; }
+ inline wxString GetHostName() const { return m_hostname; }
+ inline wxString GetURL() const { return m_url; }
inline wxProtocol& GetProtocol() { return *m_protocol; }
inline wxURLError GetError() const { return m_error; }
inline wxString GetPath() const { return m_path; }
void MyFrame::Download(wxInputStream *input)
{
wxProgressDialog progress("Downloading ...", "0% downloaded");
- wxBufferedInputStream buf_in(*input);
wxFileOutputStream f_out("test.url");
-
- size_t file_size = input->StreamSize();
size_t downloaded;
- int BUFSIZE = (file_size > 100) ? (file_size / 100) : file_size;
- int bytes_read = BUFSIZE;
+ int BUFSIZE, bytes_read;
+ size_t file_size;
wxString message;
int percents;
char *buf;
-// TODO: Support for streams which don't support StreamSize
-
+ if (input->GetSize() == (size_t)-1) {
+ file_size = (size_t)-1;
+ bytes_read = BUFSIZE = 10240;
+ } else {
+ file_size = input->GetSize();
+ if (file_size > 10240)
+ bytes_read = BUFSIZE = file_size / 1024;
+ else
+ bytes_read = BUFSIZE = 1024;
+ }
buf = new char[BUFSIZE];
downloaded = 0;
bytes_read = BUFSIZE;
while (downloaded < file_size && bytes_read != 0) {
- bytes_read = buf_in.Read(buf, BUFSIZE).LastRead();
+ bytes_read = input->Read(buf, BUFSIZE).LastRead();
f_out.Write(buf, bytes_read);
downloaded += bytes_read;
wxSocketBase *sock = evt.Socket();
- printf("OnSockRequest OK\n");
- printf("OnSockRequest (event = %d)\n",evt.SocketEvent());
+ wxPrintf(_T("OnSockRequest OK\n"));
+ wxPrintf(_T("OnSockRequest (event = %d)\n"),evt.SocketEvent());
switch (evt.SocketEvent()) {
case GSOCK_INPUT:
unsigned char c;
break;
case GSOCK_LOST:
- printf("Destroying socket\n");
+ wxPrintf(_T("Destroying socket\n"));
wxPendingDelete.Append(sock);
UpdateStatus(-1);
return;
break;
+ default:
+ wxPrintf(_T("Invalid event !\n"));
}
- printf("OnSockRequest Exiting\n");
+ wxPrintf(_T("OnSockRequest Exiting\n"));
}
void MyFrame::OnSockRequestServer(wxSocketEvent& evt)
wxSocketBase *sock2;
wxSocketServer *server = (wxSocketServer *) evt.Socket();
- printf("OnSockRequestServer OK\n");
- printf("OnSockRequest (Main = %d) (event = %d)\n",wxThread::IsMain(), evt.SocketEvent());
+ wxPrintf(_T("OnSockRequestServer OK\n"));
+ wxPrintf(_T("OnSockRequest (Main = %d) (event = %d)\n"),wxThread::IsMain(), evt.SocketEvent());
sock2 = server->Accept();
if (sock2 == NULL)
void MyFrame::UpdateStatus(int incr)
{
- char s[30];
+ wxChar s[30];
nb_clients += incr;
- sprintf(s, "%d clients connected", nb_clients);
+ wxSprintf(s, _T("%d clients connected"), nb_clients);
SetStatusText(s);
}
info = (wxInetCacheNode*) m_Cache.Get(right);
// Add item into cache:
- if (info != NULL)
+ if (info == NULL)
{
wxURL url(right);
s = url.GetInputStream();
}
}
+class wxFileSystemInternetModule : public wxModule
+{
+ DECLARE_DYNAMIC_CLASS(wxFileSystemInternetModule)
+
+ public:
+ virtual bool OnInit()
+ {
+ wxFileSystem::AddHandler(new wxInternetFSHandler);
+ return TRUE;
+ }
+ virtual void OnExit() {}
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxFileSystemInternetModule, wxModule)
+
#endif // wxUSE_FS_INET
wxInputFTPStream(wxFTP *ftp_clt, wxSocketBase *sock)
: wxSocketInputStream(*sock), m_ftp(ftp_clt) {}
- size_t StreamSize() const { return m_ftpsize; }
+ size_t GetSize() const { return m_ftpsize; }
virtual ~wxInputFTPStream(void)
{
if (LastError() == wxStream_NOERROR)
{
m_addr = NULL;
m_read = FALSE;
+ m_proxy_mode = FALSE;
SetNotify(GSOCK_LOST_FLAG);
}
return GetHeader(_T("Content-Type"));
}
+void wxHTTP::SetProxyMode(bool on)
+{
+ m_proxy_mode = on;
+}
+
void wxHTTP::SetHeader(const wxString& header, const wxString& h_data)
{
if (m_read) {
wxString wxHTTP::GetHeader(const wxString& header)
{
- wxNode *node = m_headers.Find(header);
+ wxNode *node;
+ wxString upper_header;
+
+ upper_header = header.Upper();
+
+ node = m_headers.Find(upper_header);
if (!node)
return wxEmptyString;
wxString left_str = tokenzr.GetNextToken();
wxString *str = new wxString(tokenzr.GetNextToken());
+ left_str.MakeUpper();
+
m_headers.Append(left_str, (wxObject *) str);
}
return TRUE;
{
wxIPV4address *addr;
- if (m_connected) {
+ if (m_addr) {
delete m_addr;
m_addr = NULL;
Close();
{
wxChar *tmp_buf;
wxChar buf[200]; // 200 is arbitrary.
- wxString tmp_str;
+ wxString tmp_str = path;
switch (req) {
case wxHTTP_GET:
SetFlags(NONE);
Notify(FALSE);
- tmp_str = wxURL::ConvertToValidURI(path);
wxSprintf(buf, _T("%s %s HTTP/1.0\n\r"), tmp_buf, tmp_str.GetData());
const wxWX2MBbuf pathbuf = wxConvLibc.cWX2MB(buf);
Write(pathbuf, strlen(MBSTRINGCAST pathbuf));
unsigned long m_read_bytes;
wxHTTPStream(wxHTTP *http) : wxSocketInputStream(*http), m_http(http) {}
- size_t StreamSize() const { return m_httpsize; }
+ size_t GetSize() const { return m_httpsize; }
virtual ~wxHTTPStream(void) { m_http->Abort(); }
protected:
bool wxHTTP::Abort(void)
{
- return wxSocketClient::Close();
+ bool ret, connected;
+
+ ret = wxSocketClient::Close();
+
+ return ret;
}
wxInputStream *wxHTTP::GetInputStream(const wxString& path)
{
wxHTTPStream *inp_stream = new wxHTTPStream(this);
+ wxString new_path;
- if (!m_addr || m_connected) {
- m_perr = wxPROTO_CONNERR;
+ m_perr = wxPROTO_CONNERR;
+ if (!m_addr)
return NULL;
- }
+ // We set m_connected back to FALSE so wxSocketBase will know what to do.
if (!wxProtocol::Connect(*m_addr))
return NULL;
inp_stream->m_read_bytes = 0;
Notify(FALSE);
+ SetFlags(SPEED | WAITALL);
return inp_stream;
}
#include "wx/url.h"
#include "wx/module.h"
+#include <stdlib.h>
+
/////////////////////////////////////////////////////////////////
// wxProtoInfo
/////////////////////////////////////////////////////////////////
bool wxProtocolModule::OnInit()
{
- wxURL::g_proxy = new wxHTTP();
+ char *env_http_prox;
+
+ wxURL::g_proxy = NULL;
+ // Initialize the proxy when HTTP_PROXY is defined
+ env_http_prox = getenv("HTTP_PROXY");
+ if (env_http_prox)
+ wxURL::SetDefaultProxy(env_http_prox);
+
return TRUE;
}
void wxProtocolModule::OnExit()
{
- delete wxURL::g_proxy;
+ if (wxURL::g_proxy)
+ delete wxURL::g_proxy;
wxURL::g_proxy = NULL;
}
#include <wx/defs.h>
#include <wx/object.h>
+#include <wx/log.h>
#include <wx/gsocket.h>
#include <wx/sckaddr.h>
bool wxIPV4address::Hostname(const wxString& name)
{
+ // Some people are sometimes fool.
+ if (name == _T("")) {
+ wxLogWarning( _T("Trying to solve a NULL hostname: giving up") );
+ return FALSE;
+ }
+
return (GAddress_INET_SetHostName(m_address, name.fn_str()) == GSOCK_NOERROR);
}
// Update the flags of m_socket.
SetFlags(m_flags);
GSocket_SetPeer(m_socket, addr_man.GetAddress());
- if (GSocket_Connect(m_socket, GSOCK_STREAMED) != GSOCK_NOERROR) {
+ if (GSocket_Connect(m_socket, GSOCK_STREAMED) != GSOCK_NOERROR)
return FALSE;
- }
// Enables bg events.
// ------------------
#if wxUSE_SOCKETS
-#ifndef WX_PRECOMP
-#endif
-
#include <string.h>
#include <ctype.h>
-// wxWindows headers
#include <wx/string.h>
#include <wx/list.h>
#include <wx/utils.h>
-
-// wxSocket header
-#include "wx/url.h"
+#include <wx/url.h>
#if !USE_SHARED_LIBRARY
IMPLEMENT_CLASS(wxProtoInfo, wxObject)
// Protocols list
wxProtoInfo *wxURL::g_protocols = NULL;
-wxHTTP *wxURL::g_proxy;
+wxHTTP *wxURL::g_proxy = NULL;
// --------------------------------------------------------------
// wxURL
wxURL::wxURL(const wxString& url)
{
m_protocol = NULL;
- if (g_proxy->IsConnected()) {
- m_protocol = g_proxy;
- m_protoname = "proxy";
- m_path = url;
- return;
- }
- m_url = url;
m_error = wxURL_NOERR;
+ m_url = url;
+ m_useProxy = (g_proxy != NULL);
+ m_proxy = g_proxy;
ParseURL();
}
{
wxString last_url = m_url;
- // Clean up
- CleanData();
-
- // Extract protocol name
- if (!PrepProto(last_url)) {
- m_error = wxURL_SNTXERR;
- return FALSE;
- }
+ // If the URL was already parsed (so m_protocol != NULL), we pass this section.
+ if (!m_protocol) {
- // Find and create the protocol object
- if (!FetchProtocol()) {
- m_error = wxURL_NOPROTO;
- return FALSE;
- }
+ // Clean up
+ CleanData();
- // Do we need a host name ?
- if (m_protoinfo->m_needhost) {
- // Extract it
- if (!PrepHost(last_url)) {
+ // Extract protocol name
+ if (!PrepProto(last_url)) {
m_error = wxURL_SNTXERR;
return FALSE;
}
+
+ // Find and create the protocol object
+ if (!FetchProtocol()) {
+ m_error = wxURL_NOPROTO;
+ return FALSE;
+ }
+
+ // Do we need a host name ?
+ if (m_protoinfo->m_needhost) {
+ // Extract it
+ if (!PrepHost(last_url)) {
+ m_error = wxURL_SNTXERR;
+ return FALSE;
+ }
+ }
+
+ // Extract full path
+ if (!PrepPath(last_url)) {
+ m_error = wxURL_NOPATH;
+ return FALSE;
+ }
}
+ // URL parse finished.
- // Extract full path
- if (!PrepPath(last_url)) {
- m_error = wxURL_NOPATH;
- return FALSE;
+ if (m_useProxy) {
+ // We destroy the newly created protocol.
+ CleanData();
+
+ // Third, we rebuild the URL.
+ m_url = m_protoname + _T(":");
+ if (m_protoinfo->m_needhost)
+ m_url = m_url + _T("//") + m_hostname;
+
+ m_url += m_path;
+
+ // We initialize specific variables.
+ m_protocol = m_proxy; // FIXME: we should clone the protocol
}
m_error = wxURL_NOERR;
void wxURL::CleanData()
{
- if (m_protoname != _T("proxy"))
+ if (!m_useProxy)
delete m_protocol;
}
wxURL::~wxURL()
{
CleanData();
+ if (m_proxy && m_proxy != g_proxy)
+ delete m_proxy;
}
// --------------------------------------------------------------
int pos;
// Find end
- pos = url.Find(':');
+ pos = url.Find(_T(':'));
if (pos == -1)
return FALSE;
url = url(2, url.Length());
- pos = url.Find('/');
+ pos = url.Find(_T('/'));
if (pos == -1)
pos = url.Length();
return FALSE;
temp_url = url(0, pos);
- url = url(url.Find('/'), url.Length());
+ url = url(url.Find(_T('/')), url.Length());
// Retrieve service number
- pos2 = temp_url.Find(':', TRUE);
+ pos2 = temp_url.Find(_T(':'), TRUE);
if (pos2 != -1 && pos2 < pos) {
m_servname = temp_url(pos2+1, pos);
if (!m_servname.IsNumber())
}
// Retrieve user and password.
- pos2 = temp_url.Find('@');
+ pos2 = temp_url.Find(_T('@'));
// Even if pos2 equals -1, this code is right.
m_hostname = temp_url(pos2+1, temp_url.Length());
- m_user = "";
- m_password = "";
+ m_user = _T("");
+ m_password = _T("");
if (pos2 == -1)
return TRUE;
temp_url = temp_url(0, pos2);
- pos2 = temp_url.Find(':');
+ pos2 = temp_url.Find(_T(':'));
if (pos2 == -1)
return FALSE;
bool wxURL::PrepPath(wxString& url)
{
if (url.Length() != 0)
- m_path = url;
+ m_path = ConvertToValidURI(url);
else
- m_path = "/";
+ m_path = _T("/");
return TRUE;
}
wxIPV4address addr;
wxInputStream *the_i_stream = NULL;
- if (!m_protocol)
- if (!ParseURL())
- return NULL;
-
if (!m_protocol) {
m_error = wxURL_NOPROTO;
return NULL;
m_protocol->SetPassword(m_password);
}
- if (m_protoinfo->m_needhost) {
+ // m_protoinfo is NULL when we use a proxy
+ if (!m_useProxy && m_protoinfo->m_needhost) {
if (!addr.Hostname(m_hostname)) {
m_error = wxURL_NOHOST;
return NULL;
}
}
- the_i_stream = m_protocol->GetInputStream(m_path);
+ // When we use a proxy, we have to pass the whole URL to it.
+ if (m_useProxy)
+ the_i_stream = m_protocol->GetInputStream(m_url);
+ else
+ the_i_stream = m_protocol->GetInputStream(m_path);
+
if (!the_i_stream) {
m_error = wxURL_PROTOERR;
return NULL;
void wxURL::SetDefaultProxy(const wxString& url_proxy)
{
- g_proxy->Close();
-
- if (url_proxy.IsNull())
+ if (url_proxy.IsNull()) {
+ g_proxy->Close();
+ delete g_proxy;
+ g_proxy = NULL;
return;
+ }
wxString tmp_str = url_proxy;
- int pos = tmp_str.Find(':');
+ int pos = tmp_str.Find(_T(':'));
+ if (pos == -1)
+ return;
+
wxString hostname = tmp_str(0, pos),
- port = tmp_str(pos, tmp_str.Length()-pos);
+ port = tmp_str(pos+1, tmp_str.Length()-pos);
wxIPV4address addr;
- addr.Hostname(hostname);
- addr.Service(port);
-
+ if (!addr.Hostname(hostname))
+ return;
+ if (!addr.Service(port))
+ return;
+
+ if (g_proxy)
+ // Finally, when all is right, we connect the new proxy.
+ g_proxy->Close();
+ else
+ g_proxy = new wxHTTP();
g_proxy->Connect(addr, TRUE); // Watcom needs the 2nd arg for some reason
}
void wxURL::SetProxy(const wxString& url_proxy)
{
if (url_proxy.IsNull()) {
- m_proxy.Close();
+ if (m_proxy) {
+ m_proxy->Close();
+ delete m_proxy;
+ }
+ m_useProxy = FALSE;
return;
}
- CleanData();
-
wxString tmp_str;
wxString hostname, port;
int pos;
wxIPV4address addr;
tmp_str = url_proxy;
- pos = tmp_str.Find(':');
+ pos = tmp_str.Find(_T(':'));
+ // This is an invalid proxy name.
+ if (pos == -1)
+ return;
+
hostname = tmp_str(0, pos);
port = tmp_str(pos, tmp_str.Length()-pos);
addr.Hostname(hostname);
addr.Service(port);
- m_proxy.Connect(addr, TRUE); // Watcom needs the 2nd arg for some reason
+ // Finally, create the whole stuff.
+ if (m_proxy && m_proxy != g_proxy)
+ delete m_proxy;
+ m_proxy = new wxHTTP();
+ m_proxy->Connect(addr, TRUE); // Watcom needs the 2nd arg for some reason
- m_protocol = &m_proxy;
- m_protoname = "proxy";
- m_path = url_proxy;
+ CleanData();
+ // Reparse url.
+ m_useProxy = TRUE;
+ ParseURL();
}
wxString wxURL::ConvertToValidURI(const wxString& uri)
if (c == _T(' '))
out_str += _T('+');
else {
- if (!isalpha(c) && c != _T('.') && c != _T('+') && c != _T('.') &&
- c != _T('/')) {
+ if (!isalpha(c) && c != _T('.') && c != _T('+') && c != _T('/')) {
hexa_code.Printf(_T("%%%02X"), c);
out_str += hexa_code;
} else
bool wxHtmlFilterHTML::CanRead(const wxFSFile& file) const
{
- return (file.GetMimeType() == "text/html");
+// return (file.GetMimeType() == "text/html");
+// This is true in most case but some page can return:
+// "text/html; char-encoding=...."
+// So we use Find instead
+ return (file.GetMimeType().Find(_T("text/html")) == 0);
}
SetBackgroundColour(wxColour(0xFF, 0xFF, 0xFF));
m_OpenedPage = m_OpenedAnchor = wxEmptyString;
m_Parser -> SetDC(dc);
- if (m_Cell) delete m_Cell;
+ if (m_Cell) {
+ delete m_Cell;
+ m_Cell = NULL;
+ }
m_Cell = (wxHtmlContainerCell*) m_Parser -> Parse(source);
delete dc;
m_Cell -> SetIndent(m_Borders, HTML_INDENT_ALL, HTML_UNITS_PIXELS);
#include <stdlib.h>
#ifdef sun
- #include <sys/filio.h>
+# include <sys/filio.h>
#endif
#ifdef sgi
- #include <bstring.h>
+# include <bstring.h>
#endif
#include <signal.h>
return GSOCK_INVADDR;
}
- if (sck->m_stream)
- type = SOCK_STREAM;
- else
- type = SOCK_DGRAM;
+ /* We always have a stream here */
+ sck->m_stream = TRUE;
- sck->m_fd = socket(sck->m_local->m_realfamily, type, 0);
+ /* Create the socket */
+ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
if (sck->m_fd == -1) {
sck->m_error = GSOCK_IOERR;
return GSOCK_IOERR;
}
+ /* Bind the socket to the LOCAL address */
if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
close(sck->m_fd);
sck->m_fd = -1;
return GSOCK_IOERR;
}
+ /* Enable listening up to 5 connections */
if (listen(sck->m_fd, 5) < 0) {
close(sck->m_fd);
sck->m_fd = -1;
return GSOCK_IOERR;
}
- sck->m_server = TRUE;
-
return GSOCK_NOERROR;
-
}
/*
assert(socket != NULL);
+ /* If the socket has already been created, we exit immediately */
if (socket->m_fd == -1 || !socket->m_server) {
socket->m_error = GSOCK_INVSOCK;
return NULL;
}
+ /* Reenable GSOCK_CONNECTION event */
_GSocket_Enable(socket, GSOCK_CONNECTION);
+ /* Create a GSocket object for the new connection */
connection = GSocket_new();
+ /* Accept the incoming connection */
connection->m_fd = accept(socket->m_fd, NULL, NULL);
if (connection->m_fd == -1) {
GSocket_destroy(connection);
return NULL;
}
+ /* Initialize all fields */
connection->m_stream = TRUE;
connection->m_server = FALSE;
connection->m_oriented = TRUE;
sck->m_server = FALSE;
sck->m_oriented = FALSE;
+ /* Create the socket */
sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
+ /* Bind it to the LOCAL address */
if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
close(sck->m_fd);
sck->m_fd = -1;
return GSOCK_INVADDR;
}
+ /* Test whether we want the socket to be a stream (e.g. TCP) */
sck->m_stream = (stream == GSOCK_STREAMED);
sck->m_oriented = TRUE;
else
type = SOCK_DGRAM;
+ /* Create the socket */
sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
if (sck->m_fd == -1) {
return GSOCK_IOERR;
}
+ /* Connect it to the PEER address */
if (connect(sck->m_fd, sck->m_peer->m_addr,
sck->m_peer->m_len) != 0) {
close(sck->m_fd);
return GSOCK_IOERR;
}
+ /* It is not a server */
sck->m_server = FALSE;
return GSOCK_NOERROR;
return -1;
}
+ /* Reenable GSOCK_INPUT event */
_GSocket_Enable(socket, GSOCK_INPUT);
- if (socket->m_oriented)
+ if (socket->m_stream)
return _GSocket_Recv_Stream(socket, buffer, size);
else
return _GSocket_Recv_Dgram(socket, buffer, size);
_GSocket_Enable(socket, GSOCK_OUTPUT);
- if (socket->m_oriented)
+ if (socket->m_stream)
return _GSocket_Send_Stream(socket, buffer, size);
else
return _GSocket_Send_Dgram(socket, buffer, size);
assert (socket != NULL);
for (count=0;count<GSOCK_MAX_EVENT;count++) {
+ /* We test each flag and, if it is enabled, we enable the corresponding
+ event */
if ((event & (1 << count)) != 0) {
socket->m_fbacks[count] = fallback;
socket->m_data[count] = cdata;
return -1;
}
+ /* Translate a system address into a GSocket address */
if (!socket->m_peer)
socket->m_peer = GAddress_new();
_GAddress_translate_from(socket->m_peer, &from, fromlen);
return -1;
}
+ /* Frees memory allocated from _GAddress_translate_to */
free(addr);
return ret;
* -------------------------------------------------------------------------
*/
+/* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
+ * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
+ * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
+ */
#define CHECK_ADDRESS(address, family, retval) \
{ \
if (address->m_family == GSOCK_NOFAMILY) \
addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
- /* only name for the moment */
+ /* If it is a numeric host name, convert it now */
if (inet_aton(hostname, addr) == 0) {
struct in_addr *array_addr;
+ /* It is a real name, we solve it */
if ((he = gethostbyname(hostname)) == NULL) {
address->m_error = GSOCK_NOHOST;
return GSOCK_NOHOST;
return GSOCK_INVOP;
}
- /* TODO: TCP or UDP */
se = getservbyname(port, protocol);
if (!se) {
if (isdigit(port[0])) {