You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by li...@apache.org on 2008/03/17 16:00:26 UTC
svn commit: r637925 - in /incubator/shindig/trunk/java/gadgets/src:
main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java
Author: lindner
Date: Mon Mar 17 08:00:22 2008
New Revision: 637925
URL: http://svn.apache.org/viewvc?rev=637925&view=rev
Log:
Apply Brian Eaton's test cases patch from SHINDIG-134
Added:
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java
Modified:
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
Modified: incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java?rev=637925&r1=637924&r2=637925&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/http/ProxyHandler.java Mon Mar 17 08:00:22 2008
@@ -52,7 +52,14 @@
public class ProxyHandler {
private static final String UNPARSEABLE_CRUFT = "throw 1; < don't be evil' >";
-
+ private static final String POST_DATA_PARAM = "postData";
+ private static final String METHOD_PARAM = "httpMethod";
+ private static final String SECURITY_TOKEN_PARAM = "st";
+ private static final String HEADERS_PARAM = "headers";
+ private static final String NOCACHE_PARAM = "nocache";
+ private static final String URL_PARAM = "url";
+ private static final String AUTHZ_PARAM = "authz";
+
private final RemoteContentFetcher fetcher;
private final static Set<String> DISALLOWED_RESPONSE_HEADERS
@@ -80,7 +87,7 @@
JSONObject resp = new JSONObject()
.put("body", results.getResponseAsString())
.put("rc", results.getHttpStatusCode());
- String url = request.getParameter("url");
+ String url = request.getParameter(URL_PARAM);
JSONObject json = new JSONObject().put(url, resp);
output = UNPARSEABLE_CRUFT + json.toString();
} catch (JSONException e) {
@@ -140,10 +147,10 @@
}
try {
- URL originalUrl = validateUrl(request.getParameter("url"));
+ URL originalUrl = validateUrl(request.getParameter(URL_PARAM));
GadgetSigner signer = state.getGadgetSigner();
URL signedUrl;
- if ("signed".equals(request.getParameter("authz"))) {
+ if ("signed".equals(request.getParameter(AUTHZ_PARAM))) {
GadgetToken token = extractAndValidateToken(request, signer);
if (token == null) {
return new RemoteContent(HttpServletResponse.SC_UNAUTHORIZED,
@@ -158,11 +165,11 @@
byte[] postBody = null;
if ("POST".equals(method)) {
- method = getParameter(request, "httpMethod", "GET");
+ method = getParameter(request, METHOD_PARAM, "GET");
postBody = URLDecoder.decode(
- getParameter(request, "postData", ""), encoding).getBytes();
+ getParameter(request, POST_DATA_PARAM, ""), encoding).getBytes();
- String headerData = request.getParameter("headers");
+ String headerData = request.getParameter(HEADERS_PARAM);
if (headerData == null || headerData.length() == 0) {
headers = Collections.emptyMap();
} else {
@@ -193,7 +200,7 @@
RemoteContentRequest.Options options
= new RemoteContentRequest.Options();
- options.ignoreCache = "1".equals(request.getParameter("nocache"));
+ options.ignoreCache = "1".equals(request.getParameter(NOCACHE_PARAM));
RemoteContentRequest req = new RemoteContentRequest(
method, signedUrl.toURI(), headers, postBody, options);
return fetcher.fetch(req);
@@ -268,7 +275,7 @@
if (signer == null) {
return null;
}
- String token = getParameter(request, "st", "");
+ String token = getParameter(request, SECURITY_TOKEN_PARAM, "");
return signer.createToken(token);
}
@@ -279,8 +286,8 @@
@SuppressWarnings("unchecked")
private URL signUrl(CrossServletState state, URL originalUrl, GadgetToken token,
HttpServletRequest request) throws GadgetException {
- String method = getParameter(request, "httpMethod", "GET");
- String body = getParameter(request, "postData", null);
+ String method = getParameter(request, METHOD_PARAM, "GET");
+ String body = getParameter(request, POST_DATA_PARAM, null);
RequestSigner signer = state.makeSignedFetchRequestSigner(token);
return signer.signRequest(method, originalUrl, body);
}
Modified: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java?rev=637925&r1=637924&r2=637925&view=diff
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java (original)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/GadgetTestFixture.java Mon Mar 17 08:00:22 2008
@@ -21,8 +21,10 @@
import org.apache.shindig.gadgets.http.CrossServletState;
+import org.apache.shindig.gadgets.http.ProxyHandler;
import org.apache.shindig.gadgets.spec.GadgetSpec;
import org.apache.shindig.gadgets.spec.MessageBundle;
+import org.apache.shindig.util.BlobCrypterException;
import java.util.Set;
import java.util.concurrent.Executors;
@@ -35,6 +37,7 @@
public final HttpServletRequest request = mock(HttpServletRequest.class, true);
public final HttpServletResponse response = mock(HttpServletResponse.class, true);
public final GadgetServer gadgetServer;
+ public final ProxyHandler proxyHandler;
public final RemoteContentFetcher fetcher = mock(RemoteContentFetcher.class, true);
@SuppressWarnings(value="unchecked")
public final DataFetcher<GadgetSpec> specFetcher = mock(DataFetcher.class, true);
@@ -51,7 +54,17 @@
@Override
public GadgetSigner getGadgetSigner() {
- return null;
+ return new GadgetSigner() {
+ @Override
+ public GadgetToken createToken(String tokenString)
+ throws GadgetException {
+ try {
+ return new BasicGadgetToken("owner", "viewer", "app", "domain");
+ } catch (BlobCrypterException e) {
+ throw new GadgetException(GadgetException.Code.INVALID_GADGET_TOKEN, e);
+ }
+ }
+ };
}
@Override
@@ -86,7 +99,26 @@
@Override
public RequestSigner makeSignedFetchRequestSigner(GadgetToken token) {
- return null;
+ // Real implementations should use their own key, probably pulled from
+ // disk rather than hardcoded in the source.
+ final String PRIVATE_KEY_TEXT =
+ "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V" +
+ "A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d" +
+ "7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ" +
+ "hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H" +
+ "X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm" +
+ "uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw" +
+ "rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z" +
+ "zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn" +
+ "qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG" +
+ "WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno" +
+ "cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+" +
+ "3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8" +
+ "AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54" +
+ "Lw03eHTNQghS0A==";
+ final String PRIVATE_KEY_NAME = "shindig-insecure-key";
+ return new SignedFetchRequestSigner(token, PRIVATE_KEY_NAME,
+ PRIVATE_KEY_TEXT);
}
};
@@ -107,5 +139,6 @@
config.setFeatureRegistry(registry);
config.setGadgetBlacklist(blacklist);
gadgetServer = new GadgetServer(config);
+ proxyHandler = new ProxyHandler(fetcher);
}
}
Added: incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java?rev=637925&view=auto
==============================================================================
--- incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java (added)
+++ incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/http/ProxyHandlerTest.java Mon Mar 17 08:00:22 2008
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.shindig.gadgets.http;
+
+import static org.easymock.EasyMock.expect;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.net.URI;
+
+import org.apache.shindig.gadgets.GadgetTestFixture;
+import org.apache.shindig.gadgets.RemoteContent;
+import org.apache.shindig.gadgets.RemoteContentRequest;
+import org.easymock.EasyMock;
+import org.easymock.IArgumentMatcher;
+import org.json.JSONObject;
+
+public class ProxyHandlerTest extends GadgetTestFixture {
+
+ private final static String URL_ONE = "http://www.example.com/test.html";
+ private final static String DATA_ONE = "hello world";
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final PrintWriter writer = new PrintWriter(baos);
+
+ private void expectGetAndReturnData(String url, byte[] data) throws Exception {
+ RemoteContentRequest req = new RemoteContentRequest(
+ "GET", new URI(url), null, null, new RemoteContentRequest.Options());
+ RemoteContent resp = new RemoteContent(200, data, null);
+ expect(fetcher.fetch(req)).andReturn(resp);
+ }
+
+ private void expectPostAndReturnData(String url, byte[] body, byte[] data) throws Exception {
+ RemoteContentRequest req = new RemoteContentRequest(
+ "POST", new URI(url), null, body, new RemoteContentRequest.Options());
+ RemoteContent resp = new RemoteContent(200, data, null);
+ expect(fetcher.fetch(req)).andReturn(resp);
+ }
+
+ private void setupPostRequestMock(String url, String body) throws Exception {
+ setupGenericRequestMock("POST", url);
+ expect(request.getParameter("postData")).andReturn(body).atLeastOnce();
+ }
+
+ private void setupGetRequestMock(String url) throws Exception {
+ setupGenericRequestMock("GET", url);
+ }
+
+ private void setupGenericRequestMock(String method, String url) throws Exception {
+ expect(request.getMethod()).andReturn("POST").atLeastOnce();
+ expect(request.getParameter("httpMethod")).andReturn(method).atLeastOnce();
+ expect(request.getParameter("url")).andReturn(url).atLeastOnce();
+ expect(response.getWriter()).andReturn(writer).atLeastOnce();
+ }
+
+ private JSONObject readJSONResponse(String body) throws Exception {
+ String json = body.substring("throw 1; < don't be evil' >".length(), body.length());
+ return new JSONObject(json);
+ }
+
+ public void testFetchJson() throws Exception {
+ setupGetRequestMock(URL_ONE);
+ expectGetAndReturnData(URL_ONE, DATA_ONE.getBytes());
+ replay();
+ proxyHandler.fetchJson(request, response, state);
+ verify();
+ writer.close();
+ JSONObject json = readJSONResponse(baos.toString());
+ JSONObject info = json.getJSONObject(URL_ONE);
+ assertEquals(200, info.getInt("rc"));
+ assertEquals(DATA_ONE, info.get("body"));
+ }
+
+ public void testFetchDecodedUrl() throws Exception {
+ String origUrl = "http://www.example.com";
+ String cleanedUrl = "http://www.example.com/";
+ setupGetRequestMock(origUrl);
+ expectGetAndReturnData(cleanedUrl, DATA_ONE.getBytes());
+ replay();
+ proxyHandler.fetchJson(request, response, state);
+ verify();
+ writer.close();
+ JSONObject json = readJSONResponse(baos.toString());
+ JSONObject info = json.getJSONObject(origUrl);
+ assertEquals(200, info.getInt("rc"));
+ assertEquals(DATA_ONE, info.get("body"));
+ }
+
+ public void testEmptyDocument() throws Exception {
+ setupGetRequestMock(URL_ONE);
+ expectGetAndReturnData(URL_ONE, "".getBytes());
+ replay();
+ proxyHandler.fetchJson(request, response, state);
+ verify();
+ writer.close();
+ JSONObject json = readJSONResponse(baos.toString());
+ JSONObject info = json.getJSONObject(URL_ONE);
+ assertEquals(200, info.getInt("rc"));
+ assertEquals("", info.get("body"));
+ }
+
+ public void testPostRequest() throws Exception {
+ String body = "abc";
+ setupPostRequestMock(URL_ONE, body);
+ expectPostAndReturnData(URL_ONE, body.getBytes(), DATA_ONE.getBytes());
+ replay();
+ proxyHandler.fetchJson(request, response, state);
+ verify();
+ writer.close();
+ JSONObject json = readJSONResponse(baos.toString());
+ JSONObject info = json.getJSONObject(URL_ONE);
+ assertEquals(200, info.getInt("rc"));
+ assertEquals(DATA_ONE, info.get("body"));
+ }
+
+ public void testSignedGetRequest() throws Exception {
+ setupGetRequestMock(URL_ONE);
+ expect(request.getParameter("st")).andReturn("fake-token").atLeastOnce();
+ expect(request.getParameter("authz")).andReturn("signed").atLeastOnce();
+ RemoteContent resp = new RemoteContent(200, DATA_ONE.getBytes(), null);
+ expect(fetcher.fetch(looksLikeSignedFetch(URL_ONE))).andReturn(resp);
+ replay();
+ proxyHandler.fetchJson(request, response, state);
+ verify();
+ writer.close();
+ }
+
+ private RemoteContentRequest looksLikeSignedFetch(String url) {
+ EasyMock.reportMatcher(new SignedFetchArgumentMatcher(url));
+ return null;
+ }
+
+ private class SignedFetchArgumentMatcher implements IArgumentMatcher {
+
+ private String expectedUrl;
+
+ public SignedFetchArgumentMatcher(String expectedUrl) {
+ this.expectedUrl = expectedUrl;
+ }
+
+ @Override
+ public void appendTo(StringBuffer sb) {
+ sb.append("SignedFetchArgumentMatcher(");
+ sb.append(expectedUrl);
+ sb.append(")");
+ }
+
+ @Override
+ public boolean matches(Object arg0) {
+ RemoteContentRequest request = (RemoteContentRequest)arg0;
+ String url = request.getUri().toASCIIString();
+ return (url.startsWith(expectedUrl) &&
+ url.contains("opensocial_ownerid") && url.contains("opensocial_viewerid") &&
+ url.contains("opensocial_appid") && url.contains("opensocial_appid"));
+ }
+
+ }
+}