/******************************************************************************* * Copyright (c) 2004, 2013 Composent, Inc., IBM All rights reserved. This * program and the accompanying materials are made available under the terms of * the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Composent, Inc. - initial API and implementation * Maarten Meijer - bug 237936, added gzip encoded transfer default * Henrich Kraemer - bug 263869, testHttpsReceiveFile fails using HTTP proxy * Henrich Kraemer - bug 263613, [transport] Update site contacting / downloading is not cancelable * Tasktop Technologies - cancellation support for streams ******************************************************************************/ package org.eclipse.mylyn.internal.commons.net.http; import java.io.IOException; import java.io.InputStream; import java.util.zip.GZIPInputStream; import org.apache.commons.httpclient.HttpConnection; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpState; import org.apache.commons.httpclient.methods.PostMethod; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.mylyn.commons.net.WebUtil; import org.eclipse.mylyn.commons.net.http.CommonHttpMethod3; /** * Based on {@code org.eclipse.ecf.provider.filetransfer.httpclient.HttpClientRetrieveFileTransfer}. * * @author Steffen Pingel */ public class CommonPostMethod3 extends PostMethod implements CommonHttpMethod3 { private boolean gzipAccepted; private boolean gzipReceived; private InputStream inputStream; private final Object releaseLock = new Object(); public CommonPostMethod3() { init(); } public CommonPostMethod3(String requestPath) { super(requestPath); init(); } @Override public int execute(HttpState state, HttpConnection conn) throws HttpException, IOException { if (gzipAccepted) { this.setRequestHeader("Accept-encoding", CONTENT_ENCODING_GZIP); //$NON-NLS-1$ } return super.execute(state, conn); } public InputStream getResponseBodyAsStream(IProgressMonitor monitor) throws IOException { if (inputStream == null) { inputStream = WebUtil.getResponseBodyAsStream(this, monitor); } gzipReceived = isZippedResponse(); if (gzipReceived) { inputStream = new GZIPInputStream(inputStream); } return inputStream; } private void init() { gzipAccepted = true; } public final boolean isGzipAccepted() { return gzipAccepted; } private boolean isZippedResponse() { // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=269018 return this.getResponseHeader(CONTENT_ENCODING) != null && this.getResponseHeader(CONTENT_ENCODING).getValue().equals(CONTENT_ENCODING_GZIP); } // This override is a workaround for // https://bugs.eclipse.org/bugs/show_bug.cgi?id=279457 // This makes GetMethod.releaseConnection non-reentrant, // as with reentrancy under some circumstances a NPE can be // thrown with multithreaded access @Override public void releaseConnection() { synchronized (releaseLock) { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { // ignore } inputStream = null; } super.releaseConnection(); } } public void releaseConnection(IProgressMonitor monitor) { if (monitor != null && monitor.isCanceled()) { // force a connection close on cancel to avoid blocking to do reading the remainder of the response abort(); } try { releaseConnection(); } catch (NullPointerException e) { // ignore, see bug 255417 } } @Override protected void responseBodyConsumed() { // ensure worker is released to pool super.responseBodyConsumed(); } public final void setGzipAccepted(boolean gzipAccepted) { this.gzipAccepted = gzipAccepted; } }