
com.threewks.thundr.http.service.gae.HttpResponseImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of thundr-gae Show documentation
Show all versions of thundr-gae Show documentation
A thundr module enabling thundr for use on GAE (Google App Engine)
/*
* This file is a component of thundr, a software library from 3wks.
* Read more: http://3wks.github.io/thundr/
* Copyright (C) 2014 3wks,
*
* Licensed 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 com.threewks.thundr.http.service.gae;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpCookie;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.apache.commons.lang3.StringUtils;
import com.atomicleopard.expressive.EList;
import com.atomicleopard.expressive.Expressive;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.threewks.thundr.http.Header;
import com.threewks.thundr.http.service.BaseHttpResponse;
import com.threewks.thundr.http.service.HttpException;
import com.threewks.thundr.http.service.HttpRequestException;
import com.threewks.thundr.http.service.HttpResponse;
import com.threewks.thundr.http.service.HttpResponseException;
public class HttpResponseImpl extends BaseHttpResponse implements HttpResponse {
private Future future;
private HTTPResponse response;
private Map> headers;
private Map> headersLower;
private Map> cookies;
private URL url;
public HttpResponseImpl(Future future, HttpServiceImpl service, URL url) {
super(service);
this.future = future;
this.url = url;
}
@Override
public int getStatus() {
return response().getResponseCode();
}
@Override
public String getContentType() {
return getHeader(Header.ContentType);
}
@Override
public String getHeader(String name) {
List headers = getHeaders(name);
return headers == null ? null : headers.get(0);
}
@Override
public List getHeaders(String name) {
response();
List headers = headersLower.get(StringUtils.lowerCase(name));
return headers == null ? null : Collections.unmodifiableList(headers);
}
@Override
public Map> getHeaders() {
response();
return Collections.unmodifiableMap(headers);
}
@Override
public HttpCookie getCookie(String cookieName) {
List cookies = getCookies(cookieName);
return cookies == null ? null : cookies.get(0);
}
@Override
public List getCookies(String name) {
response();
return cookies.get(name);
}
@Override
public List getCookies() {
response();
return Expressive.flatten(cookies.values());
}
@Override
public String getBody() {
byte[] data = getBodyAsBytes();
String characterEncoding = getCharset();
try {
return data == null ? "" : new String(data, characterEncoding);
} catch (UnsupportedEncodingException e) {
throw new HttpException(e, "Failed to read body as string- character encoding '%s' not supported: %s", characterEncoding, e.getMessage());
}
}
@Override
public byte[] getBodyAsBytes() {
return response().getContent();
}
@Override
public InputStream getBodyAsStream() {
byte[] content = response().getContent();
content = content == null ? new byte[0] : content;
return new ByteArrayInputStream(content);
}
@Override
public URI getUri() {
try {
// final url is only non-null when we follow redirects
URL finalUrl = response().getFinalUrl();
return finalUrl == null ? url.toURI() : finalUrl.toURI();
} catch (URISyntaxException e) {
throw new HttpResponseException(e, "Uri cannot be parsed: %s", e.getMessage());
}
}
private HTTPResponse response() {
if (response == null) {
try {
response = future.get();
headers = buildHeaderMap(response);
headersLower = buildHeadersLowerMap(headers);
cookies = buildCookieMap(headersLower);
return response;
} catch (InterruptedException e) {
throw new HttpRequestException("Failed to wait for completion of asynchronous request: %s", e.getMessage());
} catch (ExecutionException e) {
throw new HttpRequestException(e, "Failed to get result for asynchronous request: %s", e.getMessage());
}
}
return response;
}
private Map> buildHeaderMap(HTTPResponse response) {
Map> headers = new LinkedHashMap>();
for (HTTPHeader header : response.getHeadersUncombined()) {
String key = header.getName();
String value = header.getValue();
List values = headers.get(key);
if (values == null) {
values = new ArrayList();
headers.put(key, values);
}
values.add(value);
}
return headers;
}
private Map> buildHeadersLowerMap(Map> headers) {
Map> lowercase = new LinkedHashMap>();
for (Map.Entry> entry : headers.entrySet()) {
lowercase.put(StringUtils.lowerCase(entry.getKey()), new ArrayList<>(entry.getValue()));
}
return lowercase;
}
private Map> buildCookieMap(Map> headersLower) {
Map> cookies = new LinkedHashMap>();
for (String setCookieHeader : getCookieHeaders(headersLower)) {
List cookieSet = parseCookies(setCookieHeader);
for (HttpCookie httpCookie : cookieSet) {
String name = httpCookie.getName();
List existingCookies = cookies.get(name);
if (existingCookies == null) {
existingCookies = new ArrayList();
cookies.put(name, existingCookies);
}
existingCookies.add(httpCookie);
}
}
return cookies;
}
/**
* Get all cookie headers from the given header map.
*
* Note: this will get all "Set-Cookie" and "Set-Cookie2" headers.
*
* @param headers the map of headers to get the set cookie headers from.
* @return a list of headers.
*/
static List getCookieHeaders(Map> headers) {
EList cookieHeaders = Expressive.list();
cookieHeaders.addItems(headers.get(Header.SetCookie.toLowerCase()));
cookieHeaders.addItems(headers.get(Header.SetCookie2.toLowerCase()));
return cookieHeaders;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy