1 // Copyright 2010 Google Inc. All Rights Reserved.
3 package com
.google
.appengine
.tools
.remoteapi
;
5 import org
.apache
.commons
.httpclient
.Cookie
;
6 import org
.apache
.commons
.httpclient
.util
.EncodingUtil
;
8 import java
.io
.IOException
;
9 import java
.util
.ArrayList
;
10 import java
.util
.List
;
13 * Abstract class that handles making HTTP requests to App Engine. The actual
14 * mechanism by which the HTTP requests are made is left to subclasses to
16 * <p> This class is thread-safe. </p>
19 abstract class AppEngineClient
{
20 private final String hostname
;
21 private final int port
;
22 private final String userEmail
;
23 private final Cookie
[] authCookies
;
24 private final String remoteApiPath
;
25 private final int maxResponseSize
;
27 private final String appId
;
29 AppEngineClient(RemoteApiOptions options
,
30 List
<Cookie
> authCookies
, String appId
) {
31 if (options
== null) {
32 throw new IllegalArgumentException("options not set");
34 if (authCookies
== null) {
35 throw new IllegalArgumentException("authCookies not set");
37 this.hostname
= options
.getHostname();
38 this.port
= options
.getPort();
39 this.userEmail
= options
.getUserEmail();
40 this.authCookies
= authCookies
.toArray(new Cookie
[0]);
41 this.remoteApiPath
= options
.getRemoteApiPath();
42 this.maxResponseSize
= options
.getMaxHttpResponseSize();
48 * @return the {@link Cookie} objects that should be used for authentication
50 Cookie
[] getAuthCookies() {
54 int getMaxResponseSize() {
55 return maxResponseSize
;
59 * @return the path to the remote api for this app (if logged in), {@code null} otherwise
61 String
getRemoteApiPath() {
66 * @return the app id for this app (if logged in), {@code null} otherwise
76 String
serializeCredentials() {
77 StringBuilder out
= new StringBuilder();
78 out
.append("host=" + hostname
+ "\n");
79 out
.append("email=" + userEmail
+ "\n");
80 for (Cookie cookie
: authCookies
) {
81 out
.append("cookie=" + cookie
.getName() + "=" + cookie
.getValue() + "\n");
83 return out
.toString();
86 String
makeUrl(String path
) {
87 if (!path
.startsWith("/")) {
88 throw new IllegalArgumentException("path doesn't start with a slash: " + path
);
90 String protocol
= port
== 443 ?
"https" : "http";
91 return protocol
+ "://" + hostname
+ ":" + port
+ path
;
94 List
<String
[]> getHeadersForPost(String mimeType
) {
95 List
<String
[]> headers
= getHeadersBase();
96 headers
.add(new String
[]{"Content-type", mimeType
});
100 List
<String
[]> getHeadersForGet() {
101 return getHeadersBase();
104 List
<String
[]> getHeadersBase() {
105 List
<String
[]> headers
= new ArrayList
<String
[]>();
106 headers
.add(new String
[]{"Host", hostname
});
107 headers
.add(new String
[]{"X-appcfg-api-version", "1"});
111 abstract Response
get(String path
) throws IOException
;
113 abstract Response
post(String path
, String mimeType
, byte[] body
) throws IOException
;
115 static class Response
{
116 private final int statusCode
;
117 private final byte[] responseBody
;
118 private final String responseCharSet
;
120 Response(int statusCode
, byte[] responseBody
, String responseCharSet
) {
121 this.statusCode
= statusCode
;
122 this.responseBody
= responseBody
;
123 this.responseCharSet
= responseCharSet
;
126 int getStatusCode() {
130 byte[] getBodyAsBytes() {
134 String
getBodyAsString() {
135 return EncodingUtil
.getString(responseBody
, responseCharSet
);