/* * WPCleaner: A tool to help on Wikipedia maintenance tasks. * Copyright (C) 2013 Nicolas Vervelle * * See README.txt file for licensing information. */ package org.wikipediacleaner.api; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.zip.GZIPInputStream; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Manage interactions with the tool server. */ public class HttpServer { /** * Logs. */ private final Log log = LogFactory.getLog(HttpServer.class); /** * HTTP Client. */ private final HttpClient httpClient; /** * Base URL. */ private final String baseUrl; /** * Maximum number of attempts. */ private final static int MAX_ATTEMPTS = 3; /** * Create an HttpServer object. * * @param httpClient HTTP client. */ HttpServer(HttpClient httpClient, String baseUrl) { this.httpClient = httpClient; this.baseUrl = baseUrl; } /** * Send a POST request to the Tool Server. * * @param path Path on the tool server. * @param properties Request properties. * @param manager Response manager. * @throws APIException */ public void sendPost( String path, Map<String, String> properties, ResponseManager manager) throws APIException { HttpMethod method = null; InputStream inputStream = null; int statusCode = HttpStatus.SC_SEE_OTHER; int count = 0; while ((statusCode != HttpStatus.SC_OK) && (count < MAX_ATTEMPTS)) { if (count > 0) { try { Thread.sleep(2000 * count); } catch (InterruptedException e) { // Nothing } } count++; try { String url = baseUrl + path; method = HttpUtils.createHttpMethod(url, properties, false); statusCode = httpClient.executeMethod(method); inputStream = method.getResponseBodyAsStream(); inputStream = new BufferedInputStream(inputStream); Header contentEncoding = method.getResponseHeader("Content-Encoding"); if (contentEncoding != null) { if (contentEncoding.getValue().equals("gzip")) { inputStream = new GZIPInputStream(inputStream); } } if (statusCode == HttpStatus.SC_OK) { if (manager != null) { manager.manageResponse(inputStream); } } else { log.warn("Error accessing url: " + statusCode + "-" + HttpStatus.getStatusText(statusCode)); waitBeforeRetrying(count); } try { while (inputStream.read() >= 0) { // } } catch (IOException e) { // } } catch (HttpException e) { throw new APIException("HttpException: " + e.getMessage()); } catch (IOException e) { throw new APIException("IOException: " + e.getMessage()); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { log.warn("Error closing stream: " + e.getMessage()); } } if (method != null) { method.releaseConnection(); } } } if (statusCode != HttpStatus.SC_OK) { throw new APIException("URL access returned " + HttpStatus.getStatusText(statusCode)); } } /** * Send a GET request to the Tool Server. * * @param path Path on the tool server. * @param manager Response manager. * @throws APIException */ public void sendGet( String path, ResponseManager manager) throws APIException { HttpMethod method = null; InputStream inputStream = null; int statusCode = HttpStatus.SC_SEE_OTHER; int count = 0; while ((statusCode != HttpStatus.SC_OK) && (count < MAX_ATTEMPTS)) { if (count > 0) { try { Thread.sleep(2000 * count); } catch (InterruptedException e) { // Nothing } } count++; try { String url = baseUrl + path; method = HttpUtils.createHttpMethod(url, null, true); statusCode = httpClient.executeMethod(method); if (statusCode == HttpStatus.SC_NOT_FOUND) { return; } inputStream = method.getResponseBodyAsStream(); inputStream = new BufferedInputStream(inputStream); Header contentEncoding = method.getResponseHeader("Content-Encoding"); if (contentEncoding != null) { if (contentEncoding.getValue().equals("gzip")) { inputStream = new GZIPInputStream(inputStream); } } if (statusCode == HttpStatus.SC_OK) { if (manager != null) { manager.manageResponse(inputStream); } } else { log.warn("Error accessing url: " + statusCode + "-" + HttpStatus.getStatusText(statusCode)); waitBeforeRetrying(count); } try { while (inputStream.read() >= 0) { // } } catch (IOException e) { // } } catch (HttpException e) { throw new APIException("HttpException: " + e.getMessage()); } catch (IOException e) { throw new APIException("IOException: " + e.getMessage()); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { log.warn("Error closing stream: " + e.getMessage()); } } if (method != null) { method.releaseConnection(); } } } if (statusCode != HttpStatus.SC_OK) { throw new APIException("URL access returned " + HttpStatus.getStatusText(statusCode)); } } /** * @return Base URL. */ public String getBaseUrl() { return baseUrl; } /** * Wait after a problem occurred. */ private void waitBeforeRetrying(int count) { try { Thread.sleep(10000 * Math.min(count, 1)); } catch (InterruptedException e) { log.warn("Waiting before retrying"); } } }