Add the permutation's strong name to the HTTP headers of GWT RPC requests.

http://gwt-code-reviews.appspot.com/9804

Patch by: bobv
Review by: rjrjr


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@4941 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java b/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java
index cdcbc7b..cd2ae19 100644
--- a/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java
+++ b/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java
@@ -15,6 +15,7 @@
  */
 package com.google.gwt.user.client.rpc.impl;
 
+import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.JavaScriptObject;
 import com.google.gwt.http.client.Request;
 import com.google.gwt.http.client.RequestBuilder;
@@ -34,6 +35,12 @@
  */
 public abstract class RemoteServiceProxy implements SerializationStreamFactory,
     ServiceDefTarget {
+
+  /**
+   * NB: Keep in sync with RemoteServiceServlet.
+   */
+  private static final String STRONG_NAME_HEADER = "X-GWT-Permutation";
+
   /**
    * A global id to track any given request.
    */
@@ -300,6 +307,7 @@
         getServiceEntryPoint());
 
     rb.setHeader("Content-Type", "text/x-gwt-rpc; charset=utf-8");
+    rb.setHeader(STRONG_NAME_HEADER, GWT.getPermutationStrongName());
     rb.setCallback(responseHandler);
     rb.setRequestData(requestData);
     return rb;
diff --git a/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java b/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
index 16dde6f..fdabbb1 100644
--- a/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
+++ b/user/src/com/google/gwt/user/server/rpc/RemoteServiceServlet.java
@@ -40,6 +40,11 @@
 public class RemoteServiceServlet extends HttpServlet implements
     SerializationPolicyProvider {
 
+  /**
+   * NB: Keep in sync with RemoteServiceProxy.
+   */
+  private static final String STRONG_NAME_HEADER = "X-GWT-Permutation";
+
   private final ThreadLocal<HttpServletRequest> perThreadRequest = new ThreadLocal<HttpServletRequest>();
 
   private final ThreadLocal<HttpServletResponse> perThreadResponse = new ThreadLocal<HttpServletResponse>();
@@ -288,6 +293,16 @@
   }
 
   /**
+   * Returns the strong name of the permutation, as reported by the client that
+   * issued the request, or <code>null</code> if it could not be determined.
+   * This information is encoded in the {@value #STRONG_NAME_HEADER} HTTP
+   * header.
+   */
+  protected final String getPermutationStrongName() {
+    return getThreadLocalRequest().getHeader(STRONG_NAME_HEADER);
+  }
+
+  /**
    * Gets the <code>HttpServletRequest</code> object for the current call. It is
    * stored thread-locally so that simultaneous invocations can have different
    * request objects.
diff --git a/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTest.java b/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTest.java
index 4145b16..37011ca 100644
--- a/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTest.java
+++ b/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTest.java
@@ -100,6 +100,25 @@
     assertTrue(req.isPending());
   }
 
+  public void testPermutationStrongName() {
+    RemoteServiceServletTestServiceAsync service = getAsyncService();
+
+    delayTestFinish(TEST_DELAY);
+
+    assertNotNull(GWT.getPermutationStrongName());
+    service.testExpectPermutationStrongName(GWT.getPermutationStrongName(),
+        new AsyncCallback<Void>() {
+
+          public void onFailure(Throwable caught) {
+            TestSetValidator.rethrowException(caught);
+          }
+
+          public void onSuccess(Void result) {
+            finishTest();
+          }
+        });
+  }
+
   public void testServiceInterfaceLocation() {
     RemoteServiceServletTestServiceAsync service = getAsyncService();
 
diff --git a/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTestService.java b/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTestService.java
index e55e36f..e6ebdb6 100644
--- a/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTestService.java
+++ b/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTestService.java
@@ -16,10 +16,13 @@
 package com.google.gwt.user.client.rpc;
 
 /**
- * TODO: document me.
+ * A RemoteService for testing the details of the "over-HTTP" part of
+ * RPC-over-HTTP.
  */
 public interface RemoteServiceServletTestService extends RemoteService {
   void test();
 
   void testExpectCustomHeader();
+
+  void testExpectPermutationStrongName(String expectedStrongName);
 }
diff --git a/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTestServiceAsync.java b/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTestServiceAsync.java
index 154e091..4a09462 100644
--- a/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTestServiceAsync.java
+++ b/user/test/com/google/gwt/user/client/rpc/RemoteServiceServletTestServiceAsync.java
@@ -19,10 +19,13 @@
 import com.google.gwt.http.client.RequestBuilder;
 
 /**
- * TODO: document me.
+ * Async peer of {@link RemoteServiceServletTestService}.
  */
 public interface RemoteServiceServletTestServiceAsync {
   Request test(AsyncCallback<Void> callback);
 
   RequestBuilder testExpectCustomHeader(AsyncCallback<Void> callback);
+
+  void testExpectPermutationStrongName(String expectedStrongName,
+      AsyncCallback<Void> callback);
 }
diff --git a/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTestServiceImplBase.java b/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTestServiceImplBase.java
index 39e1934..9f94630 100644
--- a/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTestServiceImplBase.java
+++ b/user/test/com/google/gwt/user/server/rpc/RemoteServiceServletTestServiceImplBase.java
@@ -20,7 +20,8 @@
 import javax.servlet.http.HttpServletRequest;
 
 /**
- * TODO: document me.
+ * A RemoteService for testing the details of the "over-HTTP" part of
+ * RPC-over-HTTP.
  */
 public class RemoteServiceServletTestServiceImplBase extends
     RemoteServiceServlet implements RemoteServiceServletTestService {
@@ -34,4 +35,15 @@
       throw new RuntimeException("Missing header");
     }
   }
+
+  public void testExpectPermutationStrongName(String expectedStrongName) {
+    if (getPermutationStrongName() == null) {
+      throw new NullPointerException("getPermutationStrongName()");
+    }
+
+    if (!expectedStrongName.equals(getPermutationStrongName())) {
+      throw new RuntimeException(expectedStrongName + " != "
+          + getPermutationStrongName());
+    }
+  }
 }