Issue 591:Need to handle 2+ cookies from TE

This commit is contained in:
Adrian Cole 2011-06-02 11:08:58 -07:00
parent 9ac8ad2b5f
commit e49e0254ce
2 changed files with 86 additions and 38 deletions

View File

@ -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<HttpResponse, VCloudSession> {
static final Pattern pattern = Pattern.compile("(vcloud-token=)?([^;]+)(;.*)?");
static final Pattern pattern = Pattern.compile("(vcloud-token)=?([^;]+)(;.*)?");
private final ParseSax.Factory factory;
private final Provider<OrgListHandler> orgHandlerProvider;
@ -61,26 +63,18 @@ public class ParseLoginResponseFromHeaders implements Function<HttpResponse, VCl
}
/**
* parses the http response headers to create a new {@link VCloudSession}
* object.
* parses the http response headers to create a new {@link VCloudSession} object.
*/
public VCloudSession apply(HttpResponse from) {
String cookieHeader = from.getFirstHeaderOrNull("x-vcloud-authorization");
if (cookieHeader == null)
cookieHeader = from.getFirstHeaderOrNull(HttpHeaders.SET_COOKIE);
checkNotNull(cookieHeader, "Header %s or %s must be present", "x-vcloud-authorization", HttpHeaders.SET_COOKIE);
final Matcher matcher = pattern.matcher(cookieHeader);
boolean matchFound = matcher.find();
try {
if (matchFound) {
final String token = parseTokenFromHeaders(from);
final Map<String, ReferenceType> org = factory.create(orgHandlerProvider.get()).parse(
from.getPayload().getInput());
return new VCloudSession() {
@VCloudToken
public String getVCloudToken() {
return matcher.group(2);
return token;
}
@Org
@ -88,11 +82,26 @@ public class ParseLoginResponseFromHeaders implements Function<HttpResponse, VCl
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);
}
}
}
}

View File

@ -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;
@ -96,6 +97,44 @@ public class ParseLoginResponseFromHeadersTest extends BaseHandlerTest {
}
@Test
public void testApplyTerremarkMultipleCookies() {
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> 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.<String, String> 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.<String, String> 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()