RFC: Rewrite of cookie support in plugin

Deepak Bhole dbhole at redhat.com
Fri Jul 3 14:49:31 PDT 2009


This patch rewrites cookie support in the plugin. The old way was
static, set at initialization time. Additionally, it did not support
cookie provision for connection requests made by the applet internally.

This patch fixes all of that. Cookie information is now supplied to Java
in real-time from Mozilla side, as it should be.

Thanks to Omair for the initial error trace.

This patch fixes rhbz 506730:
https://bugzilla.redhat.com/show_bug.cgi?id=506730

http://www.sbm.no/ will now load correctly with this patch.

ChangeLog:
    * IcedTeaPlugin.cc: Add suppport for cookie info requests from applets.
    * plugin/icedtea/sun/applet/PluginAppletViewer.java: Rework cookie support
    to make it dynamic.
    * plugin/icedtea/sun/applet/PluginMain.java: Wire in custom cookie store
    that dynamically requests cookie information from C++ side.
    * rt/net/sourceforge/jnlp/JNLPFile.java: Remove old cookie handling code.
    * rt/net/sourceforge/jnlp/Launcher.java: Same.
    * rt/net/sourceforge/jnlp/NetxPanel.java: Same.
    * rt/net/sourceforge/jnlp/PluginBridge.java: Same.
    * rt/net/sourceforge/jnlp/cache/CacheUtil.java: Same.
    * rt/net/sourceforge/jnlp/cache/Resource.java: Same.
    * rt/net/sourceforge/jnlp/cache/ResourceTracker.java: Same.
    * rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: Same.

Comments?

Deepak
-------------- next part --------------
diff -r 308c172cd230 IcedTeaPlugin.cc
--- a/IcedTeaPlugin.cc	Fri Jul 03 11:52:45 2009 +0100
+++ b/IcedTeaPlugin.cc	Fri Jul 03 17:40:05 2009 -0400
@@ -1012,6 +1012,7 @@
   void ProcessMessage();
   void ConsumeMsgFromJVM();
   nsresult GetProxyInfo(const char* siteAddr, char** proxyScheme, char** proxyHost, char** proxyPort);
+  nsresult GetCookieInfo(const char* siteAddr, char** cookieString);
   nsCOMPtr<IcedTeaEventSink> sink;
   nsCOMPtr<nsISocketTransport> transport;
   nsCOMPtr<nsIProcess> applet_viewer_process;
@@ -1070,7 +1071,6 @@
   IcedTeaPluginFactory* factory;
   PRUint32 instance_identifier;
   nsCString instanceIdentifierPrefix;
-  nsresult GetCookie(const char* siteAddr, char** cookieString);
 };
 
 
@@ -2380,16 +2380,6 @@
 	  encodedAppletTag += tagMessage.get()[i];
   }
 
-  nsCString cookieInfo(instanceIdentifierPrefix);
-  cookieInfo += "cookie ";
-
-  char* cookieString;
-  if (GetCookie(documentbase, &cookieString) == NS_OK)
-  {
-	  cookieInfo += cookieString;
-  }
-
-  factory->SendMessageToAppletViewer (cookieInfo);
   factory->SendMessageToAppletViewer (encodedAppletTag);
 
   // Set back-pointer to peer instance.
@@ -2760,8 +2750,15 @@
   return NS_OK;
 }
 
-NS_IMETHODIMP
-IcedTeaPluginInstance::GetCookie(const char* siteAddr, char** cookieString) 
+/** 
+ * Returns the cookie information for the given url
+ *
+ * @param siteAddr The URI to check (must be decoded)
+ * @return cookieString The cookie string for the given URI
+ */
+
+NS_IMETHODIMP
+IcedTeaPluginFactory::GetCookieInfo(const char* siteAddr, char** cookieString) 
 {
 
   nsresult rv;
@@ -3497,6 +3494,35 @@
 
 		  // free allocated memory
           delete proxyScheme, proxyHost, proxyPort;
+
+		} else if (command == "PluginCookieInfo") 
+        {
+
+          nsresult rv;
+          nsCOMPtr<nsINetUtil> net_util = do_GetService(NS_NETUTIL_CONTRACTID, &rv);
+
+          if (!net_util)
+            printf("Error instantiating NetUtil service.\n");
+
+          // decode the url
+          nsDependentCSubstring url;
+          net_util->UnescapeString(rest, 0, url);
+
+          nsCString cookieInfo("plugin PluginCookieInfo ");
+          cookieInfo += rest;
+          cookieInfo += " ";
+
+          char* cookieString;
+          if (GetCookieInfo(((nsCString) url).get(), &cookieString) == NS_OK)
+          {
+              cookieInfo += cookieString;
+              PLUGIN_DEBUG_2ARG("Cookie for %s is %s\n", ((nsCString) url).get(), cookieString);
+          } else {
+              PLUGIN_DEBUG_1ARG("No cookie found for %s\n", ((nsCString) url).get());
+          }
+
+          // send back what we found
+          SendMessageToAppletViewer (cookieInfo);
 
 		}
 	}
diff -r 308c172cd230 plugin/icedtea/sun/applet/PluginAppletViewer.java
--- a/plugin/icedtea/sun/applet/PluginAppletViewer.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/plugin/icedtea/sun/applet/PluginAppletViewer.java	Fri Jul 03 17:40:05 2009 -0400
@@ -84,6 +84,7 @@
 import java.io.PrintStream;
 import java.io.Reader;
 import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
 import java.lang.reflect.InvocationTargetException;
 import java.net.MalformedURLException;
 import java.net.SocketPermission;
@@ -180,9 +181,6 @@
      private static PluginStreamHandler streamhandler;
      
      private static PluginCallRequestFactory requestFactory;
-     
-     private static HashMap<Integer, String> siteCookies = 
-         new HashMap<Integer,String>();
 
      private static HashMap<Integer, PAV_INIT_STATUS> status = 
          new HashMap<Integer,PAV_INIT_STATUS>();
@@ -226,7 +224,7 @@
          AccessController.doPrivileged(new PrivilegedAction() {
              public Object run() {
             	 	try {
-            	 		panel = new NetxPanel(doc, siteCookies.get(identifier), atts, false);
+            	 		panel = new NetxPanel(doc, atts, false);
             	 		AppletViewerPanel.debug("Using NetX panel");
             	 		PluginDebug.debug(atts.toString());
             	 	} catch (Exception ex) {
@@ -483,16 +481,6 @@
             			 PluginDebug.debug ("REQUEST TAG NOT SET: " + request.tag + ". BYPASSING");
             		 }
             	 }
-             } else if (message.startsWith("cookie")) {
-                 
-                 int cookieStrIndex = message.indexOf(" ");
-                 String cookieStr = null;
-
-                 if (cookieStrIndex > 0)
-                     cookieStr = message.substring(cookieStrIndex);
-
-                 // Always set the cookie -- even if it is null
-                 siteCookies.put(identifier, cookieStr);
              } else {
                  PluginDebug.debug ("Handling message: " + message + " instance " + identifier + " " + Thread.currentThread());
 
@@ -842,7 +830,6 @@
       * applets on this page.
       */
      public Enumeration getApplets() {
- 	AppletSecurity security = (AppletSecurity)System.getSecurityManager();
  	Vector v = new Vector();
  	SocketPermission panelSp =
  	    new SocketPermission(panel.getCodeBase().getHost(), "connect");
@@ -896,7 +883,7 @@
  	    // streamhandler.pluginOutputStream has been closed.
  	}
      }
- 
+     
      public long getWindow() {
     	 PluginDebug.debug ("STARTING getWindow");
     	 PluginCallRequest request = requestFactory.getPluginCallRequest("window",
@@ -1113,6 +1100,40 @@
          return request.getObject();
      }
  
+     public static Object requestPluginCookieInfo(URI uri) {
+
+         PluginCallRequest request;
+         try
+         {
+             String encodedURI = UrlUtil.encode(uri.toString(), "UTF-8"); 
+             request = requestFactory.getPluginCallRequest("cookieinfo",
+                               "plugin PluginCookieInfo " + encodedURI, 
+                               "plugin PluginCookieInfo " + encodedURI);
+
+         } catch (UnsupportedEncodingException e)
+         {
+             e.printStackTrace();
+             return null;
+         }
+
+         streamhandler.postCallRequest(request);
+         streamhandler.write(request.getMessage());
+         try {
+             PluginDebug.debug ("wait cookieinfo request 1");
+             synchronized(request) {
+                 PluginDebug.debug ("wait cookieinfo request 2");
+                 while (request.isDone() == false)
+                     request.wait();
+                 PluginDebug.debug ("wait cookieinfo request 3");
+             }
+         } catch (InterruptedException e) {
+             throw new RuntimeException("Interrupted waiting for cookieinfo request.",
+                                        e);
+         }
+         PluginDebug.debug (" Cookieinfo DONE");
+         return request.getObject();
+     }
+
      public static Object requestPluginProxyInfo(URI uri) {
 
          String requestURI = null;
@@ -1623,10 +1644,6 @@
      public static void parse(int identifier, long handle, Reader in, URL url)
          throws IOException {
          
-         // wait until cookie is set (even if cookie is null, it needs to be 
-         // "set" to that first
-         while (!siteCookies.containsKey(identifier));
-
     	 final int fIdentifier = identifier;
     	 final long fHandle = handle;
     	 final Reader fIn = in;
diff -r 308c172cd230 plugin/icedtea/sun/applet/PluginCallRequestFactory.java
--- a/plugin/icedtea/sun/applet/PluginCallRequestFactory.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/plugin/icedtea/sun/applet/PluginCallRequestFactory.java	Fri Jul 03 17:40:05 2009 -0400
@@ -51,6 +51,8 @@
 			return new GetWindowPluginCallRequest(message, returnString);
 		} else if (id == "proxyinfo") {
             return new PluginProxyInfoRequest(message, returnString);
+        }  else if (id == "cookieinfo") {
+            return new PluginCookieInfoRequest(message, returnString);
         } else {
 			throw new RuntimeException ("Unknown plugin call request type requested from factory");
 		}
diff -r 308c172cd230 plugin/icedtea/sun/applet/PluginMain.java
--- a/plugin/icedtea/sun/applet/PluginMain.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/plugin/icedtea/sun/applet/PluginMain.java	Fri Jul 03 17:40:05 2009 -0400
@@ -68,10 +68,11 @@
 import java.io.IOException;
 import java.io.PrintStream;
 import java.net.Authenticator;
+import java.net.CookieHandler;
+import java.net.CookieManager;
 import java.net.PasswordAuthentication;
 import java.net.ProxySelector;
 import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.Properties;
 
 import javax.net.ssl.HttpsURLConnection;
@@ -218,6 +219,9 @@
 		// plug in a custom authenticator and proxy selector
         Authenticator.setDefault(new CustomAuthenticator());
         ProxySelector.setDefault(new PluginProxySelector());
+        
+        CookieManager ckManager = new CookieManager(new PluginCookieStore(), null);
+        CookieHandler.setDefault(ckManager);
 	}
 
     static boolean messageAvailable() {
diff -r 308c172cd230 rt/net/sourceforge/jnlp/JNLPFile.java
--- a/rt/net/sourceforge/jnlp/JNLPFile.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/rt/net/sourceforge/jnlp/JNLPFile.java	Fri Jul 03 17:40:05 2009 -0400
@@ -69,9 +69,6 @@
 
     /** the URL used to resolve relative URLs in the file */
     protected URL codeBase;
-    
-    /** cookie string to send alongwith resource requests */
-    protected String cookieStr;
 
     /** file version */
     protected Version fileVersion;
@@ -159,7 +156,6 @@
         parse(root, strict, location);
 
         this.fileLocation = location;
-        this.cookieStr = cookieStr;
     }
 
     /**
@@ -196,7 +192,7 @@
 
         try {
             ResourceTracker tracker = new ResourceTracker(false); // no prefetch
-            tracker.addResource(location, cookieStr, null/*version*/, policy);
+            tracker.addResource(location, null/*version*/, policy);
 
             return tracker.getInputStream(location);
         }
