Affected version
3.5.3 and master.
Bug description
usePreemptive has no effect whenever a <server> configures both <all> and a block for the method being used, which is the shape most people write. The effective value is always false.
HttpMethodConfiguration.copy() copies everything except that one field:
HttpMethodConfiguration copy() {
HttpMethodConfiguration copy = new HttpMethodConfiguration();
copy.setConnectionTimeout(getConnectionTimeout());
copy.setReadTimeout(getReadTimeout());
if (getHeaders() != null) {
copy.getHeaders().putAll(getHeaders());
}
if (getParams() != null) {
copy.getParams().putAll(getParams());
}
copy.setUseDefaultHeaders(isUseDefaultHeaders());
return copy;
}
and ConfigurationUtils contains no reference to usePreemptive at all, so merge() never carries it over either. The merged configuration therefore keeps the field's default of false no matter what was configured.
Why it is not caught
HttpWagonPreemptiveTest configures <all> and nothing else. With only one block there is nothing to merge, so getMethodConfiguration returns it directly and the flag survives. Add a <get> block alongside and it stops working.
Workaround
Configure usePreemptive in a block that is not merged — in practice, use <all> on its own for that server.
Note
There is a second, related oddity nearby: AbstractHttpClientWagon.put primes the auth cache whenever credentials exist, regardless of this setting, and the source says so — // FIXME Perform only when preemptive has been configured. So PUT is preemptive even when the flag is honoured and false. Worth deciding together, since fixing the merge without looking at that would still leave the observable behaviour surprising.
Found while writing the HTTP configuration guide in #905, which documents the current behaviour and the workaround.
Affected version
3.5.3 and
master.Bug description
usePreemptivehas no effect whenever a<server>configures both<all>and a block for the method being used, which is the shape most people write. The effective value is alwaysfalse.HttpMethodConfiguration.copy()copies everything except that one field:and
ConfigurationUtilscontains no reference tousePreemptiveat all, somerge()never carries it over either. The merged configuration therefore keeps the field's default offalseno matter what was configured.Why it is not caught
HttpWagonPreemptiveTestconfigures<all>and nothing else. With only one block there is nothing to merge, sogetMethodConfigurationreturns it directly and the flag survives. Add a<get>block alongside and it stops working.Workaround
Configure
usePreemptivein a block that is not merged — in practice, use<all>on its own for that server.Note
There is a second, related oddity nearby:
AbstractHttpClientWagon.putprimes the auth cache whenever credentials exist, regardless of this setting, and the source says so —// FIXME Perform only when preemptive has been configured. So PUT is preemptive even when the flag is honoured and false. Worth deciding together, since fixing the merge without looking at that would still leave the observable behaviour surprising.Found while writing the HTTP configuration guide in #905, which documents the current behaviour and the workaround.