diff options
Diffstat (limited to 'org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubClient.java')
-rw-r--r-- | org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubClient.java | 270 |
1 files changed, 139 insertions, 131 deletions
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubClient.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubClient.java index 6ceaed08..38f09b95 100644 --- a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubClient.java +++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubClient.java @@ -7,6 +7,7 @@ * * Contributors: * Kevin Sawicki (GitHub Inc.) - initial API and implementation + * Christian Trutz - HttpClient 4.1 *******************************************************************************/ package org.eclipse.egit.github.core.client; @@ -20,24 +21,31 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Type; import java.util.Date; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.apache.commons.httpclient.Credentials; -import org.apache.commons.httpclient.HostConfiguration; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.HttpMethodBase; -import org.apache.commons.httpclient.NameValuePair; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; -import org.apache.commons.httpclient.auth.BasicScheme; -import org.apache.commons.httpclient.methods.EntityEnclosingMethod; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.PutMethod; -import org.apache.commons.httpclient.methods.StringRequestEntity; -import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.StatusLine; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.AuthCache; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.client.utils.URLEncodedUtils; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.client.BasicAuthCache; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; import org.eclipse.egit.github.core.Assert; import org.eclipse.egit.github.core.RequestError; @@ -46,40 +54,42 @@ import org.eclipse.egit.github.core.RequestError; */ public class GitHubClient { - private static final NameValuePair PER_PAGE_PARAM = new NameValuePair( + private static final NameValuePair PER_PAGE_PARAM = new BasicNameValuePair( IGitHubConstants.PARAM_PER_PAGE, Integer.toString(100)); - private static final AuthScope ANY_SCOPE = new AuthScope( - AuthScope.ANY_HOST, AuthScope.ANY_PORT); + private final HttpHost httpHost; - private HostConfiguration hostConfig; + private final HttpContext httpContext; - private HttpClient client = new HttpClient(); + private final DefaultHttpClient client = new DefaultHttpClient(); - private Gson gson = new GsonBuilder() + private final Gson gson = new GsonBuilder() .registerTypeAdapter(Date.class, new DateFormatter()) .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .serializeNulls().create(); - private boolean sendCredentials = false; - /** * Create default client */ public GitHubClient() { - this.hostConfig = new HostConfiguration(); - this.hostConfig.setHost(IGitHubConstants.HOST_API, -1, - Protocol.getProtocol(IGitHubConstants.PROTOCOL_HTTPS)); + this(new HttpHost(IGitHubConstants.HOST_API, -1, + IGitHubConstants.PROTOCOL_HTTPS)); } /** - * Create client for configuration + * Create client for host configuration * - * @param configuration + * @param httpHost */ - public GitHubClient(HostConfiguration configuration) { - Assert.notNull("Configuration cannot be null", configuration); //$NON-NLS-1$ - this.hostConfig = configuration; + public GitHubClient(HttpHost httpHost) { + Assert.notNull("Http host cannot be null", httpHost); //$NON-NLS-1$ + this.httpHost = httpHost; + + // Preemptive authentication + httpContext = new BasicHttpContext(); + AuthCache authCache = new BasicAuthCache(); + authCache.put(this.httpHost, new BasicScheme()); + httpContext.setAttribute(ClientContext.AUTH_CACHE, authCache); } /** @@ -88,10 +98,8 @@ public class GitHubClient { * @param uri * @return post */ - protected PostMethod createPost(String uri) { - PostMethod method = new PostMethod(uri); - setMethodDefaults(method); - return method; + protected HttpPost createPost(String uri) { + return new HttpPost(uri); } /** @@ -100,25 +108,8 @@ public class GitHubClient { * @param uri * @return post */ - protected PutMethod createPut(String uri) { - PutMethod method = new PutMethod(uri); - setMethodDefaults(method); - return method; - } - - /** - * Set method defaults - * - * @param method - * @return method - */ - protected HttpMethod setMethodDefaults(HttpMethod method) { - if (this.sendCredentials) { - method.setDoAuthentication(true); - method.getHostAuthState().setPreemptive(); - method.getHostAuthState().setAuthScheme(new BasicScheme()); - } - return method; + protected HttpPut createPut(String uri) { + return new HttpPut(uri); } /** @@ -127,11 +118,8 @@ public class GitHubClient { * @param uri * @return get method */ - protected GetMethod createGet(String uri) { - GetMethod method = new GetMethod(uri); - method.setFollowRedirects(true); - setMethodDefaults(method); - return method; + protected HttpGet createGet(String uri) { + return new HttpGet(uri); } /** @@ -141,33 +129,33 @@ public class GitHubClient { * @param password */ public void setCredentials(String user, String password) { - this.sendCredentials = user != null && password != null; - Credentials credentials = null; - if (this.sendCredentials) - credentials = new UsernamePasswordCredentials(user, password); - this.client.getState().setCredentials(ANY_SCOPE, credentials); + if (user != null && password != null) + this.client.getCredentialsProvider().setCredentials( + new AuthScope(httpHost.getHostName(), httpHost.getPort()), + new UsernamePasswordCredentials(user, password)); + else + this.client.getCredentialsProvider().clear(); } /** * Parse json to specified type * * @param <V> - * @param method + * @param response * @param type * @return type * @throws IOException */ - protected <V> V parseJson(HttpMethodBase method, Type type) + protected <V> V parseJson(HttpResponse response, Type type) throws IOException { - InputStream stream = method.getResponseBodyAsStream(); + InputStream stream = response.getEntity().getContent(); if (stream == null) throw new JsonParseException("Empty body"); //$NON-NLS-1$ InputStreamReader reader = new InputStreamReader(stream); try { return this.gson.fromJson(reader, type); } catch (JsonParseException jpe) { - jpe.printStackTrace(); - throw new IOException(jpe); + throw new IOException(jpe.getMessage()); } } @@ -178,24 +166,36 @@ public class GitHubClient { * @param page * @return name value pair array */ - protected NameValuePair[] getPairs(Map<String, String> data, int page) { - if (data == null || data.isEmpty()) - return new NameValuePair[] { - new NameValuePair(IGitHubConstants.PARAM_PAGE, - Integer.toString(page)), PER_PAGE_PARAM }; - - int size = data.containsKey(IGitHubConstants.PARAM_PER_PAGE) ? data - .size() : data.size() + 1; - NameValuePair[] pairs = new NameValuePair[size]; - int i = 0; - for (Entry<String, String> entry : data.entrySet()) - pairs[i++] = new NameValuePair(entry.getKey(), entry.getValue()); - if (i < size) - pairs[i] = PER_PAGE_PARAM; + protected List<NameValuePair> getPairs(Map<String, String> data, int page) { + List<NameValuePair> pairs = new LinkedList<NameValuePair>(); + if (data == null || data.isEmpty()) { + pairs.add(new BasicNameValuePair(IGitHubConstants.PARAM_PAGE, + Integer.toString(page))); + pairs.add(PER_PAGE_PARAM); + } else { + for (Entry<String, String> entry : data.entrySet()) + pairs.add(new BasicNameValuePair(entry.getKey(), entry + .getValue())); + if (!data.containsKey(IGitHubConstants.PARAM_PER_PAGE)) + pairs.add(PER_PAGE_PARAM); + } return pairs; } /** + * Get uri for request + * + * @param request + * @return uri + */ + protected String getUri(GitHubRequest request) { + return request.getUri() + + (request.getUri().indexOf('?') == -1 ? '?' : '&') + + URLEncodedUtils.format( + getPairs(request.getParams(), request.getPage()), null); + } + + /** * Get response stream from uri. It is the responsibility of the calling * method to close the returned stream. * @@ -204,25 +204,29 @@ public class GitHubClient { * @throws IOException */ public InputStream getStream(GitHubRequest request) throws IOException { - GetMethod method = createGet(request.getUri()); - if (method.getQueryString() == null) - method.setQueryString(getPairs(request.getParams(), - request.getPage())); + HttpGet method = createGet(getUri(request)); try { - int status = this.client.executeMethod(this.hostConfig, method); + HttpResponse response = this.client.execute(this.httpHost, method, + this.httpContext); + StatusLine statusLine = response.getStatusLine(); + if (statusLine == null) { + throw new IllegalStateException( + "HTTP response status line should not be null."); //$NON-NLS-1$ + } + int status = statusLine.getStatusCode(); switch (status) { case 200: - return method.getResponseBodyAsStream(); + return response.getEntity().getContent(); case 400: case 401: case 403: case 404: case 422: case 500: - RequestError error = parseJson(method, RequestError.class); + RequestError error = parseJson(response, RequestError.class); throw new RequestException(error, status); default: - throw new IOException(method.getStatusText()); + throw new IOException(statusLine.getReasonPhrase()); } } catch (JsonParseException jpe) { throw new IOException(jpe.getMessage()); @@ -237,15 +241,19 @@ public class GitHubClient { * @throws IOException */ public GitHubResponse get(GitHubRequest request) throws IOException { - GetMethod method = createGet(request.getUri()); - if (method.getQueryString() == null) - method.setQueryString(getPairs(request.getParams(), - request.getPage())); + HttpGet method = createGet(getUri(request)); try { - int status = this.client.executeMethod(this.hostConfig, method); + HttpResponse response = this.client.execute(this.httpHost, method, + this.httpContext); + StatusLine statusLine = response.getStatusLine(); + if (statusLine == null) { + throw new IllegalStateException( + "HTTP response status line should not be null."); //$NON-NLS-1$ + } + int status = statusLine.getStatusCode(); switch (status) { case 200: - return new GitHubResponse(method, parseJson(method, + return new GitHubResponse(response, parseJson(response, request.getType())); case 400: case 401: @@ -253,15 +261,13 @@ public class GitHubClient { case 404: case 422: case 500: - RequestError error = parseJson(method, RequestError.class); + RequestError error = parseJson(response, RequestError.class); throw new RequestException(error, status); default: - throw new IOException(method.getStatusText()); + throw new IOException(statusLine.getReasonPhrase()); } } catch (JsonParseException jpe) { throw new IOException(jpe.getMessage()); - } finally { - method.releaseConnection(); } } @@ -275,38 +281,40 @@ public class GitHubClient { * @return resource * @throws IOException */ - protected <V> V sendJson(EntityEnclosingMethod method, Object params, - Type type) throws IOException { + protected <V> V sendJson(HttpEntityEnclosingRequestBase method, + Object params, Type type) throws IOException { if (params != null) { StringBuilder payload = new StringBuilder(); this.gson.toJson(params, payload); - method.setRequestEntity(new StringRequestEntity(payload.toString(), + method.setEntity(new StringEntity(payload.toString(), IGitHubConstants.CONTENT_TYPE_JSON, IGitHubConstants.CHARSET_UTF8)); } - - try { - int status = this.client.executeMethod(this.hostConfig, method); - switch (status) { - case 200: - case 201: - if (type != null) - return parseJson(method, type); - case 204: - break; - case 400: - case 401: - case 403: - case 404: - case 422: - case 500: - RequestError error = parseJson(method, RequestError.class); - throw new RequestException(error, status); - default: - throw new IOException(method.getStatusText()); - } - } finally { - method.releaseConnection(); + HttpResponse response = this.client.execute(this.httpHost, method, + this.httpContext); + StatusLine statusLine = response.getStatusLine(); + if (statusLine == null) { + throw new IllegalStateException( + "HTTP response status line should not be null."); //$NON-NLS-1$ + } + int status = statusLine.getStatusCode(); + switch (status) { + case 200: + case 201: + if (type != null) + return parseJson(response, type); + case 204: + break; + case 400: + case 401: + case 403: + case 404: + case 422: + case 500: + RequestError error = parseJson(response, RequestError.class); + throw new RequestException(error, status); + default: + throw new IOException(statusLine.getReasonPhrase()); } return null; } @@ -322,8 +330,8 @@ public class GitHubClient { * @throws IOException */ public <V> V post(String uri, Object params, Type type) throws IOException { - PostMethod method = createPost(uri); - return sendJson(method, params, type); + HttpPost message = createPost(uri); + return sendJson(message, params, type); } /** @@ -337,8 +345,8 @@ public class GitHubClient { * @throws IOException */ public <V> V put(String uri, Object params, Type type) throws IOException { - PutMethod method = createPut(uri); - return sendJson(method, params, type); + HttpPut message = createPut(uri); + return sendJson(message, params, type); } } |