Skip to content

Commit

Permalink
[MRESOLVER-433] Config for expect/continue inhibition (#363) (#366)
Browse files Browse the repository at this point in the history
Add configuration to inhibit expect/continue handshake.

---

https://issues.apache.org/jira/browse/MRESOLVER-433
Backport of relevants parts from this commit: 178cfba
  • Loading branch information
cstamas authored Nov 17, 2023
1 parent 4b74a36 commit 1de8710
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,22 @@ public final class ConfigurationProperties {
*/
public static final int DEFAULT_HTTP_MAX_CONNECTIONS_PER_ROUTE = 50;

/**
* Boolean flag should the HTTP transport use expect-continue handshake for PUT requests. Not all transport support
* this option. This option may be needed for some broken HTTP servers.
*
* @see #DEFAULT_HTTP_EXPECT_CONTINUE
* @since 1.9.17
*/
public static final String HTTP_EXPECT_CONTINUE = PREFIX_CONNECTOR + "http.expectContinue";

/**
* Default value if {@link #HTTP_EXPECT_CONTINUE} is not set: {@code true}.
*
* @since 1.9.17
*/
public static final boolean DEFAULT_HTTP_EXPECT_CONTINUE = true;

/**
* The mode that sets HTTPS transport "security mode": to ignore any SSL errors (certificate validity checks,
* hostname verification). The default value is {@link #HTTPS_SECURITY_MODE_DEFAULT}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,15 @@ final class HttpTransporter extends AbstractTransporter {
builder.useSystemProperties();
}

final boolean expectContinue = ConfigUtils.getBoolean(
session,
ConfigurationProperties.DEFAULT_HTTP_EXPECT_CONTINUE,
ConfigurationProperties.HTTP_EXPECT_CONTINUE + "." + repository.getId(),
ConfigurationProperties.HTTP_EXPECT_CONTINUE);
if (expectContinue != ConfigurationProperties.DEFAULT_HTTP_EXPECT_CONTINUE) {
state.setExpectContinue(expectContinue);
}

final boolean reuseConnections = ConfigUtils.getBoolean(
session,
ConfigurationProperties.DEFAULT_HTTP_REUSE_CONNECTIONS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,27 @@ public void testPut_Authenticated_ExpectContinueRejected() throws Exception {
assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
}

@Test
public void testPut_Authenticated_ExpectContinueDisabled() throws Exception {
session.setConfigProperty(ConfigurationProperties.HTTP_EXPECT_CONTINUE, false);
httpServer.setAuthentication("testuser", "testpass");
httpServer.setExpectSupport(HttpServer.ExpectContinue.FAIL); // if transport tries Expect/Continue explode
auth = new AuthenticationBuilder()
.addUsername("testuser")
.addPassword("testpass")
.build();
newTransporter(httpServer.getHttpUrl());
RecordingTransportListener listener = new RecordingTransportListener();
PutTask task =
new PutTask(URI.create("repo/file.txt")).setListener(listener).setDataString("upload");
transporter.put(task);
assertEquals(0L, listener.dataOffset);
assertEquals(6L, listener.dataLength);
assertEquals(1, listener.startedCount); // w/ expectContinue enabled would have here 2
assertTrue("Count: " + listener.progressedCount, listener.progressedCount > 0);
assertEquals("upload", TestFileUtils.readString(new File(repoDir, "file.txt")));
}

@Test
public void testPut_Authenticated_ExpectContinueRejected_ExplicitlyConfiguredHeader() throws Exception {
Map<String, String> headers = new HashMap<>();
Expand Down
1 change: 1 addition & 0 deletions src/site/markdown/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Option | Type | Description | Default Value | Supports Repo ID Suffix
`aether.connector.http.cacheState` | boolean | Flag indicating whether a memory-based cache is used for user tokens, connection managers, expect continue requests and authentication schemes. | `true` | no
`aether.connector.http.connectionMaxTtl` | int | Total time to live in seconds for an HTTP connection, after that time, the connection will be dropped (no matter for how long it was idle). | `300` | yes
`aether.connector.http.credentialEncoding` | String | The encoding/charset to use when exchanging credentials with HTTP servers. | `"ISO-8859-1"` | yes
`aether.connector.http.expectContinue` | boolean | Whether to use expect/continue handshake during PUTs. Some broken HTTP servers needs this disabled. | `true` | yes
`aether.connector.http.headers` | `Map<String, String>` | The request headers to use for HTTP-based repository connectors. The headers are specified using a map of strings mapping a header name to its value. The repository-specific headers map is supposed to be complete, i.e. is not merged with the general headers map. | - | yes
`aether.connector.http.maxConnectionsPerRoute` | int | The maximum concurrent connections per route HTTP client is allowed to use. | `50` | yes
`aether.connector.http.preemptiveAuth` | boolean | Should HTTP client use preemptive-authentication for all HTTP verbs (works only w/ BASIC). By default is disabled, as it is considered less secure. | `false` | yes
Expand Down

0 comments on commit 1de8710

Please sign in to comment.