Skip to content
Commits on Source (8)
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Auto detect text files and perform LF normalization
* text=auto
*.java text diff=java
*.html text diff=html
*.css text
*.js text
.classpath
.project
.settings
.pydevproject
.clover
target
maven-eclipse.xml
.idea
*.iml
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
language: java
sudo: false
jdk:
- openjdk7
- oraclejdk8
after_success:
- mvn clean cobertura:cobertura coveralls:report
Apache HttpComponents Core
Copyright 2005-2017 The Apache Software Foundation
Copyright 2005-2018 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
Release 4.4.10
-------------------
This is a maintenance release that adds Automatic-Module-Name to the manifest for compatibility
with Java 9 Platform Module System and fixes a number of issues discovered since 4.4.9
Changelog
-------------------
* HTTPCORE-510: Avoid an ArithmeticException in AbstractMultiworkerIOReactor by failing earlier by checking
ioThreadCount in IOReactorConfig constructor.
Contributed by Gary Gregory <ggregory at apache.org>
* Workaround for misbehaved servers that return HTTP 204 responses with a content
Contributed by Alessandro Gherardi <alessandro.gherardi at schneider-electric.com>
* HTTPCORE-508: Reject response messages with status code lesser than 100 as invalid
Contributed by Oleg Kalnichevski <olegk at apache.org>
* HTTPCORE-511: Do not cache result of Runtime.getRuntime().availableProcessors() in IOReactorConfig.
Contributed by Gary Gregory <ggregory at apache.org>
* HTTPCORE-509: AVAIL_PROCS is auto-configured based on core count.
Contributed by Gary Gregory <ggregory at apache.org>
* [HTTPCORE-513] Better handling of very large content by ExpandableBuffer
Contributed by imoldovan-intacct <imoldovan at intacct.com>
* HTTPCORE-514: Exceptions defined by HttpCore should clean message strings when built to replace non-printable
characters with hex values.
Contributed by Gary Gregory <ggregory at apache.org>
* HTTPCORE-515: Add convenience API org.apache.http.impl.nio.DefaultHttpServerIODispatch.create(T, SSLContext,
ConnectionConfig, HttpRequestFactory).
Contributed by Gary Gregory <ggregory at apache.org>
* HTTPCORE-517: Allow SecurityManager to stop socket connections.
Contributed by Gary Gregory <ggregory at apache.org> and Paul Thompson <pathompson at atlassian dot com>
* HTTPCORE-519: Failing tests on Fedora 28 due to weak encryption algorithms in test keystore.
Contributed by Gary Gregory <ggregory at apache.org> and Michael Simacek <msimacek at redhat dot com>
* HTTPCLIENT-1914: negative value of max connection per route to restore the default max value (by removing
the underlying entry from the route map).
Contributed by Corneliu Chitic <corneliu.chitic at computaris.com>
* HTTPCORE-527: Add remote address when throwing a ConnectException.
Contributed by Jason Tedor <jason at tedor dot me>
* HTTPCORE-523: Improve HeaderValueParser API doc
Contributed by Julian Reschke <julian.reschke at gmx.de>
* Add Automatic-Module-Name in manifest so Java9 modular applications can depend on this library
Contributed by Varun Nandi <varunkn at amazon.com>
* HTTPCORE-528: Non-blocking SSL I/O session spins upon abnormal connection closure by the opposite endpoint.
Contributed by Oleg Kalnichevski <olegk at apache.org>
Release 4.4.9
-------------------
This is a maintenance release that fixes a number of issues discovered since 4.4.8 ands a few low-level methods.
This is a maintenance release that fixes a number of issues discovered since 4.4.8 and adds a few low-level methods.
Changelog
-------------------
......
httpcomponents-core (4.4.10-1) unstable; urgency=medium
* New upstream release
- Refreshed the patch
* Generate Java 8 compatible bytecode
* Standards-Version updated to 4.2.0
* Use salsa.debian.org Vcs-* URLs
-- Emmanuel Bourg <ebourg@apache.org> Mon, 06 Aug 2018 14:51:19 +0200
httpcomponents-core (4.4.9-1) unstable; urgency=medium
* New upstream release
......
......@@ -3,15 +3,16 @@ Section: java
Priority: optional
Maintainer: Debian Java Maintainers <pkg-java-maintainers@lists.alioth.debian.org>
Uploaders: Emmanuel Bourg <ebourg@apache.org>
Build-Depends: debhelper (>= 11),
default-jdk,
libbuild-helper-maven-plugin-java,
libmaven-antrun-plugin-java,
libmaven-bundle-plugin-java,
maven-debian-helper
Standards-Version: 4.1.3
Vcs-Git: https://anonscm.debian.org/git/pkg-java/httpcomponents-core.git
Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/httpcomponents-core.git
Build-Depends:
debhelper (>= 11),
default-jdk,
libbuild-helper-maven-plugin-java,
libmaven-antrun-plugin-java,
libmaven-bundle-plugin-java,
maven-debian-helper
Standards-Version: 4.2.0
Vcs-Git: https://salsa.debian.org/java-team/httpcomponents-core.git
Vcs-Browser: https://salsa.debian.org/java-team/httpcomponents-core
Homepage: http://hc.apache.org/httpcomponents-core-ga/index.html
Package: libhttpcore-java
......
maven.test.skip=true
maven.compiler.source=1.5
maven.compiler.target=1.5
maven.compiler.source=8
maven.compiler.target=8
maven.compiler.release=8
......@@ -8,9 +8,9 @@ Subject: add-maven-bundle-plugin
--- a/httpcore/pom.xml
+++ b/httpcore/pom.xml
@@ -94,6 +94,40 @@
</execution>
</executions>
@@ -101,6 +101,40 @@
</archive>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
......
......@@ -5,6 +5,3 @@
override_dh_installchangelogs:
dh_installchangelogs -- RELEASE_NOTES.txt
get-orig-source:
uscan --download-current-version --force-download --rename
......@@ -28,7 +28,7 @@
<parent>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcomponents-core</artifactId>
<version>4.4.9</version>
<version>4.4.10</version>
</parent>
<artifactId>httpcore-ab</artifactId>
<name>Apache HttpCore Benchmarking Tool</name>
......@@ -58,6 +58,31 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive combine.children="append">
<manifestEntries>
<Automatic-Module-Name>org.apache.httpcomponents.httpcore-ab</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
......
......@@ -28,7 +28,7 @@
<parent>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcomponents-core</artifactId>
<version>4.4.9</version>
<version>4.4.10</version>
</parent>
<artifactId>httpcore-nio</artifactId>
<name>Apache HttpCore NIO</name>
......@@ -93,6 +93,26 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive combine.children="append">
<manifestEntries>
<Automatic-Module-Name>org.apache.httpcomponents.httpcore-nio</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
......
......@@ -31,11 +31,15 @@ import java.io.IOException;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestFactory;
import org.apache.http.annotation.Contract;
import org.apache.http.annotation.ThreadingBehavior;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.impl.nio.codecs.DefaultHttpRequestParserFactory;
import org.apache.http.impl.nio.reactor.AbstractIODispatch;
import org.apache.http.nio.NHttpConnectionFactory;
import org.apache.http.nio.NHttpMessageParserFactory;
import org.apache.http.nio.NHttpServerEventHandler;
import org.apache.http.nio.reactor.IOSession;
import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
......@@ -59,7 +63,7 @@ public class DefaultHttpServerIODispatch<H extends NHttpServerEventHandler>
* Creates a new instance of this class to be used for dispatching I/O event
* notifications to the given protocol handler.
*
* @param handler the client protocol handler.
* @param handler the server protocol handler.
* @param sslContext an SSLContext or null (for a plain text connection.)
* @param config a connection configuration
* @return a new instance
......@@ -76,7 +80,31 @@ public class DefaultHttpServerIODispatch<H extends NHttpServerEventHandler>
* Creates a new instance of this class to be used for dispatching I/O event
* notifications to the given protocol handler.
*
* @param handler the client protocol handler.
* @param eventHandler the server protocol handler.
* @param sslContext an SSLContext or null (for a plain text connection.)
* @param config a connection configuration
* @param httpRequestFactory the request factory used by this object to generate {@link HttpRequest} instances.
* @return a new instance
* @since 4.4.10
*/
public static <T extends NHttpServerEventHandler> DefaultHttpServerIODispatch<T> create(final T eventHandler,
final SSLContext sslContext, final ConnectionConfig config, final HttpRequestFactory httpRequestFactory) {
final NHttpMessageParserFactory<HttpRequest> httpRequestParserFactory = new DefaultHttpRequestParserFactory(
null, httpRequestFactory);
// @formatter:off
return sslContext == null
? new DefaultHttpServerIODispatch<T>(eventHandler,
new DefaultNHttpServerConnectionFactory(null, httpRequestParserFactory, null, config))
: new DefaultHttpServerIODispatch<T>(eventHandler,
new SSLNHttpServerConnectionFactory(sslContext, null, httpRequestParserFactory, null, config));
// @formatter:om
}
/**
* Creates a new instance of this class to be used for dispatching I/O event
* notifications to the given protocol handler.
*
* @param handler the server protocol handler.
* @param sslContext an SSLContext or null (for a plain text connection.)
* @param sslHandler customizes various aspects of the TLS/SSL protocol.
* @param config a connection configuration
......
......@@ -280,6 +280,10 @@ public class DefaultConnectingIOReactor extends AbstractMultiworkerIOReactor
closeChannel(socketChannel);
request.failed(ex);
return;
} catch (final SecurityException ex) {
closeChannel(socketChannel);
request.failed(new IOException(ex));
return;
}
final SessionRequestHandle requestHandle = new SessionRequestHandle(request);
......
......@@ -36,8 +36,6 @@ import org.apache.http.util.Args;
*/
public final class IOReactorConfig implements Cloneable {
private static final int AVAIL_PROCS = Runtime.getRuntime().availableProcessors();
public static final IOReactorConfig DEFAULT = new Builder().build();
// TODO: make final
......@@ -61,7 +59,7 @@ public final class IOReactorConfig implements Cloneable {
this.selectInterval = 1000;
this.shutdownGracePeriod = 500;
this.interestOpQueued = false;
this.ioThreadCount = AVAIL_PROCS;
this.ioThreadCount = Builder.getDefaultMaxIoThreadCount();
this.soTimeout = 0;
this.soReuseAddress = false;
this.soLinger = -1;
......@@ -91,7 +89,7 @@ public final class IOReactorConfig implements Cloneable {
this.selectInterval = selectInterval;
this.shutdownGracePeriod = shutdownGracePeriod;
this.interestOpQueued = interestOpQueued;
this.ioThreadCount = ioThreadCount;
this.ioThreadCount = Args.positive(ioThreadCount, "ioThreadCount");
this.soTimeout = soTimeout;
this.soReuseAddress = soReuseAddress;
this.soLinger = soLinger;
......@@ -378,6 +376,33 @@ public final class IOReactorConfig implements Cloneable {
public static class Builder {
private static int DefaultMaxIoThreadCount = -1;
/**
* Gets the default value for {@code ioThreadCount}. Returns
* {@link Runtime#availableProcessors()} if
* {@link #setDefaultMaxIoThreadCount(int)} was called with a value <=0.
*
* @return the default value for ioThreadCount.
* @since 4.4.10
*/
public static int getDefaultMaxIoThreadCount() {
return DefaultMaxIoThreadCount > 0 ? DefaultMaxIoThreadCount : Runtime.getRuntime().availableProcessors();
}
/**
* Sets the default value for {@code ioThreadCount}. Use a value <= 0 to
* cause {@link #getDefaultMaxIoThreadCount()} to return
* {@link Runtime#availableProcessors()}.
*
* @param defaultMaxIoThreadCount
* the default value for ioThreadCount.
* @since 4.4.10
*/
public static void setDefaultMaxIoThreadCount(final int defaultMaxIoThreadCount) {
DefaultMaxIoThreadCount = defaultMaxIoThreadCount;
}
private long selectInterval;
private long shutdownGracePeriod;
private boolean interestOpQueued;
......@@ -396,7 +421,7 @@ public final class IOReactorConfig implements Cloneable {
this.selectInterval = 1000;
this.shutdownGracePeriod = 500;
this.interestOpQueued = false;
this.ioThreadCount = AVAIL_PROCS;
this.ioThreadCount = getDefaultMaxIoThreadCount();
this.soTimeout = 0;
this.soReuseAddress = false;
this.soLinger = -1;
......
......@@ -688,10 +688,13 @@ public abstract class AbstractNIOConnPool<T, C, E extends PoolEntry<T, C>>
@Override
public void setMaxPerRoute(final T route, final int max) {
Args.notNull(route, "Route");
Args.positive(max, "Max value");
this.lock.lock();
try {
this.maxPerRoute.put(route, Integer.valueOf(max));
if (max > -1) {
this.maxPerRoute.put(route, Integer.valueOf(max));
} else {
this.maxPerRoute.remove(route);
}
} finally {
this.lock.unlock();
}
......
......@@ -171,7 +171,7 @@ abstract class RouteSpecificPool<T, C, E extends PoolEntry<T, C>> {
public void timeout(final SessionRequest request) {
final BasicFuture<E> future = removeRequest(request);
if (future != null) {
future.failed(new ConnectException());
future.failed(new ConnectException("Timeout connecting to [" + request.getRemoteAddress() + "]"));
}
}
......
......@@ -272,6 +272,9 @@ public class HttpAsyncRequestExecutor implements NHttpClientEventHandler {
final HttpResponse response = conn.getHttpResponse();
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode < HttpStatus.SC_CONTINUE) {
throw new ProtocolException("Invalid response: " + response.getStatusLine());
}
if (statusCode < HttpStatus.SC_OK) {
// 1xx intermediate response
if (statusCode != HttpStatus.SC_CONTINUE) {
......
......@@ -366,7 +366,7 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
this.status = CLOSED;
}
// Abnormal session termination
if (this.status == ACTIVE && this.endOfStream
if (this.status <= CLOSING && this.endOfStream
&& this.sslEngine.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP) {
this.status = CLOSED;
}
......@@ -393,6 +393,10 @@ public class SSLIOSession implements IOSession, SessionBufferStatus, SocketAcces
break;
}
if (this.endOfStream) {
newMask = newMask & ~EventMask.READ;
}
// Do we have encrypted data ready to be sent?
if (this.outEncrypted.hasData()) {
newMask = newMask | EventMask.WRITE;
......
......@@ -27,6 +27,7 @@
package org.apache.http.nio.util;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import org.apache.http.io.BufferInfo;
......@@ -112,11 +113,29 @@ public class ExpandableBuffer implements BufferInfo, org.apache.http.nio.util.Bu
/**
* Expands buffer's capacity.
*
* @throws BufferOverflowException in case we get over the maximum allowed value
*/
protected void expand() {
protected void expand() throws BufferOverflowException {
int newcapacity = (this.buffer.capacity() + 1) << 1;
if (newcapacity < 0) {
newcapacity = Integer.MAX_VALUE;
final int vmBytes = Long.SIZE >> 3;
final int javaBytes = 8; // this is to be checked when the JVM version changes
@SuppressWarnings("unused") // we really need the 8 if we're going to make this foolproof
final int headRoom = (vmBytes >= javaBytes) ? vmBytes : javaBytes;
// Reason: In GC the size of objects is passed as int (2 bytes).
// Then, the header size of the objects is added to the size.
// Long has the longest header available. Object header seems to be linked to it.
// Details: I added a minimum of 8 just to be safe and because 8 is used in
// java.lang.Object.ArrayList: private static final int MAX_ARRAY_SIZE = 2147483639.
//
// WARNING: This code assumes you are providing enough heap room with -Xmx.
// source of inspiration: https://bugs.openjdk.java.net/browse/JDK-8059914
newcapacity = Integer.MAX_VALUE - headRoom;
if (newcapacity <= this.buffer.capacity()) {
throw new BufferOverflowException();
}
}
expandCapacity(newcapacity);
}
......