From e49e0254ce0f405ca2af0d07f795f14acb00e091 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Thu, 2 Jun 2011 11:08:58 -0700 Subject: [PATCH] Issue 591:Need to handle 2+ cookies from TE --- .../ParseLoginResponseFromHeaders.java | 61 ++++++++++-------- .../ParseLoginResponseFromHeadersTest.java | 63 +++++++++++++++---- 2 files changed, 86 insertions(+), 38 deletions(-) diff --git a/common/vcloud/src/main/java/org/jclouds/vcloud/functions/ParseLoginResponseFromHeaders.java b/common/vcloud/src/main/java/org/jclouds/vcloud/functions/ParseLoginResponseFromHeaders.java index 4453929364..6c71e10d4e 100755 --- a/common/vcloud/src/main/java/org/jclouds/vcloud/functions/ParseLoginResponseFromHeaders.java +++ b/common/vcloud/src/main/java/org/jclouds/vcloud/functions/ParseLoginResponseFromHeaders.java @@ -18,10 +18,10 @@ */ package org.jclouds.vcloud.functions; -import static com.google.common.base.Preconditions.checkNotNull; import static org.jclouds.http.HttpUtils.releasePayload; import java.util.Map; +import java.util.NoSuchElementException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -41,6 +41,8 @@ import org.jclouds.vcloud.endpoints.Org; import org.jclouds.vcloud.xml.OrgListHandler; import com.google.common.base.Function; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; /** * This parses {@link VCloudSession} from HTTP headers. @@ -49,7 +51,7 @@ import com.google.common.base.Function; */ @Singleton public class ParseLoginResponseFromHeaders implements Function { - static final Pattern pattern = Pattern.compile("(vcloud-token=)?([^;]+)(;.*)?"); + static final Pattern pattern = Pattern.compile("(vcloud-token)=?([^;]+)(;.*)?"); private final ParseSax.Factory factory; private final Provider orgHandlerProvider; @@ -61,38 +63,45 @@ public class ParseLoginResponseFromHeaders implements Function org = factory.create(orgHandlerProvider.get()).parse( + final String token = parseTokenFromHeaders(from); + final Map org = factory.create(orgHandlerProvider.get()).parse( from.getPayload().getInput()); - return new VCloudSession() { - @VCloudToken - public String getVCloudToken() { - return matcher.group(2); - } + return new VCloudSession() { + @VCloudToken + public String getVCloudToken() { + return token; + } - @Org - public Map getOrgs() { - return org; - } - }; - - } + @Org + public Map getOrgs() { + return org; + } + }; } finally { releasePayload(from); } - throw new HttpResponseException("x-vcloud-authorization not found ", null, from); + } + + public String parseTokenFromHeaders(HttpResponse from) { + String cookieHeader = from.getFirstHeaderOrNull("x-vcloud-authorization"); + if (cookieHeader != null) { + Matcher matcher = pattern.matcher(cookieHeader); + return matcher.find() ? matcher.group(2) : cookieHeader; + } else { + try { + cookieHeader = Iterables.find(from.getHeaders().get(HttpHeaders.SET_COOKIE), Predicates.contains(pattern)); + Matcher matcher = pattern.matcher(cookieHeader); + matcher.find(); + return matcher.group(2); + } catch (NoSuchElementException e) { + throw new HttpResponseException(String.format("Header %s or %s must be present", "x-vcloud-authorization", + HttpHeaders.SET_COOKIE), null, from); + } + } } } diff --git a/common/vcloud/src/test/java/org/jclouds/vcloud/functions/ParseLoginResponseFromHeadersTest.java b/common/vcloud/src/test/java/org/jclouds/vcloud/functions/ParseLoginResponseFromHeadersTest.java index d4945d37f0..fdfeadc1ea 100644 --- a/common/vcloud/src/test/java/org/jclouds/vcloud/functions/ParseLoginResponseFromHeadersTest.java +++ b/common/vcloud/src/test/java/org/jclouds/vcloud/functions/ParseLoginResponseFromHeadersTest.java @@ -23,6 +23,7 @@ import static org.testng.Assert.assertEquals; import java.net.URI; import org.jclouds.http.HttpResponse; +import org.jclouds.http.HttpResponseException; import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.io.Payloads; import org.jclouds.vcloud.VCloudMediaType; @@ -54,60 +55,98 @@ public class ParseLoginResponseFromHeadersTest extends BaseHandlerTest { @Test public void testApply() { HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass() - .getResourceAsStream("/orglist.xml")), ImmutableMultimap. of("x-vcloud-authorization", - "vcloud-token=9er4d061-4bff-48fa-84b1-5da7166764d2; path=/")); + .getResourceAsStream("/orglist.xml")), ImmutableMultimap. of("x-vcloud-authorization", + "vcloud-token=9er4d061-4bff-48fa-84b1-5da7166764d2; path=/")); response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8"); response.getPayload().getContentMetadata().setContentLength(307l); VCloudSession reply = parser.apply(response); assertEquals(reply.getVCloudToken(), "9er4d061-4bff-48fa-84b1-5da7166764d2"); assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org", - VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48")))); + VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48")))); } @Test public void testApplyBlueLock() { HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass() - .getResourceAsStream("/orglist.xml")), ImmutableMultimap. of("x-vcloud-authorization", - "MUKOJ2HoAfoMmLnHRp4esNb2MtWscCLLhVysnsIsCG0=")); + .getResourceAsStream("/orglist.xml")), ImmutableMultimap. of("x-vcloud-authorization", + "MUKOJ2HoAfoMmLnHRp4esNb2MtWscCLLhVysnsIsCG0=")); response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8"); response.getPayload().getContentMetadata().setContentLength(307l); VCloudSession reply = parser.apply(response); assertEquals(reply.getVCloudToken(), "MUKOJ2HoAfoMmLnHRp4esNb2MtWscCLLhVysnsIsCG0="); assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org", - VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48")))); + VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48")))); } @Test public void testApplyTerremark() { HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass() - .getResourceAsStream("/orglist.xml")), ImmutableMultimap. of("Set-Cookie", - "vcloud-token=37ce2715-9aba-4f48-8e45-2db8a8da702d; path=/")); + .getResourceAsStream("/orglist.xml")), ImmutableMultimap. of("Set-Cookie", + "vcloud-token=37ce2715-9aba-4f48-8e45-2db8a8da702d; path=/")); response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8"); response.getPayload().getContentMetadata().setContentLength(307l); VCloudSession reply = parser.apply(response); assertEquals(reply.getVCloudToken(), "37ce2715-9aba-4f48-8e45-2db8a8da702d"); assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org", - VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48")))); + VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48")))); } + @Test + public void testApplyTerremarkMultipleCookies() { + HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass() + .getResourceAsStream("/orglist.xml")), ImmutableMultimap. builder().put("Set-Cookie", + "NSC_ESUO_21654_72.46.239.132_443=fooo;expires=Thu, 02-Jun-2011 17:19:26 GMT;path=/;secure;httponly") + .put("Set-Cookie", "vcloud-token=37ce2715-9aba-4f48-8e45-2db8a8da702d; path=/").build()); + response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8"); + response.getPayload().getContentMetadata().setContentLength(307l); + + VCloudSession reply = parser.apply(response); + assertEquals(reply.getVCloudToken(), "37ce2715-9aba-4f48-8e45-2db8a8da702d"); + assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org", + VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48")))); + + } + + @Test(expectedExceptions = HttpResponseException.class) + public void testUnmatchedCookieThrowsHttpResponseException() { + HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass() + .getResourceAsStream("/orglist.xml")), ImmutableMultimap. builder().put("Set-Cookie", + "NSC_ESUO_21654_72.46.239.132_443=fooo;expires=Thu, 02-Jun-2011 17:19:26 GMT;path=/;secure;httponly") + .build()); + response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8"); + response.getPayload().getContentMetadata().setContentLength(307l); + + parser.apply(response); + } + + @Test(expectedExceptions = HttpResponseException.class) + public void testNoThrowsHttpResponseException() { + HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass() + .getResourceAsStream("/orglist.xml")), ImmutableMultimap. of()); + response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8"); + response.getPayload().getContentMetadata().setContentLength(307l); + + parser.apply(response); + } + @Test public void testApplyVirtacore() { HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass() - .getResourceAsStream("/orglist.xml")), ImmutableMultimap. of("x-vcloud-authorization", - "vcloud-token=IPy0w7UGD4lwtdWAK/ZVzfuLK+dztxGRqsOhWqV0i48=")); + .getResourceAsStream("/orglist.xml")), ImmutableMultimap. of("x-vcloud-authorization", + "vcloud-token=IPy0w7UGD4lwtdWAK/ZVzfuLK+dztxGRqsOhWqV0i48=")); response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8"); response.getPayload().getContentMetadata().setContentLength(307l); VCloudSession reply = parser.apply(response); assertEquals(reply.getVCloudToken(), "IPy0w7UGD4lwtdWAK/ZVzfuLK+dztxGRqsOhWqV0i48="); assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org", - VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48")))); + VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48")))); } }