@@ -255,13 +251,6 @@
      */
     public URL getCodeBase() {
         return codeBase;
-    }
-
-    /**
-     * Returns the cookie string that will be send when resources for this file are requested 
-     */
-    public String getCookieStr() {
-        return cookieStr;
     }
     
     /**
diff -r 308c172cd230 rt/net/sourceforge/jnlp/Launcher.java
--- a/rt/net/sourceforge/jnlp/Launcher.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/rt/net/sourceforge/jnlp/Launcher.java	Fri Jul 03 17:40:06 2009 -0400
@@ -389,7 +389,7 @@
                     IconDesc.SPLASH, preferredWidth, preferredHeight);
             if (splashImageURL != null) {
                 ResourceTracker resourceTracker = new ResourceTracker(true);
-                resourceTracker.addResource(splashImageURL, "SPLASH", file.getFileVersion(), updatePolicy);
+                resourceTracker.addResource(splashImageURL, file.getFileVersion(), updatePolicy);
                 splashScreen = new JNLPSplashScreen(resourceTracker, null, null);
                 splashScreen.setSplashImageURL(splashImageURL);
                 if (splashScreen.isSplashScreenValid()) {
diff -r 308c172cd230 rt/net/sourceforge/jnlp/NetxPanel.java
--- a/rt/net/sourceforge/jnlp/NetxPanel.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/rt/net/sourceforge/jnlp/NetxPanel.java	Fri Jul 03 17:40:06 2009 -0400
@@ -41,7 +41,6 @@
     private PluginBridge bridge = null;
     private boolean exitOnFailure = true;
     private AppletInstance appInst = null;
-    private String cookieStr;
     private boolean appletAlive;
 
     public NetxPanel(URL documentURL, Hashtable atts)
@@ -50,11 +49,10 @@
     }
     
     // overloaded constructor, called when initialized via plugin 
-    public NetxPanel(URL documentURL, String cookieStr, Hashtable atts, boolean exitOnFailure)
+    public NetxPanel(URL documentURL, Hashtable atts, boolean exitOnFailure)
     {
         this(documentURL, atts);
         this.exitOnFailure = exitOnFailure;
-        this.cookieStr = cookieStr;
         this.appletAlive = true;
     }
 
@@ -64,7 +62,6 @@
 
     	try {
     		bridge = new PluginBridge(baseURL,
-    				cookieStr,
     				getDocumentBase(),
     				getJarFiles(), 
     				getCode(),
diff -r 308c172cd230 rt/net/sourceforge/jnlp/PluginBridge.java
--- a/rt/net/sourceforge/jnlp/PluginBridge.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/rt/net/sourceforge/jnlp/PluginBridge.java	Fri Jul 03 17:40:06 2009 -0400
@@ -43,7 +43,7 @@
     String[] cache_ex_jars = new String[0];
     Hashtable atts;
 
-    public PluginBridge(URL codebase, String cookieStr, URL documentBase, String jar, String main,
+    public PluginBridge(URL codebase, URL documentBase, String jar, String main,
                         int width, int height, Hashtable atts)
     throws Exception
     {
@@ -104,7 +104,6 @@
         else
             security = null;
         
-        this.cookieStr = cookieStr;
     }
 
     public String getTitle()
diff -r 308c172cd230 rt/net/sourceforge/jnlp/cache/CacheUtil.java
--- a/rt/net/sourceforge/jnlp/cache/CacheUtil.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/rt/net/sourceforge/jnlp/cache/CacheUtil.java	Fri Jul 03 17:40:06 2009 -0400
@@ -75,9 +75,9 @@
      * @param version the version, or null
      * @return either the location in the cache or the original location
      */
-    public static URL getCachedResource(URL location, String cookieStr, Version version, UpdatePolicy policy) {
+    public static URL getCachedResource(URL location, Version version, UpdatePolicy policy) {
         ResourceTracker rt = new ResourceTracker();
-        rt.addResource(location, cookieStr, version, policy);
+        rt.addResource(location, version, policy);
         try {
             File f = rt.getCacheFile(location);
             return f.toURL();
diff -r 308c172cd230 rt/net/sourceforge/jnlp/cache/Resource.java
--- a/rt/net/sourceforge/jnlp/cache/Resource.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/rt/net/sourceforge/jnlp/cache/Resource.java	Fri Jul 03 17:40:06 2009 -0400
@@ -68,9 +68,6 @@
     /** the remote location of the resource */
     URL location;
     
-    /** cookie string to send with the resource request */
-    String cookieStr;
-
     /** the local file downloaded to */
     File localFile;
 
@@ -98,20 +95,19 @@
     /**
      * Create a resource.
      */
-    private Resource(URL location, String cookieStr, UpdatePolicy updatePolicy, Version requestVersion) {
+    private Resource(URL location, UpdatePolicy updatePolicy, Version requestVersion) {
         this.location = location;
         this.requestVersion = requestVersion;
         this.updatePolicy = updatePolicy;
-        this.cookieStr = cookieStr;
     }
 
     /**
      * Return a shared Resource object representing the given
      * location and version.
      */
-    public static Resource getResource(URL location, String cookieStr, UpdatePolicy updatePolicy, Version requestVersion) {
+    public static Resource getResource(URL location, UpdatePolicy updatePolicy, Version requestVersion) {
         synchronized (resources) {
-            Resource resource = new Resource(location, cookieStr, updatePolicy, requestVersion);
+            Resource resource = new Resource(location, updatePolicy, requestVersion);
 
             int index = resources.indexOf(resource);
             if (index >= 0) { // return existing object
@@ -132,13 +128,6 @@
      */
     public URL getLocation() {
         return location;
-    }
-    
-    /**
-     * Returns the cookie string associated with this resource
-     */
-    public String getCookieStr() {
-        return cookieStr;
     }
 
     /**
diff -r 308c172cd230 rt/net/sourceforge/jnlp/cache/ResourceTracker.java
--- a/rt/net/sourceforge/jnlp/cache/ResourceTracker.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/rt/net/sourceforge/jnlp/cache/ResourceTracker.java	Fri Jul 03 17:40:06 2009 -0400
@@ -148,11 +148,11 @@
      * @param version the resource version
      * @param updatePolicy whether to check for updates if already in cache
      */
-    public void addResource(URL location, String cookieStr, Version version, UpdatePolicy updatePolicy) {
+    public void addResource(URL location, Version version, UpdatePolicy updatePolicy) {
         if (location == null)
             throw new IllegalArgumentException("location==null");
 
-        Resource resource = Resource.getResource(location, cookieStr, updatePolicy, version);
+        Resource resource = Resource.getResource(location, updatePolicy, version);
         boolean downloaded = false;
 
         synchronized (resources) {
@@ -606,9 +606,6 @@
         try {
             // create out second in case in does not exist
             URLConnection con = getVersionedResourceURL(resource).openConnection();
-            
-            if (resource.getCookieStr() != null && resource.getCookieStr().length() > 0)
-                con.setRequestProperty("Cookie", resource.getCookieStr());
 
             InputStream in = new BufferedInputStream(con.getInputStream());
             OutputStream out = CacheUtil.getOutputStream(resource.location, resource.downloadVersion);
@@ -657,9 +654,6 @@
 
             // connect
             URLConnection connection = getVersionedResourceURL(resource).openConnection(); // this won't change so should be okay unsynchronized
-            
-            if (resource.getCookieStr() != null && resource.getCookieStr().length() > 0)
-                connection.setRequestProperty("Cookie", resource.getCookieStr());
 
             int size = connection.getContentLength();
             boolean current = CacheUtil.isCurrent(resource.location, resource.requestVersion, connection) && resource.getUpdatePolicy() != UpdatePolicy.FORCE;
diff -r 308c172cd230 rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
--- a/rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Fri Jul 03 11:52:45 2009 +0100
+++ b/rt/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Fri Jul 03 17:40:06 2009 -0400
@@ -314,7 +314,6 @@
                 initialJars.add(jars[i]); // regardless of part
 
             tracker.addResource(jars[i].getLocation(),
-                                file.getCookieStr(),
                                 jars[i].getVersion(), 
                                 jars[i].isCacheable() ? JNLPRuntime.getDefaultUpdatePolicy() : UpdatePolicy.FORCE
                                );
@@ -776,8 +775,7 @@
 
                             available.add(desc);
 
-                            tracker.addResource(desc.getLocation(), 
-                                    file.getCookieStr(),
+                            tracker.addResource(desc.getLocation(),
                                     desc.getVersion(), 
                                     JNLPRuntime.getDefaultUpdatePolicy()
                             );


More information about the distro-pkg-dev mailing list