diff --git a/wagon-providers/pom.xml b/wagon-providers/pom.xml index 6f1983a6c..7c5cbed42 100644 --- a/wagon-providers/pom.xml +++ b/wagon-providers/pom.xml @@ -78,4 +78,5 @@ under the License. test + diff --git a/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/AbstractHttpClientWagon.java b/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/AbstractHttpClientWagon.java index 3e9fe91ff..8c76ef7a7 100644 --- a/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/AbstractHttpClientWagon.java +++ b/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/AbstractHttpClientWagon.java @@ -91,6 +91,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; +import java.net.URLConnection; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.channels.Channels; @@ -122,6 +123,7 @@ public abstract class AbstractHttpClientWagon final class WagonHttpEntity extends AbstractHttpEntity { + public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream"; private final Resource resource; private final Wagon wagon; @@ -152,6 +154,49 @@ private WagonHttpEntity( final InputStream stream, final Resource resource, fina this.length = resource == null ? -1 : resource.getContentLength(); this.wagon = wagon; + + // if the autoset content flag is SET and the content type is blank + // then try to determine what the content type is and set it + if ( AUTOSET_CONTENT_TYPE && getContentType() == null ) + { + setContentType( determineContentType() ); + } + } + + /** + * Best effort to determine the content type. + * + * if the content is coming from a file and the content type is determinable from the file extension + * or + * if the content is coming from a stream and the content type is determinable from the stream + * (guessContentTypeFromStream will return null if the InputStream does not support mark()) + * then determine and return the content type + * if the content type is not determinable then return "application/octet-stream" + * + * NOTE: this method is expected to always return a non-empty String + */ + private String determineContentType() + { + try + { + String mimeType = this.source != null + ? URLConnection.guessContentTypeFromName( this.source.getName() ) + : this.stream != null + ? URLConnection.guessContentTypeFromStream( this.stream ) + : DEFAULT_CONTENT_TYPE; + + // if URLConnection was unable to determine the type then default it + if ( mimeType == null ) + { + mimeType = DEFAULT_CONTENT_TYPE; + } + return mimeType; + } + catch ( IOException e ) + { + // will only occur when guessContentTypeFromStream gets an IOException + return DEFAULT_CONTENT_TYPE; + } } public Resource getResource() @@ -279,6 +324,12 @@ public boolean isStreaming() private static final boolean SSL_ALLOW_ALL = Boolean.valueOf( System.getProperty( "maven.wagon.http.ssl.allowall", "false" ) ); + /** + * If enabled, then the content-type HTTP header will be set using the file extension + * or the stream header to determine the type, enabled by default + */ + private static final boolean AUTOSET_CONTENT_TYPE = + Boolean.valueOf( System.getProperty( "maven.wagon.http.autocontenttype", "true" ) ); /** * Maximum concurrent connections per distinct route.