com.google.appengine.tools.cloudstorage.oauth.URLFetchUtils Maven / Gradle / Ivy
/*
* Copyright 2012 Google Inc. All Rights Reserved.
*
* 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.google.appengine.tools.cloudstorage.oauth;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.api.client.http.HttpContent;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponseException;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map.Entry;
/**
* URLFetch-related utilities.
*/
final class URLFetchUtils {
@VisibleForTesting
static final DateTimeFormatter DATE_FORMAT =
DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss 'GMT'")
.withZoneUTC().withLocale(Locale.US);
private URLFetchUtils() {}
/**
* This holds onto the relevant data for logging or error handling.
* Holding onto an instance of this class rather than the request itself is useful because it
* avoids holding a reference to the payload.
*/
static class HTTPRequestInfo {
private final String method;
private final long length;
private final URL url;
private final HttpHeaders h1;
private final List h2;
HTTPRequestInfo(HttpRequest req) {
method = req.getRequestMethod();
url = req.getUrl().toURL();
long myLength;
HttpContent content = req.getContent();
try {
myLength = content == null ? -1 : content.getLength();
} catch (IOException e) {
myLength = -1;
}
length = myLength;
h1 = req.getHeaders();
h2 = null;
}
HTTPRequestInfo(HTTPRequest req) {
method = req.getMethod().toString();
byte[] payload = req.getPayload();
length = payload == null ? -1 : payload.length;
url = req.getURL();
h1 = null;
h2 = req.getHeaders();
}
public void appendToString(StringBuilder b) {
b.append(method).append(' ').append(url);
if (h1 != null) {
for (Entry h : h1.entrySet()) {
b.append('\n').append(h.getKey()).append(": ").append(h.getValue());
}
}
if (h2 != null) {
for (HTTPHeader h : h2) {
b.append('\n').append(h.getName()).append(": ").append(h.getValue());
}
}
b.append("\n\n");
if (length <= 0) {
b.append("no content");
} else {
b.append(length).append(" bytes of content");
}
b.append('\n');
}
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
appendToString(buffer);
return buffer.toString();
}
}
/**
* Parses the date or returns null if it fails to do so.
*/
static Date parseDate(String dateString) {
try {
return DATE_FORMAT.parseDateTime(dateString).toDate();
} catch (IllegalArgumentException e) {
return null;
}
}
private static void appendResponse(HttpResponseException exception, StringBuilder b) {
b.append(exception.getStatusCode()).append(" with ");
Long contentLength = exception.getHeaders().getContentLength();
b.append(contentLength != null ? contentLength : Long.valueOf(0));
b.append(" bytes of content");
HttpHeaders headers = exception.getHeaders();
for (String name : headers.keySet()) {
b.append('\n').append(name).append(": ").append(headers.get(name));
}
b.append('\n').append(exception.getContent()).append('\n');
}
static void appendResponse(HTTPResponse resp, StringBuilder b) {
byte[] content = resp.getContent();
b.append(resp.getResponseCode()).append(" with ").append(content == null ? 0 : content.length);
b.append(" bytes of content");
for (HTTPHeader h : resp.getHeadersUncombined()) {
b.append('\n').append(h.getName()).append(": ").append(h.getValue());
}
b.append('\n').append(content == null ? "" : new String(content, UTF_8)).append('\n');
}
static String describeRequestAndResponse(HTTPRequestInfo req, HttpResponseException resp) {
StringBuilder b = new StringBuilder(256).append("Request: ");
req.appendToString(b);
b.append("\nResponse: ");
appendResponse(resp, b);
return b.toString();
}
static String describeRequestAndResponse(HTTPRequestInfo req, HTTPResponse resp) {
StringBuilder b = new StringBuilder(256).append("Request: ");
req.appendToString(b);
b.append("\nResponse: ");
appendResponse(resp, b);
return b.toString();
}
/** Gets all headers with the name {@code headerName}, case-insensitive. */
private static Iterable getHeaders(HTTPResponse resp, String headerName) {
final String lowercaseHeaderName = headerName.toLowerCase();
return Iterables.filter(resp.getHeadersUncombined(), new Predicate() {
@Override public boolean apply(HTTPHeader header) {
return header.getName().toLowerCase().equals(lowercaseHeaderName);
}
});
}
/**
* Checks that exactly one header named {@code headerName} is present and returns its value.
*/
static String getSingleHeader(HTTPResponse resp, String headerName) {
return Iterables.getOnlyElement(getHeaders(resp, headerName)).getValue();
}
static HTTPRequest copyRequest(HTTPRequest in) {
HTTPRequest out = new HTTPRequest(in.getURL(), in.getMethod(), in.getFetchOptions());
for (HTTPHeader h : in.getHeaders()) {
out.addHeader(h);
}
out.setPayload(in.getPayload());
return out;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy