diff options
author | Christian Trutz | 2011-05-16 17:46:59 +0000 |
---|---|---|
committer | Kevin Sawicki | 2011-05-16 17:46:59 +0000 |
commit | 5296efdc3cd88f2869de93b0dcf93c1dfcf481c5 (patch) | |
tree | cd9c39b4ba318c72064fcb42244470d913f5311a | |
parent | 4a1dff2af46ad965398453b46f6ea3b2c6be4336 (diff) | |
download | egit-github-5296efdc3cd88f2869de93b0dcf93c1dfcf481c5.tar.gz egit-github-5296efdc3cd88f2869de93b0dcf93c1dfcf481c5.tar.xz egit-github-5296efdc3cd88f2869de93b0dcf93c1dfcf481c5.zip |
GitHubClient refactored to use HttpClient 4.1
Change-Id: I87ac2e8e097e6436a4765126af2b044013e5592f
Signed-off-by: Christian Trutz <christian.trutz@gmail.com>
Signed-off-by: Kevin Sawicki <kevin@github.com>
8 files changed, 173 insertions, 158 deletions
diff --git a/org.eclipse.egit.github.core.tests/META-INF/MANIFEST.MF b/org.eclipse.egit.github.core.tests/META-INF/MANIFEST.MF index bc4e2aea..5d2c0236 100644 --- a/org.eclipse.egit.github.core.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.egit.github.core.tests/META-INF/MANIFEST.MF @@ -7,7 +7,7 @@ Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 Import-Package: com.google.gson;version="1.6.0", com.google.gson.reflect;version="1.6.0", - org.apache.commons.httpclient;version="3.1.0", + org.apache.http;version="4.1.0", org.mockito;version="1.8.4", org.mockito.runners;version="1.8.4", org.mockito.stubbing;version="1.8.4" diff --git a/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/live/LiveTest.java b/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/live/LiveTest.java index 93e2493d..fd7cc666 100644 --- a/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/live/LiveTest.java +++ b/org.eclipse.egit.github.core.tests/src/org/eclipse/egit/github/core/tests/live/LiveTest.java @@ -15,7 +15,7 @@ import java.net.URL; import junit.framework.TestCase; -import org.apache.commons.httpclient.HostConfiguration; +import org.apache.http.HttpHost; import org.eclipse.egit.github.core.client.GitHubClient; /** @@ -51,11 +51,10 @@ public abstract class LiveTest extends TestCase { protected GitHubClient createClient(String url) throws IOException { GitHubClient client = null; if (url != null) { - HostConfiguration config = new HostConfiguration(); URL parsed = new URL(url); - config.setHost(parsed.getHost(), parsed.getPort(), + HttpHost httpHost = new HttpHost(parsed.getHost(), parsed.getPort(), parsed.getProtocol()); - client = new GitHubClient(config); + client = new GitHubClient(httpHost); } else client = new GitHubClient(); return configure(client); diff --git a/org.eclipse.egit.github.core/META-INF/MANIFEST.MF b/org.eclipse.egit.github.core/META-INF/MANIFEST.MF index fda2872b..b35dd3ba 100644 --- a/org.eclipse.egit.github.core/META-INF/MANIFEST.MF +++ b/org.eclipse.egit.github.core/META-INF/MANIFEST.MF @@ -9,10 +9,18 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5 Import-Package: com.google.gson;version="1.6.0", com.google.gson.annotations;version="1.6.0", com.google.gson.reflect;version="1.6.0", - org.apache.commons.httpclient;version="3.1.0", - org.apache.commons.httpclient.auth;version="3.1.0", - org.apache.commons.httpclient.methods;version="3.1.0", - org.apache.commons.httpclient.protocol;version="3.1.0" + org.apache.http;version="4.1.0", + org.apache.http.auth;version="4.1.0", + org.apache.http.client;version="4.1.0", + org.apache.http.client.entity;version="4.1.0", + org.apache.http.client.methods;version="4.1.0", + org.apache.http.client.protocol;version="4.1.0", + org.apache.http.client.utils;version="4.1.0", + org.apache.http.entity;version="4.1.0", + org.apache.http.impl.auth;version="4.1.0", + org.apache.http.impl.client;version="4.1.0", + org.apache.http.message;version="4.1.0", + org.apache.http.protocol;version="4.1.0" Export-Package: org.eclipse.egit.github.core, org.eclipse.egit.github.core.client, org.eclipse.egit.github.core.service, 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); } } diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubResponse.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubResponse.java index 43c2a3d2..8bd37928 100644 --- a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubResponse.java +++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubResponse.java @@ -10,7 +10,7 @@ *******************************************************************************/ package org.eclipse.egit.github.core.client; -import org.apache.commons.httpclient.HttpMethod; +import org.apache.http.HttpResponse; /** * GitHub API response class. @@ -27,8 +27,8 @@ public class GitHubResponse { * @param method * @param body */ - public GitHubResponse(HttpMethod method, Object body) { - links = new PageLinks(method); + public GitHubResponse(HttpResponse response, Object body) { + links = new PageLinks(response); this.body = body; } diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PageLinks.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PageLinks.java index d08cef8d..e48301e6 100644 --- a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PageLinks.java +++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PageLinks.java @@ -10,8 +10,8 @@ *******************************************************************************/ package org.eclipse.egit.github.core.client; -import org.apache.commons.httpclient.Header; -import org.apache.commons.httpclient.HttpMethod; +import org.apache.http.Header; +import org.apache.http.HttpResponse; /** * Page link class to be used to determine the links to other pages of request @@ -32,11 +32,11 @@ public class PageLinks { /** * Parse links from executed method * - * @param method + * @param response */ - public PageLinks(HttpMethod method) { - Header[] linkHeaders = method - .getResponseHeaders(IGitHubConstants.HEADER_LINK); + public PageLinks(HttpResponse response) { + Header[] linkHeaders = response + .getHeaders(IGitHubConstants.HEADER_LINK); if (linkHeaders.length > 0) { String[] links = linkHeaders[0].getValue().split(DELIM_LINKS); for (String link : links) { @@ -70,13 +70,13 @@ public class PageLinks { } } } else { - Header[] nextHeaders = method - .getResponseHeaders(IGitHubConstants.HEADER_NEXT); + Header[] nextHeaders = response + .getHeaders(IGitHubConstants.HEADER_NEXT); if (nextHeaders.length > 0) next = nextHeaders[0].getValue(); - Header[] lastHeaders = method - .getResponseHeaders(IGitHubConstants.HEADER_LAST); + Header[] lastHeaders = response + .getHeaders(IGitHubConstants.HEADER_LAST); if (lastHeaders.length > 0) last = lastHeaders[0].getValue(); } diff --git a/org.eclipse.mylyn.github.ui/META-INF/MANIFEST.MF b/org.eclipse.mylyn.github.ui/META-INF/MANIFEST.MF index f6433a99..0b56028f 100644 --- a/org.eclipse.mylyn.github.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.mylyn.github.ui/META-INF/MANIFEST.MF @@ -25,4 +25,5 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.5.0", org.eclipse.egit.github.core;bundle-version="0.1.0" Export-Package: org.eclipse.mylyn.github.ui.internal;x-internal:=true Bundle-ActivationPolicy: lazy -Import-Package: org.eclipse.egit.ui.internal;version="0.12.0" +Import-Package: org.apache.http;version="4.1.0", + org.eclipse.egit.ui.internal;version="0.12.0" diff --git a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/RepositorySelectionWizardPage.java b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/RepositorySelectionWizardPage.java index 2c8293b8..c26e13cf 100644 --- a/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/RepositorySelectionWizardPage.java +++ b/org.eclipse.mylyn.github.ui/src/org/eclipse/mylyn/github/ui/internal/RepositorySelectionWizardPage.java @@ -17,7 +17,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.apache.commons.httpclient.HostConfiguration; +import org.apache.http.HttpHost; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.egit.github.core.Repository; import org.eclipse.egit.github.core.client.GitHubClient; @@ -208,10 +208,9 @@ public class RepositorySelectionWizardPage extends WizardPage { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - HostConfiguration config = new HostConfiguration(); - config.setHost(IGitHubConstants.HOST_API_V2, -1, + HttpHost httpHost = new HttpHost(IGitHubConstants.HOST_API_V2, -1, IGitHubConstants.PROTOCOL_HTTPS); - GitHubClient client = new GitHubClient(config); + GitHubClient client = new GitHubClient(httpHost); client.setCredentials(user, password); RepositoryService service = new RepositoryService(client); repoCount = 0; |