swext/Extension_wiki-publisher.mk | 15 swext/Jar_mediawiki.mk | 7 swext/mediawiki/src/com/sun/star/wiki/Helper.java | 234 +++++----- swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java | 109 ++-- swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java | 31 - swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java | 215 ++++++++- swext/mediawiki/src/description.xml | 2 7 files changed, 382 insertions(+), 231 deletions(-)
New commits: commit 18b934af9979522c8cff1ff76504ce19c3e6916d Author: Michael Stahl <[email protected]> Date: Thu Oct 8 23:26:39 2015 +0200 swext: increment the extension version number to 1.2.0 ... and also set the User-Agent header so the servers know who's messing with them. Change-Id: I0173db05868c5fcd0f85435adf78884ca562596d diff --git a/swext/mediawiki/src/com/sun/star/wiki/Helper.java b/swext/mediawiki/src/com/sun/star/wiki/Helper.java index b40b5f1..8a15621 100644 --- a/swext/mediawiki/src/com/sun/star/wiki/Helper.java +++ b/swext/mediawiki/src/com/sun/star/wiki/Helper.java @@ -643,6 +643,8 @@ public class Helper // ((HttpsURLConnection) conn).setSSLSocketFactory(new LoggingProtocolSocketFactory()); conn.setRequestMethod(method); + // TODO: is it possible to read the version from the extension metadata? + conn.setRequestProperty("User-Agent", "LibreOffice Wiki Publisher 1.2.0"); // note: don't connect yet so that the caller can do some further setup return conn; diff --git a/swext/mediawiki/src/description.xml b/swext/mediawiki/src/description.xml index 1e637bd..e83d4f3 100644 --- a/swext/mediawiki/src/description.xml +++ b/swext/mediawiki/src/description.xml @@ -17,7 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . --> <description xmlns="http://openoffice.org/extensions/description/2006" xmlns:d="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink"> - <version value="1.1.2"/> + <version value="1.2.0"/> <identifier value="com.sun.wiki-publisher"/> <display-name> <name lang="en-US">Wiki Publisher</name> commit 2ccef1c93d4c1a478fbdd8a49caf0735f68ba141 Author: Michael Stahl <[email protected]> Date: Thu Oct 8 21:51:40 2015 +0200 swext: add a logging out stream to help debugging TLS connections Change-Id: Idbabae3edad5e95a37fa9834d24a72ebd13087ae diff --git a/swext/mediawiki/src/com/sun/star/wiki/Helper.java b/swext/mediawiki/src/com/sun/star/wiki/Helper.java index f5e5c48..b40b5f1 100644 --- a/swext/mediawiki/src/com/sun/star/wiki/Helper.java +++ b/swext/mediawiki/src/com/sun/star/wiki/Helper.java @@ -639,6 +639,9 @@ public class Helper ((HttpsURLConnection) conn).setSSLSocketFactory(new WikiProtocolSocketFactory()); } +// enable this to help debug connections where TLS gets in the way +// ((HttpsURLConnection) conn).setSSLSocketFactory(new LoggingProtocolSocketFactory()); + conn.setRequestMethod(method); // note: don't connect yet so that the caller can do some further setup diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java b/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java index 5d7efe1..3d2d22da 100644 --- a/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java @@ -25,6 +25,7 @@ import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyStore; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; @@ -167,3 +168,166 @@ class WikiProtocolSocketFactory extends SSLSocketFactory } } +// A factory that creates streams that log everything that's written +// to stderr - useful for debugging encrypted TLS connections +class LoggingProtocolSocketFactory extends SSLSocketFactory +{ + private SSLContext m_aSSLContext; + + private static class LogSocket extends SSLSocket + { + private SSLSocket m_Socket; + + public LogSocket(Socket socket) + { + m_Socket = (SSLSocket) socket; + } + + private static class LogStream extends java.io.FilterOutputStream + { + public LogStream(java.io.OutputStream stream) + { + super(stream); + } + + @Override + public void write(byte[] buf, int offset, int len) + throws IOException + { + System.err.println("LogStream.write: \"" + new String(buf, offset, len, "UTF-8") + "\""); + out.write(buf, offset, len); + } + } + + @Override + public java.io.OutputStream getOutputStream() throws IOException + { + return new LogStream(m_Socket.getOutputStream()); + } + + @Override public void addHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener listener) { m_Socket.addHandshakeCompletedListener(listener); } + @Override public String[] getEnabledCipherSuites() { return m_Socket.getEnabledCipherSuites(); } + @Override public String[] getEnabledProtocols() { return m_Socket.getEnabledProtocols(); } + @Override public boolean getEnableSessionCreation() { return m_Socket.getEnableSessionCreation(); } + @Override public boolean getNeedClientAuth() { return m_Socket.getNeedClientAuth(); } + @Override public javax.net.ssl.SSLSession getSession() { return m_Socket.getSession(); } + @Override public javax.net.ssl.SSLParameters getSSLParameters() { return m_Socket.getSSLParameters(); } + @Override public String[] getSupportedCipherSuites() { return m_Socket.getSupportedCipherSuites(); } + @Override public String[] getSupportedProtocols() { return m_Socket.getSupportedProtocols(); } + @Override public boolean getUseClientMode() { return m_Socket.getUseClientMode(); } + @Override public boolean getWantClientAuth() { return m_Socket.getWantClientAuth(); } + @Override public void removeHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener listener) { m_Socket.removeHandshakeCompletedListener(listener); } + @Override public void setEnabledCipherSuites(String[] suites) { m_Socket.setEnabledCipherSuites(suites); } + @Override public void setEnabledProtocols(String[] protocols) { m_Socket.setEnabledProtocols(protocols); } + @Override public void setEnableSessionCreation(boolean flag) { m_Socket.setEnableSessionCreation(flag); } + @Override public void setNeedClientAuth(boolean need) { m_Socket.setNeedClientAuth(need); } + @Override public void setSSLParameters(javax.net.ssl.SSLParameters params) { m_Socket.setSSLParameters(params); } + @Override public void setUseClientMode(boolean mode) { m_Socket.setUseClientMode(mode); } + @Override public void setWantClientAuth(boolean want) { m_Socket.setWantClientAuth(want); } + @Override public void startHandshake() throws IOException { m_Socket.startHandshake(); } + + @Override public void bind(java.net.SocketAddress bindpoint) throws IOException { m_Socket.bind(bindpoint); } + @Override public void close() throws IOException { m_Socket.close(); } + @Override public void connect(java.net.SocketAddress endpoint) throws IOException { m_Socket.connect(endpoint); } + @Override public void connect(java.net.SocketAddress endpoint, int timeout) throws IOException { m_Socket.connect(endpoint, timeout); } + @Override public java.nio.channels.SocketChannel getChannel() { return m_Socket.getChannel(); } + @Override public InetAddress getInetAddress() { return m_Socket.getInetAddress(); } + @Override public java.io.InputStream getInputStream() throws IOException { return m_Socket.getInputStream(); } + @Override public boolean getKeepAlive() throws java.net.SocketException { return m_Socket.getKeepAlive(); } + @Override public InetAddress getLocalAddress() { return m_Socket.getLocalAddress(); } + @Override public int getLocalPort() { return m_Socket.getLocalPort(); } + @Override public java.net.SocketAddress getLocalSocketAddress() { return m_Socket.getLocalSocketAddress(); } + @Override public boolean getOOBInline() throws java.net.SocketException { return m_Socket.getOOBInline(); } + @Override public int getPort() { return m_Socket.getPort(); } + @Override public int getReceiveBufferSize() throws java.net.SocketException { return m_Socket.getReceiveBufferSize(); } + @Override public java.net.SocketAddress getRemoteSocketAddress() { return m_Socket.getRemoteSocketAddress(); } + @Override public boolean getReuseAddress() throws java.net.SocketException { return m_Socket.getReuseAddress(); } + @Override public int getSendBufferSize() throws java.net.SocketException { return m_Socket.getSendBufferSize(); } + @Override public int getSoLinger() throws java.net.SocketException { return m_Socket.getSoLinger(); } + @Override public int getSoTimeout() throws java.net.SocketException { return m_Socket.getSoTimeout(); } + @Override public boolean getTcpNoDelay() throws java.net.SocketException { return m_Socket.getTcpNoDelay(); } + @Override public int getTrafficClass() throws java.net.SocketException { return m_Socket.getTrafficClass(); } + @Override public boolean isBound() { return m_Socket.isBound(); } + @Override public boolean isClosed() { return m_Socket.isClosed(); } + @Override public boolean isConnected() { return m_Socket.isConnected(); } + @Override public boolean isInputShutdown() { return m_Socket.isInputShutdown(); } + @Override public boolean isOutputShutdown() { return m_Socket.isOutputShutdown(); } + @Override public void sendUrgentData(int data) throws IOException { m_Socket.sendUrgentData(data); } + @Override public void setKeepAlive(boolean on) throws java.net.SocketException { m_Socket.setKeepAlive(on); } + @Override public void setOOBInline(boolean on) throws java.net.SocketException { m_Socket.setOOBInline(on); } + @Override public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { m_Socket.setPerformancePreferences(connectionTime, latency, bandwidth); } + @Override public void setReceiveBufferSize(int size) throws java.net.SocketException { m_Socket.setReceiveBufferSize(size); } + @Override public void setReuseAddress(boolean on) throws java.net.SocketException { m_Socket.setReuseAddress(on); } + @Override public void setSendBufferSize(int size) throws java.net.SocketException { m_Socket.setSendBufferSize(size); } + @Override public void setSoLinger(boolean on, int linger) throws java.net.SocketException { m_Socket.setSoLinger(on, linger); } + @Override public void setSoTimeout(int timeout) throws java.net.SocketException{ m_Socket.setSoTimeout(timeout); } + @Override public void setTcpNoDelay(boolean on) throws java.net.SocketException{ m_Socket.setTcpNoDelay(on); } + @Override public void setTrafficClass(int tc) throws java.net.SocketException { m_Socket.setTrafficClass(tc); } + @Override public void shutdownInput() throws IOException { m_Socket.shutdownInput(); } + @Override public void shutdownOutput() throws IOException { m_Socket.shutdownOutput(); } + @Override public String toString() { return m_Socket.toString(); } + + } + + @Override + public Socket createSocket(InetAddress address, int port) + throws IOException + { + return new LogSocket(((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(address, port)); + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) + throws IOException + { + return new LogSocket(((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(address, port, localAddress, localPort)); + } + + @Override + public Socket createSocket( String sHost, int nPort, InetAddress clientHost, int clientPort ) + throws IOException, UnknownHostException + { + return new LogSocket(((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(sHost, nPort, clientHost, clientPort)); + } + + @Override + public Socket createSocket( String sHost, int nPort ) + throws IOException, UnknownHostException + { + return new LogSocket(((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(sHost, nPort)); + } + + @Override + public Socket createSocket( Socket aSocket, String sHost, int nPort, boolean bAutoClose ) + throws IOException + { + return new LogSocket(((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(aSocket, sHost, nPort, bAutoClose)); + } + + @Override + public String[] getDefaultCipherSuites() + { + // have to implement abstract method, just use the default + return ((SSLSocketFactory) SSLSocketFactory.getDefault()).getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() + { + // have to implement abstract method, just use the default + return ((SSLSocketFactory) SSLSocketFactory.getDefault()).getSupportedCipherSuites(); + } + + @Override + public boolean equals(Object obj) + { + return ((obj != null) && obj.getClass().equals(LoggingProtocolSocketFactory.class)); + } + + @Override + public int hashCode() + { + return LoggingProtocolSocketFactory.class.hashCode(); + } +} + commit 4b6ceed4a4a9b152905a8b1712ffb9bd61373c16 Author: Michael Stahl <[email protected]> Date: Wed Oct 7 18:25:57 2015 +0200 swext: Wiki Publisher does not use those apache-commons libraries ... itself, they were apparently just dependencies of commons-httpclient, so remove them. Change-Id: I8fd5c85db058c4aa14c4f5fea20fd17ba361b0b2 diff --git a/swext/Extension_wiki-publisher.mk b/swext/Extension_wiki-publisher.mk index 94ea40b..ec31c96 100644 --- a/swext/Extension_wiki-publisher.mk +++ b/swext/Extension_wiki-publisher.mk @@ -16,19 +16,6 @@ $(eval $(call gb_Extension_use_unpacked,wiki-publisher,xsltml)) $(eval $(call gb_Extension_use_default_description,wiki-publisher,swext/mediawiki/src/description-en-US.txt)) $(eval $(call gb_Extension_use_default_license,wiki-publisher)) -ifeq ($(SYSTEM_APACHE_COMMONS),) -$(eval $(call gb_Extension_use_external_project,wiki-publisher,apache_commons_logging)) -$(eval $(call gb_Extension_use_external_project,wiki-publisher,apache_commons_codec)) -$(eval $(call gb_Extension_use_external_project,wiki-publisher,apache_commons_lang)) - -$(eval $(call gb_Extension_add_file,wiki-publisher,$(if $(filter TRUE,$(HAVE_JAVA6)),commons-codec-1.9.jar,commons-codec-1.6.jar),\ -$(call gb_UnpackedTarball_get_dir,apache_commons_codec)$(if $(filter TRUE,$(HAVE_JAVA6)),/dist/commons-codec-1.9.jar,/dist/commons-codec-1.6-SNAPSHOT.jar)\ -)) -$(eval $(call gb_Extension_add_file,wiki-publisher,$(if $(filter TRUE,$(HAVE_JAVA6)),commons-lang3-3.3.1.jar,commons-lang-2.4.jar),\ -$(call gb_UnpackedTarball_get_dir,apache_commons_lang)$(if $(filter TRUE,$(HAVE_JAVA6)),/target/commons-lang3-3.3.1.jar,/dist/commons-lang-2.4.jar)\ -)) -$(eval $(call gb_Extension_add_file,wiki-publisher,commons-logging-$(COMMONS_LOGGING_VERSION).jar,$(call gb_UnpackedTarball_get_dir,apache_commons_logging)/target/commons-logging-$(COMMONS_LOGGING_VERSION).jar)) -endif $(eval $(call gb_Extension_add_file,wiki-publisher,Addons.xcu,$(call gb_XcuFile_for_extension,swext/mediawiki/src/registry/data/org/openoffice/Office/Addons.xcu))) $(eval $(call gb_Extension_add_file,wiki-publisher,Filter.xcu,$(SRCDIR)/swext/mediawiki/src/registry/data/org/openoffice/TypeDetection/Filter.xcu)) $(eval $(call gb_Extension_add_file,wiki-publisher,OptionsDialog.xcu,$(call gb_XcuFile_for_extension,swext/mediawiki/src/registry/data/org/openoffice/Office/OptionsDialog.xcu))) diff --git a/swext/Jar_mediawiki.mk b/swext/Jar_mediawiki.mk index 49f0a8b..2341580 100644 --- a/swext/Jar_mediawiki.mk +++ b/swext/Jar_mediawiki.mk @@ -14,12 +14,6 @@ $(eval $(call gb_Jar_set_packageroot,mediawiki,com)) $(eval $(call gb_Jar_set_manifest,mediawiki,$(SRCDIR)/swext/mediawiki/src/com/sun/star/wiki/MANIFEST.MF)) -$(eval $(call gb_Jar_use_externals,mediawiki,\ - commons-codec \ - commons-lang \ - commons-logging \ -)) - $(eval $(call gb_Jar_use_jars,mediawiki,\ juh \ jurt \ commit f7d149a731a0284d3d7b7b1c26c736654e0712fd Author: Michael Stahl <[email protected]> Date: Wed Oct 7 17:40:29 2015 +0200 swext: remove commons-httpclient dependency from Wiki Publisher JRE 6 has sufficient HttpURLConnection etc. stuff to make this work without bundling external libraries. Change-Id: I6c71980c718169024006f02a96c442a71d798d55 diff --git a/swext/Extension_wiki-publisher.mk b/swext/Extension_wiki-publisher.mk index ffee9ac..94ea40b 100644 --- a/swext/Extension_wiki-publisher.mk +++ b/swext/Extension_wiki-publisher.mk @@ -19,13 +19,11 @@ $(eval $(call gb_Extension_use_default_license,wiki-publisher)) ifeq ($(SYSTEM_APACHE_COMMONS),) $(eval $(call gb_Extension_use_external_project,wiki-publisher,apache_commons_logging)) $(eval $(call gb_Extension_use_external_project,wiki-publisher,apache_commons_codec)) -$(eval $(call gb_Extension_use_external_project,wiki-publisher,apache_commons_httpclient)) $(eval $(call gb_Extension_use_external_project,wiki-publisher,apache_commons_lang)) $(eval $(call gb_Extension_add_file,wiki-publisher,$(if $(filter TRUE,$(HAVE_JAVA6)),commons-codec-1.9.jar,commons-codec-1.6.jar),\ $(call gb_UnpackedTarball_get_dir,apache_commons_codec)$(if $(filter TRUE,$(HAVE_JAVA6)),/dist/commons-codec-1.9.jar,/dist/commons-codec-1.6-SNAPSHOT.jar)\ )) -$(eval $(call gb_Extension_add_file,wiki-publisher,commons-httpclient-3.1.jar,$(call gb_UnpackedTarball_get_dir,apache_commons_httpclient)/dist/commons-httpclient.jar)) $(eval $(call gb_Extension_add_file,wiki-publisher,$(if $(filter TRUE,$(HAVE_JAVA6)),commons-lang3-3.3.1.jar,commons-lang-2.4.jar),\ $(call gb_UnpackedTarball_get_dir,apache_commons_lang)$(if $(filter TRUE,$(HAVE_JAVA6)),/target/commons-lang3-3.3.1.jar,/dist/commons-lang-2.4.jar)\ )) diff --git a/swext/Jar_mediawiki.mk b/swext/Jar_mediawiki.mk index 2c6bc3f..49f0a8b 100644 --- a/swext/Jar_mediawiki.mk +++ b/swext/Jar_mediawiki.mk @@ -17,7 +17,6 @@ $(eval $(call gb_Jar_set_manifest,mediawiki,$(SRCDIR)/swext/mediawiki/src/com/su $(eval $(call gb_Jar_use_externals,mediawiki,\ commons-codec \ commons-lang \ - commons-httpclient \ commons-logging \ )) diff --git a/swext/mediawiki/src/com/sun/star/wiki/Helper.java b/swext/mediawiki/src/com/sun/star/wiki/Helper.java index 50750de..f5e5c48 100644 --- a/swext/mediawiki/src/com/sun/star/wiki/Helper.java +++ b/swext/mediawiki/src/com/sun/star/wiki/Helper.java @@ -53,18 +53,10 @@ import com.sun.star.uno.XComponentContext; import com.sun.star.util.XChangesBatch; import java.net.*; import java.io.*; +import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLException; import javax.swing.text.html.HTMLEditorKit; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HostConfiguration; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.cookie.CookiePolicy; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; -import org.apache.commons.httpclient.protocol.Protocol; -import org.apache.commons.httpclient.URI; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.httpclient.methods.PostMethod; public class Helper { @@ -142,8 +134,6 @@ public class Helper private static String[] m_pConfigStrings; - private static MultiThreadedHttpConnectionManager m_aConnectionManager; - private static HttpClient m_aClient; private static boolean m_bAllowConnection = true; private static Boolean m_bShowInBrowser = null; @@ -174,35 +164,11 @@ public class Helper return m_pConfigStrings[nID]; } - synchronized private static HttpClient GetHttpClient() - throws WikiCancelException - { - if ( !m_bAllowConnection ) - throw new WikiCancelException(); - - if ( m_aConnectionManager == null ) - m_aConnectionManager = new MultiThreadedHttpConnectionManager(); - - if ( m_aClient == null ) - { - m_aClient = new HttpClient( m_aConnectionManager ); - m_aClient.getParams().setParameter( "http.protocol.cookie-policy", CookiePolicy.BROWSER_COMPATIBILITY ); - m_aClient.getParams().setParameter( "http.protocol.single-cookie-header", Boolean.TRUE ); - m_aClient.getParams().setParameter( "http.protocol.content-charset", "UTF-8" ); - } - - return m_aClient; - } - synchronized protected static void AllowConnection( boolean bAllow ) { m_bAllowConnection = bAllow; - if ( !bAllow && m_aConnectionManager != null ) - { - m_aClient = null; - m_aConnectionManager.shutdown(); - m_aConnectionManager = null; - } + // TODO: how to shut down any pending connections? + // hope it doesn't matter? } synchronized protected static boolean IsConnectionAllowed() @@ -282,11 +248,6 @@ public class Helper return m_xInteractionHandler; } - private static Protocol GetOwnHttps( int nPort ) - { - return new Protocol( "https", new WikiProtocolSocketFactory(), ( ( nPort < 0 ) ? 443 : nPort ) ); - } - protected static String GetMainURL( String sWebPage, String sVURL ) { String sResultURL = ""; @@ -366,9 +327,6 @@ public class Helper } - - - protected static String CreateTempFile( XComponentContext xContext ) { String sURL = ""; @@ -579,30 +537,30 @@ public class Helper return xNameAccess; } - private static void SetConfigurationProxy( HostConfiguration aHostConfig, XComponentContext xContext ) + private static Proxy GetConfigurationProxy(URI uri, XComponentContext xContext) { - if ( aHostConfig == null || xContext == null ) - return; + assert(uri != null); + assert(xContext != null); try { XNameAccess xNameAccess = GetConfigNameAccess( xContext, "org.openoffice.Inet/Settings" ); int nProxyType = AnyConverter.toInt( xNameAccess.getByName( "ooInetProxyType" ) ); - if ( nProxyType == 0 ) - aHostConfig.setProxyHost( null ); - else - { + if ( nProxyType == 0 ) { + return Proxy.NO_PROXY; + } else { if ( nProxyType == 1 ) { // system proxy + return null; } else if ( nProxyType == 2 ) { String aProxyNameProp = "ooInetHTTPProxyName"; String aProxyPortProp = "ooInetHTTPProxyPort"; - if ( aHostConfig.getProtocol().getScheme().equals( "https" ) ) + if (uri.getScheme().equals("https")) { aProxyNameProp = "ooInetHTTPSProxyName"; aProxyPortProp = "ooInetHTTPSProxyPort"; @@ -620,7 +578,8 @@ public class Helper nProxyPort = 80; // TODO: check whether the URL is in the NoProxy list - aHostConfig.setProxy( aProxyName, nProxyPort ); + InetSocketAddress address = new InetSocketAddress(aProxyName, nProxyPort); + return new Proxy(Proxy.Type.HTTP, address); } } } @@ -628,6 +587,7 @@ public class Helper { e.printStackTrace(); } + return null; // invalid configuration value? } protected static void ShowURLInBrowser( XComponentContext xContext, String sURL ) @@ -648,33 +608,70 @@ public class Helper } } - protected static void ExecuteMethod( HttpMethodBase aMethod, HostConfiguration aHostConfig, URI aURI, XComponentContext xContext, boolean bSetHost ) + protected static HttpURLConnection PrepareMethod(String method, URI uri, XComponentContext xContext) throws WikiCancelException, IOException, SSLException { - if ( aMethod != null && aHostConfig != null && aURI != null && xContext != null ) + assert(method != null); + assert(uri != null); + assert(xContext != null); + + if (!IsConnectionAllowed()) { + throw new WikiCancelException(); + } + + if (java.net.CookieHandler.getDefault() == null) { + // set a cookie manager so cookies don't get lost + // apparently it's not possible to do that on a per-connection + // basis but only globally? + java.net.CookieHandler.setDefault(new java.net.CookieManager()); + } + + Proxy proxy = GetConfigurationProxy(uri, xContext); + HttpURLConnection conn = null; + if (proxy != null) { + conn = (HttpURLConnection) uri.toURL().openConnection(proxy); + } else { + conn = (HttpURLConnection) uri.toURL().openConnection(); + } + if (uri.getScheme().equals("https") && AllowUnknownCert(xContext, uri.getHost())) { - if ( bSetHost ) - { - aHostConfig.setHost( aURI ); - SetConfigurationProxy( aHostConfig, xContext ); - } + // let unknown certificates be accepted + ((HttpsURLConnection) conn).setSSLSocketFactory(new WikiProtocolSocketFactory()); + } - if ( aHostConfig.getProtocol().getScheme().equals( "https" ) - && AllowUnknownCert( xContext, aURI.getHost() ) ) - { - // let unknown certificates be accepted - { - { - aHostConfig.setHost( aHostConfig.getHost(), ( aURI.getPort() < 0 ? 443 : aURI.getPort() ), Helper.GetOwnHttps( aURI.getPort() ) ); - Helper.GetHttpClient().executeMethod( aHostConfig, aMethod ); - } + conn.setRequestMethod(method); + // note: don't connect yet so that the caller can do some further setup + + return conn; + } + + protected static String ReadResponseBody(HttpURLConnection conn) + throws IOException + { + String ret = null; + InputStream stream = conn.getInputStream(); + try { + // there doesn't seem to be an easier way get the content encoding + String type = conn.getContentType(); + String charset = "ISO-8859-1"; // default in RFC2616 + for (String param : type.split(";")) { + if (param.trim().toLowerCase().startsWith("charset=")) { + charset = param.trim().substring("charset=".length()); + break; } } - else - { - Helper.GetHttpClient().executeMethod( aHostConfig, aMethod ); + BufferedReader br = + new BufferedReader(new InputStreamReader(stream, charset)); + StringBuilder buf = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) { + buf.append(line); } + ret = buf.toString(); + } finally { + stream.close(); } + return ret; } private static class HTMLParse extends HTMLEditorKit @@ -738,76 +735,74 @@ public class Helper return sResult; } - protected static HostConfiguration Login( URI aMainURL, String sWikiUser, String sWikiPass, XComponentContext xContext ) - throws java.io.IOException, WikiCancelException + protected static boolean Login(URI aMainURL, String sWikiUser, String sWikiPass, XComponentContext xContext) + throws java.io.IOException, WikiCancelException, URISyntaxException { - HostConfiguration aHostConfig = null; + boolean success = false; if ( sWikiUser != null && sWikiPass != null && xContext != null ) { - HostConfiguration aNewHostConfig = new HostConfiguration(); - - URI aURI = new URI( aMainURL.toString() + "index.php?title=Special:Userlogin", false ); - GetMethod aGetCookie = new GetMethod( aURI.getEscapedPathQuery() ); - - ExecuteMethod( aGetCookie, aNewHostConfig, aURI, xContext, true ); - - int nResultCode = aGetCookie.getStatusCode(); String sLoginPage = null; - if ( nResultCode == 200 ) - sLoginPage = aGetCookie.getResponseBodyAsString(); - - aGetCookie.releaseConnection(); + URI aURI = new URI(aMainURL.toString() + "index.php?title=Special:Userlogin"); + HttpURLConnection connGet = PrepareMethod("GET", aURI, xContext); + connGet.setInstanceFollowRedirects(true); + + connGet.connect(); + int nResultCode = connGet.getResponseCode(); + if (nResultCode == 200) { + sLoginPage = ReadResponseBody(connGet); + } if ( sLoginPage != null ) { String sLoginToken = GetLoginToken( sLoginPage ); - PostMethod aPost = new PostMethod(); - URI aPostURI = new URI( aMainURL.getPath() + "index.php?title=Special:Userlogin&action=submitlogin", false ); - aPost.setPath( aPostURI.getEscapedPathQuery() ); + URI aPostURI = new URI(aMainURL.toString() + "index.php?title=Special:Userlogin&action=submitlogin"); - aPost.addParameter( "wpName", sWikiUser ); - aPost.addParameter( "wpRemember", "1" ); - aPost.addParameter( "wpPassword", sWikiPass ); - if ( sLoginToken.length() > 0 ) - aPost.addParameter( "wpLoginToken", sLoginToken ); + HttpURLConnection connPost = PrepareMethod("POST", aPostURI, xContext); + connPost.setInstanceFollowRedirects(true); + connPost.setDoInput(true); + connPost.setDoOutput(true); + connPost.connect(); + + OutputStreamWriter post = new OutputStreamWriter(connPost.getOutputStream()); + post.write("wpName="); + post.write(URLEncoder.encode(sWikiUser, "UTF-8")); + post.write("&wpRemember=1"); + post.write("&wpPassword="); + post.write(URLEncoder.encode(sWikiPass, "UTF-8")); + + if (sLoginToken.length() > 0) { + post.write("&wpLoginToken="); + post.write(URLEncoder.encode(sLoginToken, "UTF-8")); + } String[][] pArgs = GetSpecialArgs( xContext, aMainURL.getHost() ); if ( pArgs != null ) for ( int nArgInd = 0; nArgInd < pArgs.length; nArgInd++ ) if ( pArgs[nArgInd].length == 2 && pArgs[nArgInd][0] != null && pArgs[nArgInd][1] != null ) - aPost.addParameter( pArgs[nArgInd][0], pArgs[nArgInd][1] ); - - ExecuteMethod( aPost, aNewHostConfig, aPostURI, xContext, false ); - - nResultCode = aPost.getStatusCode(); - - while( nResultCode >= 301 && nResultCode <= 303 || nResultCode == 307 ) - { - String sRedirectURL = aPost.getResponseHeader( "Location" ).getValue(); - aPost.releaseConnection(); + { + post.write("&"); + post.write(URLEncoder.encode(pArgs[nArgInd][0], "UTF-8")); + post.write("="); + post.write(URLEncoder.encode(pArgs[nArgInd][0], "UTF-8")); + } - aURI = new URI( sRedirectURL ); - aPost = new PostMethod(); - aPost.setPath( aURI.getEscapedPathQuery() ); - ExecuteMethod( aPost, aNewHostConfig, aURI, xContext, false ); + post.flush(); + post.close(); - nResultCode = aPost.getStatusCode(); - } + nResultCode = connPost.getResponseCode(); if ( nResultCode == 200 ) { - String sResult = aPost.getResponseBodyAsString(); + String sResult = ReadResponseBody(connPost); if ( !LoginReportsError( sResult ) ) - aHostConfig = aNewHostConfig; + success = true; } - - aPost.releaseConnection(); } } - return aHostConfig; + return success; } protected static String[] GetPasswordsForURLAndUser( XComponentContext xContext, String sURL, String sUserName ) diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java b/swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java index e16db71..58638b5 100644 --- a/swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiArticle.java @@ -19,15 +19,14 @@ package com.sun.star.wiki; import java.io.StringReader; +import java.io.OutputStreamWriter; import java.util.Map; +import java.net.URLEncoder; +import java.net.URI; +import java.net.HttpURLConnection; import javax.swing.text.html.HTMLEditorKit; -import org.apache.commons.httpclient.HostConfiguration; -import org.apache.commons.httpclient.URI; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.httpclient.methods.PostMethod; - import com.sun.star.uno.XComponentContext; @@ -47,12 +46,11 @@ public class WikiArticle private final String m_sTitle; private final URI m_aMainURI; - private HostConfiguration m_aHostConfig; - + private boolean m_isLoggedIn = false; /** Creates a new instance of WikiArticle */ public WikiArticle( XComponentContext xContext, String sTitle, Map<String,String> wikiSettings, boolean bLogin, WikiPropDialog aPropDialog ) - throws java.net.MalformedURLException, java.io.IOException, WikiCancelException + throws java.net.URISyntaxException, java.io.IOException, WikiCancelException { m_xContext = xContext; @@ -61,7 +59,7 @@ public class WikiArticle m_sWikiPass = wikiSettings.get("Password"); m_sTitle = sTitle; - m_aMainURI = new URI( sMainUrl, false ); + m_aMainURI = new URI(sMainUrl); if ( bLogin ) { @@ -112,23 +110,21 @@ public class WikiArticle private String getArticleWiki() - throws java.io.IOException, WikiCancelException + throws java.net.URISyntaxException, java.io.IOException, WikiCancelException { String sWikiCode = null; - if ( m_aHostConfig != null ) + if (m_isLoggedIn) { - URI aURI = new URI( m_aMainURI.toString() + "index.php?title=" + m_sTitle + "&action=edit", false ); - GetMethod aRequest = new GetMethod( aURI.getEscapedPathQuery() ); + URI aURI = new URI(m_aMainURI.toString() + "index.php?title=" + m_sTitle + "&action=edit"); + HttpURLConnection connGet = Helper.PrepareMethod("GET", aURI, m_xContext); + connGet.connect(); - Helper.ExecuteMethod( aRequest, m_aHostConfig, aURI, m_xContext, false ); - - int nResultCode = aRequest.getStatusCode(); + int nResultCode = connGet.getResponseCode(); String sWebPage = null; - if ( nResultCode == 200 ) - sWebPage = aRequest.getResponseBodyAsString(); - - aRequest.releaseConnection(); + if (nResultCode == 200) { + sWebPage = Helper.ReadResponseBody(connGet); + } if ( sWebPage != null ) { @@ -156,19 +152,19 @@ public class WikiArticle } private void InitArticleHTML() - throws java.io.IOException, WikiCancelException + throws java.net.URISyntaxException, java.io.IOException, WikiCancelException { - if ( m_aHostConfig != null ) + if (m_isLoggedIn) { - URI aURI = new URI( m_aMainURI.toString() + "index.php?title=" + m_sTitle, false ); - GetMethod aRequest = new GetMethod( aURI.getEscapedPathQuery() ); - - Helper.ExecuteMethod( aRequest, m_aHostConfig, aURI, m_xContext, false ); + URI uri = new URI(m_aMainURI.toString() + "index.php?title=" + m_sTitle); + HttpURLConnection connGet = Helper.PrepareMethod("GET", uri, m_xContext); + connGet.connect(); - int nResultCode = aRequest.getStatusCode(); + int nResultCode = connGet.getResponseCode(); String sWebPage = null; - if ( nResultCode == 200 ) - sWebPage = aRequest.getResponseBodyAsString(); + if (nResultCode == 200) { + sWebPage = Helper.ReadResponseBody(connGet); + } if ( sWebPage != null ) { @@ -192,36 +188,46 @@ public class WikiArticle } protected boolean setArticle( String sWikiCode, String sWikiComment, boolean bMinorEdit ) - throws java.io.IOException, WikiCancelException + throws java.net.URISyntaxException, java.io.IOException, WikiCancelException { boolean bResult = false; - if ( m_aHostConfig != null && sWikiCode != null && sWikiComment != null ) + if (m_isLoggedIn && sWikiCode != null && sWikiComment != null) { // get the edit time and token getArticleWiki(); - URI aURI = new URI( m_aMainURI.getPath() + "index.php?title=" + m_sTitle + "&action=submit", false ); - PostMethod aPost = new PostMethod(); - aPost.setPath( aURI.getEscapedPathQuery() ); - - aPost.addParameter( "wpTextbox1", sWikiCode ); - aPost.addParameter( "wpSummary", sWikiComment ); - aPost.addParameter( "wpSection", "" ); - aPost.addParameter( "wpEdittime", m_sEditTime ); - aPost.addParameter( "wpSave", "Save page" ); - aPost.addParameter( "wpEditToken", m_sEditToken ); - - if ( bMinorEdit ) - aPost.addParameter( "wpMinoredit", "1" ); + URI uri = new URI(m_aMainURI.toString() + "index.php?title=" + m_sTitle + "&action=submit"); + + HttpURLConnection connPost = Helper.PrepareMethod("POST", uri, m_xContext); + connPost.setDoInput(true); + connPost.setDoOutput(true); + connPost.connect(); + + OutputStreamWriter post = new OutputStreamWriter(connPost.getOutputStream()); + post.write("wpTextbox1="); + post.write(URLEncoder.encode(sWikiCode, "UTF-8")); + post.write("&wpSummary="); + post.write(URLEncoder.encode(sWikiComment, "UTF-8")); + post.write("&wpSection="); + post.write("&wpEdittime="); + post.write(URLEncoder.encode(m_sEditTime, "UTF-8")); + post.write("&wpSave=Save%20page"); + post.write("&wpEditToken="); + post.write(URLEncoder.encode(m_sEditToken, "UTF-8")); + + if (bMinorEdit) { + post.write("&wpMinoredit=1"); + } - Helper.ExecuteMethod( aPost, m_aHostConfig, aURI, m_xContext, false ); + post.flush(); + post.close(); - int nResultCode = aPost.getStatusCode(); + int nResultCode = connPost.getResponseCode(); if ( nResultCode < 400 ) bResult = true; - String aResult = aPost.getResponseBodyAsString(); + String aResult = Helper.ReadResponseBody(connPost); // TODO: remove the debug printing, try to detect the error System.out.print( "nSubmitCode = " + nResultCode + "\n===\n" + aResult ); @@ -231,15 +237,12 @@ public class WikiArticle } private boolean Login() - throws java.io.IOException, WikiCancelException + throws java.net.URISyntaxException, java.io.IOException, WikiCancelException { - m_aHostConfig = Helper.Login( m_aMainURI, m_sWikiUser, m_sWikiPass, m_xContext ); - return ( m_aHostConfig != null ); + m_isLoggedIn = Helper.Login( m_aMainURI, m_sWikiUser, m_sWikiPass, m_xContext ); + return m_isLoggedIn; } - - - protected boolean NotExist() { boolean bResult = true; diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java b/swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java index aef6cb6..ad9e2ca 100644 --- a/swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiEditSettingDialog.java @@ -21,12 +21,10 @@ package com.sun.star.wiki; import java.util.HashMap; import java.util.Map; +import java.net.URI; +import java.net.HttpURLConnection; import javax.net.ssl.SSLException; -import org.apache.commons.httpclient.HostConfiguration; -import org.apache.commons.httpclient.URI; -import org.apache.commons.httpclient.methods.GetMethod; - import com.sun.star.awt.XDialog; import com.sun.star.beans.XPropertySet; import com.sun.star.lang.EventObject; @@ -199,8 +197,6 @@ public class WikiEditSettingDialog extends WikiDialog String sUserName = ( String ) GetPropSet( "UsernameField" ).getPropertyValue( "Text" ); String sPassword = ( String ) GetPropSet( "PasswordField" ).getPropertyValue( "Text" ); - HostConfiguration aHostConfig = new HostConfiguration(); - boolean bInitHost = true; boolean bAllowIndex = true; do @@ -213,20 +209,17 @@ public class WikiEditSettingDialog extends WikiDialog if ( sURL.length() > 0 ) { - URI aURI = new URI( sURL, false ); - GetMethod aRequest = new GetMethod( aURI.getEscapedPathQuery() ); - aRequest.setFollowRedirects( false ); - Helper.ExecuteMethod( aRequest, aHostConfig, aURI, m_xContext, bInitHost ); - bInitHost = false; + URI aURI = new URI(sURL); + HttpURLConnection connGet = Helper.PrepareMethod("GET", aURI, m_xContext); + connGet.setInstanceFollowRedirects(false); + connGet.connect(); - int nResultCode = aRequest.getStatusCode(); + int nResultCode = connGet.getResponseCode(); String sWebPage = null; if ( nResultCode == 200 ) - sWebPage = aRequest.getResponseBodyAsString(); + sWebPage = Helper.ReadResponseBody(connGet); else if ( nResultCode >= 301 && nResultCode <= 303 || nResultCode == 307 ) - sRedirectURL = aRequest.getResponseHeader( "Location" ).getValue(); - - aRequest.releaseConnection(); + sRedirectURL = connGet.getHeaderField("Location"); if ( sWebPage != null && sWebPage.length() > 0 ) { @@ -252,10 +245,10 @@ public class WikiEditSettingDialog extends WikiDialog } else { - URI aMainURI = new URI( sMainURL, true ); // it must be an escaped URL, otherwise an exception should be thrown + URI aMainURI = new URI(sMainURL); if ( ( sUserName.length() > 0 || sPassword.length() > 0 ) - && Helper.Login( aMainURI, sUserName, sPassword, m_xContext ) == null ) + && !Helper.Login(aMainURI, sUserName, sPassword, m_xContext)) { // a wrong login information is provided // show error @@ -268,7 +261,7 @@ public class WikiEditSettingDialog extends WikiDialog } else { - setting.put( "Url", aMainURI.getEscapedURI() ); + setting.put( "Url", aMainURI.toASCIIString() ); setting.put( "Username", sUserName ); setting.put( "Password", sPassword ); if ( addMode ) diff --git a/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java b/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java index b6da4a5..5d7efe1 100644 --- a/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java +++ b/swext/mediawiki/src/com/sun/star/wiki/WikiProtocolSocketFactory.java @@ -25,17 +25,14 @@ import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyStore; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import org.apache.commons.httpclient.ConnectTimeoutException; -import org.apache.commons.httpclient.HttpClientError; -import org.apache.commons.httpclient.params.HttpConnectionParams; -import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; -class WikiProtocolSocketFactory implements SecureProtocolSocketFactory +class WikiProtocolSocketFactory extends SSLSocketFactory { private SSLContext m_aSSLContext; @@ -105,43 +102,59 @@ class WikiProtocolSocketFactory implements SecureProtocolSocketFactory } if ( m_aSSLContext == null ) - throw new HttpClientError(); + throw new RuntimeException("failed to create SSLContext"); return m_aSSLContext; } - public Socket createSocket( String sHost, int nPort, InetAddress clientHost, int clientPort ) - throws IOException, UnknownHostException + @Override + public Socket createSocket(InetAddress address, int port) + throws IOException { - return GetNotSoSecureSSLContext().getSocketFactory().createSocket( sHost, nPort, clientHost, clientPort ); + return GetNotSoSecureSSLContext().getSocketFactory().createSocket(address, port); + } + + @Override + public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) + throws IOException + { + return GetNotSoSecureSSLContext().getSocketFactory().createSocket(address, port, localAddress, localPort); } - public Socket createSocket( final String sHost, final int nPort, final InetAddress aLocalAddress, final int nLocalPort, final HttpConnectionParams params ) - throws IOException, UnknownHostException, ConnectTimeoutException + @Override + public Socket createSocket( String sHost, int nPort, InetAddress clientHost, int clientPort ) + throws IOException, UnknownHostException { - if ( params == null ) - return createSocket( sHost, nPort, aLocalAddress, nLocalPort ); - - int nTimeout = params.getConnectionTimeout(); - Socket aSocket = GetNotSoSecureSSLContext().getSocketFactory().createSocket(); - aSocket.bind( new InetSocketAddress( aLocalAddress, nLocalPort ) ); - aSocket.connect( new InetSocketAddress( sHost, nPort ), nTimeout ); - return aSocket; + return GetNotSoSecureSSLContext().getSocketFactory().createSocket( sHost, nPort, clientHost, clientPort ); } + @Override public Socket createSocket( String sHost, int nPort ) throws IOException, UnknownHostException { return GetNotSoSecureSSLContext().getSocketFactory().createSocket( sHost, nPort ); } + @Override public Socket createSocket( Socket aSocket, String sHost, int nPort, boolean bAutoClose ) - throws IOException, UnknownHostException + throws IOException { return GetNotSoSecureSSLContext().getSocketFactory().createSocket( aSocket, sHost, nPort, bAutoClose ); } @Override + public String[] getDefaultCipherSuites() + { + return GetNotSoSecureSSLContext().getSocketFactory().getDefaultCipherSuites(); + } + + @Override + public String[] getSupportedCipherSuites() + { + return GetNotSoSecureSSLContext().getSocketFactory().getSupportedCipherSuites(); + } + + @Override public boolean equals(Object obj) { return ((obj != null) && obj.getClass().equals(WikiProtocolSocketFactory.class)); _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
