Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/AutoCloseInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ChunkedInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ChunkedOutputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/CircularRedirectException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ConnectMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ConnectTimeoutException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ConnectionPoolTimeoutException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ContentLengthInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Cookie.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Credentials.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/DefaultHttpMethodRetryHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/DefaultMethodRetryHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Header.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HeaderElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HeaderGroup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HostConfiguration.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpClient.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpClientError.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpConnectionManager.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpConstants.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpContentTooLargeException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpHost.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodBase.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodDirector.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpMethodRetryHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpParser.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpRecoverableException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpState.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpStatus.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpURL.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpVersion.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/HttpsURL.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/InvalidRedirectLocationException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/MethodRetryHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NTCredentials.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NameValuePair.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/NoHttpResponseException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProtocolException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProxyClient.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ProxyHost.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/RedirectException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/ResponseConsumedWatcher.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/SimpleHttpConnectionManager.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/StatusLine.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/URI.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/URIException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/UsernamePasswordCredentials.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/Wire.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/WireLogInputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/WireLogOutputStream.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthChallengeException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthChallengeParser.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthChallengeProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthPolicy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthScheme.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthSchemeBase.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthScope.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthState.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/AuthenticationException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/BasicScheme.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/CredentialsNotAvailableException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/CredentialsProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/DigestScheme.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/HttpAuthRealm.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/HttpAuthenticator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/InvalidCredentialsException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/MalformedChallengeException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/NTLM.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/NTLMScheme.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/RFC2617Scheme.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/auth/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/Cookie2.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookieAttributeHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookieOrigin.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookiePathComparator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookiePolicy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookieSpec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookieSpecBase.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/CookieVersionSupport.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/IgnoreCookiesSpec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/MalformedCookieException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/NetscapeDraftSpec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/RFC2109Spec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/RFC2965Spec.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/cookie/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/ByteArrayRequestEntity.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/DeleteMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/EntityEnclosingMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/ExpectContinueMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/FileRequestEntity.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/GetMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/HeadMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/InputStreamRequestEntity.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/MultipartPostMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/OptionsMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/PostMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/PutMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/RequestEntity.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/StringRequestEntity.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/TraceMethod.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/ByteArrayPartSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/FilePart.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/FilePartSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/MultipartRequestEntity.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/Part.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/PartBase.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/PartSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/StringPart.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/multipart/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/methods/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/DefaultHttpParams.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/DefaultHttpParamsFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HostParams.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpClientParams.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpConnectionManagerParams.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpConnectionParams.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpMethodParams.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpParams.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/HttpParamsFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/params/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/ControllerThreadSocketFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/DefaultProtocolSocketFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/Protocol.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/ProtocolSocketFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/ReflectionSocketFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/SSLProtocolSocketFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/SecureProtocolSocketFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/protocol/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/DateParseException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/DateParser.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/DateUtil.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/EncodingUtil.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ExceptionUtil.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/HttpURLConnection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/IdleConnectionHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/IdleConnectionTimeoutThread.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/LangUtils.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ParameterFormatter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/ParameterParser.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/TimeoutController.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/URIUtil.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 96f14f440726936ee35b0547416534e59d3db24c refers to a dead (removed) revision in file `3rdParty_sources/commons-httpclient/org/apache/commons/httpclient/util/package.html'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/httpclient/org/apache/http/auth/AUTH.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/AUTH.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/AUTH.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,64 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import org.apache.http.annotation.Immutable; + +/** + * Constants and static helpers related to the HTTP authentication. + * + * + * @since 4.0 + */ +@Immutable +public final class AUTH { + + /** + * The www authenticate challange header. + */ + public static final String WWW_AUTH = "WWW-Authenticate"; + + /** + * The www authenticate response header. + */ + public static final String WWW_AUTH_RESP = "Authorization"; + + /** + * The proxy authenticate challange header. + */ + public static final String PROXY_AUTH = "Proxy-Authenticate"; + + /** + * The proxy authenticate response header. + */ + public static final String PROXY_AUTH_RESP = "Proxy-Authorization"; + + private AUTH() { + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/AuthOption.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/AuthOption.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/AuthOption.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,66 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import org.apache.http.annotation.Immutable; + +/** + * @since 4.2 + */ +@Immutable +public final class AuthOption { + + private final AuthScheme authScheme; + private final Credentials creds; + + public AuthOption(final AuthScheme authScheme, final Credentials creds) { + super(); + if (authScheme == null) { + throw new IllegalArgumentException("Auth scheme may not be null"); + } + if (creds == null) { + throw new IllegalArgumentException("User credentials may not be null"); + } + this.authScheme = authScheme; + this.creds = creds; + } + + public AuthScheme getAuthScheme() { + return this.authScheme; + } + + public Credentials getCredentials() { + return this.creds; + } + + @Override + public String toString() { + return this.authScheme.toString(); + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/auth/AuthProtocolState.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/AuthProtocolState.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/AuthProtocolState.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,33 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +public enum AuthProtocolState { + + UNCHALLENGED, CHALLENGED, HANDSHAKE, FAILURE, SUCCESS + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/AuthScheme.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/AuthScheme.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/AuthScheme.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,130 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import org.apache.http.Header; +import org.apache.http.HttpRequest; + +/** + * This interface represents an abstract challenge-response oriented + * authentication scheme. + *

+ * An authentication scheme should be able to support the following + * functions: + *

    + *
  • Parse and process the challenge sent by the target server + * in response to request for a protected resource + *
  • Provide its textual designation + *
  • Provide its parameters, if available + *
  • Provide the realm this authentication scheme is applicable to, + * if available + *
  • Generate authorization string for the given set of credentials + * and the HTTP request in response to the authorization challenge. + *
+ *

+ * Authentication schemes may be stateful involving a series of + * challenge-response exchanges. + *

+ * IMPORTANT: implementations of this interface MUST also implement {@link ContextAwareAuthScheme} + * interface in order to remain API compatible with newer versions of HttpClient. + * + * @since 4.0 + */ + +public interface AuthScheme { + + /** + * Processes the given challenge token. Some authentication schemes + * may involve multiple challenge-response exchanges. Such schemes must be able + * to maintain the state information when dealing with sequential challenges + * + * @param header the challenge header + */ + void processChallenge(final Header header) throws MalformedChallengeException; + + /** + * Returns textual designation of the given authentication scheme. + * + * @return the name of the given authentication scheme + */ + String getSchemeName(); + + /** + * Returns authentication parameter with the given name, if available. + * + * @param name The name of the parameter to be returned + * + * @return the parameter with the given name + */ + String getParameter(final String name); + + /** + * Returns authentication realm. If the concept of an authentication + * realm is not applicable to the given authentication scheme, returns + * null. + * + * @return the authentication realm + */ + String getRealm(); + + /** + * Tests if the authentication scheme is provides authorization on a per + * connection basis instead of usual per request basis + * + * @return true if the scheme is connection based, false + * if the scheme is request based. + */ + boolean isConnectionBased(); + + /** + * Authentication process may involve a series of challenge-response exchanges. + * This method tests if the authorization process has been completed, either + * successfully or unsuccessfully, that is, all the required authorization + * challenges have been processed in their entirety. + * + * @return true if the authentication process has been completed, + * false otherwise. + */ + boolean isComplete(); + + /** + * Produces an authorization string for the given set of {@link Credentials}. + * + * @param credentials The set of credentials to be used for athentication + * @param request The request being authenticated + * @throws AuthenticationException if authorization string cannot + * be generated due to an authentication failure + * + * @return the authorization string + * + * @deprecated (4.1) Use {@link ContextAwareAuthScheme#authenticate(Credentials, HttpRequest, org.apache.http.protocol.HttpContext)} + */ + @Deprecated + Header authenticate(Credentials credentials, HttpRequest request) + throws AuthenticationException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/AuthSchemeFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/AuthSchemeFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/AuthSchemeFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,48 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import org.apache.http.params.HttpParams; + +/** + * Factory for {@link AuthScheme} implementations. + * + * @since 4.0 + */ +public interface AuthSchemeFactory { + + /** + * Creates an instance of {@link AuthScheme} using given HTTP parameters. + * + * @param params HTTP parameters. + * + * @return auth scheme. + */ + AuthScheme newInstance(HttpParams params); + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/AuthSchemeRegistry.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/AuthSchemeRegistry.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/AuthSchemeRegistry.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,144 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.http.annotation.ThreadSafe; + +import org.apache.http.params.HttpParams; + +/** + * Authentication scheme registry that can be used to obtain the corresponding + * authentication scheme implementation for a given type of authorization challenge. + * + * @since 4.0 + */ +@ThreadSafe +public final class AuthSchemeRegistry { + + private final ConcurrentHashMap registeredSchemes; + + public AuthSchemeRegistry() { + super(); + this.registeredSchemes = new ConcurrentHashMap(); + } + + /** + * Registers a {@link AuthSchemeFactory} with the given identifier. If a factory with the + * given name already exists it will be overridden. This name is the same one used to + * retrieve the {@link AuthScheme authentication scheme} from {@link #getAuthScheme}. + * + *

+ * Please note that custom authentication preferences, if used, need to be updated accordingly + * for the new {@link AuthScheme authentication scheme} to take effect. + *

+ * + * @param name the identifier for this scheme + * @param factory the {@link AuthSchemeFactory} class to register + * + * @see #getAuthScheme + */ + public void register( + final String name, + final AuthSchemeFactory factory) { + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + if (factory == null) { + throw new IllegalArgumentException("Authentication scheme factory may not be null"); + } + registeredSchemes.put(name.toLowerCase(Locale.ENGLISH), factory); + } + + /** + * Unregisters the class implementing an {@link AuthScheme authentication scheme} with + * the given name. + * + * @param name the identifier of the class to unregister + */ + public void unregister(final String name) { + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + registeredSchemes.remove(name.toLowerCase(Locale.ENGLISH)); + } + + /** + * Gets the {@link AuthScheme authentication scheme} with the given name. + * + * @param name the {@link AuthScheme authentication scheme} identifier + * @param params the {@link HttpParams HTTP parameters} for the authentication + * scheme. + * + * @return {@link AuthScheme authentication scheme} + * + * @throws IllegalStateException if a scheme with the given name cannot be found + */ + public AuthScheme getAuthScheme(final String name, final HttpParams params) + throws IllegalStateException { + + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + AuthSchemeFactory factory = registeredSchemes.get(name.toLowerCase(Locale.ENGLISH)); + if (factory != null) { + return factory.newInstance(params); + } else { + throw new IllegalStateException("Unsupported authentication scheme: " + name); + } + } + + /** + * Obtains a list containing the names of all registered {@link AuthScheme authentication + * schemes} + * + * @return list of registered scheme names + */ + public List getSchemeNames() { + return new ArrayList(registeredSchemes.keySet()); + } + + /** + * Populates the internal collection of registered {@link AuthScheme authentication schemes} + * with the content of the map passed as a parameter. + * + * @param map authentication schemes + */ + public void setItems(final Map map) { + if (map == null) { + return; + } + registeredSchemes.clear(); + registeredSchemes.putAll(map); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/AuthScope.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/AuthScope.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/AuthScope.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,304 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import java.util.Locale; + +import org.apache.http.HttpHost; +import org.apache.http.annotation.Immutable; + +import org.apache.http.util.LangUtils; + +/** + * The class represents an authentication scope consisting of a host name, + * a port number, a realm name and an authentication scheme name which + * {@link Credentials Credentials} apply to. + * + * + * @since 4.0 + */ +@Immutable +public class AuthScope { + + /** + * The null value represents any host. In the future versions of + * HttpClient the use of this parameter will be discontinued. + */ + public static final String ANY_HOST = null; + + /** + * The -1 value represents any port. + */ + public static final int ANY_PORT = -1; + + /** + * The null value represents any realm. + */ + public static final String ANY_REALM = null; + + /** + * The null value represents any authentication scheme. + */ + public static final String ANY_SCHEME = null; + + /** + * Default scope matching any host, port, realm and authentication scheme. + * In the future versions of HttpClient the use of this parameter will be + * discontinued. + */ + public static final AuthScope ANY = new AuthScope(ANY_HOST, ANY_PORT, ANY_REALM, ANY_SCHEME); + + /** The authentication scheme the credentials apply to. */ + private final String scheme; + + /** The realm the credentials apply to. */ + private final String realm; + + /** The host the credentials apply to. */ + private final String host; + + /** The port the credentials apply to. */ + private final int port; + + /** Creates a new credentials scope for the given + * host, port, realm, and + * authentication scheme. + * + * @param host the host the credentials apply to. May be set + * to null if credentials are applicable to + * any host. + * @param port the port the credentials apply to. May be set + * to negative value if credentials are applicable to + * any port. + * @param realm the realm the credentials apply to. May be set + * to null if credentials are applicable to + * any realm. + * @param scheme the authentication scheme the credentials apply to. + * May be set to null if credentials are applicable to + * any authentication scheme. + */ + public AuthScope(final String host, int port, + final String realm, final String scheme) + { + this.host = (host == null) ? ANY_HOST: host.toLowerCase(Locale.ENGLISH); + this.port = (port < 0) ? ANY_PORT: port; + this.realm = (realm == null) ? ANY_REALM: realm; + this.scheme = (scheme == null) ? ANY_SCHEME: scheme.toUpperCase(Locale.ENGLISH); + } + + /** + * @since 4.2 + */ + public AuthScope(final HttpHost host, final String realm, final String schemeName) { + this(host.getHostName(), host.getPort(), realm, schemeName); + } + + /** + * @since 4.2 + */ + public AuthScope(final HttpHost host) { + this(host, ANY_REALM, ANY_SCHEME); + } + + /** Creates a new credentials scope for the given + * host, port, realm, and any + * authentication scheme. + * + * @param host the host the credentials apply to. May be set + * to null if credentials are applicable to + * any host. + * @param port the port the credentials apply to. May be set + * to negative value if credentials are applicable to + * any port. + * @param realm the realm the credentials apply to. May be set + * to null if credentials are applicable to + * any realm. + */ + public AuthScope(final String host, int port, final String realm) { + this(host, port, realm, ANY_SCHEME); + } + + /** Creates a new credentials scope for the given + * host, port, any realm name, and any + * authentication scheme. + * + * @param host the host the credentials apply to. May be set + * to null if credentials are applicable to + * any host. + * @param port the port the credentials apply to. May be set + * to negative value if credentials are applicable to + * any port. + */ + public AuthScope(final String host, int port) { + this(host, port, ANY_REALM, ANY_SCHEME); + } + + /** + * Creates a copy of the given credentials scope. + */ + public AuthScope(final AuthScope authscope) { + super(); + if (authscope == null) { + throw new IllegalArgumentException("Scope may not be null"); + } + this.host = authscope.getHost(); + this.port = authscope.getPort(); + this.realm = authscope.getRealm(); + this.scheme = authscope.getScheme(); + } + + /** + * @return the host + */ + public String getHost() { + return this.host; + } + + /** + * @return the port + */ + public int getPort() { + return this.port; + } + + /** + * @return the realm name + */ + public String getRealm() { + return this.realm; + } + + /** + * @return the scheme type + */ + public String getScheme() { + return this.scheme; + } + + /** + * Tests if the authentication scopes match. + * + * @return the match factor. Negative value signifies no match. + * Non-negative signifies a match. The greater the returned value + * the closer the match. + */ + public int match(final AuthScope that) { + int factor = 0; + if (LangUtils.equals(this.scheme, that.scheme)) { + factor += 1; + } else { + if (this.scheme != ANY_SCHEME && that.scheme != ANY_SCHEME) { + return -1; + } + } + if (LangUtils.equals(this.realm, that.realm)) { + factor += 2; + } else { + if (this.realm != ANY_REALM && that.realm != ANY_REALM) { + return -1; + } + } + if (this.port == that.port) { + factor += 4; + } else { + if (this.port != ANY_PORT && that.port != ANY_PORT) { + return -1; + } + } + if (LangUtils.equals(this.host, that.host)) { + factor += 8; + } else { + if (this.host != ANY_HOST && that.host != ANY_HOST) { + return -1; + } + } + return factor; + } + + /** + * @see java.lang.Object#equals(Object) + */ + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (o == this) { + return true; + } + if (!(o instanceof AuthScope)) { + return super.equals(o); + } + AuthScope that = (AuthScope) o; + return + LangUtils.equals(this.host, that.host) + && this.port == that.port + && LangUtils.equals(this.realm, that.realm) + && LangUtils.equals(this.scheme, that.scheme); + } + + /** + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + if (this.scheme != null) { + buffer.append(this.scheme.toUpperCase(Locale.ENGLISH)); + buffer.append(' '); + } + if (this.realm != null) { + buffer.append('\''); + buffer.append(this.realm); + buffer.append('\''); + } else { + buffer.append(""); + } + if (this.host != null) { + buffer.append('@'); + buffer.append(this.host); + if (this.port >= 0) { + buffer.append(':'); + buffer.append(this.port); + } + } + return buffer.toString(); + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.host); + hash = LangUtils.hashCode(hash, this.port); + hash = LangUtils.hashCode(hash, this.realm); + hash = LangUtils.hashCode(hash, this.scheme); + return hash; + } +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/AuthState.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/AuthState.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/AuthState.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,240 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import java.util.Queue; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * This class provides detailed information about the state of the authentication process. + * + * @since 4.0 + */ +@NotThreadSafe +public class AuthState { + + /** Actual state of authentication protocol */ + private AuthProtocolState state; + + /** Actual authentication scheme */ + private AuthScheme authScheme; + + /** Actual authentication scope */ + private AuthScope authScope; + + /** Credentials selected for authentication */ + private Credentials credentials; + + /** Available auth options */ + private Queue authOptions; + + public AuthState() { + super(); + this.state = AuthProtocolState.UNCHALLENGED; + } + + /** + * Resets the auth state. + * + * @since 4.2 + */ + public void reset() { + this.state = AuthProtocolState.UNCHALLENGED; + this.authOptions = null; + this.authScheme = null; + this.authScope = null; + this.credentials = null; + } + + /** + * @since 4.2 + */ + public AuthProtocolState getState() { + return this.state; + } + + /** + * @since 4.2 + */ + public void setState(final AuthProtocolState state) { + this.state = state != null ? state : AuthProtocolState.UNCHALLENGED; + } + + /** + * Returns actual {@link AuthScheme}. May be null. + */ + public AuthScheme getAuthScheme() { + return this.authScheme; + } + + /** + * Returns actual {@link Credentials}. May be null. + */ + public Credentials getCredentials() { + return this.credentials; + } + + /** + * Updates the auth state with {@link AuthScheme} and {@link Credentials}. + * + * @param authScheme auth scheme. May not be null. + * @param credentials user crednetials. May not be null. + * + * @since 4.2 + */ + public void update(final AuthScheme authScheme, final Credentials credentials) { + if (authScheme == null) { + throw new IllegalArgumentException("Auth scheme may not be null or empty"); + } + if (credentials == null) { + throw new IllegalArgumentException("Credentials may not be null or empty"); + } + this.authScheme = authScheme; + this.credentials = credentials; + this.authOptions = null; + } + + /** + * Returns available {@link AuthOption}s. May be null. + * + * @since 4.2 + */ + public Queue getAuthOptions() { + return this.authOptions; + } + + /** + * Returns true if {@link AuthOption}s are available, false + * otherwise. + * + * @since 4.2 + */ + public boolean hasAuthOptions() { + return this.authOptions != null && !this.authOptions.isEmpty(); + } + + /** + * Updates the auth state with a queue of {@link AuthOption}s. + * + * @param authOptions a queue of auth options. May not be null or empty. + * + * @since 4.2 + */ + public void update(final Queue authOptions) { + if (authOptions == null || authOptions.isEmpty()) { + throw new IllegalArgumentException("Queue of auth options may not be null or empty"); + } + this.authOptions = authOptions; + this.authScheme = null; + this.credentials = null; + } + + /** + * Invalidates the authentication state by resetting its parameters. + * + * @deprecated (4.2) use {@link #reset()} + */ + @Deprecated + public void invalidate() { + reset(); + } + + /** + * @deprecated (4.2) do not use + */ + @Deprecated + public boolean isValid() { + return this.authScheme != null; + } + + /** + * Assigns the given {@link AuthScheme authentication scheme}. + * + * @param authScheme the {@link AuthScheme authentication scheme} + * + * @deprecated (4.2) use {@link #update(AuthScheme, Credentials)} + */ + @Deprecated + public void setAuthScheme(final AuthScheme authScheme) { + if (authScheme == null) { + reset(); + return; + } + this.authScheme = authScheme; + } + + /** + * Sets user {@link Credentials} to be used for authentication + * + * @param credentials User credentials + * + * @deprecated (4.2) use {@link #update(AuthScheme, Credentials)} + */ + @Deprecated + public void setCredentials(final Credentials credentials) { + this.credentials = credentials; + } + + /** + * Returns actual {@link AuthScope} if available + * + * @return actual authentication scope if available, null. + * + */ + +package org.apache.http.auth; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.ProtocolException; + +/** + * Signals a failure in authentication process + * + * + * @since 4.0 + */ +@Immutable +public class AuthenticationException extends ProtocolException { + + private static final long serialVersionUID = -6794031905674764776L; + + /** + * Creates a new AuthenticationException with a null detail message. + */ + public AuthenticationException() { + super(); + } + + /** + * Creates a new AuthenticationException with the specified message. + * + * @param message the exception detail message + */ + public AuthenticationException(String message) { + super(message); + } + + /** + * Creates a new AuthenticationException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public AuthenticationException(String message, Throwable cause) { + super(message, cause); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/BasicUserPrincipal.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/BasicUserPrincipal.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/BasicUserPrincipal.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,89 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import java.io.Serializable; +import java.security.Principal; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.util.LangUtils; + +/** + * Basic user principal used for HTTP authentication + * + * @since 4.0 + */ +@Immutable +public final class BasicUserPrincipal implements Principal, Serializable { + + private static final long serialVersionUID = -2266305184969850467L; + + private final String username; + + public BasicUserPrincipal(final String username) { + super(); + if (username == null) { + throw new IllegalArgumentException("User name may not be null"); + } + this.username = username; + } + + public String getName() { + return this.username; + } + + @Override + public int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.username); + return hash; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o instanceof BasicUserPrincipal) { + BasicUserPrincipal that = (BasicUserPrincipal) o; + if (LangUtils.equals(this.username, that.username)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("[principal: "); + buffer.append(this.username); + buffer.append("]"); + return buffer.toString(); + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/auth/ChallengeState.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/ChallengeState.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/ChallengeState.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,37 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.http.auth; + +/** + * Challenge mode (TARGET or PROXY) + * + * @since 4.2 + */ +public enum ChallengeState { + + TARGET, PROXY + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/ContextAwareAuthScheme.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/ContextAwareAuthScheme.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/ContextAwareAuthScheme.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,62 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import org.apache.http.Header; +import org.apache.http.HttpRequest; +import org.apache.http.protocol.HttpContext; + +/** + * This interface represents an extended authentication scheme + * that requires access to {@link HttpContext} in order to + * generate an authorization string. + * + * TODO: Fix AuthScheme interface in the next major version + * + * @since 4.1 + */ + +public interface ContextAwareAuthScheme extends AuthScheme { + + /** + * Produces an authorization string for the given set of + * {@link Credentials}. + * + * @param credentials The set of credentials to be used for athentication + * @param request The request being authenticated + * @param context HTTP context + * @throws AuthenticationException if authorization string cannot + * be generated due to an authentication failure + * + * @return the authorization string + */ + Header authenticate( + Credentials credentials, + HttpRequest request, + HttpContext context) throws AuthenticationException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/Credentials.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/Credentials.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/Credentials.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,44 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import java.security.Principal; + +/** + * This interface represents a set of credentials consisting of a security + * principal and a secret (password) that can be used to establish user + * identity + * + * @since 4.0 + */ +public interface Credentials { + + Principal getUserPrincipal(); + + String getPassword(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/InvalidCredentialsException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/InvalidCredentialsException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/InvalidCredentialsException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,69 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import org.apache.http.annotation.Immutable; + +/** + * Authentication credentials required to respond to a authentication + * challenge are invalid + * + * + * @since 4.0 + */ +@Immutable +public class InvalidCredentialsException extends AuthenticationException { + + private static final long serialVersionUID = -4834003835215460648L; + + /** + * Creates a new InvalidCredentialsException with a null detail message. + */ + public InvalidCredentialsException() { + super(); + } + + /** + * Creates a new InvalidCredentialsException with the specified message. + * + * @param message the exception detail message + */ + public InvalidCredentialsException(String message) { + super(message); + } + + /** + * Creates a new InvalidCredentialsException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public InvalidCredentialsException(String message, Throwable cause) { + super(message, cause); + } +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/MalformedChallengeException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/MalformedChallengeException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/MalformedChallengeException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,71 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.ProtocolException; + +/** + * Signals that authentication challenge is in some way invalid or + * illegal in the given context + * + * + * @since 4.0 + */ +@Immutable +public class MalformedChallengeException extends ProtocolException { + + private static final long serialVersionUID = 814586927989932284L; + + /** + * Creates a new MalformedChallengeException with a null detail message. + */ + public MalformedChallengeException() { + super(); + } + + /** + * Creates a new MalformedChallengeException with the specified message. + * + * @param message the exception detail message + */ + public MalformedChallengeException(String message) { + super(message); + } + + /** + * Creates a new MalformedChallengeException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public MalformedChallengeException(String message, Throwable cause) { + super(message, cause); + } +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/NTCredentials.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/NTCredentials.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/NTCredentials.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,179 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import java.io.Serializable; +import java.security.Principal; +import java.util.Locale; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.util.LangUtils; + +/** + * {@link Credentials} implementation for Microsoft Windows platforms that includes + * Windows specific attributes such as name of the domain the user belongs to. + * + * @since 4.0 + */ +@Immutable +public class NTCredentials implements Credentials, Serializable { + + private static final long serialVersionUID = -7385699315228907265L; + + /** The user principal */ + private final NTUserPrincipal principal; + + /** Password */ + private final String password; + + /** The host the authentication request is originating from. */ + private final String workstation; + + /** + * The constructor with the fully qualified username and password combined + * string argument. + * + * @param usernamePassword the domain/username:password formed string + */ + public NTCredentials(String usernamePassword) { + super(); + if (usernamePassword == null) { + throw new IllegalArgumentException("Username:password string may not be null"); + } + String username; + int atColon = usernamePassword.indexOf(':'); + if (atColon >= 0) { + username = usernamePassword.substring(0, atColon); + this.password = usernamePassword.substring(atColon + 1); + } else { + username = usernamePassword; + this.password = null; + } + int atSlash = username.indexOf('/'); + if (atSlash >= 0) { + this.principal = new NTUserPrincipal( + username.substring(0, atSlash).toUpperCase(Locale.ENGLISH), + username.substring(atSlash + 1)); + } else { + this.principal = new NTUserPrincipal( + null, + username.substring(atSlash + 1)); + } + this.workstation = null; + } + + /** + * Constructor. + * @param userName The user name. This should not include the domain to authenticate with. + * For example: "user" is correct whereas "DOMAIN\\user" is not. + * @param password The password. + * @param workstation The workstation the authentication request is originating from. + * Essentially, the computer name for this machine. + * @param domain The domain to authenticate within. + */ + public NTCredentials( + final String userName, + final String password, + final String workstation, + final String domain) { + super(); + if (userName == null) { + throw new IllegalArgumentException("User name may not be null"); + } + this.principal = new NTUserPrincipal(domain, userName); + this.password = password; + if (workstation != null) { + this.workstation = workstation.toUpperCase(Locale.ENGLISH); + } else { + this.workstation = null; + } + } + + public Principal getUserPrincipal() { + return this.principal; + } + + public String getUserName() { + return this.principal.getUsername(); + } + + public String getPassword() { + return this.password; + } + + /** + * Retrieves the name to authenticate with. + * + * @return String the domain these credentials are intended to authenticate with. + */ + public String getDomain() { + return this.principal.getDomain(); + } + + /** + * Retrieves the workstation name of the computer originating the request. + * + * @return String the workstation the user is logged into. + */ + public String getWorkstation() { + return this.workstation; + } + + @Override + public int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.principal); + hash = LangUtils.hashCode(hash, this.workstation); + return hash; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o instanceof NTCredentials) { + NTCredentials that = (NTCredentials) o; + if (LangUtils.equals(this.principal, that.principal) + && LangUtils.equals(this.workstation, that.workstation)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("[principal: "); + buffer.append(this.principal); + buffer.append("][workstation: "); + buffer.append(this.workstation); + buffer.append("]"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/NTUserPrincipal.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/NTUserPrincipal.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/NTUserPrincipal.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,113 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import java.io.Serializable; +import java.security.Principal; +import java.util.Locale; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.util.LangUtils; + +/** + * Microsoft Windows specific user principal implementation. + * + * @since 4.0 + */ +@Immutable +public class NTUserPrincipal implements Principal, Serializable { + + private static final long serialVersionUID = -6870169797924406894L; + + private final String username; + private final String domain; + private final String ntname; + + public NTUserPrincipal( + final String domain, + final String username) { + super(); + if (username == null) { + throw new IllegalArgumentException("User name may not be null"); + } + this.username = username; + if (domain != null) { + this.domain = domain.toUpperCase(Locale.ENGLISH); + } else { + this.domain = null; + } + if (this.domain != null && this.domain.length() > 0) { + StringBuilder buffer = new StringBuilder(); + buffer.append(this.domain); + buffer.append('/'); + buffer.append(this.username); + this.ntname = buffer.toString(); + } else { + this.ntname = this.username; + } + } + + public String getName() { + return this.ntname; + } + + public String getDomain() { + return this.domain; + } + + public String getUsername() { + return this.username; + } + + @Override + public int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.username); + hash = LangUtils.hashCode(hash, this.domain); + return hash; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o instanceof NTUserPrincipal) { + NTUserPrincipal that = (NTUserPrincipal) o; + if (LangUtils.equals(this.username, that.username) + && LangUtils.equals(this.domain, that.domain)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return this.ntname; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/UsernamePasswordCredentials.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/UsernamePasswordCredentials.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/UsernamePasswordCredentials.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,122 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth; + +import java.io.Serializable; +import java.security.Principal; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.util.LangUtils; + +/** + * Simple {@link Credentials} implementation based on a user name / password + * pair. + * + * @since 4.0 + */ +@Immutable +public class UsernamePasswordCredentials implements Credentials, Serializable { + + private static final long serialVersionUID = 243343858802739403L; + + private final BasicUserPrincipal principal; + private final String password; + + /** + * The constructor with the username and password combined string argument. + * + * @param usernamePassword the username:password formed string + * @see #toString + */ + public UsernamePasswordCredentials(String usernamePassword) { + super(); + if (usernamePassword == null) { + throw new IllegalArgumentException("Username:password string may not be null"); + } + int atColon = usernamePassword.indexOf(':'); + if (atColon >= 0) { + this.principal = new BasicUserPrincipal(usernamePassword.substring(0, atColon)); + this.password = usernamePassword.substring(atColon + 1); + } else { + this.principal = new BasicUserPrincipal(usernamePassword); + this.password = null; + } + } + + + /** + * The constructor with the username and password arguments. + * + * @param userName the user name + * @param password the password + */ + public UsernamePasswordCredentials(String userName, String password) { + super(); + if (userName == null) { + throw new IllegalArgumentException("Username may not be null"); + } + this.principal = new BasicUserPrincipal(userName); + this.password = password; + } + + public Principal getUserPrincipal() { + return this.principal; + } + + public String getUserName() { + return this.principal.getName(); + } + + public String getPassword() { + return password; + } + + @Override + public int hashCode() { + return this.principal.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o instanceof UsernamePasswordCredentials) { + UsernamePasswordCredentials that = (UsernamePasswordCredentials) o; + if (LangUtils.equals(this.principal, that.principal)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return this.principal.toString(); + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/auth/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,35 @@ + + + + + +The API for client-side HTTP authentication against a server. + + Index: 3rdParty_sources/httpclient/org/apache/http/auth/params/AuthPNames.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/params/AuthPNames.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/params/AuthPNames.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,69 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth.params; + +import org.apache.http.auth.AuthScheme; + +/** + * Parameter names for HTTP authentication classes. + * + * @since 4.0 + */ +public interface AuthPNames { + + /** + * Defines the charset to be used when encoding + * {@link org.apache.http.auth.Credentials}. + *

+ * This parameter expects a value of type {@link String}. + */ + public static final String CREDENTIAL_CHARSET = "http.auth.credential-charset"; + + /** + * Defines the order of preference for supported {@link AuthScheme}s when + * authenticating with the target host. + *

+ * This parameter expects a value of type {@link java.util.Collection}. The + * collection is expected to contain {@link String} instances representing + * a name of an authentication scheme as returned by + * {@link AuthScheme#getSchemeName()}. + */ + public static final String TARGET_AUTH_PREF = "http.auth.target-scheme-pref"; + + /** + * Defines the order of preference for supported {@link AuthScheme}s when + * authenticating with the proxy host. + *

+ * This parameter expects a value of type {@link java.util.Collection}. The + * collection is expected to contain {@link String} instances representing + * a name of an authentication scheme as returned by + * {@link AuthScheme#getSchemeName()}. + */ + public static final String PROXY_AUTH_PREF = "http.auth.proxy-scheme-pref"; + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/params/AuthParamBean.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/params/AuthParamBean.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/params/AuthParamBean.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,50 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth.params; + +import org.apache.http.params.HttpAbstractParamBean; +import org.apache.http.params.HttpParams; + +/** + * This is a Java Bean class that can be used to wrap an instance of + * {@link HttpParams} and manipulate HTTP authentication parameters + * using Java Beans conventions. + * + * @since 4.0 + */ +public class AuthParamBean extends HttpAbstractParamBean { + + public AuthParamBean (final HttpParams params) { + super(params); + } + + public void setCredentialCharset (final String charset) { + AuthParams.setCredentialCharset(params, charset); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/params/AuthParams.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/params/AuthParams.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/params/AuthParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,83 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.auth.params; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HTTP; + +/** + * An adaptor for manipulating HTTP authentication parameters + * in {@link HttpParams}. + * + * @since 4.0 + * + * @see AuthPNames + */ +@Immutable +public final class AuthParams { + + private AuthParams() { + super(); + } + + /** + * Obtains the charset for encoding + * {@link org.apache.http.auth.Credentials}.If not configured, + * {@link HTTP#DEFAULT_PROTOCOL_CHARSET}is used instead. + * + * @return The charset + */ + public static String getCredentialCharset(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + String charset = (String) params.getParameter + (AuthPNames.CREDENTIAL_CHARSET); + if (charset == null) { + charset = HTTP.DEF_PROTOCOL_CHARSET.name(); + } + return charset; + } + + + /** + * Sets the charset to be used when encoding + * {@link org.apache.http.auth.Credentials}. + * + * @param charset The charset + */ + public static void setCredentialCharset(final HttpParams params, final String charset) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setParameter(AuthPNames.CREDENTIAL_CHARSET, charset); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/auth/params/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/auth/params/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/auth/params/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Parameters for configuring HTTP authentication classes. + + + Index: 3rdParty_sources/httpclient/org/apache/http/client/AuthCache.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/AuthCache.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/AuthCache.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,49 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScheme; + +/** + * Abstract {@link AuthScheme} cache. Initialized {@link AuthScheme} objects + * from this cache can be used to preemptively authenticate against known + * hosts. + * + * @since 4.1 + */ +public interface AuthCache { + + void put(HttpHost host, AuthScheme authScheme); + + AuthScheme get(HttpHost host); + + void remove(HttpHost host); + + void clear(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/AuthenticationHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/AuthenticationHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/AuthenticationHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,101 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import java.util.Map; + +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.protocol.HttpContext; + +/** +/** + * A handler for determining if an HTTP response represents an authentication + * challenge that was sent back to the client as a result of authentication + * failure. + *

+ * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link AuthenticationStrategy} + */ +@Deprecated +public interface AuthenticationHandler { + + /** + * Determines if the given HTTP response response represents + * an authentication challenge that was sent back as a result + * of authentication failure + * @param response HTTP response. + * @param context HTTP context. + * @return true if user authentication is required, + * false otherwise. + */ + boolean isAuthenticationRequested( + HttpResponse response, + HttpContext context); + + /** + * Extracts from the given HTTP response a collection of authentication + * challenges, each of which represents an authentication scheme supported + * by the authentication host. + * + * @param response HTTP response. + * @param context HTTP context. + * @return a collection of challenges keyed by names of corresponding + * authentication schemes. + * @throws MalformedChallengeException if one of the authentication + * challenges is not valid or malformed. + */ + Map getChallenges( + HttpResponse response, + HttpContext context) throws MalformedChallengeException; + + /** + * Selects one authentication challenge out of all available and + * creates and generates {@link AuthScheme} instance capable of + * processing that challenge. + * @param challenges collection of challenges. + * @param response HTTP response. + * @param context HTTP context. + * @return authentication scheme to use for authentication. + * @throws AuthenticationException if an authentication scheme + * could not be selected. + */ + AuthScheme selectScheme( + Map challenges, + HttpResponse response, + HttpContext context) throws AuthenticationException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/AuthenticationStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/AuthenticationStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/AuthenticationStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,130 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import java.util.Map; +import java.util.Queue; + +import org.apache.http.Header; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthOption; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.protocol.HttpContext; + +/** +/** + * A handler for determining if an HTTP response represents an authentication challenge that was + * sent back to the client as a result of authentication failure. + *

+ * Implementations of this interface must be thread-safe. Access to shared data must be + * synchronized as methods of this interface may be executed from multiple threads. + * + * @since 4.2 + */ +public interface AuthenticationStrategy { + + /** + * Determines if the given HTTP response response represents + * an authentication challenge that was sent back as a result + * of authentication failure. + * + * @param authhost authentication host. + * @param response HTTP response. + * @param context HTTP context. + * @return true if user authentication is required, + * false otherwise. + */ + boolean isAuthenticationRequested( + HttpHost authhost, + HttpResponse response, + HttpContext context); + + /** + * Extracts from the given HTTP response a collection of authentication + * challenges, each of which represents an authentication scheme supported + * by the authentication host. + * + * @param authhost authentication host. + * @param response HTTP response. + * @param context HTTP context. + * @return a collection of challenges keyed by names of corresponding + * authentication schemes. + * @throws MalformedChallengeException if one of the authentication + * challenges is not valid or malformed. + */ + Map getChallenges( + HttpHost authhost, + HttpResponse response, + HttpContext context) throws MalformedChallengeException; + + /** + * Selects one authentication challenge out of all available and + * creates and generates {@link AuthOption} instance capable of + * processing that challenge. + * + * @param challenges collection of challenges. + * @param authhost authentication host. + * @param response HTTP response. + * @param context HTTP context. + * @return authentication auth schemes that can be used for authentication. Can be empty. + * @throws MalformedChallengeException if one of the authentication + * challenges is not valid or malformed. + */ + Queue select( + Map challenges, + HttpHost authhost, + HttpResponse response, + HttpContext context) throws MalformedChallengeException; + + /** + * Callback invoked in case of successful authentication. + * + * @param authhost authentication host. + * @param authScheme authentication scheme used. + * @param context HTTP context. + */ + void authSucceeded( + HttpHost authhost, + AuthScheme authScheme, + HttpContext context); + + /** + * Callback invoked in case of unsuccessful authentication. + * + * @param authhost authentication host. + * @param authScheme authentication scheme used. + * @param context HTTP context. + */ + void authFailed( + HttpHost authhost, + AuthScheme authScheme, + HttpContext context); + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/BackoffManager.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/BackoffManager.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/BackoffManager.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,53 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.client; + +import org.apache.http.conn.routing.HttpRoute; + +/** + * Represents a controller that dynamically adjusts the size + * of an available connection pool based on feedback from + * using the connections. + * + * @since 4.2 + * + */ +public interface BackoffManager { + + /** + * Called when we have decided that the result of + * using a connection should be interpreted as a + * backoff signal. + */ + public void backOff(HttpRoute route); + + /** + * Called when we have determined that the result of + * using a connection has succeeded and that we may + * probe for more connections. + */ + public void probe(HttpRoute route); +} Index: 3rdParty_sources/httpclient/org/apache/http/client/CircularRedirectException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/CircularRedirectException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/CircularRedirectException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,68 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import org.apache.http.annotation.Immutable; + +/** + * Signals a circular redirect + * + * + * @since 4.0 + */ +@Immutable +public class CircularRedirectException extends RedirectException { + + private static final long serialVersionUID = 6830063487001091803L; + + /** + * Creates a new CircularRedirectException with a null detail message. + */ + public CircularRedirectException() { + super(); + } + + /** + * Creates a new CircularRedirectException with the specified detail message. + * + * @param message The exception detail message + */ + public CircularRedirectException(String message) { + super(message); + } + + /** + * Creates a new CircularRedirectException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public CircularRedirectException(String message, Throwable cause) { + super(message, cause); + } +} Index: 3rdParty_sources/httpclient/org/apache/http/client/ClientProtocolException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/ClientProtocolException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/ClientProtocolException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,61 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import java.io.IOException; + +import org.apache.http.annotation.Immutable; + +/** + * Signals an error in the HTTP protocol. + * + * @since 4.0 + */ +@Immutable +public class ClientProtocolException extends IOException { + + private static final long serialVersionUID = -5596590843227115865L; + + public ClientProtocolException() { + super(); + } + + public ClientProtocolException(String s) { + super(s); + } + + public ClientProtocolException(Throwable cause) { + initCause(cause); + } + + public ClientProtocolException(String message, Throwable cause) { + super(message); + initCause(cause); + } + + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/ConnectionBackoffStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/ConnectionBackoffStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/ConnectionBackoffStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,63 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.client; + +import org.apache.http.HttpResponse; + +/** + * When managing a dynamic number of connections for a given route, this + * strategy assesses whether a given request execution outcome should + * result in a backoff signal or not, based on either examining the + * Throwable that resulted or by examining the resulting + * response (e.g. for its status code). + * + * @since 4.2 + * + */ +public interface ConnectionBackoffStrategy { + + /** + * Determines whether seeing the given Throwable as + * a result of request execution should result in a backoff + * signal. + * @param t the Throwable that happened + * @return true if a backoff signal should be + * given + */ + boolean shouldBackoff(Throwable t); + + /** + * Determines whether receiving the given {@link HttpResponse} as + * a result of request execution should result in a backoff + * signal. Implementations MUST restrict themselves to examining + * the response header and MUST NOT consume any of the response + * body, if any. + * @param resp the HttpResponse that was received + * @return true if a backoff signal should be + * given + */ + boolean shouldBackoff(HttpResponse resp); +} Index: 3rdParty_sources/httpclient/org/apache/http/client/CookieStore.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/CookieStore.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/CookieStore.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,71 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import java.util.Date; +import java.util.List; + +import org.apache.http.cookie.Cookie; + +/** + * This interface represents an abstract store for {@link Cookie} + * objects. + * + * @since 4.0 + */ +public interface CookieStore { + + /** + * Adds an {@link Cookie}, replacing any existing equivalent cookies. + * If the given cookie has already expired it will not be added, but existing + * values will still be removed. + * + * @param cookie the {@link Cookie cookie} to be added + */ + void addCookie(Cookie cookie); + + /** + * Returns all cookies contained in this store. + * + * @return all cookies + */ + List getCookies(); + + /** + * Removes all of {@link Cookie}s in this store that have expired by + * the specified {@link java.util.Date}. + * + * @return true if any cookies were purged. + */ + boolean clearExpired(Date date); + + /** + * Clears all cookies. + */ + void clear(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/CredentialsProvider.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/CredentialsProvider.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/CredentialsProvider.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,71 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; + +/** + * Abstract credentials provider that maintains a collection of user + * credentials. + *

+ * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + */ +public interface CredentialsProvider { + + /** + * Sets the {@link Credentials credentials} for the given authentication + * scope. Any previous credentials for the given scope will be overwritten. + * + * @param authscope the {@link AuthScope authentication scope} + * @param credentials the authentication {@link Credentials credentials} + * for the given scope. + * + * @see #getCredentials(AuthScope) + */ + void setCredentials(AuthScope authscope, Credentials credentials); + + /** + * Get the {@link Credentials credentials} for the given authentication scope. + * + * @param authscope the {@link AuthScope authentication scope} + * @return the credentials + * + * @see #setCredentials(AuthScope, Credentials) + */ + Credentials getCredentials(AuthScope authscope); + + /** + * Clears all credentials. + */ + void clear(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/HttpClient.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/HttpClient.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/HttpClient.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,281 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import java.io.IOException; + +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; + +/** + * This interface represents only the most basic contract for HTTP request + * execution. It imposes no restrictions or particular details on the request + * execution process and leaves the specifics of state management, + * authentication and redirect handling up to individual implementations. + * This should make it easier to decorate the interface with additional + * functionality such as response content caching. + *

+ * The usual execution flow can be demonstrated by the code snippet below: + *

+ * HttpClient httpclient = new DefaultHttpClient();
+ *
+ * // Prepare a request object
+ * HttpGet httpget = new HttpGet("http://www.apache.org/");
+ *
+ * // Execute the request
+ * HttpResponse response = httpclient.execute(httpget);
+ *
+ * // Examine the response status
+ * System.out.println(response.getStatusLine());
+ *
+ * // Get hold of the response entity
+ * HttpEntity entity = response.getEntity();
+ *
+ * // If the response does not enclose an entity, there is no need
+ * // to worry about connection release
+ * if (entity != null) {
+ *     InputStream instream = entity.getContent();
+ *     try {
+ *
+ *         BufferedReader reader = new BufferedReader(
+ *                 new InputStreamReader(instream));
+ *         // do something useful with the response
+ *         System.out.println(reader.readLine());
+ *
+ *     } catch (IOException ex) {
+ *
+ *         // In case of an IOException the connection will be released
+ *         // back to the connection manager automatically
+ *         throw ex;
+ *
+ *     } catch (RuntimeException ex) {
+ *
+ *         // In case of an unexpected exception you may want to abort
+ *         // the HTTP request in order to shut down the underlying
+ *         // connection and release it back to the connection manager.
+ *         httpget.abort();
+ *         throw ex;
+ *
+ *     } finally {
+ *
+ *         // Closing the input stream will trigger connection release
+ *         instream.close();
+ *
+ *     }
+ *
+ *     // When HttpClient instance is no longer needed,
+ *     // shut down the connection manager to ensure
+ *     // immediate deallocation of all system resources
+ *     httpclient.getConnectionManager().shutdown();
+ * }
+ * 
+ * + * @since 4.0 + */ +public interface HttpClient { + + + /** + * Obtains the parameters for this client. + * These parameters will become defaults for all requests being + * executed with this client, and for the parameters of + * dependent objects in this client. + * + * @return the default parameters + */ + HttpParams getParams(); + + /** + * Obtains the connection manager used by this client. + * + * @return the connection manager + */ + ClientConnectionManager getConnectionManager(); + + /** + * Executes a request using the default context. + * + * @param request the request to execute + * + * @return the response to the request. This is always a final response, + * never an intermediate response with an 1xx status code. + * Whether redirects or authentication challenges will be returned + * or handled automatically depends on the implementation and + * configuration of this client. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + HttpResponse execute(HttpUriRequest request) + throws IOException, ClientProtocolException; + + /** + * Executes a request using the given context. + * The route to the target will be determined by the HTTP client. + * + * @param request the request to execute + * @param context the context to use for the execution, or + * null to use the default context + * + * @return the response to the request. This is always a final response, + * never an intermediate response with an 1xx status code. + * Whether redirects or authentication challenges will be returned + * or handled automatically depends on the implementation and + * configuration of this client. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + HttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException, ClientProtocolException; + + /** + * Executes a request to the target using the default context. + * + * @param target the target host for the request. + * Implementations may accept null + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * + * @return the response to the request. This is always a final response, + * never an intermediate response with an 1xx status code. + * Whether redirects or authentication challenges will be returned + * or handled automatically depends on the implementation and + * configuration of this client. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + HttpResponse execute(HttpHost target, HttpRequest request) + throws IOException, ClientProtocolException; + + /** + * Executes a request to the target using the given context. + * + * @param target the target host for the request. + * Implementations may accept null + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * @param context the context to use for the execution, or + * null to use the default context + * + * @return the response to the request. This is always a final response, + * never an intermediate response with an 1xx status code. + * Whether redirects or authentication challenges will be returned + * or handled automatically depends on the implementation and + * configuration of this client. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + HttpResponse execute(HttpHost target, HttpRequest request, + HttpContext context) + throws IOException, ClientProtocolException; + + /** + * Executes a request using the default context and processes the + * response using the given response handler. + * + * @param request the request to execute + * @param responseHandler the response handler + * + * @return the response object as generated by the response handler. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + T execute( + HttpUriRequest request, + ResponseHandler responseHandler) + throws IOException, ClientProtocolException; + + /** + * Executes a request using the given context and processes the + * response using the given response handler. + * + * @param request the request to execute + * @param responseHandler the response handler + * + * @return the response object as generated by the response handler. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + T execute( + HttpUriRequest request, + ResponseHandler responseHandler, + HttpContext context) + throws IOException, ClientProtocolException; + + /** + * Executes a request to the target using the default context and + * processes the response using the given response handler. + * + * @param target the target host for the request. + * Implementations may accept null + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * @param responseHandler the response handler + * + * @return the response object as generated by the response handler. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + T execute( + HttpHost target, + HttpRequest request, + ResponseHandler responseHandler) + throws IOException, ClientProtocolException; + + /** + * Executes a request to the target using the given context and + * processes the response using the given response handler. + * + * @param target the target host for the request. + * Implementations may accept null + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * @param responseHandler the response handler + * @param context the context to use for the execution, or + * null to use the default context + * + * @return the response object as generated by the response handler. + * @throws IOException in case of a problem or the connection was aborted + * @throws ClientProtocolException in case of an http protocol error + */ + T execute( + HttpHost target, + HttpRequest request, + ResponseHandler responseHandler, + HttpContext context) + throws IOException, ClientProtocolException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/HttpRequestRetryHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/HttpRequestRetryHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/HttpRequestRetryHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,60 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import java.io.IOException; + +import org.apache.http.protocol.HttpContext; + +/** + * A handler for determining if an HttpRequest should be retried after a + * recoverable exception during execution. + *

+ * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + */ +public interface HttpRequestRetryHandler { + + /** + * Determines if a method should be retried after an IOException + * occurs during execution. + * + * @param exception the exception that occurred + * @param executionCount the number of times this method has been + * unsuccessfully executed + * @param context the context for the request execution + * + * @return true if the method should be retried, false + * otherwise + */ + boolean retryRequest(IOException exception, int executionCount, HttpContext context); + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/HttpResponseException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/HttpResponseException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/HttpResponseException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,52 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import org.apache.http.annotation.Immutable; + +/** + * Signals a non 2xx HTTP response. + * + * @since 4.0 + */ +@Immutable +public class HttpResponseException extends ClientProtocolException { + + private static final long serialVersionUID = -7186627969477257933L; + + private final int statusCode; + + public HttpResponseException(int statusCode, final String s) { + super(s); + this.statusCode = statusCode; + } + + public int getStatusCode() { + return this.statusCode; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/NonRepeatableRequestException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/NonRepeatableRequestException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/NonRepeatableRequestException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,73 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.ProtocolException; + +/** + * Signals failure to retry the request due to non-repeatable request + * entity. + * + * + * @since 4.0 + */ +@Immutable +public class NonRepeatableRequestException extends ProtocolException { + + private static final long serialVersionUID = 82685265288806048L; + + /** + * Creates a new NonRepeatableEntityException with a null detail message. + */ + public NonRepeatableRequestException() { + super(); + } + + /** + * Creates a new NonRepeatableEntityException with the specified detail message. + * + * @param message The exception detail message + */ + public NonRepeatableRequestException(String message) { + super(message); + } + + /** + * Creates a new NonRepeatableEntityException with the specified detail message. + * + * @param message The exception detail message + * @param cause the cause + */ + public NonRepeatableRequestException(String message, Throwable cause) { + super(message, cause); + } + + + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/RedirectException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/RedirectException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/RedirectException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,70 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.ProtocolException; + +/** + * Signals violation of HTTP specification caused by an invalid redirect + * + * + * @since 4.0 + */ +@Immutable +public class RedirectException extends ProtocolException { + + private static final long serialVersionUID = 4418824536372559326L; + + /** + * Creates a new RedirectException with a null detail message. + */ + public RedirectException() { + super(); + } + + /** + * Creates a new RedirectException with the specified detail message. + * + * @param message The exception detail message + */ + public RedirectException(String message) { + super(message); + } + + /** + * Creates a new RedirectException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public RedirectException(String message, Throwable cause) { + super(message, cause); + } +} Index: 3rdParty_sources/httpclient/org/apache/http/client/RedirectHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/RedirectHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/RedirectHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,77 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import java.net.URI; + +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolException; +import org.apache.http.protocol.HttpContext; + +/** + * A handler for determining if an HTTP request should be redirected to + * a new location in response to an HTTP response received from the target + * server. + *

+ * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + * + * @deprecated (4.1) use {@link RedirectStrategy} + */ +@Deprecated +public interface RedirectHandler { + + /** + * Determines if a request should be redirected to a new location + * given the response from the target server. + * + * @param response the response received from the target server + * @param context the context for the request execution + * + * @return true if the request should be redirected, false + * otherwise + */ + boolean isRedirectRequested(HttpResponse response, HttpContext context); + + /** + * Determines the location request is expected to be redirected to + * given the response from the target server and the current request + * execution context. + * + * @param response the response received from the target server + * @param context the context for the request execution + * + * @return redirect URI + */ + URI getLocationURI(HttpResponse response, HttpContext context) + throws ProtocolException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/RedirectStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/RedirectStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/RedirectStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,81 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolException; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.protocol.HttpContext; + +/** + * A strategy for determining if an HTTP request should be redirected to + * a new location in response to an HTTP response received from the target + * server. + *

+ * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.1 + */ +public interface RedirectStrategy { + + /** + * Determines if a request should be redirected to a new location + * given the response from the target server. + * + * @param request the executed request + * @param response the response received from the target server + * @param context the context for the request execution + * + * @return true if the request should be redirected, false + * otherwise + */ + boolean isRedirected( + HttpRequest request, + HttpResponse response, + HttpContext context) throws ProtocolException; + + /** + * Determines the redirect location given the response from the target + * server and the current request execution context and generates a new + * request to be sent to the location. + * + * @param request the executed request + * @param response the response received from the target server + * @param context the context for the request execution + * + * @return redirected request + */ + HttpUriRequest getRedirect( + HttpRequest request, + HttpResponse response, + HttpContext context) throws ProtocolException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/RequestDirector.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/RequestDirector.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/RequestDirector.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import java.io.IOException; + +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpException; +import org.apache.http.protocol.HttpContext; + +/** + * A client-side request director. + * The director decides which steps are necessary to execute a request. + * It establishes connections and optionally processes redirects and + * authentication challenges. The director may therefore generate and + * send a sequence of requests in order to execute one initial request. + * + * @since 4.0 + */ +public interface RequestDirector { + + + /** + * Executes a request. + *
Note: + * For the time being, a new director is instantiated for each request. + * This is the same behavior as for HttpMethodDirector + * in HttpClient 3. + * + * @param target the target host for the request. + * Implementations may accept null + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * @param context the context for executing the request + * + * @return the final response to the request. + * This is never an intermediate response with status code 1xx. + * + * @throws HttpException in case of a problem + * @throws IOException in case of an IO problem + * or if the connection was aborted + */ + HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) + throws HttpException, IOException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/ResponseHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/ResponseHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/ResponseHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,54 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import java.io.IOException; + +import org.apache.http.HttpResponse; + +/** + * Handler that encapsulates the process of generating a response object + * from a {@link HttpResponse}. + * + * + * @since 4.0 + */ +public interface ResponseHandler { + + /** + * Processes an {@link HttpResponse} and returns some value + * corresponding to that response. + * + * @param response The response to process + * @return A value determined by the response + * + * @throws ClientProtocolException in case of an http protocol error + * @throws IOException in case of a problem or the connection was aborted + */ + T handleResponse(HttpResponse response) throws ClientProtocolException, IOException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/ServiceUnavailableRetryStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/ServiceUnavailableRetryStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/ServiceUnavailableRetryStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,60 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import org.apache.http.HttpResponse; +import org.apache.http.protocol.HttpContext; + +/** + * Strategy interface that allows API users to plug in their own logic to + * control whether or not a retry should automatically be done, how many times + * it should be retried and so on. + * + * @since 4.2 + */ +public interface ServiceUnavailableRetryStrategy { + + /** + * Determines if a method should be retried given the response from the target server. + * + * @param response the response from the target server + * @param executionCount the number of times this method has been + * unsuccessfully executed + * @param context the context for the request execution + + * @return true if the method should be retried, false + * otherwise + */ + boolean retryRequest(HttpResponse response, int executionCount, HttpContext context); + + /** + * @return The interval between the subsequent auto-retries. + */ + long getRetryInterval(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/UserTokenHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/UserTokenHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/UserTokenHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,58 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client; + +import org.apache.http.protocol.HttpContext; + +/** + * A handler for determining if the given execution context is user specific + * or not. The token object returned by this handler is expected to uniquely + * identify the current user if the context is user specific or to be + * null if the context does not contain any resources or details + * specific to the current user. + *

+ * The user token will be used to ensure that user specific resources will not + * be shared with or reused by other users. + * + * @since 4.0 + */ +public interface UserTokenHandler { + + /** + * The token object returned by this method is expected to uniquely + * identify the current user if the context is user specific or to be + * null if it is not. + * + * @param context the execution context + * + * @return user token that uniquely identifies the user or + * null if the context is not user specific. + */ + Object getUserToken(HttpContext context); + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/entity/DecompressingEntity.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/entity/DecompressingEntity.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/entity/DecompressingEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,102 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.client.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.http.HttpEntity; +import org.apache.http.entity.HttpEntityWrapper; + +/** + * Common base class for decompressing {@link HttpEntity} implementations. + * + * @since 4.1 + */ +abstract class DecompressingEntity extends HttpEntityWrapper { + + /** + * Default buffer size. + */ + private static final int BUFFER_SIZE = 1024 * 2; + + /** + * DecompressingEntities are not repeatable, so they will return the same + * InputStream instance when {@link #getContent()} is called. + */ + private InputStream content; + + /** + * Creates a new {@link DecompressingEntity}. + * + * @param wrapped + * the non-null {@link HttpEntity} to be wrapped + */ + public DecompressingEntity(final HttpEntity wrapped) { + super(wrapped); + } + + abstract InputStream getDecompressingInputStream(final InputStream wrapped) throws IOException; + + /** + * {@inheritDoc} + */ + @Override + public InputStream getContent() throws IOException { + if (wrappedEntity.isStreaming()) { + if (content == null) { + content = getDecompressingInputStream(wrappedEntity.getContent()); + } + return content; + } else { + return getDecompressingInputStream(wrappedEntity.getContent()); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void writeTo(OutputStream outstream) throws IOException { + if (outstream == null) { + throw new IllegalArgumentException("Output stream may not be null"); + } + InputStream instream = getContent(); + try { + byte[] buffer = new byte[BUFFER_SIZE]; + + int l; + + while ((l = instream.read(buffer)) != -1) { + outstream.write(buffer, 0, l); + } + } finally { + instream.close(); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/entity/DeflateDecompressingEntity.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/entity/DeflateDecompressingEntity.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/entity/DeflateDecompressingEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,174 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * +*/ +package org.apache.http.client.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.io.PushbackInputStream; +import java.util.zip.DataFormatException; +import java.util.zip.Inflater; +import java.util.zip.InflaterInputStream; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.entity.HttpEntityWrapper; + +/** + * {@link HttpEntityWrapper} responsible for handling deflate Content Coded responses. In RFC2616 + * terms, deflate means a zlib stream as defined in RFC1950. Some server + * implementations have misinterpreted RFC2616 to mean that a deflate stream as + * defined in RFC1951 should be used (or maybe they did that since that's how IE behaves?). It's + * confusing that deflate in HTTP 1.1 means zlib streams rather than + * deflate streams. We handle both types in here, since that's what is seen on the + * internet. Moral - prefer gzip! + * + * @see GzipDecompressingEntity + * + * @since 4.1 + */ +public class DeflateDecompressingEntity extends DecompressingEntity { + + /** + * Creates a new {@link DeflateDecompressingEntity} which will wrap the specified + * {@link HttpEntity}. + * + * @param entity + * a non-null {@link HttpEntity} to be wrapped + */ + public DeflateDecompressingEntity(final HttpEntity entity) { + super(entity); + } + + /** + * Returns the non-null InputStream that should be returned to by all requests to + * {@link #getContent()}. + * + * @return a non-null InputStream + * @throws IOException if there was a problem + */ + @Override + InputStream getDecompressingInputStream(final InputStream wrapped) throws IOException { + /* + * A zlib stream will have a header. + * + * CMF | FLG [| DICTID ] | ...compressed data | ADLER32 | + * + * * CMF is one byte. + * + * * FLG is one byte. + * + * * DICTID is four bytes, and only present if FLG.FDICT is set. + * + * Sniff the content. Does it look like a zlib stream, with a CMF, etc? c.f. RFC1950, + * section 2.2. http://tools.ietf.org/html/rfc1950#page-4 + * + * We need to see if it looks like a proper zlib stream, or whether it is just a deflate + * stream. RFC2616 calls zlib streams deflate. Confusing, isn't it? That's why some servers + * implement deflate Content-Encoding using deflate streams, rather than zlib streams. + * + * We could start looking at the bytes, but to be honest, someone else has already read + * the RFCs and implemented that for us. So we'll just use the JDK libraries and exception + * handling to do this. If that proves slow, then we could potentially change this to check + * the first byte - does it look like a CMF? What about the second byte - does it look like + * a FLG, etc. + */ + + /* We read a small buffer to sniff the content. */ + byte[] peeked = new byte[6]; + + PushbackInputStream pushback = new PushbackInputStream(wrapped, peeked.length); + + int headerLength = pushback.read(peeked); + + if (headerLength == -1) { + throw new IOException("Unable to read the response"); + } + + /* We try to read the first uncompressed byte. */ + byte[] dummy = new byte[1]; + + Inflater inf = new Inflater(); + + try { + int n; + while ((n = inf.inflate(dummy)) == 0) { + if (inf.finished()) { + + /* Not expecting this, so fail loudly. */ + throw new IOException("Unable to read the response"); + } + + if (inf.needsDictionary()) { + + /* Need dictionary - then it must be zlib stream with DICTID part? */ + break; + } + + if (inf.needsInput()) { + inf.setInput(peeked); + } + } + + if (n == -1) { + throw new IOException("Unable to read the response"); + } + + /* + * We read something without a problem, so it's a valid zlib stream. Just need to reset + * and return an unused InputStream now. + */ + pushback.unread(peeked, 0, headerLength); + return new InflaterInputStream(pushback); + } catch (DataFormatException e) { + + /* Presume that it's an RFC1951 deflate stream rather than RFC1950 zlib stream and try + * again. */ + pushback.unread(peeked, 0, headerLength); + return new InflaterInputStream(pushback, new Inflater(true)); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Header getContentEncoding() { + + /* This HttpEntityWrapper has dealt with the Content-Encoding. */ + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public long getContentLength() { + + /* Length of inflated content is unknown. */ + return -1; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/entity/GzipDecompressingEntity.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/entity/GzipDecompressingEntity.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/entity/GzipDecompressingEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,79 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.client.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.GZIPInputStream; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.entity.HttpEntityWrapper; + +/** + * {@link HttpEntityWrapper} for handling gzip Content Coded responses. + * + * @since 4.1 + */ +public class GzipDecompressingEntity extends DecompressingEntity { + + /** + * Creates a new {@link GzipDecompressingEntity} which will wrap the specified + * {@link HttpEntity}. + * + * @param entity + * the non-null {@link HttpEntity} to be wrapped + */ + public GzipDecompressingEntity(final HttpEntity entity) { + super(entity); + } + + @Override + InputStream getDecompressingInputStream(final InputStream wrapped) throws IOException { + return new GZIPInputStream(wrapped); + } + + /** + * {@inheritDoc} + */ + @Override + public Header getContentEncoding() { + + /* This HttpEntityWrapper has dealt with the Content-Encoding. */ + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public long getContentLength() { + + /* length of ungzipped content is not known */ + return -1; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/entity/UrlEncodedFormEntity.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/entity/UrlEncodedFormEntity.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/entity/UrlEncodedFormEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,108 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.entity; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.List; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.NameValuePair; +import org.apache.http.client.utils.URLEncodedUtils; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.protocol.HTTP; + +/** + * An entity composed of a list of url-encoded pairs. + * This is typically useful while sending an HTTP POST request. + * + * @since 4.0 + */ +@NotThreadSafe // AbstractHttpEntity is not thread-safe +public class UrlEncodedFormEntity extends StringEntity { + + /** + * Constructs a new {@link UrlEncodedFormEntity} with the list + * of parameters in the specified encoding. + * + * @param parameters list of name/value pairs + * @param charset encoding the name/value pairs be encoded with + * @throws UnsupportedEncodingException if the encoding isn't supported + */ + public UrlEncodedFormEntity ( + final List parameters, + final String charset) throws UnsupportedEncodingException { + super(URLEncodedUtils.format(parameters, + charset != null ? charset : HTTP.DEF_CONTENT_CHARSET.name()), + ContentType.create(URLEncodedUtils.CONTENT_TYPE, charset)); + } + + /** + * Constructs a new {@link UrlEncodedFormEntity} with the list + * of parameters in the specified encoding. + * + * @param parameters iterable collection of name/value pairs + * @param charset encoding the name/value pairs be encoded with + * + * @since 4.2 + */ + public UrlEncodedFormEntity ( + final Iterable parameters, + final Charset charset) { + super(URLEncodedUtils.format(parameters, + charset != null ? charset : HTTP.DEF_CONTENT_CHARSET), + ContentType.create(URLEncodedUtils.CONTENT_TYPE, charset)); + } + + /** + * Constructs a new {@link UrlEncodedFormEntity} with the list + * of parameters with the default encoding of {@link HTTP#DEFAULT_CONTENT_CHARSET} + * + * @param parameters list of name/value pairs + * @throws UnsupportedEncodingException if the default encoding isn't supported + */ + public UrlEncodedFormEntity ( + final List parameters) throws UnsupportedEncodingException { + this(parameters, (Charset) null); + } + + /** + * Constructs a new {@link UrlEncodedFormEntity} with the list + * of parameters with the default encoding of {@link HTTP#DEFAULT_CONTENT_CHARSET} + * + * @param parameters iterable collection of name/value pairs + * + * @since 4.2 + */ + public UrlEncodedFormEntity ( + final Iterable parameters) { + this(parameters, null); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/entity/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/entity/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/entity/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Additional HTTP entity implementations that depend on HttpClient +specific features. + + Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/AbortableHttpRequest.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/AbortableHttpRequest.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/AbortableHttpRequest.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,82 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.io.IOException; + +import org.apache.http.client.HttpClient; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionRequest; +import org.apache.http.conn.ConnectionReleaseTrigger; +import org.apache.http.conn.ManagedClientConnection; + +/** + * Interface representing an HTTP request that can be aborted by shutting + * down the underlying HTTP connection. + * + * + * + * @since 4.0 + */ +public interface AbortableHttpRequest { + + /** + * Sets the {@link ClientConnectionRequest} callback that can be + * used to abort a long-lived request for a connection. + * If the request is already aborted, throws an {@link IOException}. + * + * @see ClientConnectionManager + */ + void setConnectionRequest(ClientConnectionRequest connRequest) throws IOException; + + /** + * Sets the {@link ConnectionReleaseTrigger} callback that can + * be used to abort an active connection. + * Typically, this will be the {@link ManagedClientConnection} itself. + * If the request is already aborted, throws an {@link IOException}. + */ + void setReleaseTrigger(ConnectionReleaseTrigger releaseTrigger) throws IOException; + + /** + * Aborts this http request. Any active execution of this method should + * return immediately. If the request has not started, it will abort after + * the next execution. Aborting this request will cause all subsequent + * executions with this request to fail. + * + * @see HttpClient#execute(HttpUriRequest) + * @see HttpClient#execute(org.apache.http.HttpHost, + * org.apache.http.HttpRequest) + * @see HttpClient#execute(HttpUriRequest, + * org.apache.http.protocol.HttpContext) + * @see HttpClient#execute(org.apache.http.HttpHost, + * org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) + */ + void abort(); + +} + Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpDelete.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpDelete.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpDelete.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,77 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.net.URI; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * HTTP DELETE method + *

+ * The HTTP DELETE method is defined in section 9.7 of + * RFC2616: + *

+ * The DELETE method requests that the origin server delete the resource + * identified by the Request-URI. [...] The client cannot + * be guaranteed that the operation has been carried out, even if the + * status code returned from the origin server indicates that the action + * has been completed successfully. + *
+ * + * @since 4.0 + */ +@NotThreadSafe // HttpRequestBase is @NotThreadSafe +public class HttpDelete extends HttpRequestBase { + + public final static String METHOD_NAME = "DELETE"; + + + public HttpDelete() { + super(); + } + + public HttpDelete(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpDelete(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpEntityEnclosingRequestBase.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpEntityEnclosingRequestBase.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpEntityEnclosingRequestBase.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,77 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.client.utils.CloneUtils; +import org.apache.http.protocol.HTTP; + +/** + * Basic implementation of an entity enclosing HTTP request + * that can be modified + * + * @since 4.0 + */ +@NotThreadSafe // HttpRequestBase is @NotThreadSafe +public abstract class HttpEntityEnclosingRequestBase + extends HttpRequestBase implements HttpEntityEnclosingRequest { + + private HttpEntity entity; + + public HttpEntityEnclosingRequestBase() { + super(); + } + + public HttpEntity getEntity() { + return this.entity; + } + + public void setEntity(final HttpEntity entity) { + this.entity = entity; + } + + public boolean expectContinue() { + Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE); + return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue()); + } + + @Override + public Object clone() throws CloneNotSupportedException { + HttpEntityEnclosingRequestBase clone = + (HttpEntityEnclosingRequestBase) super.clone(); + if (this.entity != null) { + clone.entity = (HttpEntity) CloneUtils.clone(this.entity); + } + return clone; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpGet.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpGet.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpGet.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,77 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.net.URI; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * HTTP GET method. + *

+ * The HTTP GET method is defined in section 9.3 of + * RFC2616: + *

+ * The GET method means retrieve whatever information (in the form of an + * entity) is identified by the Request-URI. If the Request-URI refers + * to a data-producing process, it is the produced data which shall be + * returned as the entity in the response and not the source text of the + * process, unless that text happens to be the output of the process. + *
+ *

+ * + * @since 4.0 + */ +@NotThreadSafe +public class HttpGet extends HttpRequestBase { + + public final static String METHOD_NAME = "GET"; + + public HttpGet() { + super(); + } + + public HttpGet(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpGet(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpHead.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpHead.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpHead.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,80 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.net.URI; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * HTTP HEAD method. + *

+ * The HTTP HEAD method is defined in section 9.4 of + * RFC2616: + *

+ * The HEAD method is identical to GET except that the server MUST NOT + * return a message-body in the response. The metainformation contained + * in the HTTP headers in response to a HEAD request SHOULD be identical + * to the information sent in response to a GET request. This method can + * be used for obtaining metainformation about the entity implied by the + * request without transferring the entity-body itself. This method is + * often used for testing hypertext links for validity, accessibility, + * and recent modification. + *
+ *

+ * + * @since 4.0 + */ +@NotThreadSafe +public class HttpHead extends HttpRequestBase { + + public final static String METHOD_NAME = "HEAD"; + + public HttpHead() { + super(); + } + + public HttpHead(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpHead(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpOptions.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpOptions.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpOptions.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,102 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.net.URI; +import java.util.HashSet; +import java.util.Set; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.HeaderIterator; +import org.apache.http.HttpResponse; + +/** + * HTTP OPTIONS method. + *

+ * The HTTP OPTIONS method is defined in section 9.2 of + * RFC2616: + *

+ * The OPTIONS method represents a request for information about the + * communication options available on the request/response chain + * identified by the Request-URI. This method allows the client to + * determine the options and/or requirements associated with a resource, + * or the capabilities of a server, without implying a resource action + * or initiating a resource retrieval. + *
+ *

+ * + * @since 4.0 + */ +@NotThreadSafe +public class HttpOptions extends HttpRequestBase { + + public final static String METHOD_NAME = "OPTIONS"; + + public HttpOptions() { + super(); + } + + public HttpOptions(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpOptions(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + + public Set getAllowedMethods(final HttpResponse response) { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + + HeaderIterator it = response.headerIterator("Allow"); + Set methods = new HashSet(); + while (it.hasNext()) { + Header header = it.nextHeader(); + HeaderElement[] elements = header.getElements(); + for (HeaderElement element : elements) { + methods.add(element.getName()); + } + } + return methods; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpPatch.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpPatch.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpPatch.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,75 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.net.URI; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * HTTP PATCH method. + *

+ * The HTTP PATCH method is defined in RF5789:

The PATCH + * method requests that a set of changes described in the request entity be + * applied to the resource identified by the Request- URI. Differs from the PUT + * method in the way the server processes the enclosed entity to modify the + * resource identified by the Request-URI. In a PUT request, the enclosed entity + * origin server, and the client is requesting that the stored version be + * replaced. With PATCH, however, the enclosed entity contains a set of + * instructions describing how a resource currently residing on the origin + * server should be modified to produce a new version.
+ *

+ * + * @since 4.2 + */ +@NotThreadSafe +public class HttpPatch extends HttpEntityEnclosingRequestBase { + + public final static String METHOD_NAME = "PATCH"; + + public HttpPatch() { + super(); + } + + public HttpPatch(final URI uri) { + super(); + setURI(uri); + } + + public HttpPatch(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpPost.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpPost.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpPost.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,84 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.net.URI; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * HTTP POST method. + *

+ * The HTTP POST method is defined in section 9.5 of + * RFC2616: + *

+ * The POST method is used to request that the origin server accept the entity + * enclosed in the request as a new subordinate of the resource identified by + * the Request-URI in the Request-Line. POST is designed to allow a uniform + * method to cover the following functions: + *
    + *
  • Annotation of existing resources
  • + *
  • Posting a message to a bulletin board, newsgroup, mailing list, or + * similar group of articles
  • + *
  • Providing a block of data, such as the result of submitting a form, + * to a data-handling process
  • + *
  • Extending a database through an append operation
  • + *
+ *
+ *

+ * + * @since 4.0 + */ +@NotThreadSafe +public class HttpPost extends HttpEntityEnclosingRequestBase { + + public final static String METHOD_NAME = "POST"; + + public HttpPost() { + super(); + } + + public HttpPost(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpPost(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpPut.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpPut.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpPut.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,76 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.net.URI; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * HTTP PUT method. + *

+ * The HTTP PUT method is defined in section 9.6 of + * RFC2616: + *

+ * The PUT method requests that the enclosed entity be stored under the + * supplied Request-URI. If the Request-URI refers to an already + * existing resource, the enclosed entity SHOULD be considered as a + * modified version of the one residing on the origin server. + *
+ *

+ * + * @since 4.0 + */ +@NotThreadSafe +public class HttpPut extends HttpEntityEnclosingRequestBase { + + public final static String METHOD_NAME = "PUT"; + + public HttpPut() { + super(); + } + + public HttpPut(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpPut(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpRequestBase.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpRequestBase.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpRequestBase.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,203 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.io.IOException; +import java.net.URI; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.ProtocolVersion; +import org.apache.http.RequestLine; +import org.apache.http.client.utils.CloneUtils; +import org.apache.http.conn.ClientConnectionRequest; +import org.apache.http.conn.ConnectionReleaseTrigger; +import org.apache.http.message.AbstractHttpMessage; +import org.apache.http.message.BasicRequestLine; +import org.apache.http.message.HeaderGroup; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; + +/** + * Basic implementation of an HTTP request that can be modified. Methods of the + * {@link AbortableHttpRequest} interface implemented by this class are thread safe. + * + * @since 4.0 + */ +@NotThreadSafe +public abstract class HttpRequestBase extends AbstractHttpMessage + implements HttpUriRequest, AbortableHttpRequest, Cloneable { + + private Lock abortLock; + private volatile boolean aborted; + + private URI uri; + private ClientConnectionRequest connRequest; + private ConnectionReleaseTrigger releaseTrigger; + + public HttpRequestBase() { + super(); + this.abortLock = new ReentrantLock(); + } + + public abstract String getMethod(); + + public ProtocolVersion getProtocolVersion() { + return HttpProtocolParams.getVersion(getParams()); + } + + /** + * Returns the original request URI. + *

+ * Please note URI remains unchanged in the course of request execution and + * is not updated if the request is redirected to another location. + */ + public URI getURI() { + return this.uri; + } + + public RequestLine getRequestLine() { + String method = getMethod(); + ProtocolVersion ver = getProtocolVersion(); + URI uri = getURI(); + String uritext = null; + if (uri != null) { + uritext = uri.toASCIIString(); + } + if (uritext == null || uritext.length() == 0) { + uritext = "/"; + } + return new BasicRequestLine(method, uritext, ver); + } + + public void setURI(final URI uri) { + this.uri = uri; + } + + public void setConnectionRequest(final ClientConnectionRequest connRequest) + throws IOException { + if (this.aborted) { + throw new IOException("Request already aborted"); + } + this.abortLock.lock(); + try { + this.connRequest = connRequest; + } finally { + this.abortLock.unlock(); + } + } + + public void setReleaseTrigger(final ConnectionReleaseTrigger releaseTrigger) + throws IOException { + if (this.aborted) { + throw new IOException("Request already aborted"); + } + this.abortLock.lock(); + try { + this.releaseTrigger = releaseTrigger; + } finally { + this.abortLock.unlock(); + } + } + + private void cleanup() { + if (this.connRequest != null) { + this.connRequest.abortRequest(); + this.connRequest = null; + } + if (this.releaseTrigger != null) { + try { + this.releaseTrigger.abortConnection(); + } catch (IOException ex) { + } + this.releaseTrigger = null; + } + } + + public void abort() { + if (this.aborted) { + return; + } + this.abortLock.lock(); + try { + this.aborted = true; + cleanup(); + } finally { + this.abortLock.unlock(); + } + } + + public boolean isAborted() { + return this.aborted; + } + + /** + * Resets internal state of the request making it reusable. + * + * @since 4.2 + */ + public void reset() { + this.abortLock.lock(); + try { + cleanup(); + this.aborted = false; + } finally { + this.abortLock.unlock(); + } + } + + /** + * A convenience method to simplify migration from HttpClient 3.1 API. This method is + * equivalent to {@link #reset()}. + * + * @since 4.2 + */ + public void releaseConnection() { + reset(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + HttpRequestBase clone = (HttpRequestBase) super.clone(); + clone.abortLock = new ReentrantLock(); + clone.aborted = false; + clone.releaseTrigger = null; + clone.connRequest = null; + clone.headergroup = (HeaderGroup) CloneUtils.clone(this.headergroup); + clone.params = (HttpParams) CloneUtils.clone(this.params); + return clone; + } + + @Override + public String toString() { + return getMethod() + " " + getURI() + " " + getProtocolVersion(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpTrace.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpTrace.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpTrace.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,79 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.net.URI; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * HTTP TRACE method. + *

+ * The HTTP TRACE method is defined in section 9.6 of + * RFC2616: + *

+ * The TRACE method is used to invoke a remote, application-layer loop- + * back of the request message. The final recipient of the request + * SHOULD reflect the message received back to the client as the + * entity-body of a 200 (OK) response. The final recipient is either the + * origin server or the first proxy or gateway to receive a Max-Forwards + * value of zero (0) in the request (see section 14.31). A TRACE request + * MUST NOT include an entity. + *
+ *

+ * + * @since 4.0 + */ +@NotThreadSafe +public class HttpTrace extends HttpRequestBase { + + public final static String METHOD_NAME = "TRACE"; + + public HttpTrace() { + super(); + } + + public HttpTrace(final URI uri) { + super(); + setURI(uri); + } + + /** + * @throws IllegalArgumentException if the uri is invalid. + */ + public HttpTrace(final String uri) { + super(); + setURI(URI.create(uri)); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpUriRequest.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpUriRequest.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/HttpUriRequest.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,86 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.methods; + +import java.net.URI; + +import org.apache.http.HttpRequest; + +/** + * Extended version of the {@link HttpRequest} interface that provides + * convenience methods to access request properties such as request URI + * and method type. + * + * + * + * @since 4.0 + */ +public interface HttpUriRequest extends HttpRequest { + + /** + * Returns the HTTP method this request uses, such as GET, + * PUT, POST, or other. + */ + String getMethod(); + + /** + * Returns the URI this request uses, such as + * http://example.org/path/to/file. + *
+ * Note that the URI may be absolute URI (as above) or may be a relative URI. + *

+ * Implementations are encouraged to return + * the URI that was initially requested. + *

+ *

+ * To find the final URI after any redirects have been processed, + * please see the section entitled + * HTTP execution context + * in the + * HttpClient Tutorial + *

+ */ + URI getURI(); + + /** + * Aborts execution of the request. + * + * @throws UnsupportedOperationException if the abort operation + * is not supported / cannot be implemented. + */ + void abort() throws UnsupportedOperationException; + + /** + * Tests if the request execution has been aborted. + * + * @return true if the request execution has been aborted, + * false otherwise. + */ + boolean isAborted(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/methods/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/methods/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/methods/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Request implementations for the various HTTP methods like GET and POST. + + + Index: 3rdParty_sources/httpclient/org/apache/http/client/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,89 @@ + + + + + +The API for client-side HTTP communication. +

+The usual execution flow can be demonstrated by the +code snippet below: + +

+HttpClient httpclient = new DefaultHttpClient();
+
+// Prepare a request object
+HttpGet httpget = new HttpGet("http://www.apache.org/");
+
+// Execute the request
+HttpResponse response = httpclient.execute(httpget);
+
+// Examine the response status
+System.out.println(response.getStatusLine());
+
+// Get hold of the response entity
+HttpEntity entity = response.getEntity();
+
+// If the response does not enclose an entity, there is no need
+// to worry about connection release
+if (entity != null) {
+    InputStream instream = entity.getContent();
+    try {
+
+        BufferedReader reader = new BufferedReader(
+                new InputStreamReader(instream));
+        // do something useful with the response
+        System.out.println(reader.readLine());
+
+    } catch (IOException ex) {
+
+        // In case of an IOException the connection will be released
+        // back to the connection manager automatically
+        throw ex;
+
+    } catch (RuntimeException ex) {
+
+        // In case of an unexpected exception you may want to abort
+        // the HTTP request in order to shut down the underlying
+        // connection and release it back to the connection manager.
+        httpget.abort();
+        throw ex;
+
+    } finally {
+
+        // Closing the input stream will trigger connection release
+        instream.close();
+
+    }
+}
+
+
+ + + Index: 3rdParty_sources/httpclient/org/apache/http/client/params/AllClientPNames.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/params/AllClientPNames.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/params/AllClientPNames.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,58 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.params; + +import org.apache.http.params.CoreConnectionPNames; +import org.apache.http.params.CoreProtocolPNames; +import org.apache.http.auth.params.AuthPNames; +import org.apache.http.cookie.params.CookieSpecPNames; +import org.apache.http.conn.params.ConnManagerPNames; +import org.apache.http.conn.params.ConnConnectionPNames; +import org.apache.http.conn.params.ConnRoutePNames; + +/** + * Collected parameter names for the HttpClient module. + * This interface combines the parameter definitions of the HttpClient + * module and all dependency modules or informational units. + * It does not define additional parameter names, but references + * other interfaces defining parameter names. + *
+ * This interface is meant as a navigation aid for developers. + * When referring to parameter names, you should use the interfaces + * in which the respective constants are actually defined. + * + * @since 4.0 + */ +@SuppressWarnings("deprecation") +public interface AllClientPNames extends + CoreConnectionPNames, CoreProtocolPNames, + ClientPNames, AuthPNames, CookieSpecPNames, + ConnConnectionPNames, ConnManagerPNames, ConnRoutePNames { + + // no additional definitions +} + Index: 3rdParty_sources/httpclient/org/apache/http/client/params/AuthPolicy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/params/AuthPolicy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/params/AuthPolicy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,76 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.params; + +import org.apache.http.annotation.Immutable; + +/** + * Standard authentication schemes supported by HttpClient. + * + * @since 4.0 + */ +@Immutable +public final class AuthPolicy { + + private AuthPolicy() { + super(); + } + + /** + * The NTLM scheme is a proprietary Microsoft Windows Authentication + * protocol (considered to be the most secure among currently supported + * authentication schemes). + */ + public static final String NTLM = "NTLM"; + + /** + * Digest authentication scheme as defined in RFC2617. + */ + public static final String DIGEST = "Digest"; + + /** + * Basic authentication scheme as defined in RFC2617 (considered inherently + * insecure, but most widely supported) + */ + public static final String BASIC = "Basic"; + + /** + * SPNEGO Authentication scheme. + * + * @since 4.1 + */ + public static final String SPNEGO = "negotiate"; + + /** + * Kerberos Authentication scheme. + * + * @since 4.2 + */ + public static final String KERBEROS = "Kerberos"; + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/params/ClientPNames.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/params/ClientPNames.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/params/ClientPNames.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,134 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.params; + +/** + * Parameter names for HTTP client parameters. + * + * @since 4.0 + */ +public interface ClientPNames { + + /** + * @deprecated (4.2) do not use + */ + @Deprecated + public static final String CONNECTION_MANAGER_FACTORY_CLASS_NAME = "http.connection-manager.factory-class-name"; + + /** + * Defines whether redirects should be handled automatically + *

+ * This parameter expects a value of type {@link Boolean}. + *

+ */ + public static final String HANDLE_REDIRECTS = "http.protocol.handle-redirects"; + + /** + * Defines whether relative redirects should be rejected. HTTP specification + * requires the location value be an absolute URI. + *

+ * This parameter expects a value of type {@link Boolean}. + *

+ */ + public static final String REJECT_RELATIVE_REDIRECT = "http.protocol.reject-relative-redirect"; + + /** + * Defines the maximum number of redirects to be followed. + * The limit on number of redirects is intended to prevent infinite loops. + *

+ * This parameter expects a value of type {@link Integer}. + *

+ */ + public static final String MAX_REDIRECTS = "http.protocol.max-redirects"; + + /** + * Defines whether circular redirects (redirects to the same location) should be allowed. + * The HTTP spec is not sufficiently clear whether circular redirects are permitted, + * therefore optionally they can be enabled + *

+ * This parameter expects a value of type {@link Boolean}. + *

+ */ + public static final String ALLOW_CIRCULAR_REDIRECTS = "http.protocol.allow-circular-redirects"; + + /** + * Defines whether authentication should be handled automatically. + *

+ * This parameter expects a value of type {@link Boolean}. + *

+ */ + public static final String HANDLE_AUTHENTICATION = "http.protocol.handle-authentication"; + + /** + * Defines the name of the cookie specification to be used for HTTP state management. + *

+ * This parameter expects a value of type {@link String}. + *

+ */ + public static final String COOKIE_POLICY = "http.protocol.cookie-policy"; + + /** + * Defines the virtual host to be used in the Host + * request header instead of the physical host. + *

+ * This parameter expects a value of type {@link org.apache.http.HttpHost}. + *

+ * If a port is not provided, it will be derived from the request URL. + */ + public static final String VIRTUAL_HOST = "http.virtual-host"; + + /** + * Defines the request headers to be sent per default with each request. + *

+ * This parameter expects a value of type {@link java.util.Collection}. The + * collection is expected to contain {@link org.apache.http.Header}s. + *

+ */ + public static final String DEFAULT_HEADERS = "http.default-headers"; + + /** + * Defines the default host. The default value will be used if the target host is + * not explicitly specified in the request URI. + *

+ * This parameter expects a value of type {@link org.apache.http.HttpHost}. + *

+ */ + public static final String DEFAULT_HOST = "http.default-host"; + + /** + * Defines the timeout in milliseconds used when retrieving an instance of + * {@link org.apache.http.conn.ManagedClientConnection} from the + * {@link org.apache.http.conn.ClientConnectionManager}. + *

+ * This parameter expects a value of type {@link Long}. + *

+ * @since 4.2 + */ + public static final String CONN_MANAGER_TIMEOUT = "http.conn-manager.timeout"; + +} + Index: 3rdParty_sources/httpclient/org/apache/http/client/params/ClientParamBean.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/params/ClientParamBean.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/params/ClientParamBean.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,104 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.params; + +import java.util.Collection; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.Header; +import org.apache.http.HttpHost; +import org.apache.http.params.HttpAbstractParamBean; +import org.apache.http.params.HttpParams; + +/** + * This is a Java Bean class that can be used to wrap an instance of + * {@link HttpParams} and manipulate HTTP client parameters using + * Java Beans conventions. + * + * @since 4.0 + */ +@NotThreadSafe +public class ClientParamBean extends HttpAbstractParamBean { + + public ClientParamBean (final HttpParams params) { + super(params); + } + + /** + * @deprecated (4.2) do not use. + */ + @Deprecated + public void setConnectionManagerFactoryClassName (final String factory) { + params.setParameter(ClientPNames.CONNECTION_MANAGER_FACTORY_CLASS_NAME, factory); + } + + public void setHandleRedirects (final boolean handle) { + params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, handle); + } + + public void setRejectRelativeRedirect (final boolean reject) { + params.setBooleanParameter(ClientPNames.REJECT_RELATIVE_REDIRECT, reject); + } + + public void setMaxRedirects (final int maxRedirects) { + params.setIntParameter(ClientPNames.MAX_REDIRECTS, maxRedirects); + } + + public void setAllowCircularRedirects (final boolean allow) { + params.setBooleanParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, allow); + } + + public void setHandleAuthentication (final boolean handle) { + params.setBooleanParameter(ClientPNames.HANDLE_AUTHENTICATION, handle); + } + + public void setCookiePolicy (final String policy) { + params.setParameter(ClientPNames.COOKIE_POLICY, policy); + } + + public void setVirtualHost (final HttpHost host) { + params.setParameter(ClientPNames.VIRTUAL_HOST, host); + } + + public void setDefaultHeaders (final Collection

headers) { + params.setParameter(ClientPNames.DEFAULT_HEADERS, headers); + } + + public void setDefaultHost (final HttpHost host) { + params.setParameter(ClientPNames.DEFAULT_HOST, host); + } + + /** + * @since 4.2 + */ + public void setConnectionManagerTimeout(final long timeout) { + params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, timeout); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/params/CookiePolicy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/params/CookiePolicy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/params/CookiePolicy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,77 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.params; + +import org.apache.http.annotation.Immutable; + +/** + * Standard cookie specifications supported by HttpClient. + * + * @since 4.0 + */ +@Immutable +public final class CookiePolicy { + + /** + * The policy that provides high degree of compatibilty + * with common cookie management of popular HTTP agents. + */ + public static final String BROWSER_COMPATIBILITY = "compatibility"; + + /** + * The Netscape cookie draft compliant policy. + */ + public static final String NETSCAPE = "netscape"; + + /** + * The RFC 2109 compliant policy. + */ + public static final String RFC_2109 = "rfc2109"; + + /** + * The RFC 2965 compliant policy. + */ + public static final String RFC_2965 = "rfc2965"; + + /** + * The default 'best match' policy. + */ + public static final String BEST_MATCH = "best-match"; + + /** + * The policy that ignores cookies. + * + * @since 4.1-beta1 + */ + public static final String IGNORE_COOKIES = "ignoreCookies"; + + private CookiePolicy() { + super(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/params/HttpClientParams.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/params/HttpClientParams.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/params/HttpClientParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,129 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.params; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +/** + * An adaptor for manipulating HTTP client parameters in {@link HttpParams}. + * + * @since 4.0 + */ +@Immutable +public class HttpClientParams { + + private HttpClientParams() { + super(); + } + + public static boolean isRedirecting(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getBooleanParameter + (ClientPNames.HANDLE_REDIRECTS, true); + } + + public static void setRedirecting(final HttpParams params, boolean value) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setBooleanParameter + (ClientPNames.HANDLE_REDIRECTS, value); + } + + public static boolean isAuthenticating(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getBooleanParameter + (ClientPNames.HANDLE_AUTHENTICATION, true); + } + + public static void setAuthenticating(final HttpParams params, boolean value) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setBooleanParameter + (ClientPNames.HANDLE_AUTHENTICATION, value); + } + + public static String getCookiePolicy(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + String cookiePolicy = (String) + params.getParameter(ClientPNames.COOKIE_POLICY); + if (cookiePolicy == null) { + return CookiePolicy.BEST_MATCH; + } + return cookiePolicy; + } + + public static void setCookiePolicy(final HttpParams params, final String cookiePolicy) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setParameter(ClientPNames.COOKIE_POLICY, cookiePolicy); + } + + /** + * Set the parameter {@code ClientPNames.CONN_MANAGER_TIMEOUT}. + * + * @since 4.2 + */ + public static void setConnectionManagerTimeout(final HttpParams params, long timeout) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, timeout); + } + + /** + * Get the connectiion manager timeout value. + * This is defined by the parameter {@code ClientPNames.CONN_MANAGER_TIMEOUT}. + * Failing that it uses the parameter {@code CoreConnectionPNames.CONNECTION_TIMEOUT} + * which defaults to 0 if not defined. + * + * @since 4.2 + * @return the timeout value + */ + public static long getConnectionManagerTimeout(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + Long timeout = (Long) params.getParameter(ClientPNames.CONN_MANAGER_TIMEOUT); + if (timeout != null) { + return timeout.longValue(); + } + return HttpConnectionParams.getConnectionTimeout(params); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/params/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/params/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/params/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,35 @@ + + + + + +Parameters for configuring the default HttpClient implementation. + + Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/ClientContext.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/ClientContext.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/ClientContext.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,109 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +/** + * {@link org.apache.http.protocol.HttpContext} attribute names for + * client side HTTP protocol processing. + * + * @since 4.0 + */ +public interface ClientContext { + + /** + * Attribute name of a {@link org.apache.http.conn.scheme.Scheme} + * object that represents the actual protocol scheme registry. + */ + public static final String SCHEME_REGISTRY = "http.scheme-registry"; + /** + * Attribute name of a {@link org.apache.http.cookie.CookieSpecRegistry} + * object that represents the actual cookie specification registry. + */ + public static final String COOKIESPEC_REGISTRY = "http.cookiespec-registry"; + + /** + * Attribute name of a {@link org.apache.http.cookie.CookieSpec} + * object that represents the actual cookie specification. + */ + public static final String COOKIE_SPEC = "http.cookie-spec"; + + /** + * Attribute name of a {@link org.apache.http.cookie.CookieOrigin} + * object that represents the actual details of the origin server. + */ + public static final String COOKIE_ORIGIN = "http.cookie-origin"; + + /** + * Attribute name of a {@link org.apache.http.client.CookieStore} + * object that represents the actual cookie store. + */ + public static final String COOKIE_STORE = "http.cookie-store"; + + /** + * Attribute name of a {@link org.apache.http.auth.AuthSchemeRegistry} + * object that represents the actual authentication scheme registry. + */ + public static final String AUTHSCHEME_REGISTRY = "http.authscheme-registry"; + + /** + * Attribute name of a {@link org.apache.http.client.CredentialsProvider} + * object that represents the actual credentials provider. + */ + public static final String CREDS_PROVIDER = "http.auth.credentials-provider"; + + /** + * Attribute name of a {@link org.apache.http.client.AuthCache} object + * that represents the auth scheme cache. + */ + public static final String AUTH_CACHE = "http.auth.auth-cache"; + + /** + * Attribute name of a {@link org.apache.http.auth.AuthState} + * object that represents the actual target authentication state. + */ + public static final String TARGET_AUTH_STATE = "http.auth.target-scope"; + + /** + * Attribute name of a {@link org.apache.http.auth.AuthState} + * object that represents the actual proxy authentication state. + */ + public static final String PROXY_AUTH_STATE = "http.auth.proxy-scope"; + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + public static final String AUTH_SCHEME_PREF = "http.auth.scheme-pref"; + + /** + * Attribute name of a {@link java.lang.Object} object that represents + * the actual user identity such as user {@link java.security.Principal}. + */ + public static final String USER_TOKEN = "http.user-token"; + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/ClientContextConfigurer.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/ClientContextConfigurer.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/ClientContextConfigurer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,70 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.auth.AuthSchemeRegistry; +import org.apache.http.client.CookieStore; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.cookie.CookieSpecRegistry; +import org.apache.http.protocol.HttpContext; + +/** + * Configuration facade for {@link HttpContext} instances. + * + * @since 4.0 + */ +@NotThreadSafe +public class ClientContextConfigurer implements ClientContext { + + private final HttpContext context; + + public ClientContextConfigurer (final HttpContext context) { + if (context == null) + throw new IllegalArgumentException("HTTP context may not be null"); + this.context = context; + } + + public void setCookieSpecRegistry(final CookieSpecRegistry registry) { + this.context.setAttribute(COOKIESPEC_REGISTRY, registry); + } + + public void setAuthSchemeRegistry(final AuthSchemeRegistry registry) { + this.context.setAttribute(AUTHSCHEME_REGISTRY, registry); + } + + public void setCookieStore(final CookieStore store) { + this.context.setAttribute(COOKIE_STORE, store); + } + + public void setCredentialsProvider(final CredentialsProvider provider) { + this.context.setAttribute(CREDS_PROVIDER, provider); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAcceptEncoding.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAcceptEncoding.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAcceptEncoding.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,60 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.http.client.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.annotation.Immutable; +import org.apache.http.protocol.HttpContext; + +/** + * Class responsible for handling Content Encoding requests in HTTP. + *

+ * Instances of this class are stateless, therefore they're thread-safe and immutable. + * + * @see "http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5" + * + * @since 4.1 + */ +@Immutable +public class RequestAcceptEncoding implements HttpRequestInterceptor { + + /** + * Adds the header {@code "Accept-Encoding: gzip,deflate"} to the request. + */ + public void process( + final HttpRequest request, + final HttpContext context) throws HttpException, IOException { + + /* Signal support for Accept-Encoding transfer encodings. */ + if (!request.containsHeader("Accept-Encoding")) { + request.addHeader("Accept-Encoding", "gzip,deflate"); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAddCookies.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAddCookies.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAddCookies.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,226 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.apache.http.annotation.Immutable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.ProtocolException; +import org.apache.http.client.CookieStore; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.params.HttpClientParams; +import org.apache.http.conn.HttpRoutedConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.CookieSpecRegistry; +import org.apache.http.cookie.SetCookie2; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.ExecutionContext; + +/** + * Request interceptor that matches cookies available in the current + * {@link CookieStore} to the request being executed and generates + * corresponding Cookie request headers. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#COOKIE_POLICY}
  • + *
+ * + * @since 4.0 + */ +@Immutable +public class RequestAddCookies implements HttpRequestInterceptor { + + private final Log log = LogFactory.getLog(getClass()); + + public RequestAddCookies() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase("CONNECT")) { + return; + } + + // Obtain cookie store + CookieStore cookieStore = (CookieStore) context.getAttribute( + ClientContext.COOKIE_STORE); + if (cookieStore == null) { + this.log.debug("Cookie store not specified in HTTP context"); + return; + } + + // Obtain the registry of cookie specs + CookieSpecRegistry registry = (CookieSpecRegistry) context.getAttribute( + ClientContext.COOKIESPEC_REGISTRY); + if (registry == null) { + this.log.debug("CookieSpec registry not specified in HTTP context"); + return; + } + + // Obtain the target host (required) + HttpHost targetHost = (HttpHost) context.getAttribute( + ExecutionContext.HTTP_TARGET_HOST); + if (targetHost == null) { + this.log.debug("Target host not set in the context"); + return; + } + + // Obtain the client connection (required) + HttpRoutedConnection conn = (HttpRoutedConnection) context.getAttribute( + ExecutionContext.HTTP_CONNECTION); + if (conn == null) { + this.log.debug("HTTP connection not set in the context"); + return; + } + + String policy = HttpClientParams.getCookiePolicy(request.getParams()); + if (this.log.isDebugEnabled()) { + this.log.debug("CookieSpec selected: " + policy); + } + + URI requestURI; + if (request instanceof HttpUriRequest) { + requestURI = ((HttpUriRequest) request).getURI(); + } else { + try { + requestURI = new URI(request.getRequestLine().getUri()); + } catch (URISyntaxException ex) { + throw new ProtocolException("Invalid request URI: " + + request.getRequestLine().getUri(), ex); + } + } + + String hostName = targetHost.getHostName(); + int port = targetHost.getPort(); + if (port < 0) { + HttpRoute route = conn.getRoute(); + if (route.getHopCount() == 1) { + port = conn.getRemotePort(); + } else { + // Target port will be selected by the proxy. + // Use conventional ports for known schemes + String scheme = targetHost.getSchemeName(); + if (scheme.equalsIgnoreCase("http")) { + port = 80; + } else if (scheme.equalsIgnoreCase("https")) { + port = 443; + } else { + port = 0; + } + } + } + + CookieOrigin cookieOrigin = new CookieOrigin( + hostName, + port, + requestURI.getPath(), + conn.isSecure()); + + // Get an instance of the selected cookie policy + CookieSpec cookieSpec = registry.getCookieSpec(policy, request.getParams()); + // Get all cookies available in the HTTP state + List cookies = new ArrayList(cookieStore.getCookies()); + // Find cookies matching the given origin + List matchedCookies = new ArrayList(); + Date now = new Date(); + for (Cookie cookie : cookies) { + if (!cookie.isExpired(now)) { + if (cookieSpec.match(cookie, cookieOrigin)) { + if (this.log.isDebugEnabled()) { + this.log.debug("Cookie " + cookie + " match " + cookieOrigin); + } + matchedCookies.add(cookie); + } + } else { + if (this.log.isDebugEnabled()) { + this.log.debug("Cookie " + cookie + " expired"); + } + } + } + // Generate Cookie request headers + if (!matchedCookies.isEmpty()) { + List
headers = cookieSpec.formatCookies(matchedCookies); + for (Header header : headers) { + request.addHeader(header); + } + } + + int ver = cookieSpec.getVersion(); + if (ver > 0) { + boolean needVersionHeader = false; + for (Cookie cookie : matchedCookies) { + if (ver != cookie.getVersion() || !(cookie instanceof SetCookie2)) { + needVersionHeader = true; + } + } + + if (needVersionHeader) { + Header header = cookieSpec.getVersionHeader(); + if (header != null) { + // Advertise cookie version support + request.addHeader(header); + } + } + } + + // Stick the CookieSpec and CookieOrigin instances to the HTTP context + // so they could be obtained by the response interceptor + context.setAttribute(ClientContext.COOKIE_SPEC, cookieSpec); + context.setAttribute(ClientContext.COOKIE_ORIGIN, cookieOrigin); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAuthCache.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAuthCache.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAuthCache.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,137 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AuthProtocolState; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.AuthState; +import org.apache.http.auth.Credentials; +import org.apache.http.client.AuthCache; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.protocol.ExecutionContext; +import org.apache.http.protocol.HttpContext; + +/** + * Request interceptor that can preemptively authenticate against known hosts, + * if there is a cached {@link AuthScheme} instance in the local + * {@link AuthCache} associated with the given target or proxy host. + * + * @since 4.1 + */ +@Immutable +public class RequestAuthCache implements HttpRequestInterceptor { + + private final Log log = LogFactory.getLog(getClass()); + + public RequestAuthCache() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE); + if (authCache == null) { + this.log.debug("Auth cache not set in the context"); + return; + } + + CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute( + ClientContext.CREDS_PROVIDER); + if (credsProvider == null) { + this.log.debug("Credentials provider not set in the context"); + return; + } + + HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); + if (target.getPort() < 0) { + SchemeRegistry schemeRegistry = (SchemeRegistry) context.getAttribute( + ClientContext.SCHEME_REGISTRY); + Scheme scheme = schemeRegistry.getScheme(target); + target = new HttpHost(target.getHostName(), + scheme.resolvePort(target.getPort()), target.getSchemeName()); + } + + AuthState targetState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE); + if (target != null && targetState != null && targetState.getState() == AuthProtocolState.UNCHALLENGED) { + AuthScheme authScheme = authCache.get(target); + if (authScheme != null) { + doPreemptiveAuth(target, authScheme, targetState, credsProvider); + } + } + + HttpHost proxy = (HttpHost) context.getAttribute(ExecutionContext.HTTP_PROXY_HOST); + AuthState proxyState = (AuthState) context.getAttribute(ClientContext.PROXY_AUTH_STATE); + if (proxy != null && proxyState != null && proxyState.getState() == AuthProtocolState.UNCHALLENGED) { + AuthScheme authScheme = authCache.get(proxy); + if (authScheme != null) { + doPreemptiveAuth(proxy, authScheme, proxyState, credsProvider); + } + } + } + + private void doPreemptiveAuth( + final HttpHost host, + final AuthScheme authScheme, + final AuthState authState, + final CredentialsProvider credsProvider) { + String schemeName = authScheme.getSchemeName(); + if (this.log.isDebugEnabled()) { + this.log.debug("Re-using cached '" + schemeName + "' auth scheme for " + host); + } + + AuthScope authScope = new AuthScope(host, AuthScope.ANY_REALM, schemeName); + Credentials creds = credsProvider.getCredentials(authScope); + + if (creds != null) { + authState.setState(AuthProtocolState.SUCCESS); + authState.update(authScheme, creds); + } else { + this.log.debug("No credentials for preemptive authentication"); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAuthenticationBase.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAuthenticationBase.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestAuthenticationBase.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,131 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import java.io.IOException; +import java.util.Queue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.auth.AuthOption; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthState; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.ContextAwareAuthScheme; +import org.apache.http.auth.Credentials; +import org.apache.http.protocol.HttpContext; + +abstract class RequestAuthenticationBase implements HttpRequestInterceptor { + + final Log log = LogFactory.getLog(getClass()); + + public RequestAuthenticationBase() { + super(); + } + + void process( + final AuthState authState, + final HttpRequest request, + final HttpContext context) throws HttpException, IOException { + AuthScheme authScheme = authState.getAuthScheme(); + Credentials creds = authState.getCredentials(); + switch (authState.getState()) { + case FAILURE: + return; + case SUCCESS: + ensureAuthScheme(authScheme); + if (authScheme.isConnectionBased()) { + return; + } + break; + case CHALLENGED: + Queue authOptions = authState.getAuthOptions(); + if (authOptions != null) { + while (!authOptions.isEmpty()) { + AuthOption authOption = authOptions.remove(); + authScheme = authOption.getAuthScheme(); + creds = authOption.getCredentials(); + authState.update(authScheme, creds); + if (this.log.isDebugEnabled()) { + this.log.debug("Generating response to an authentication challenge using " + + authScheme.getSchemeName() + " scheme"); + } + try { + Header header = authenticate(authScheme, creds, request, context); + request.addHeader(header); + break; + } catch (AuthenticationException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn(authScheme + " authentication error: " + ex.getMessage()); + } + } + } + return; + } else { + ensureAuthScheme(authScheme); + } + } + if (authScheme != null) { + try { + Header header = authenticate(authScheme, creds, request, context); + request.addHeader(header); + } catch (AuthenticationException ex) { + if (this.log.isErrorEnabled()) { + this.log.error(authScheme + " authentication error: " + ex.getMessage()); + } + } + } + } + + private void ensureAuthScheme(final AuthScheme authScheme) { + if (authScheme == null) { + throw new IllegalStateException("Auth scheme is not set"); + } + } + + @SuppressWarnings("deprecation") + private Header authenticate( + final AuthScheme authScheme, + final Credentials creds, + final HttpRequest request, + final HttpContext context) throws AuthenticationException { + if (authScheme == null) { + throw new IllegalStateException("Auth state object is null"); + } + if (authScheme instanceof ContextAwareAuthScheme) { + return ((ContextAwareAuthScheme) authScheme).authenticate(creds, request, context); + } else { + return authScheme.authenticate(creds, request); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestClientConnControl.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestClientConnControl.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestClientConnControl.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,97 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.annotation.Immutable; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.conn.HttpRoutedConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.protocol.ExecutionContext; +import org.apache.http.protocol.HTTP; +import org.apache.http.protocol.HttpContext; + +/** + * This protocol interceptor is responsible for adding Connection + * or Proxy-Connection headers to the outgoing requests, which + * is essential for managing persistence of HTTP/1.0 connections. + * + * @since 4.0 + */ +@Immutable +public class RequestClientConnControl implements HttpRequestInterceptor { + + private final Log log = LogFactory.getLog(getClass()); + + private static final String PROXY_CONN_DIRECTIVE = "Proxy-Connection"; + + public RequestClientConnControl() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + + String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase("CONNECT")) { + request.setHeader(PROXY_CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); + return; + } + + // Obtain the client connection (required) + HttpRoutedConnection conn = (HttpRoutedConnection) context.getAttribute( + ExecutionContext.HTTP_CONNECTION); + if (conn == null) { + this.log.debug("HTTP connection not set in the context"); + return; + } + + HttpRoute route = conn.getRoute(); + + if (route.getHopCount() == 1 || route.isTunnelled()) { + if (!request.containsHeader(HTTP.CONN_DIRECTIVE)) { + request.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); + } + } + if (route.getHopCount() == 2 && !route.isTunnelled()) { + if (!request.containsHeader(PROXY_CONN_DIRECTIVE)) { + request.addHeader(PROXY_CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); + } + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestDefaultHeaders.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestDefaultHeaders.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestDefaultHeaders.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,77 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import java.io.IOException; +import java.util.Collection; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.Header; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.client.params.ClientPNames; +import org.apache.http.protocol.HttpContext; + +/** + * Request interceptor that adds default request headers. + * + * @since 4.0 + */ +@Immutable +public class RequestDefaultHeaders implements HttpRequestInterceptor { + + public RequestDefaultHeaders() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + + String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase("CONNECT")) { + return; + } + + // Add default headers + @SuppressWarnings("unchecked") + Collection
defHeaders = (Collection
) request.getParams().getParameter( + ClientPNames.DEFAULT_HEADERS); + + if (defHeaders != null) { + for (Header defHeader : defHeaders) { + request.addHeader(defHeader); + } + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestProxyAuthentication.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestProxyAuthentication.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestProxyAuthentication.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,92 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.AuthState; +import org.apache.http.conn.HttpRoutedConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.protocol.ExecutionContext; +import org.apache.http.protocol.HttpContext; + +/** + * Generates authentication header for the proxy host, if required, + * based on the actual state of the HTTP authentication context. + * + * @since 4.0 + */ +@Immutable +public class RequestProxyAuthentication extends RequestAuthenticationBase { + + public RequestProxyAuthentication() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + if (request.containsHeader(AUTH.PROXY_AUTH_RESP)) { + return; + } + + HttpRoutedConnection conn = (HttpRoutedConnection) context.getAttribute( + ExecutionContext.HTTP_CONNECTION); + if (conn == null) { + this.log.debug("HTTP connection not set in the context"); + return; + } + HttpRoute route = conn.getRoute(); + if (route.isTunnelled()) { + return; + } + + // Obtain authentication state + AuthState authState = (AuthState) context.getAttribute( + ClientContext.PROXY_AUTH_STATE); + if (authState == null) { + this.log.debug("Proxy auth state not set in the context"); + return; + } + if (this.log.isDebugEnabled()) { + this.log.debug("Proxy auth state: " + authState.getState()); + } + process(authState, request, context); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestTargetAuthentication.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestTargetAuthentication.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/RequestTargetAuthentication.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,83 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.AuthState; +import org.apache.http.protocol.HttpContext; + +/** + * Generates authentication header for the target host, if required, + * based on the actual state of the HTTP authentication context. + * + * @since 4.0 + */ +@Immutable +public class RequestTargetAuthentication extends RequestAuthenticationBase { + + public RequestTargetAuthentication() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase("CONNECT")) { + return; + } + + if (request.containsHeader(AUTH.WWW_AUTH_RESP)) { + return; + } + + // Obtain authentication state + AuthState authState = (AuthState) context.getAttribute( + ClientContext.TARGET_AUTH_STATE); + if (authState == null) { + this.log.debug("Target auth state not set in the context"); + return; + } + if (this.log.isDebugEnabled()) { + this.log.debug("Target auth state: " + authState.getState()); + } + process(authState, request, context); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/ResponseAuthCache.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/ResponseAuthCache.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/ResponseAuthCache.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,155 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthState; +import org.apache.http.client.AuthCache; +import org.apache.http.client.AuthenticationStrategy; +import org.apache.http.client.params.AuthPolicy; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.impl.client.BasicAuthCache; +import org.apache.http.protocol.ExecutionContext; +import org.apache.http.protocol.HttpContext; + +/** + * Response interceptor that adds successfully completed {@link AuthScheme}s + * to the local {@link AuthCache} instance. Cached {@link AuthScheme}s can be + * re-used when executing requests against known hosts, thus avoiding + * additional authentication round-trips. + * + * @since 4.1 + * + * @deprecated (4.2) use {@link AuthenticationStrategy} + */ +@Immutable +@Deprecated +public class ResponseAuthCache implements HttpResponseInterceptor { + + private final Log log = LogFactory.getLog(getClass()); + + public ResponseAuthCache() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE); + + HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); + AuthState targetState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE); + if (target != null && targetState != null) { + if (this.log.isDebugEnabled()) { + this.log.debug("Target auth state: " + targetState.getState()); + } + if (isCachable(targetState)) { + if (target.getPort() < 0) { + SchemeRegistry schemeRegistry = (SchemeRegistry) context.getAttribute( + ClientContext.SCHEME_REGISTRY); + Scheme scheme = schemeRegistry.getScheme(target); + target = new HttpHost(target.getHostName(), + scheme.resolvePort(target.getPort()), target.getSchemeName()); + } + if (authCache == null) { + authCache = new BasicAuthCache(); + context.setAttribute(ClientContext.AUTH_CACHE, authCache); + } + switch (targetState.getState()) { + case CHALLENGED: + cache(authCache, target, targetState.getAuthScheme()); + break; + case FAILURE: + uncache(authCache, target, targetState.getAuthScheme()); + } + } + } + + HttpHost proxy = (HttpHost) context.getAttribute(ExecutionContext.HTTP_PROXY_HOST); + AuthState proxyState = (AuthState) context.getAttribute(ClientContext.PROXY_AUTH_STATE); + if (proxy != null && proxyState != null) { + if (this.log.isDebugEnabled()) { + this.log.debug("Proxy auth state: " + proxyState.getState()); + } + if (isCachable(proxyState)) { + if (authCache == null) { + authCache = new BasicAuthCache(); + context.setAttribute(ClientContext.AUTH_CACHE, authCache); + } + switch (proxyState.getState()) { + case CHALLENGED: + cache(authCache, proxy, proxyState.getAuthScheme()); + break; + case FAILURE: + uncache(authCache, proxy, proxyState.getAuthScheme()); + } + } + } + } + + private boolean isCachable(final AuthState authState) { + AuthScheme authScheme = authState.getAuthScheme(); + if (authScheme == null || !authScheme.isComplete()) { + return false; + } + String schemeName = authScheme.getSchemeName(); + return schemeName.equalsIgnoreCase(AuthPolicy.BASIC) || + schemeName.equalsIgnoreCase(AuthPolicy.DIGEST); + } + + private void cache(final AuthCache authCache, final HttpHost host, final AuthScheme authScheme) { + if (this.log.isDebugEnabled()) { + this.log.debug("Caching '" + authScheme.getSchemeName() + + "' auth scheme for " + host); + } + authCache.put(host, authScheme); + } + + private void uncache(final AuthCache authCache, final HttpHost host, final AuthScheme authScheme) { + if (this.log.isDebugEnabled()) { + this.log.debug("Removing from cache '" + authScheme.getSchemeName() + + "' auth scheme for " + host); + } + authCache.remove(host); + } +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/ResponseContentEncoding.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/ResponseContentEncoding.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/ResponseContentEncoding.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,103 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import java.io.IOException; +import java.util.Locale; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.annotation.Immutable; +import org.apache.http.client.entity.DeflateDecompressingEntity; +import org.apache.http.client.entity.GzipDecompressingEntity; +import org.apache.http.protocol.HttpContext; + +/** + * {@link HttpResponseInterceptor} responsible for processing Content-Encoding + * responses. + *

+ * Instances of this class are stateless and immutable, therefore threadsafe. + * + * @since 4.1 + * + */ +@Immutable +public class ResponseContentEncoding implements HttpResponseInterceptor { + + public static final String UNCOMPRESSED = "http.client.response.uncompressed"; + + /** + * Handles the following {@code Content-Encoding}s by + * using the appropriate decompressor to wrap the response Entity: + *

    + *
  • gzip - see {@link GzipDecompressingEntity}
  • + *
  • deflate - see {@link DeflateDecompressingEntity}
  • + *
  • identity - no action needed
  • + *
+ * + * @param response the response which contains the entity + * @param context not currently used + * + * @throws HttpException if the {@code Content-Encoding} is none of the above + */ + public void process( + final HttpResponse response, + final HttpContext context) throws HttpException, IOException { + HttpEntity entity = response.getEntity(); + + // It wasn't a 304 Not Modified response, 204 No Content or similar + if (entity != null) { + Header ceheader = entity.getContentEncoding(); + if (ceheader != null) { + HeaderElement[] codecs = ceheader.getElements(); + for (HeaderElement codec : codecs) { + String codecname = codec.getName().toLowerCase(Locale.US); + if ("gzip".equals(codecname) || "x-gzip".equals(codecname)) { + response.setEntity(new GzipDecompressingEntity(response.getEntity())); + if (context != null) context.setAttribute(UNCOMPRESSED, true); + return; + } else if ("deflate".equals(codecname)) { + response.setEntity(new DeflateDecompressingEntity(response.getEntity())); + if (context != null) context.setAttribute(UNCOMPRESSED, true); + return; + } else if ("identity".equals(codecname)) { + + /* Don't need to transform the content - no-op */ + return; + } else { + throw new HttpException("Unsupported Content-Coding: " + codec.getName()); + } + } + } + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/ResponseProcessCookies.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/ResponseProcessCookies.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/ResponseProcessCookies.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,141 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.protocol; + +import java.io.IOException; +import java.util.List; + +import org.apache.http.annotation.Immutable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HeaderIterator; +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.client.CookieStore; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SM; +import org.apache.http.protocol.HttpContext; + +/** + * Response interceptor that populates the current {@link CookieStore} with data + * contained in response cookies received in the given the HTTP response. + * + * @since 4.0 + */ +@Immutable +public class ResponseProcessCookies implements HttpResponseInterceptor { + + private final Log log = LogFactory.getLog(getClass()); + + public ResponseProcessCookies() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + // Obtain actual CookieSpec instance + CookieSpec cookieSpec = (CookieSpec) context.getAttribute( + ClientContext.COOKIE_SPEC); + if (cookieSpec == null) { + this.log.debug("Cookie spec not specified in HTTP context"); + return; + } + // Obtain cookie store + CookieStore cookieStore = (CookieStore) context.getAttribute( + ClientContext.COOKIE_STORE); + if (cookieStore == null) { + this.log.debug("Cookie store not specified in HTTP context"); + return; + } + // Obtain actual CookieOrigin instance + CookieOrigin cookieOrigin = (CookieOrigin) context.getAttribute( + ClientContext.COOKIE_ORIGIN); + if (cookieOrigin == null) { + this.log.debug("Cookie origin not specified in HTTP context"); + return; + } + HeaderIterator it = response.headerIterator(SM.SET_COOKIE); + processCookies(it, cookieSpec, cookieOrigin, cookieStore); + + // see if the cookie spec supports cookie versioning. + if (cookieSpec.getVersion() > 0) { + // process set-cookie2 headers. + // Cookie2 will replace equivalent Cookie instances + it = response.headerIterator(SM.SET_COOKIE2); + processCookies(it, cookieSpec, cookieOrigin, cookieStore); + } + } + + private void processCookies( + final HeaderIterator iterator, + final CookieSpec cookieSpec, + final CookieOrigin cookieOrigin, + final CookieStore cookieStore) { + while (iterator.hasNext()) { + Header header = iterator.nextHeader(); + try { + List cookies = cookieSpec.parse(header, cookieOrigin); + for (Cookie cookie : cookies) { + try { + cookieSpec.validate(cookie, cookieOrigin); + cookieStore.addCookie(cookie); + + if (this.log.isDebugEnabled()) { + this.log.debug("Cookie accepted: \"" + + cookie + "\". "); + } + } catch (MalformedCookieException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn("Cookie rejected: \"" + + cookie + "\". " + ex.getMessage()); + } + } + } + } catch (MalformedCookieException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn("Invalid cookie header: \"" + + header + "\". " + ex.getMessage()); + } + } + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/protocol/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/protocol/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/protocol/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Additional request and response interceptors for HTTP state and +authentication management. + + Index: 3rdParty_sources/httpclient/org/apache/http/client/utils/CloneUtils.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/utils/CloneUtils.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/utils/CloneUtils.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,80 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.client.utils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.http.annotation.Immutable; + +/** + * A collection of utilities to workaround limitations of Java clone framework. + * + * @since 4.0 + */ +@Immutable +public class CloneUtils { + + public static Object clone(final Object obj) throws CloneNotSupportedException { + if (obj == null) { + return null; + } + if (obj instanceof Cloneable) { + Class clazz = obj.getClass (); + Method m; + try { + m = clazz.getMethod("clone", (Class[]) null); + } catch (NoSuchMethodException ex) { + throw new NoSuchMethodError(ex.getMessage()); + } + try { + return m.invoke(obj, (Object []) null); + } catch (InvocationTargetException ex) { + Throwable cause = ex.getCause(); + if (cause instanceof CloneNotSupportedException) { + throw ((CloneNotSupportedException) cause); + } else { + throw new Error("Unexpected exception", cause); + } + } catch (IllegalAccessException ex) { + throw new IllegalAccessError(ex.getMessage()); + } + } else { + throw new CloneNotSupportedException(); + } + } + + /** + * This class should not be instantiated. + */ + private CloneUtils() { + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/utils/HttpClientUtils.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/utils/HttpClientUtils.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/utils/HttpClientUtils.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,107 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.client.utils; + +import java.io.IOException; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.util.EntityUtils; + +/** + * Static helpers for dealing with {@link HttpResponse}s and {@link HttpClient}s. + * + * @since 4.2 + */ +public class HttpClientUtils { + + private HttpClientUtils() { + } + + /** + * Unconditionally close a response. + *

+ * Example Code: + * + *

+     * HttpResponse httpResponse = null;
+     * try {
+     *     httpResponse = httpClient.execute(httpGet);
+     * } catch (Exception e) {
+     *     // error handling
+     * } finally {
+     *     HttpClientUtils.closeQuietly(httpResponse);
+     * }
+     * 
+ * + * @param response + * the HttpResponse to release resources, may be null or already + * closed. + * + * @since 4.2 + */ + public static void closeQuietly(final HttpResponse response) { + if (response != null) { + HttpEntity entity = response.getEntity(); + if (entity != null) { + try { + EntityUtils.consume(entity); + } catch (final IOException ex) { + } + } + } + } + + /** + * Unconditionally close a httpClient. Shuts down the underlying connection + * manager and releases the resources. + *

+ * Example Code: + * + *

+     * HttpClient httpClient = null;
+     * try {
+     *   httpClient = new DefaultHttpClient(...);
+     * } catch (Exception e) {
+     *   // error handling
+     * } finally {
+     *   HttpClientUtils.closeQuietly(httpClient);
+     * }
+     * 
+ * + * @param httpClient + * the HttpClient to close, may be null or already closed. + * @since 4.2 + */ + public static void closeQuietly(final HttpClient httpClient) { + if (httpClient != null) { + httpClient.getConnectionManager().shutdown(); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/utils/Idn.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/utils/Idn.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/utils/Idn.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,46 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.utils; + +/** + * Abstraction of international domain name (IDN) conversion. + * + * @since 4.0 + */ +public interface Idn { + /** + * Converts a name from its punycode representation to Unicode. + * The name may be a single hostname or a dot-separated qualified domain name. + * @param punycode the Punycode representation + * @return the Unicode domain name + */ + String toUnicode(String punycode); +} Index: 3rdParty_sources/httpclient/org/apache/http/client/utils/JdkIdn.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/utils/JdkIdn.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/utils/JdkIdn.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,75 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.utils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.http.annotation.Immutable; + +/** + * Uses the java.net.IDN class through reflection. + * + * @since 4.0 + */ +@Immutable +public class JdkIdn implements Idn { + private final Method toUnicode; + + /** + * + * @throws ClassNotFoundException if java.net.IDN is not available + */ + public JdkIdn() throws ClassNotFoundException { + Class clazz = Class.forName("java.net.IDN"); + try { + toUnicode = clazz.getMethod("toUnicode", String.class); + } catch (SecurityException e) { + // doesn't happen + throw new IllegalStateException(e.getMessage(), e); + } catch (NoSuchMethodException e) { + // doesn't happen + throw new IllegalStateException(e.getMessage(), e); + } + } + + public String toUnicode(String punycode) { + try { + return (String) toUnicode.invoke(null, punycode); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e.getMessage(), e); + } catch (InvocationTargetException e) { + Throwable t = e.getCause(); + throw new RuntimeException(t.getMessage(), t); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/utils/Punycode.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/utils/Punycode.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/utils/Punycode.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,58 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.utils; + +import org.apache.http.annotation.Immutable; + +/** + * Facade that provides conversion between Unicode and Punycode domain names. + * It will use an appropriate implementation. + * + * @since 4.0 + */ +@Immutable +public class Punycode { + private static final Idn impl; + static { + Idn _impl; + try { + _impl = new JdkIdn(); + } catch (Exception e) { + _impl = new Rfc3492Idn(); + } + impl = _impl; + } + + public static String toUnicode(String punycode) { + return impl.toUnicode(punycode); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/utils/Rfc3492Idn.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/utils/Rfc3492Idn.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/utils/Rfc3492Idn.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,126 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.utils; + +import java.util.StringTokenizer; + +import org.apache.http.annotation.Immutable; + +/** + * Implementation from pseudo code in RFC 3492. + * + * @since 4.0 + */ +@Immutable +public class Rfc3492Idn implements Idn { + private static final int base = 36; + private static final int tmin = 1; + private static final int tmax = 26; + private static final int skew = 38; + private static final int damp = 700; + private static final int initial_bias = 72; + private static final int initial_n = 128; + private static final char delimiter = '-'; + private static final String ACE_PREFIX = "xn--"; + + private int adapt(int delta, int numpoints, boolean firsttime) { + if (firsttime) delta = delta / damp; + else delta = delta / 2; + delta = delta + (delta / numpoints); + int k = 0; + while (delta > ((base - tmin) * tmax) / 2) { + delta = delta / (base - tmin); + k = k + base; + } + return k + (((base - tmin + 1) * delta) / (delta + skew)); + } + + private int digit(char c) { + if ((c >= 'A') && (c <= 'Z')) return (c - 'A'); + if ((c >= 'a') && (c <= 'z')) return (c - 'a'); + if ((c >= '0') && (c <= '9')) return (c - '0') + 26; + throw new IllegalArgumentException("illegal digit: "+ c); + } + + public String toUnicode(String punycode) { + StringBuilder unicode = new StringBuilder(punycode.length()); + StringTokenizer tok = new StringTokenizer(punycode, "."); + while (tok.hasMoreTokens()) { + String t = tok.nextToken(); + if (unicode.length() > 0) unicode.append('.'); + if (t.startsWith(ACE_PREFIX)) t = decode(t.substring(4)); + unicode.append(t); + } + return unicode.toString(); + } + + protected String decode(String input) { + int n = initial_n; + int i = 0; + int bias = initial_bias; + StringBuilder output = new StringBuilder(input.length()); + int lastdelim = input.lastIndexOf(delimiter); + if (lastdelim != -1) { + output.append(input.subSequence(0, lastdelim)); + input = input.substring(lastdelim + 1); + } + + while (input.length() > 0) { + int oldi = i; + int w = 1; + for (int k = base;; k += base) { + if (input.length() == 0) break; + char c = input.charAt(0); + input = input.substring(1); + int digit = digit(c); + i = i + digit * w; // FIXME fail on overflow + int t; + if (k <= bias + tmin) { + t = tmin; + } else if (k >= bias + tmax) { + t = tmax; + } else { + t = k - bias; + } + if (digit < t) break; + w = w * (base - t); // FIXME fail on overflow + } + bias = adapt(i - oldi, output.length() + 1, (oldi == 0)); + n = n + i / (output.length() + 1); // FIXME fail on overflow + i = i % (output.length() + 1); + // {if n is a basic code point then fail} + output.insert(i, (char) n); + i++; + } + return output.toString(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/utils/URIBuilder.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/utils/URIBuilder.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/utils/URIBuilder.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,362 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.utils; + +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.http.Consts; +import org.apache.http.NameValuePair; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.conn.util.InetAddressUtils; +import org.apache.http.message.BasicNameValuePair; + +/** + * {@link URI} builder for HTTP requests. + * + * @since 4.2 + */ +@NotThreadSafe +public class URIBuilder { + + private String scheme; + private String encodedSchemeSpecificPart; + private String encodedAuthority; + private String userInfo; + private String encodedUserInfo; + private String host; + private int port; + private String path; + private String encodedPath; + private String encodedQuery; + private List queryParams; + private String fragment; + private String encodedFragment; + + /** + * Constructs an empty instance. + */ + public URIBuilder() { + super(); + this.port = -1; + } + + /** + * Construct an instance from the string which must be a valid URI. + * + * @param string a valid URI in string form + * @throws URISyntaxException if the input is not a valid URI + */ + public URIBuilder(final String string) throws URISyntaxException { + super(); + digestURI(new URI(string)); + } + + /** + * Construct an instance from the provided URI. + * @param uri + */ + public URIBuilder(final URI uri) { + super(); + digestURI(uri); + } + + private List parseQuery(final String query, final Charset charset) { + if (query != null && query.length() > 0) { + return URLEncodedUtils.parse(query, charset); + } + return null; + } + + /** + * Builds a {@link URI} instance. + */ + public URI build() throws URISyntaxException { + return new URI(buildString()); + } + + private String buildString() { + StringBuilder sb = new StringBuilder(); + if (this.scheme != null) { + sb.append(this.scheme).append(':'); + } + if (this.encodedSchemeSpecificPart != null) { + sb.append(this.encodedSchemeSpecificPart); + } else { + if (this.encodedAuthority != null) { + sb.append("//").append(this.encodedAuthority); + } else if (this.host != null) { + sb.append("//"); + if (this.encodedUserInfo != null) { + sb.append(this.encodedUserInfo).append("@"); + } else if (this.userInfo != null) { + sb.append(encodeUserInfo(this.userInfo)).append("@"); + } + if (InetAddressUtils.isIPv6Address(this.host)) { + sb.append("[").append(this.host).append("]"); + } else { + sb.append(this.host); + } + if (this.port >= 0) { + sb.append(":").append(this.port); + } + } + if (this.encodedPath != null) { + sb.append(normalizePath(this.encodedPath)); + } else if (this.path != null) { + sb.append(encodePath(normalizePath(this.path))); + } + if (this.encodedQuery != null) { + sb.append("?").append(this.encodedQuery); + } else if (this.queryParams != null) { + sb.append("?").append(encodeQuery(this.queryParams)); + } + } + if (this.encodedFragment != null) { + sb.append("#").append(this.encodedFragment); + } else if (this.fragment != null) { + sb.append("#").append(encodeFragment(this.fragment)); + } + return sb.toString(); + } + + private void digestURI(final URI uri) { + this.scheme = uri.getScheme(); + this.encodedSchemeSpecificPart = uri.getRawSchemeSpecificPart(); + this.encodedAuthority = uri.getRawAuthority(); + this.host = uri.getHost(); + this.port = uri.getPort(); + this.encodedUserInfo = uri.getRawUserInfo(); + this.userInfo = uri.getUserInfo(); + this.encodedPath = uri.getRawPath(); + this.path = uri.getPath(); + this.encodedQuery = uri.getRawQuery(); + this.queryParams = parseQuery(uri.getRawQuery(), Consts.UTF_8); + this.encodedFragment = uri.getRawFragment(); + this.fragment = uri.getFragment(); + } + + private String encodeUserInfo(final String userInfo) { + return URLEncodedUtils.encUserInfo(userInfo, Consts.UTF_8); + } + + private String encodePath(final String path) { + return URLEncodedUtils.encPath(path, Consts.UTF_8); + } + + private String encodeQuery(final List params) { + return URLEncodedUtils.format(params, Consts.UTF_8); + } + + private String encodeFragment(final String fragment) { + return URLEncodedUtils.encFragment(fragment, Consts.UTF_8); + } + + /** + * Sets URI scheme. + */ + public URIBuilder setScheme(final String scheme) { + this.scheme = scheme; + return this; + } + + /** + * Sets URI user info. The value is expected to be unescaped and may contain non ASCII + * characters. + */ + public URIBuilder setUserInfo(final String userInfo) { + this.userInfo = userInfo; + this.encodedSchemeSpecificPart = null; + this.encodedAuthority = null; + this.encodedUserInfo = null; + return this; + } + + /** + * Sets URI user info as a combination of username and password. These values are expected to + * be unescaped and may contain non ASCII characters. + */ + public URIBuilder setUserInfo(final String username, final String password) { + return setUserInfo(username + ':' + password); + } + + /** + * Sets URI host. + */ + public URIBuilder setHost(final String host) { + this.host = host; + this.encodedSchemeSpecificPart = null; + this.encodedAuthority = null; + return this; + } + + /** + * Sets URI port. + */ + public URIBuilder setPort(final int port) { + this.port = port < 0 ? -1 : port; + this.encodedSchemeSpecificPart = null; + this.encodedAuthority = null; + return this; + } + + /** + * Sets URI path. The value is expected to be unescaped and may contain non ASCII characters. + */ + public URIBuilder setPath(final String path) { + this.path = path; + this.encodedSchemeSpecificPart = null; + this.encodedPath = null; + return this; + } + + /** + * Removes URI query. + */ + public URIBuilder removeQuery() { + this.queryParams = null; + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + return this; + } + + /** + * Sets URI query. + *

+ * The value is expected to be encoded form data. + */ + public URIBuilder setQuery(final String query) { + this.queryParams = parseQuery(query, Consts.UTF_8); + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + return this; + } + + /** + * Adds parameter to URI query. The parameter name and value are expected to be unescaped + * and may contain non ASCII characters. + */ + public URIBuilder addParameter(final String param, final String value) { + if (this.queryParams == null) { + this.queryParams = new ArrayList(); + } + this.queryParams.add(new BasicNameValuePair(param, value)); + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + return this; + } + + /** + * Sets parameter of URI query overriding existing value if set. The parameter name and value + * are expected to be unescaped and may contain non ASCII characters. + */ + public URIBuilder setParameter(final String param, final String value) { + if (this.queryParams == null) { + this.queryParams = new ArrayList(); + } + if (!this.queryParams.isEmpty()) { + for (Iterator it = this.queryParams.iterator(); it.hasNext(); ) { + NameValuePair nvp = it.next(); + if (nvp.getName().equals(param)) { + it.remove(); + } + } + } + this.queryParams.add(new BasicNameValuePair(param, value)); + this.encodedQuery = null; + this.encodedSchemeSpecificPart = null; + return this; + } + + /** + * Sets URI fragment. The value is expected to be unescaped and may contain non ASCII + * characters. + */ + public URIBuilder setFragment(final String fragment) { + this.fragment = fragment; + this.encodedFragment = null; + return this; + } + + public String getScheme() { + return this.scheme; + } + + public String getUserInfo() { + return this.userInfo; + } + + public String getHost() { + return this.host; + } + + public int getPort() { + return this.port; + } + + public String getPath() { + return this.path; + } + + public List getQueryParams() { + if (this.queryParams != null) { + return new ArrayList(this.queryParams); + } else { + return new ArrayList(); + } + } + + public String getFragment() { + return this.fragment; + } + + @Override + public String toString() { + return buildString(); + } + + private static String normalizePath(String path) { + if (path == null) { + return null; + } + int n = 0; + for (; n < path.length(); n++) { + if (path.charAt(n) != '/') { + break; + } + } + if (n > 1) { + path = path.substring(n - 1); + } + return path; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/utils/URIUtils.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/utils/URIUtils.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/utils/URIUtils.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,347 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.utils; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Stack; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.HttpHost; + +/** + * A collection of utilities for {@link URI URIs}, to workaround + * bugs within the class or for ease-of-use features. + * + * @since 4.0 + */ +@Immutable +public class URIUtils { + + /** + * Constructs a {@link URI} using all the parameters. This should be + * used instead of + * {@link URI#URI(String, String, String, int, String, String, String)} + * or any of the other URI multi-argument URI constructors. + * + * @param scheme + * Scheme name + * @param host + * Host name + * @param port + * Port number + * @param path + * Path + * @param query + * Query + * @param fragment + * Fragment + * + * @throws URISyntaxException + * If both a scheme and a path are given but the path is + * relative, if the URI string constructed from the given + * components violates RFC 2396, or if the authority + * component of the string is present but cannot be parsed + * as a server-based authority + * + * @deprecated (4.2) use {@link URIBuilder}. + */ + @Deprecated + public static URI createURI( + final String scheme, + final String host, + int port, + final String path, + final String query, + final String fragment) throws URISyntaxException { + StringBuilder buffer = new StringBuilder(); + if (host != null) { + if (scheme != null) { + buffer.append(scheme); + buffer.append("://"); + } + buffer.append(host); + if (port > 0) { + buffer.append(':'); + buffer.append(port); + } + } + if (path == null || !path.startsWith("/")) { + buffer.append('/'); + } + if (path != null) { + buffer.append(path); + } + if (query != null) { + buffer.append('?'); + buffer.append(query); + } + if (fragment != null) { + buffer.append('#'); + buffer.append(fragment); + } + return new URI(buffer.toString()); + } + + /** + * A convenience method for creating a new {@link URI} whose scheme, host + * and port are taken from the target host, but whose path, query and + * fragment are taken from the existing URI. The fragment is only used if + * dropFragment is false. + * + * @param uri + * Contains the path, query and fragment to use. + * @param target + * Contains the scheme, host and port to use. + * @param dropFragment + * True if the fragment should not be copied. + * + * @throws URISyntaxException + * If the resulting URI is invalid. + */ + public static URI rewriteURI( + final URI uri, + final HttpHost target, + boolean dropFragment) throws URISyntaxException { + if (uri == null) { + throw new IllegalArgumentException("URI may not be null"); + } + URIBuilder uribuilder = new URIBuilder(uri); + if (target != null) { + uribuilder.setScheme(target.getSchemeName()); + uribuilder.setHost(target.getHostName()); + uribuilder.setPort(target.getPort()); + } else { + uribuilder.setScheme(null); + uribuilder.setHost(null); + uribuilder.setPort(-1); + } + if (dropFragment) { + uribuilder.setFragment(null); + } + return uribuilder.build(); + } + + /** + * A convenience method for + * {@link URIUtils#rewriteURI(URI, HttpHost, boolean)} that always keeps the + * fragment. + */ + public static URI rewriteURI( + final URI uri, + final HttpHost target) throws URISyntaxException { + return rewriteURI(uri, target, false); + } + + /** + * A convenience method that creates a new {@link URI} whose scheme, host, port, path, + * query are taken from the existing URI, dropping any fragment or user-information. + * The existing URI is returned unmodified if it has no fragment or user-information. + * + * @param uri + * original URI. + * @throws URISyntaxException + * If the resulting URI is invalid. + */ + public static URI rewriteURI(final URI uri) throws URISyntaxException { + if (uri == null) { + throw new IllegalArgumentException("URI may not be null"); + } + if (uri.getFragment() != null || uri.getUserInfo() != null) { + return new URIBuilder(uri).setFragment(null).setUserInfo(null).build(); + } else { + return uri; + } + } + + /** + * Resolves a URI reference against a base URI. Work-around for bug in + * java.net.URI () + * + * @param baseURI the base URI + * @param reference the URI reference + * @return the resulting URI + */ + public static URI resolve(final URI baseURI, final String reference) { + return URIUtils.resolve(baseURI, URI.create(reference)); + } + + /** + * Resolves a URI reference against a base URI. Work-around for bugs in + * java.net.URI (e.g. ) + * + * @param baseURI the base URI + * @param reference the URI reference + * @return the resulting URI + */ + public static URI resolve(final URI baseURI, URI reference){ + if (baseURI == null) { + throw new IllegalArgumentException("Base URI may nor be null"); + } + if (reference == null) { + throw new IllegalArgumentException("Reference URI may nor be null"); + } + String s = reference.toString(); + if (s.startsWith("?")) { + return resolveReferenceStartingWithQueryString(baseURI, reference); + } + boolean emptyReference = s.length() == 0; + if (emptyReference) { + reference = URI.create("#"); + } + URI resolved = baseURI.resolve(reference); + if (emptyReference) { + String resolvedString = resolved.toString(); + resolved = URI.create(resolvedString.substring(0, + resolvedString.indexOf('#'))); + } + return removeDotSegments(resolved); + } + + /** + * Resolves a reference starting with a query string. + * + * @param baseURI the base URI + * @param reference the URI reference starting with a query string + * @return the resulting URI + */ + private static URI resolveReferenceStartingWithQueryString( + final URI baseURI, final URI reference) { + String baseUri = baseURI.toString(); + baseUri = baseUri.indexOf('?') > -1 ? + baseUri.substring(0, baseUri.indexOf('?')) : baseUri; + return URI.create(baseUri + reference.toString()); + } + + /** + * Removes dot segments according to RFC 3986, section 5.2.4 + * + * @param uri the original URI + * @return the URI without dot segments + */ + private static URI removeDotSegments(URI uri) { + String path = uri.getPath(); + if ((path == null) || (path.indexOf("/.") == -1)) { + // No dot segments to remove + return uri; + } + String[] inputSegments = path.split("/"); + Stack outputSegments = new Stack(); + for (int i = 0; i < inputSegments.length; i++) { + if ((inputSegments[i].length() == 0) + || (".".equals(inputSegments[i]))) { + // Do nothing + } else if ("..".equals(inputSegments[i])) { + if (!outputSegments.isEmpty()) { + outputSegments.pop(); + } + } else { + outputSegments.push(inputSegments[i]); + } + } + StringBuilder outputBuffer = new StringBuilder(); + for (String outputSegment : outputSegments) { + outputBuffer.append('/').append(outputSegment); + } + try { + return new URI(uri.getScheme(), uri.getAuthority(), + outputBuffer.toString(), uri.getQuery(), uri.getFragment()); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * Extracts target host from the given {@link URI}. + * + * @param uri + * @return the target host if the URI is absolute or null if the URI is + * relative or does not contain a valid host name. + * + * @since 4.1 + */ + public static HttpHost extractHost(final URI uri) { + if (uri == null) { + return null; + } + HttpHost target = null; + if (uri.isAbsolute()) { + int port = uri.getPort(); // may be overridden later + String host = uri.getHost(); + if (host == null) { // normal parse failed; let's do it ourselves + // authority does not seem to care about the valid character-set for host names + host = uri.getAuthority(); + if (host != null) { + // Strip off any leading user credentials + int at = host.indexOf('@'); + if (at >= 0) { + if (host.length() > at+1 ) { + host = host.substring(at+1); + } else { + host = null; // @ on its own + } + } + // Extract the port suffix, if present + if (host != null) { + int colon = host.indexOf(':'); + if (colon >= 0) { + int pos = colon + 1; + int len = 0; + for (int i = pos; i < host.length(); i++) { + if (Character.isDigit(host.charAt(i))) { + len++; + } else { + break; + } + } + if (len > 0) { + try { + port = Integer.parseInt(host.substring(pos, pos + len)); + } catch (NumberFormatException ex) { + } + } + host = host.substring(0, colon); + } + } + } + } + String scheme = uri.getScheme(); + if (host != null) { + target = new HttpHost(host, port, scheme); + } + } + return target; + } + + /** + * This class should not be instantiated. + */ + private URIUtils() { + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/utils/URLEncodedUtils.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/utils/URLEncodedUtils.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/utils/URLEncodedUtils.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,544 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.client.utils; + +import java.io.IOException; +import java.net.URI; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Collections; +import java.util.List; +import java.util.Scanner; + +import org.apache.http.annotation.Immutable; +import org.apache.http.entity.ContentType; + +import org.apache.http.Consts; +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicHeaderValueParser; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.message.ParserCursor; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.CharArrayBuffer; +import org.apache.http.util.EntityUtils; + +/** + * A collection of utilities for encoding URLs. + * + * @since 4.0 + */ +@Immutable +public class URLEncodedUtils { + + public static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; + private static final String PARAMETER_SEPARATOR = "&"; + private static final String NAME_VALUE_SEPARATOR = "="; + + /** + * Returns a list of {@link NameValuePair NameValuePairs} as built from the + * URI's query portion. For example, a URI of + * http://example.org/path/to/file?a=1&b=2&c=3 would return a list of three + * NameValuePairs, one for a=1, one for b=2, and one for c=3. + *

+ * This is typically useful while parsing an HTTP PUT. + * + * @param uri + * uri to parse + * @param encoding + * encoding to use while parsing the query + */ + public static List parse (final URI uri, final String encoding) { + final String query = uri.getRawQuery(); + if (query != null && query.length() > 0) { + List result = new ArrayList(); + Scanner scanner = new Scanner(query); + parse(result, scanner, encoding); + return result; + } else { + return Collections.emptyList(); + } + } + + /** + * Returns a list of {@link NameValuePair NameValuePairs} as parsed from an + * {@link HttpEntity}. The encoding is taken from the entity's + * Content-Encoding header. + *

+ * This is typically used while parsing an HTTP POST. + * + * @param entity + * The entity to parse + * @throws IOException + * If there was an exception getting the entity's data. + */ + public static List parse ( + final HttpEntity entity) throws IOException { + ContentType contentType = ContentType.get(entity); + if (contentType != null && contentType.getMimeType().equalsIgnoreCase(CONTENT_TYPE)) { + String content = EntityUtils.toString(entity, Consts.ASCII); + if (content != null && content.length() > 0) { + Charset charset = contentType.getCharset(); + if (charset == null) { + charset = HTTP.DEF_CONTENT_CHARSET; + } + return parse(content, charset); + } + } + return Collections.emptyList(); + } + + /** + * Returns true if the entity's Content-Type header is + * application/x-www-form-urlencoded. + */ + public static boolean isEncoded (final HttpEntity entity) { + Header h = entity.getContentType(); + if (h != null) { + HeaderElement[] elems = h.getElements(); + if (elems.length > 0) { + String contentType = elems[0].getName(); + return contentType.equalsIgnoreCase(CONTENT_TYPE); + } else { + return false; + } + } else { + return false; + } + } + + /** + * Adds all parameters within the Scanner to the list of + * parameters, as encoded by encoding. For + * example, a scanner containing the string a=1&b=2&c=3 would + * add the {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the + * list of parameters. + * + * @param parameters + * List to add parameters to. + * @param scanner + * Input that contains the parameters to parse. + * @param charset + * Encoding to use when decoding the parameters. + */ + public static void parse ( + final List parameters, + final Scanner scanner, + final String charset) { + scanner.useDelimiter(PARAMETER_SEPARATOR); + while (scanner.hasNext()) { + String name = null; + String value = null; + String token = scanner.next(); + int i = token.indexOf(NAME_VALUE_SEPARATOR); + if (i != -1) { + name = decodeFormFields(token.substring(0, i).trim(), charset); + value = decodeFormFields(token.substring(i + 1).trim(), charset); + } else { + name = decodeFormFields(token.trim(), charset); + } + parameters.add(new BasicNameValuePair(name, value)); + } + } + + private static final char[] DELIM = new char[] { '&' }; + + /** + * Returns a list of {@link NameValuePair NameValuePairs} as parsed from the given string + * using the given character encoding. + * + * @param s + * text to parse. + * @param charset + * Encoding to use when decoding the parameters. + * + * @since 4.2 + */ + public static List parse (final String s, final Charset charset) { + if (s == null) { + return Collections.emptyList(); + } + BasicHeaderValueParser parser = BasicHeaderValueParser.DEFAULT; + CharArrayBuffer buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + ParserCursor cursor = new ParserCursor(0, buffer.length()); + List list = new ArrayList(); + while (!cursor.atEnd()) { + NameValuePair nvp = parser.parseNameValuePair(buffer, cursor, DELIM); + if (nvp.getName().length() > 0) { + list.add(new BasicNameValuePair( + decodeFormFields(nvp.getName(), charset), + decodeFormFields(nvp.getValue(), charset))); + } + } + return list; + } + + /** + * Returns a String that is suitable for use as an application/x-www-form-urlencoded + * list of parameters in an HTTP PUT or HTTP POST. + * + * @param parameters The parameters to include. + * @param encoding The encoding to use. + */ + public static String format ( + final List parameters, + final String encoding) { + final StringBuilder result = new StringBuilder(); + for (final NameValuePair parameter : parameters) { + final String encodedName = encodeFormFields(parameter.getName(), encoding); + final String encodedValue = encodeFormFields(parameter.getValue(), encoding); + if (result.length() > 0) { + result.append(PARAMETER_SEPARATOR); + } + result.append(encodedName); + if (encodedValue != null) { + result.append(NAME_VALUE_SEPARATOR); + result.append(encodedValue); + } + } + return result.toString(); + } + + /** + * Returns a String that is suitable for use as an application/x-www-form-urlencoded + * list of parameters in an HTTP PUT or HTTP POST. + * + * @param parameters The parameters to include. + * @param charset The encoding to use. + * + * @since 4.2 + */ + public static String format ( + final Iterable parameters, + final Charset charset) { + final StringBuilder result = new StringBuilder(); + for (final NameValuePair parameter : parameters) { + final String encodedName = encodeFormFields(parameter.getName(), charset); + final String encodedValue = encodeFormFields(parameter.getValue(), charset); + if (result.length() > 0) { + result.append(PARAMETER_SEPARATOR); + } + result.append(encodedName); + if (encodedValue != null) { + result.append(NAME_VALUE_SEPARATOR); + result.append(encodedValue); + } + } + return result.toString(); + } + + /** + * Unreserved characters, i.e. alphanumeric, plus: {@code _ - ! . ~ ' ( ) *} + *

+ * This list is the same as the {@code unreserved} list in + * RFC 2396 + */ + private static final BitSet UNRESERVED = new BitSet(256); + /** + * Punctuation characters: , ; : $ & + = + *

+ * These are the additional characters allowed by userinfo. + */ + private static final BitSet PUNCT = new BitSet(256); + /** Characters which are safe to use in userinfo, i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation */ + private static final BitSet USERINFO = new BitSet(256); + /** Characters which are safe to use in a path, i.e. {@link #UNRESERVED} plus {@link #PUNCT}uation plus / @ */ + private static final BitSet PATHSAFE = new BitSet(256); + /** Characters which are safe to use in a fragment, i.e. {@link #RESERVED} plus {@link #UNRESERVED} */ + private static final BitSet FRAGMENT = new BitSet(256); + + /** + * Reserved characters, i.e. {@code ;/?:@&=+$,[]} + *

+ * This list is the same as the {@code reserved} list in + * RFC 2396 + * as augmented by + * RFC 2732 + */ + private static final BitSet RESERVED = new BitSet(256); + + + /** + * Safe characters for x-www-form-urlencoded data, as per java.net.URLEncoder and browser behaviour, + * i.e. alphanumeric plus {@code "-", "_", ".", "*"} + */ + private static final BitSet URLENCODER = new BitSet(256); + + static { + // unreserved chars + // alpha characters + for (int i = 'a'; i <= 'z'; i++) { + UNRESERVED.set(i); + } + for (int i = 'A'; i <= 'Z'; i++) { + UNRESERVED.set(i); + } + // numeric characters + for (int i = '0'; i <= '9'; i++) { + UNRESERVED.set(i); + } + UNRESERVED.set('_'); // these are the charactes of the "mark" list + UNRESERVED.set('-'); + UNRESERVED.set('.'); + UNRESERVED.set('*'); + URLENCODER.or(UNRESERVED); // skip remaining unreserved characters + UNRESERVED.set('!'); + UNRESERVED.set('~'); + UNRESERVED.set('\''); + UNRESERVED.set('('); + UNRESERVED.set(')'); + // punct chars + PUNCT.set(','); + PUNCT.set(';'); + PUNCT.set(':'); + PUNCT.set('$'); + PUNCT.set('&'); + PUNCT.set('+'); + PUNCT.set('='); + // Safe for userinfo + USERINFO.or(UNRESERVED); + USERINFO.or(PUNCT); + + // URL path safe + PATHSAFE.or(UNRESERVED); + PATHSAFE.set('/'); // segment separator + PATHSAFE.set(';'); // param separator + PATHSAFE.set(':'); // rest as per list in 2396, i.e. : @ & = + $ , + PATHSAFE.set('@'); + PATHSAFE.set('&'); + PATHSAFE.set('='); + PATHSAFE.set('+'); + PATHSAFE.set('$'); + PATHSAFE.set(','); + + RESERVED.set(';'); + RESERVED.set('/'); + RESERVED.set('?'); + RESERVED.set(':'); + RESERVED.set('@'); + RESERVED.set('&'); + RESERVED.set('='); + RESERVED.set('+'); + RESERVED.set('$'); + RESERVED.set(','); + RESERVED.set('['); // added by RFC 2732 + RESERVED.set(']'); // added by RFC 2732 + + FRAGMENT.or(RESERVED); + FRAGMENT.or(UNRESERVED); + } + + private static final int RADIX = 16; + + /** + * Emcode/escape a portion of a URL, to use with the query part ensure {@code plusAsBlank} is true. + * + * @param content the portion to decode + * @param charset the charset to use + * @param blankAsPlus if {@code true}, then convert space to '+' (e.g. for www-url-form-encoded content), otherwise leave as is. + * @return + */ + private static String urlencode( + final String content, + final Charset charset, + final BitSet safechars, + final boolean blankAsPlus) { + if (content == null) { + return null; + } + StringBuilder buf = new StringBuilder(); + ByteBuffer bb = charset.encode(content); + while (bb.hasRemaining()) { + int b = bb.get() & 0xff; + if (safechars.get(b)) { + buf.append((char) b); + } else if (blankAsPlus && b == ' ') { + buf.append('+'); + } else { + buf.append("%"); + char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, RADIX)); + char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, RADIX)); + buf.append(hex1); + buf.append(hex2); + } + } + return buf.toString(); + } + + /** + * Decode/unescape a portion of a URL, to use with the query part ensure {@code plusAsBlank} is true. + * + * @param content the portion to decode + * @param charset the charset to use + * @param plusAsBlank if {@code true}, then convert '+' to space (e.g. for www-url-form-encoded content), otherwise leave as is. + * @return + */ + private static String urldecode( + final String content, + final Charset charset, + final boolean plusAsBlank) { + if (content == null) { + return null; + } + ByteBuffer bb = ByteBuffer.allocate(content.length()); + CharBuffer cb = CharBuffer.wrap(content); + while (cb.hasRemaining()) { + char c = cb.get(); + if (c == '%' && cb.remaining() >= 2) { + char uc = cb.get(); + char lc = cb.get(); + int u = Character.digit(uc, 16); + int l = Character.digit(lc, 16); + if (u != -1 && l != -1) { + bb.put((byte) ((u << 4) + l)); + } else { + bb.put((byte) '%'); + bb.put((byte) uc); + bb.put((byte) lc); + } + } else if (plusAsBlank && c == '+') { + bb.put((byte) ' '); + } else { + bb.put((byte) c); + } + } + bb.flip(); + return charset.decode(bb).toString(); + } + + /** + * Decode/unescape www-url-form-encoded content. + * + * @param content the content to decode, will decode '+' as space + * @param charset the charset to use + * @return + */ + private static String decodeFormFields (final String content, final String charset) { + if (content == null) { + return null; + } + return urldecode(content, charset != null ? Charset.forName(charset) : Consts.UTF_8, true); + } + + /** + * Decode/unescape www-url-form-encoded content. + * + * @param content the content to decode, will decode '+' as space + * @param charset the charset to use + * @return + */ + private static String decodeFormFields (final String content, final Charset charset) { + if (content == null) { + return null; + } + return urldecode(content, charset != null ? charset : Consts.UTF_8, true); + } + + /** + * Encode/escape www-url-form-encoded content. + *

+ * Uses the {@link #URLENCODER} set of characters, rather than + * the {@link #UNRSERVED} set; this is for compatibilty with previous + * releases, URLEncoder.encode() and most browsers. + * + * @param content the content to encode, will convert space to '+' + * @param charset the charset to use + * @return + */ + private static String encodeFormFields (final String content, final String charset) { + if (content == null) { + return null; + } + return urlencode(content, charset != null ? Charset.forName(charset) : + Consts.UTF_8, URLENCODER, true); + } + + /** + * Encode/escape www-url-form-encoded content. + *

+ * Uses the {@link #URLENCODER} set of characters, rather than + * the {@link #UNRSERVED} set; this is for compatibilty with previous + * releases, URLEncoder.encode() and most browsers. + * + * @param content the content to encode, will convert space to '+' + * @param charset the charset to use + * @return + */ + private static String encodeFormFields (final String content, final Charset charset) { + if (content == null) { + return null; + } + return urlencode(content, charset != null ? charset : Consts.UTF_8, URLENCODER, true); + } + + /** + * Encode a String using the {@link #USERINFO} set of characters. + *

+ * Used by URIBuilder to encode the userinfo segment. + * + * @param content the string to encode, does not convert space to '+' + * @param charset the charset to use + * @return the encoded string + */ + static String encUserInfo(final String content, final Charset charset) { + return urlencode(content, charset, USERINFO, false); + } + + /** + * Encode a String using the {@link #FRAGMENT} set of characters. + *

+ * Used by URIBuilder to encode the userinfo segment. + * + * @param content the string to encode, does not convert space to '+' + * @param charset the charset to use + * @return the encoded string + */ + static String encFragment(final String content, final Charset charset) { + return urlencode(content, charset, FRAGMENT, false); + } + + /** + * Encode a String using the {@link #PATHSAFE} set of characters. + *

+ * Used by URIBuilder to encode path segments. + * + * @param content the string to encode, does not convert space to '+' + * @param charset the charset to use + * @return the encoded string + */ + static String encPath(final String content, final Charset charset) { + return urlencode(content, charset, PATHSAFE, false); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/client/utils/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/client/utils/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/client/utils/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Helpers and utility classes for HttpClient. + + + Index: 3rdParty_sources/httpclient/org/apache/http/conn/BasicEofSensorWatcher.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/BasicEofSensorWatcher.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/BasicEofSensorWatcher.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,105 @@ +/* + * $Revision $ + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.InputStream; +import java.io.IOException; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * Basic implementation of {@link EofSensorWatcher}. The underlying connection + * is released on close or EOF. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicEofSensorWatcher implements EofSensorWatcher { + + /** The connection to auto-release. */ + protected final ManagedClientConnection managedConn; + + /** Whether to keep the connection alive. */ + protected final boolean attemptReuse; + + /** + * Creates a new watcher for auto-releasing a connection. + * + * @param conn the connection to auto-release + * @param reuse whether the connection should be re-used + */ + public BasicEofSensorWatcher(ManagedClientConnection conn, + boolean reuse) { + if (conn == null) + throw new IllegalArgumentException + ("Connection may not be null."); + + managedConn = conn; + attemptReuse = reuse; + } + + public boolean eofDetected(InputStream wrapped) + throws IOException { + + try { + if (attemptReuse) { + // there may be some cleanup required, such as + // reading trailers after the response body: + wrapped.close(); + managedConn.markReusable(); + } + } finally { + managedConn.releaseConnection(); + } + return false; + } + + public boolean streamClosed(InputStream wrapped) + throws IOException { + + try { + if (attemptReuse) { + // this assumes that closing the stream will + // consume the remainder of the response body: + wrapped.close(); + managedConn.markReusable(); + } + } finally { + managedConn.releaseConnection(); + } + return false; + } + + public boolean streamAbort(InputStream wrapped) + throws IOException { + + managedConn.abortConnection(); + return false; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/BasicManagedEntity.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/BasicManagedEntity.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/BasicManagedEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,198 @@ +/* + * $Revision $ + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.SocketException; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.HttpEntity; +import org.apache.http.entity.HttpEntityWrapper; +import org.apache.http.util.EntityUtils; + +/** + * An entity that releases a {@link ManagedClientConnection connection}. + * A {@link ManagedClientConnection} will + * typically not return a managed entity, but you can replace + * the unmanaged entity in the response with a managed one. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicManagedEntity extends HttpEntityWrapper + implements ConnectionReleaseTrigger, EofSensorWatcher { + + /** The connection to release. */ + protected ManagedClientConnection managedConn; + + /** Whether to keep the connection alive. */ + protected final boolean attemptReuse; + + /** + * Creates a new managed entity that can release a connection. + * + * @param entity the entity of which to wrap the content. + * Note that the argument entity can no longer be used + * afterwards, since the content will be taken by this + * managed entity. + * @param conn the connection to release + * @param reuse whether the connection should be re-used + */ + public BasicManagedEntity(HttpEntity entity, + ManagedClientConnection conn, + boolean reuse) { + super(entity); + + if (conn == null) + throw new IllegalArgumentException + ("Connection may not be null."); + + this.managedConn = conn; + this.attemptReuse = reuse; + } + + @Override + public boolean isRepeatable() { + return false; + } + + @Override + public InputStream getContent() throws IOException { + return new EofSensorInputStream(wrappedEntity.getContent(), this); + } + + private void ensureConsumed() throws IOException { + if (managedConn == null) + return; + + try { + if (attemptReuse) { + // this will not trigger a callback from EofSensorInputStream + EntityUtils.consume(wrappedEntity); + managedConn.markReusable(); + } + } finally { + releaseManagedConnection(); + } + } + + /** + * @deprecated (4.1) Use {@link EntityUtils#consume(HttpEntity)} + */ + @Override + public void consumeContent() throws IOException { + ensureConsumed(); + } + + @Override + public void writeTo(final OutputStream outstream) throws IOException { + super.writeTo(outstream); + ensureConsumed(); + } + + public void releaseConnection() throws IOException { + ensureConsumed(); + } + + public void abortConnection() throws IOException { + + if (managedConn != null) { + try { + managedConn.abortConnection(); + } finally { + managedConn = null; + } + } + } + + public boolean eofDetected(InputStream wrapped) throws IOException { + try { + if (attemptReuse && (managedConn != null)) { + // there may be some cleanup required, such as + // reading trailers after the response body: + wrapped.close(); + managedConn.markReusable(); + } + } finally { + releaseManagedConnection(); + } + return false; + } + + public boolean streamClosed(InputStream wrapped) throws IOException { + try { + if (attemptReuse && (managedConn != null)) { + boolean valid = managedConn.isOpen(); + // this assumes that closing the stream will + // consume the remainder of the response body: + try { + wrapped.close(); + managedConn.markReusable(); + } catch (SocketException ex) { + if (valid) { + throw ex; + } + } + } + } finally { + releaseManagedConnection(); + } + return false; + } + + public boolean streamAbort(InputStream wrapped) throws IOException { + if (managedConn != null) { + managedConn.abortConnection(); + } + return false; + } + + /** + * Releases the connection gracefully. + * The connection attribute will be nullified. + * Subsequent invocations are no-ops. + * + * @throws IOException in case of an IO problem. + * The connection attribute will be nullified anyway. + */ + protected void releaseManagedConnection() + throws IOException { + + if (managedConn != null) { + try { + managedConn.releaseConnection(); + } finally { + managedConn = null; + } + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionManager.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionManager.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionManager.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,114 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.util.concurrent.TimeUnit; + +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.scheme.SchemeRegistry; + +/** + * Management interface for {@link ManagedClientConnection client connections}. + * The purpose of an HTTP connection manager is to serve as a factory for new + * HTTP connections, manage persistent connections and synchronize access to + * persistent connections making sure that only one thread of execution can + * have access to a connection at a time. + *

+ * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + */ +public interface ClientConnectionManager { + + /** + * Obtains the scheme registry used by this manager. + * + * @return the scheme registry, never null + */ + SchemeRegistry getSchemeRegistry(); + + /** + * Returns a new {@link ClientConnectionRequest}, from which a + * {@link ManagedClientConnection} can be obtained or the request can be + * aborted. + */ + ClientConnectionRequest requestConnection(HttpRoute route, Object state); + + /** + * Releases a connection for use by others. + * You may optionally specify how long the connection is valid + * to be reused. Values <= 0 are considered to be valid forever. + * If the connection is not marked as reusable, the connection will + * not be reused regardless of the valid duration. + * + * If the connection has been released before, + * the call will be ignored. + * + * @param conn the connection to release + * @param validDuration the duration of time this connection is valid for reuse + * @param timeUnit the unit of time validDuration is measured in + * + * @see #closeExpiredConnections() + */ + void releaseConnection(ManagedClientConnection conn, long validDuration, TimeUnit timeUnit); + + /** + * Closes idle connections in the pool. + * Open connections in the pool that have not been used for the + * timespan given by the argument will be closed. + * Currently allocated connections are not subject to this method. + * Times will be checked with milliseconds precision + * + * All expired connections will also be closed. + * + * @param idletime the idle time of connections to be closed + * @param tunit the unit for the idletime + * + * @see #closeExpiredConnections() + */ + void closeIdleConnections(long idletime, TimeUnit tunit); + + /** + * Closes all expired connections in the pool. + * Open connections in the pool that have not been used for + * the timespan defined when the connection was released will be closed. + * Currently allocated connections are not subject to this method. + * Times will be checked with milliseconds precision. + */ + void closeExpiredConnections(); + + /** + * Shuts down this connection manager and releases allocated resources. + * This includes closing all connections, whether they are currently + * used or not. + */ + void shutdown(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionManagerFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionManagerFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionManagerFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,45 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.params.HttpParams; + +/** + * A factory for creating new {@link ClientConnectionManager} instances. + * + * + * @since 4.0 + */ +public interface ClientConnectionManagerFactory { + + ClientConnectionManager newInstance( + HttpParams params, + SchemeRegistry schemeRegistry); + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionOperator.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionOperator.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionOperator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,105 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; + +import org.apache.http.HttpHost; +import org.apache.http.conn.scheme.SchemeSocketFactory; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; + +/** + * ClientConnectionOperator represents a strategy for creating + * {@link OperatedClientConnection} instances and updating the underlying + * {@link Socket} of those objects. Implementations will most likely make use + * of {@link SchemeSocketFactory}s to create {@link Socket} instances. + *

+ * The methods in this interface allow the creation of plain and layered + * sockets. Creating a tunnelled connection through a proxy, however, + * is not within the scope of the operator. + *

+ * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + */ +public interface ClientConnectionOperator { + + /** + * Creates a new connection that can be operated. + * + * @return a new, unopened connection for use with this operator + */ + OperatedClientConnection createConnection(); + + /** + * Opens a connection to the given target host. + * + * @param conn the connection to open + * @param target the target host to connect to + * @param local the local address to route from, or + * null for the default + * @param context the context for the connection + * @param params the parameters for the connection + * + * @throws IOException in case of a problem + */ + void openConnection(OperatedClientConnection conn, + HttpHost target, + InetAddress local, + HttpContext context, + HttpParams params) + throws IOException; + + /** + * Updates a connection with a layered secure connection. + * The typical use of this method is to update a tunnelled plain + * connection (HTTP) to a secure TLS/SSL connection (HTTPS). + * + * @param conn the open connection to update + * @param target the target host for the updated connection. + * The connection must already be open or tunnelled + * to the host and port, but the scheme of the target + * will be used to create a layered connection. + * @param context the context for the connection + * @param params the parameters for the updated connection + * + * @throws IOException in case of a problem + */ + void updateSecureConnection(OperatedClientConnection conn, + HttpHost target, + HttpContext context, + HttpParams params) + throws IOException; + +} + Index: 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionRequest.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionRequest.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ClientConnectionRequest.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,71 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.util.concurrent.TimeUnit; + +/** + * Encapsulates a request for a {@link ManagedClientConnection}. + * + * @since 4.0 + */ +public interface ClientConnectionRequest { + + /** + * Obtains a connection within a given time. + * This method will block until a connection becomes available, + * the timeout expires, or the connection manager is + * {@link ClientConnectionManager#shutdown() shut down}. + * Timeouts are handled with millisecond precision. + * + * If {@link #abortRequest()} is called while this is blocking or + * before this began, an {@link InterruptedException} will + * be thrown. + * + * @param timeout the timeout, 0 or negative for no timeout + * @param tunit the unit for the timeout, + * may be null only if there is no timeout + * + * @return a connection that can be used to communicate + * along the given route + * + * @throws ConnectionPoolTimeoutException + * in case of a timeout + * @throws InterruptedException + * if the calling thread is interrupted while waiting + */ + ManagedClientConnection getConnection(long timeout, TimeUnit tunit) + throws InterruptedException, ConnectionPoolTimeoutException; + + /** + * Aborts the call to {@link #getConnection(long, TimeUnit)}, + * causing it to throw an {@link InterruptedException}. + */ + void abortRequest(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ConnectTimeoutException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ConnectTimeoutException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ConnectTimeoutException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,62 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.InterruptedIOException; + +import org.apache.http.annotation.Immutable; + +/** + * A timeout while connecting to an HTTP server or waiting for an + * available connection from an HttpConnectionManager. + * + * + * @since 4.0 + */ +@Immutable +public class ConnectTimeoutException extends InterruptedIOException { + + private static final long serialVersionUID = -4816682903149535989L; + + /** + * Creates a ConnectTimeoutException with a null detail message. + */ + public ConnectTimeoutException() { + super(); + } + + /** + * Creates a ConnectTimeoutException with the specified detail message. + * + * @param message The exception detail message + */ + public ConnectTimeoutException(final String message) { + super(message); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ConnectionKeepAliveStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ConnectionKeepAliveStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ConnectionKeepAliveStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,66 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.conn; + +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.HttpResponse; +import org.apache.http.protocol.HttpContext; + +/** + * Interface for deciding how long a connection can remain + * idle before being reused. + *

+ * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + */ +public interface ConnectionKeepAliveStrategy { + + /** + * Returns the duration of time which this connection can be safely kept + * idle. If the connection is left idle for longer than this period of time, + * it MUST not reused. A value of 0 or less may be returned to indicate that + * there is no suitable suggestion. + * + * When coupled with a {@link ConnectionReuseStrategy}, if + * {@link ConnectionReuseStrategy#keepAlive(HttpResponse, HttpContext)} + * returns true, this allows you to control how long the reuse will last. If + * keepAlive returns false, this should have no meaningful impact + * + * @param response + * The last response received over the connection. + * @param context + * the context in which the connection is being used. + * + * @return the duration in ms for which it is safe to keep the connection + * idle, or <=0 if no suggested duration. + */ + long getKeepAliveDuration(HttpResponse response, HttpContext context); + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ConnectionPoolTimeoutException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ConnectionPoolTimeoutException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ConnectionPoolTimeoutException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,60 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import org.apache.http.annotation.Immutable; + +/** + * A timeout while waiting for an available connection + * from a connection manager. + * + * + * @since 4.0 + */ +@Immutable +public class ConnectionPoolTimeoutException extends ConnectTimeoutException { + + private static final long serialVersionUID = -7898874842020245128L; + + /** + * Creates a ConnectTimeoutException with a null detail message. + */ + public ConnectionPoolTimeoutException() { + super(); + } + + /** + * Creates a ConnectTimeoutException with the specified detail message. + * + * @param message The exception detail message + */ + public ConnectionPoolTimeoutException(String message) { + super(message); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ConnectionReleaseTrigger.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ConnectionReleaseTrigger.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ConnectionReleaseTrigger.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,70 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.IOException; + +/** + * Interface for releasing a connection. This can be implemented by various + * "trigger" objects which are associated with a connection, for example + * a {@link EofSensorInputStream stream} or an {@link BasicManagedEntity entity} + * or the {@link ManagedClientConnection connection} itself. + *

+ * The methods in this interface can safely be called multiple times. + * The first invocation releases the connection, subsequent calls + * are ignored. + * + * @since 4.0 + */ +public interface ConnectionReleaseTrigger { + + /** + * Releases the connection with the option of keep-alive. This is a + * "graceful" release and may cause IO operations for consuming the + * remainder of a response entity. Use + * {@link #abortConnection abortConnection} for a hard release. The + * connection may be reused as specified by the duration. + * + * @throws IOException + * in case of an IO problem. The connection will be released + * anyway. + */ + void releaseConnection() + throws IOException; + + /** + * Releases the connection without the option of keep-alive. + * This is a "hard" release that implies a shutdown of the connection. + * Use {@link #releaseConnection()} for a graceful release. + * + * @throws IOException in case of an IO problem. + * The connection will be released anyway. + */ + void abortConnection() + throws IOException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/DnsResolver.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/DnsResolver.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/DnsResolver.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,54 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.conn; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Users may implement this interface to override the normal DNS lookup offered + * by the OS. + * + * @since 4.2 + */ +public interface DnsResolver { + + /** + * Returns the IP address for the specified host name, or null if the given + * host is not recognized or the associated IP address cannot be used to + * build an InetAddress instance. + * + * @see InetAddress + * + * @param host + * The host name to be resolved by this resolver. + * @return The IP address associated to the given host name, or null if the + * host name is not known by the implementation class. + */ + InetAddress[] resolve(String host) throws UnknownHostException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/EofSensorInputStream.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/EofSensorInputStream.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/EofSensorInputStream.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,295 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.InputStream; +import java.io.IOException; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * A stream wrapper that triggers actions on {@link #close close()} and EOF. + * Primarily used to auto-release an underlying + * {@link ManagedClientConnection connection} + * when the response body is consumed or no longer needed. + *

+ * This class is based on AutoCloseInputStream in HttpClient 3.1, + * but has notable differences. It does not allow mark/reset, distinguishes + * different kinds of event, and does not always close the underlying stream + * on EOF. That decision is left to the {@link EofSensorWatcher watcher}. + * + * @see EofSensorWatcher + * + * @since 4.0 + */ +// don't use FilterInputStream as the base class, we'd have to +// override markSupported(), mark(), and reset() to disable them +@NotThreadSafe +public class EofSensorInputStream extends InputStream implements ConnectionReleaseTrigger { + + /** + * The wrapped input stream, while accessible. + * The value changes to null when the wrapped stream + * becomes inaccessible. + */ + protected InputStream wrappedStream; + + /** + * Indicates whether this stream itself is closed. + * If it isn't, but {@link #wrappedStream wrappedStream} + * is null, we're running in EOF mode. + * All read operations will indicate EOF without accessing + * the underlying stream. After closing this stream, read + * operations will trigger an {@link IOException IOException}. + * + * @see #isReadAllowed isReadAllowed + */ + private boolean selfClosed; + + /** The watcher to be notified, if any. */ + private final EofSensorWatcher eofWatcher; + + /** + * Creates a new EOF sensor. + * If no watcher is passed, the underlying stream will simply be + * closed when EOF is detected or {@link #close close} is called. + * Otherwise, the watcher decides whether the underlying stream + * should be closed before detaching from it. + * + * @param in the wrapped stream + * @param watcher the watcher for events, or null for + * auto-close behavior without notification + */ + public EofSensorInputStream(final InputStream in, + final EofSensorWatcher watcher) { + if (in == null) { + throw new IllegalArgumentException + ("Wrapped stream may not be null."); + } + + wrappedStream = in; + selfClosed = false; + eofWatcher = watcher; + } + + /** + * Checks whether the underlying stream can be read from. + * + * @return true if the underlying stream is accessible, + * false if this stream is in EOF mode and + * detached from the underlying stream + * + * @throws IOException if this stream is already closed + */ + protected boolean isReadAllowed() throws IOException { + if (selfClosed) { + throw new IOException("Attempted read on closed stream."); + } + return (wrappedStream != null); + } + + @Override + public int read() throws IOException { + int l = -1; + + if (isReadAllowed()) { + try { + l = wrappedStream.read(); + checkEOF(l); + } catch (IOException ex) { + checkAbort(); + throw ex; + } + } + + return l; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + int l = -1; + + if (isReadAllowed()) { + try { + l = wrappedStream.read(b, off, len); + checkEOF(l); + } catch (IOException ex) { + checkAbort(); + throw ex; + } + } + + return l; + } + + @Override + public int read(byte[] b) throws IOException { + int l = -1; + + if (isReadAllowed()) { + try { + l = wrappedStream.read(b); + checkEOF(l); + } catch (IOException ex) { + checkAbort(); + throw ex; + } + } + return l; + } + + @Override + public int available() throws IOException { + int a = 0; // not -1 + + if (isReadAllowed()) { + try { + a = wrappedStream.available(); + // no checkEOF() here, available() can't trigger EOF + } catch (IOException ex) { + checkAbort(); + throw ex; + } + } + + return a; + } + + @Override + public void close() throws IOException { + // tolerate multiple calls to close() + selfClosed = true; + checkClose(); + } + + /** + * Detects EOF and notifies the watcher. + * This method should only be called while the underlying stream is + * still accessible. Use {@link #isReadAllowed isReadAllowed} to + * check that condition. + *
+ * If EOF is detected, the watcher will be notified and this stream + * is detached from the underlying stream. This prevents multiple + * notifications from this stream. + * + * @param eof the result of the calling read operation. + * A negative value indicates that EOF is reached. + * + * @throws IOException + * in case of an IO problem on closing the underlying stream + */ + protected void checkEOF(int eof) throws IOException { + + if ((wrappedStream != null) && (eof < 0)) { + try { + boolean scws = true; // should close wrapped stream? + if (eofWatcher != null) + scws = eofWatcher.eofDetected(wrappedStream); + if (scws) + wrappedStream.close(); + } finally { + wrappedStream = null; + } + } + } + + /** + * Detects stream close and notifies the watcher. + * There's not much to detect since this is called by {@link #close close}. + * The watcher will only be notified if this stream is closed + * for the first time and before EOF has been detected. + * This stream will be detached from the underlying stream to prevent + * multiple notifications to the watcher. + * + * @throws IOException + * in case of an IO problem on closing the underlying stream + */ + protected void checkClose() throws IOException { + + if (wrappedStream != null) { + try { + boolean scws = true; // should close wrapped stream? + if (eofWatcher != null) + scws = eofWatcher.streamClosed(wrappedStream); + if (scws) + wrappedStream.close(); + } finally { + wrappedStream = null; + } + } + } + + /** + * Detects stream abort and notifies the watcher. + * There's not much to detect since this is called by + * {@link #abortConnection abortConnection}. + * The watcher will only be notified if this stream is aborted + * for the first time and before EOF has been detected or the + * stream has been {@link #close closed} gracefully. + * This stream will be detached from the underlying stream to prevent + * multiple notifications to the watcher. + * + * @throws IOException + * in case of an IO problem on closing the underlying stream + */ + protected void checkAbort() throws IOException { + + if (wrappedStream != null) { + try { + boolean scws = true; // should close wrapped stream? + if (eofWatcher != null) + scws = eofWatcher.streamAbort(wrappedStream); + if (scws) + wrappedStream.close(); + } finally { + wrappedStream = null; + } + } + } + + /** + * Same as {@link #close close()}. + */ + public void releaseConnection() throws IOException { + close(); + } + + /** + * Aborts this stream. + * This is a special version of {@link #close close()} which prevents + * re-use of the underlying connection, if any. Calling this method + * indicates that there should be no attempt to read until the end of + * the stream. + */ + public void abortConnection() throws IOException { + // tolerate multiple calls + selfClosed = true; + checkAbort(); + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/conn/EofSensorWatcher.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/EofSensorWatcher.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/EofSensorWatcher.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,95 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.InputStream; +import java.io.IOException; + +/** + * A watcher for {@link EofSensorInputStream}. Each stream will notify its + * watcher at most once. + * + * @since 4.0 + */ +public interface EofSensorWatcher { + + /** + * Indicates that EOF is detected. + * + * @param wrapped the underlying stream which has reached EOF + * + * @return true if wrapped should be closed, + * false if it should be left alone + * + * @throws IOException + * in case of an IO problem, for example if the watcher itself + * closes the underlying stream. The caller will leave the + * wrapped stream alone, as if false was returned. + */ + boolean eofDetected(InputStream wrapped) + throws IOException; + + /** + * Indicates that the {@link EofSensorInputStream stream} is closed. + * This method will be called only if EOF was not detected + * before closing. Otherwise, {@link #eofDetected eofDetected} is called. + * + * @param wrapped the underlying stream which has not reached EOF + * + * @return true if wrapped should be closed, + * false if it should be left alone + * + * @throws IOException + * in case of an IO problem, for example if the watcher itself + * closes the underlying stream. The caller will leave the + * wrapped stream alone, as if false was returned. + */ + boolean streamClosed(InputStream wrapped) + throws IOException; + + /** + * Indicates that the {@link EofSensorInputStream stream} is aborted. + * This method will be called only if EOF was not detected + * before aborting. Otherwise, {@link #eofDetected eofDetected} is called. + *

+ * This method will also be invoked when an input operation causes an + * IOException to be thrown to make sure the input stream gets shut down. + * + * @param wrapped the underlying stream which has not reached EOF + * + * @return true if wrapped should be closed, + * false if it should be left alone + * + * @throws IOException + * in case of an IO problem, for example if the watcher itself + * closes the underlying stream. The caller will leave the + * wrapped stream alone, as if false was returned. + */ + boolean streamAbort(InputStream wrapped) + throws IOException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/HttpHostConnectException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/HttpHostConnectException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/HttpHostConnectException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,58 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.net.ConnectException; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.HttpHost; + +/** + * A {@link ConnectException} that specifies the {@link HttpHost} that was + * being connected to. + * + * @since 4.0 + */ +@Immutable +public class HttpHostConnectException extends ConnectException { + + private static final long serialVersionUID = -3194482710275220224L; + + private final HttpHost host; + + public HttpHostConnectException(final HttpHost host, final ConnectException cause) { + super("Connection to " + host + " refused"); + this.host = host; + initCause(cause); + } + + public HttpHost getHost() { + return this.host; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/HttpInetSocketAddress.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/HttpInetSocketAddress.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/HttpInetSocketAddress.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,63 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.net.InetAddress; +import java.net.InetSocketAddress; + +import org.apache.http.HttpHost; + +/** + * Extended {@link InetSocketAddress} implementation that also provides access to the original + * {@link HttpHost} used to resolve the address. + * + * @since 4.2 + */ +public class HttpInetSocketAddress extends InetSocketAddress { + + private static final long serialVersionUID = -6650701828361907957L; + + private final HttpHost httphost; + + public HttpInetSocketAddress(final HttpHost httphost, final InetAddress addr, int port) { + super(addr, port); + if (httphost == null) { + throw new IllegalArgumentException("HTTP host may not be null"); + } + this.httphost = httphost; + } + + public HttpHost getHttpHost() { + return this.httphost; + } + + @Override + public String toString() { + return this.httphost.getHostName() + ":" + getPort(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/HttpRoutedConnection.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/HttpRoutedConnection.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/HttpRoutedConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,78 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import javax.net.ssl.SSLSession; + +import org.apache.http.HttpInetConnection; +import org.apache.http.conn.routing.HttpRoute; + +/** + * Interface to access routing information of a client side connection. + * + * @since 4.1 + */ +public interface HttpRoutedConnection extends HttpInetConnection { + + /** + * Indicates whether this connection is secure. + * The return value is well-defined only while the connection is open. + * It may change even while the connection is open. + * + * @return true if this connection is secure, + * false otherwise + */ + boolean isSecure(); + + /** + * Obtains the current route of this connection. + * + * @return the route established so far, or + * null if not connected + */ + HttpRoute getRoute(); + + /** + * Obtains the SSL session of the underlying connection, if any. + * If this connection is open, and the underlying socket is an + * {@link javax.net.ssl.SSLSocket SSLSocket}, the SSL session of + * that socket is obtained. This is a potentially blocking operation. + *
+ * Note: Whether the underlying socket is an SSL socket + * can not necessarily be determined via {@link #isSecure}. + * Plain sockets may be considered secure, for example if they are + * connected to a known host in the same network segment. + * On the other hand, SSL sockets may be considered insecure, + * for example depending on the chosen cipher suite. + * + * @return the underlying SSL session if available, + * null otherwise + */ + SSLSession getSSLSession(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ManagedClientConnection.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ManagedClientConnection.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ManagedClientConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,226 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLSession; + +import org.apache.http.HttpClientConnection; +import org.apache.http.HttpHost; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; + +import org.apache.http.conn.routing.HttpRoute; + +/** + * A client-side connection with advanced connection logic. + * Instances are typically obtained from a connection manager. + * + * @since 4.0 + */ +public interface ManagedClientConnection extends + HttpClientConnection, HttpRoutedConnection, ConnectionReleaseTrigger { + + /** + * Indicates whether this connection is secure. + * The return value is well-defined only while the connection is open. + * It may change even while the connection is open. + * + * @return true if this connection is secure, + * false otherwise + */ + boolean isSecure(); + + /** + * Obtains the current route of this connection. + * + * @return the route established so far, or + * null if not connected + */ + HttpRoute getRoute(); + + /** + * Obtains the SSL session of the underlying connection, if any. + * If this connection is open, and the underlying socket is an + * {@link javax.net.ssl.SSLSocket SSLSocket}, the SSL session of + * that socket is obtained. This is a potentially blocking operation. + *
+ * Note: Whether the underlying socket is an SSL socket + * can not necessarily be determined via {@link #isSecure}. + * Plain sockets may be considered secure, for example if they are + * connected to a known host in the same network segment. + * On the other hand, SSL sockets may be considered insecure, + * for example depending on the chosen cipher suite. + * + * @return the underlying SSL session if available, + * null otherwise + */ + SSLSession getSSLSession(); + + /** + * Opens this connection according to the given route. + * + * @param route the route along which to open. It will be opened to + * the first proxy if present, or directly to the target. + * @param context the context for opening this connection + * @param params the parameters for opening this connection + * + * @throws IOException in case of a problem + */ + void open(HttpRoute route, HttpContext context, HttpParams params) + throws IOException; + + /** + * Indicates that a tunnel to the target has been established. + * The route is the one previously passed to {@link #open open}. + * Subsequently, {@link #layerProtocol layerProtocol} can be called + * to layer the TLS/SSL protocol on top of the tunnelled connection. + *
+ * Note: In HttpClient 3, a call to the corresponding method + * would automatically trigger the layering of the TLS/SSL protocol. + * This is not the case anymore, you can establish a tunnel without + * layering a new protocol over the connection. + * + * @param secure true if the tunnel should be considered + * secure, false otherwise + * @param params the parameters for tunnelling this connection + * + * @throws IOException in case of a problem + */ + void tunnelTarget(boolean secure, HttpParams params) + throws IOException; + + /** + * Indicates that a tunnel to an intermediate proxy has been established. + * This is used exclusively for so-called proxy chains, where + * a request has to pass through multiple proxies before reaching the + * target. In that case, all proxies but the last need to be tunnelled + * when establishing the connection. Tunnelling of the last proxy to the + * target is optional and would be indicated via {@link #tunnelTarget}. + * + * @param next the proxy to which the tunnel was established. + * This is not the proxy through which + * the tunnel was established, but the new end point + * of the tunnel. The tunnel does not yet + * reach to the target, use {@link #tunnelTarget} + * to indicate an end-to-end tunnel. + * @param secure true if the connection should be + * considered secure, false otherwise + * @param params the parameters for tunnelling this connection + * + * @throws IOException in case of a problem + */ + void tunnelProxy(HttpHost next, boolean secure, HttpParams params) + throws IOException; + + /** + * Layers a new protocol on top of a {@link #tunnelTarget tunnelled} + * connection. This is typically used to create a TLS/SSL connection + * through a proxy. + * The route is the one previously passed to {@link #open open}. + * It is not guaranteed that the layered connection is + * {@link #isSecure secure}. + * + * @param context the context for layering on top of this connection + * @param params the parameters for layering on top of this connection + * + * @throws IOException in case of a problem + */ + void layerProtocol(HttpContext context, HttpParams params) + throws IOException; + + /** + * Marks this connection as being in a reusable communication state. + * The checkpoints for reuseable communication states (in the absence + * of pipelining) are before sending a request and after receiving + * the response in its entirety. + * The connection will automatically clear the checkpoint when + * used for communication. A call to this method indicates that + * the next checkpoint has been reached. + *
+ * A reusable communication state is necessary but not sufficient + * for the connection to be reused. + * A {@link #getRoute route} mismatch, the connection being closed, + * or other circumstances might prevent reuse. + */ + void markReusable(); + + /** + * Marks this connection as not being in a reusable state. + * This can be used immediately before releasing this connection + * to prevent its reuse. Reasons for preventing reuse include + * error conditions and the evaluation of a + * {@link org.apache.http.ConnectionReuseStrategy reuse strategy}. + *
+ * Note: + * It is not necessary to call here before writing to + * or reading from this connection. Communication attempts will + * automatically unmark the state as non-reusable. It can then + * be switched back using {@link #markReusable markReusable}. + */ + void unmarkReusable(); + + /** + * Indicates whether this connection is in a reusable communication state. + * See {@link #markReusable markReusable} and + * {@link #unmarkReusable unmarkReusable} for details. + * + * @return true if this connection is marked as being in + * a reusable communication state, + * false otherwise + */ + boolean isMarkedReusable(); + + /** + * Assigns a state object to this connection. Connection managers may make + * use of the connection state when allocating persistent connections. + * + * @param state The state object + */ + void setState(Object state); + + /** + * Returns the state object associated with this connection. + * + * @return The state object + */ + Object getState(); + + /** + * Sets the duration that this connection can remain idle before it is + * reused. The connection should not be used again if this time elapses. The + * idle duration must be reset after each request sent over this connection. + * The elapsed time starts counting when the connection is released, which + * is typically after the headers (and any response body, if present) is + * fully consumed. + */ + void setIdleDuration(long duration, TimeUnit unit); + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/MultihomePlainSocketFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/MultihomePlainSocketFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/MultihomePlainSocketFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,193 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Arrays; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.conn.scheme.SchemeSocketFactory; +import org.apache.http.conn.scheme.SocketFactory; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +/** + * Socket factory that implements a simple multi-home fail-over on connect failure, + * provided the same hostname resolves to multiple {@link InetAddress}es. Please note + * the {@link #connectSocket(Socket, String, int, InetAddress, int, HttpParams)} + * method cannot be reliably interrupted by closing the socket returned by the + * {@link #createSocket()} method. + * + * @since 4.0 + * + * @deprecated (4.1) Do not use. For multihome support socket factories must implement + * {@link SchemeSocketFactory} interface. + */ +@Deprecated +@Immutable +public final class MultihomePlainSocketFactory implements SocketFactory { + + /** + * The factory singleton. + */ + private static final + MultihomePlainSocketFactory DEFAULT_FACTORY = new MultihomePlainSocketFactory(); + + /** + * Gets the singleton instance of this class. + * @return the one and only plain socket factory + */ + public static MultihomePlainSocketFactory getSocketFactory() { + return DEFAULT_FACTORY; + } + + /** + * Restricted default constructor. + */ + private MultihomePlainSocketFactory() { + super(); + } + + + // non-javadoc, see interface org.apache.http.conn.SocketFactory + public Socket createSocket() { + return new Socket(); + } + + /** + * Attempts to connects the socket to any of the {@link InetAddress}es the + * given host name resolves to. If connection to all addresses fail, the + * last I/O exception is propagated to the caller. + * + * @param sock socket to connect to any of the given addresses + * @param host Host name to connect to + * @param port the port to connect to + * @param localAddress local address + * @param localPort local port + * @param params HTTP parameters + * + * @throws IOException if an error occurs during the connection + * @throws SocketTimeoutException if timeout expires before connecting + */ + public Socket connectSocket(Socket sock, String host, int port, + InetAddress localAddress, int localPort, + HttpParams params) + throws IOException { + + if (host == null) { + throw new IllegalArgumentException("Target host may not be null."); + } + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null."); + } + + if (sock == null) + sock = createSocket(); + + if ((localAddress != null) || (localPort > 0)) { + + // we need to bind explicitly + if (localPort < 0) + localPort = 0; // indicates "any" + + InetSocketAddress isa = + new InetSocketAddress(localAddress, localPort); + sock.bind(isa); + } + + int timeout = HttpConnectionParams.getConnectionTimeout(params); + + InetAddress[] inetadrs = InetAddress.getAllByName(host); + List addresses = new ArrayList(inetadrs.length); + addresses.addAll(Arrays.asList(inetadrs)); + Collections.shuffle(addresses); + + IOException lastEx = null; + for (InetAddress remoteAddress: addresses) { + try { + sock.connect(new InetSocketAddress(remoteAddress, port), timeout); + break; + } catch (SocketTimeoutException ex) { + throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out"); + } catch (IOException ex) { + // create new socket + sock = new Socket(); + // keep the last exception and retry + lastEx = ex; + } + } + if (lastEx != null) { + throw lastEx; + } + return sock; + } // connectSocket + + + /** + * Checks whether a socket connection is secure. + * This factory creates plain socket connections + * which are not considered secure. + * + * @param sock the connected socket + * + * @return false + * + * @throws IllegalArgumentException if the argument is invalid + */ + public final boolean isSecure(Socket sock) + throws IllegalArgumentException { + + if (sock == null) { + throw new IllegalArgumentException("Socket may not be null."); + } + // This class check assumes that createSocket() calls the constructor + // directly. If it was using javax.net.SocketFactory, we couldn't make + // an assumption about the socket class here. + if (sock.getClass() != Socket.class) { + throw new IllegalArgumentException + ("Socket not created by this factory."); + } + // This check is performed last since it calls a method implemented + // by the argument object. getClass() is final in java.lang.Object. + if (sock.isClosed()) { + throw new IllegalArgumentException("Socket is closed."); + } + + return false; + + } // isSecure + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/OperatedClientConnection.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/OperatedClientConnection.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/OperatedClientConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,152 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn; + +import java.io.IOException; +import java.net.Socket; + +import org.apache.http.HttpClientConnection; +import org.apache.http.HttpHost; +import org.apache.http.HttpInetConnection; +import org.apache.http.params.HttpParams; + +/** + * A client-side connection that relies on outside logic to connect sockets to the + * appropriate hosts. It can be operated directly by an application, or through an + * {@link ClientConnectionOperator operator}. + * + * @since 4.0 + */ +public interface OperatedClientConnection extends HttpClientConnection, HttpInetConnection { + + /** + * Obtains the target host for this connection. + * If the connection is to a proxy but not tunnelled, this is + * the proxy. If the connection is tunnelled through a proxy, + * this is the target of the tunnel. + *
+ * The return value is well-defined only while the connection is open. + * It may change even while the connection is open, + * because of an {@link #update update}. + * + * @return the host to which this connection is opened + */ + HttpHost getTargetHost(); + + /** + * Indicates whether this connection is secure. + * The return value is well-defined only while the connection is open. + * It may change even while the connection is open, + * because of an {@link #update update}. + * + * @return true if this connection is secure, + * false otherwise + */ + boolean isSecure(); + + /** + * Obtains the socket for this connection. + * The return value is well-defined only while the connection is open. + * It may change even while the connection is open, + * because of an {@link #update update}. + * + * @return the socket for communicating with the + * {@link #getTargetHost target host} + */ + Socket getSocket(); + + /** + * Signals that this connection is in the process of being open. + *

+ * By calling this method, the connection can be re-initialized + * with a new Socket instance before {@link #openCompleted} is called. + * This enabled the connection to close that socket if + * {@link org.apache.http.HttpConnection#shutdown shutdown} + * is called before it is fully open. Closing an unconnected socket + * will interrupt a thread that is blocked on the connect. + * Otherwise, that thread will either time out on the connect, + * or it returns successfully and then opens this connection + * which was just shut down. + *

+ * This method can be called multiple times if the connection + * is layered over another protocol. Note: This method + * will not close the previously used socket. It is + * the caller's responsibility to close that socket if it is + * no longer required. + *

+ * The caller must invoke {@link #openCompleted} in order to complete + * the process. + * + * @param sock the unconnected socket which is about to + * be connected. + * @param target the target host of this connection + */ + void opening(Socket sock, HttpHost target) + throws IOException; + + /** + * Signals that the connection has been successfully open. + * An attempt to call this method on an open connection will cause + * an exception. + * + * @param secure true if this connection is secure, for + * example if an SSLSocket is used, or + * false if it is not secure + * @param params parameters for this connection. The parameters will + * be used when creating dependent objects, for example + * to determine buffer sizes. + */ + void openCompleted(boolean secure, HttpParams params) + throws IOException; + + /** + * Updates this connection. + * A connection can be updated only while it is open. + * Updates are used for example when a tunnel has been established, + * or when a TLS/SSL connection has been layered on top of a plain + * socket connection. + *
+ * Note: Updating the connection will not close the + * previously used socket. It is the caller's responsibility to close + * that socket if it is no longer required. + * + * @param sock the new socket for communicating with the target host, + * or null to continue using the old socket. + * If null is passed, helper objects that + * depend on the socket should be re-used. In that case, + * some changes in the parameters will not take effect. + * @param target the new target host of this connection + * @param secure true if this connection is now secure, + * false if it is not secure + * @param params new parameters for this connection + */ + void update(Socket sock, HttpHost target, + boolean secure, HttpParams params) + throws IOException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,80 @@ + + + + + +The client-side connection management and handling API that provides interfaces +and implementations for opening and managing client side HTTP connections. +

+The lowest layer of connection handling is comprised of +{@link org.apache.http.conn.OperatedClientConnection OperatedClientConnection} +and +{@link org.apache.http.conn.ClientConnectionOperator ClientConnectionOperator}. +The connection interface extends the core +{@link org.apache.http.HttpClientConnection HttpClientConnection} +by operations to set and update a socket. An operator encapsulates the logic to +open and layer sockets, typically using a +{@link org.apache.http.conn.scheme.SocketFactory}. The socket factory for +a protocol {@link org.apache.http.conn.scheme.Scheme} such as "http" or "https" +can be looked up in a {@link org.apache.http.conn.scheme.SchemeRegistry}. +Applications without a need for sophisticated connection management can use +this layer directly. +

+

+On top of that lies the connection management layer. A +{@link org.apache.http.conn.ClientConnectionManager} internally manages +operated connections, but hands out instances of +{@link org.apache.http.conn.ManagedClientConnection}. +This interface abstracts from the underlying socket operations and +provides convenient methods for opening and updating sockets in order +to establish a {@link org.apache.http.conn.routing.HttpRoute route}. +The operator is encapsulated by the connection manager and called +automatically. +

+

+Connections obtained from a manager have to be returned after use. +This can be {@link org.apache.http.conn.ConnectionReleaseTrigger triggered} +on various levels, either by releasing the +{@link org.apache.http.conn.ManagedClientConnection connection} directly, +or by calling a method on +an {@link org.apache.http.conn.BasicManagedEntity entity} received from +the connection, or by closing the +{@link org.apache.http.conn.EofSensorInputStream stream} from which +that entity is being read. +

+

+Connection managers will try to keep returned connections alive in +order to re-use them for subsequent requests along the same route. +The managed connection interface and all triggers for connection release +provide methods to enable or disable this behavior. +

+ + + Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnConnectionPNames.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnConnectionPNames.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnConnectionPNames.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,61 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.params; + +import org.apache.http.impl.conn.DefaultHttpResponseParser; + +/** + * Parameter names for HTTP client connections. + * + * @since 4.0 + */ +@Deprecated +public interface ConnConnectionPNames { + + /** + * Defines the maximum number of ignorable lines before we expect + * a HTTP response's status line. + *

+ * With HTTP/1.1 persistent connections, the problem arises that + * broken scripts could return a wrong Content-Length + * (there are more bytes sent than specified). + * Unfortunately, in some cases, this cannot be detected after the + * bad response, but only before the next one. + * So HttpClient must be able to skip those surplus lines this way. + *

+ *

+ * This parameter expects a value of type {@link Integer}. + * 0 disallows all garbage/empty lines before the status line. + * Use {@link java.lang.Integer#MAX_VALUE} for unlimited number. + *

+ * + * @deprecated Use custom {@link DefaultHttpResponseParser} implementation + */ + public static final String MAX_STATUS_LINE_GARBAGE = "http.connection.max-status-line-garbage"; + + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnConnectionParamBean.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnConnectionParamBean.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnConnectionParamBean.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,57 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.params; + +import org.apache.http.impl.conn.DefaultHttpResponseParser; +import org.apache.http.params.HttpAbstractParamBean; +import org.apache.http.params.HttpParams; + +/** + * This is a Java Bean class that can be used to wrap an instance of + * {@link HttpParams} and manipulate HTTP client connection parameters + * using Java Beans conventions. + * + * @since 4.0 + * + * @deprecated (4.2) do not use + */ +@Deprecated +public class ConnConnectionParamBean extends HttpAbstractParamBean { + + public ConnConnectionParamBean (final HttpParams params) { + super(params); + } + + /** + * @deprecated (4.2) Use custom {@link DefaultHttpResponseParser} implementation + */ + public void setMaxStatusLineGarbage (final int maxStatusLineGarbage) { + params.setIntParameter(ConnConnectionPNames.MAX_STATUS_LINE_GARBAGE, maxStatusLineGarbage); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnManagerPNames.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnManagerPNames.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnManagerPNames.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.params; + +/** + * Parameter names for connection managers in HttpConn. + * + * @since 4.0 + * + * @deprecated (4.1.2) use configuration methods of the specific connection manager implementation. +*/ +@Deprecated +public interface ConnManagerPNames { + + /** + * Defines the timeout in milliseconds used when retrieving an instance of + * {@link org.apache.http.conn.ManagedClientConnection} from the + * {@link org.apache.http.conn.ClientConnectionManager}. + *

+ * This parameter expects a value of type {@link Long}. + */ + public static final String TIMEOUT = "http.conn-manager.timeout"; + + /** + * Defines the maximum number of connections per route. + * This limit is interpreted by client connection managers + * and applies to individual manager instances. + *

+ * This parameter expects a value of type {@link ConnPerRoute}. + *

+ */ + public static final String MAX_CONNECTIONS_PER_ROUTE = "http.conn-manager.max-per-route"; + + /** + * Defines the maximum number of connections in total. + * This limit is interpreted by client connection managers + * and applies to individual manager instances. + *

+ * This parameter expects a value of type {@link Integer}. + */ + public static final String MAX_TOTAL_CONNECTIONS = "http.conn-manager.max-total"; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnManagerParamBean.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnManagerParamBean.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnManagerParamBean.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,64 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.params; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.params.HttpAbstractParamBean; +import org.apache.http.params.HttpParams; + +/** + * This is a Java Bean class that can be used to wrap an instance of + * {@link HttpParams} and manipulate connection manager parameters + * using Java Beans conventions. + * + * @since 4.0 + * + * @deprecated (4.1.2) use configuration methods of the specific connection manager implementation. + */ +@NotThreadSafe +@Deprecated +public class ConnManagerParamBean extends HttpAbstractParamBean { + + public ConnManagerParamBean (final HttpParams params) { + super(params); + } + + public void setTimeout (final long timeout) { + params.setLongParameter(ConnManagerPNames.TIMEOUT, timeout); + } + + public void setMaxTotalConnections (final int maxConnections) { + params.setIntParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, maxConnections); + } + + public void setConnectionsPerRoute(final ConnPerRouteBean connPerRoute) { + params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, connPerRoute); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnManagerParams.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnManagerParams.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnManagerParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,160 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.params; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +/** + * An adaptor for manipulating HTTP connection management + * parameters in {@link HttpParams}. + * + * @since 4.0 + * + * @see ConnManagerPNames + * + * @deprecated (4.1.2) use configuration methods of the specific connection manager implementation. + */ +@Deprecated +@Immutable +public final class ConnManagerParams implements ConnManagerPNames { + + /** The default maximum number of connections allowed overall */ + public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 20; + + /** + * Returns the timeout in milliseconds used when retrieving a + * {@link org.apache.http.conn.ManagedClientConnection} from the + * {@link org.apache.http.conn.ClientConnectionManager}. + * + * @return timeout in milliseconds. + * + * @deprecated (4.1) use {@link HttpConnectionParams#getConnectionTimeout(HttpParams)} + */ + public static long getTimeout(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getLongParameter(TIMEOUT, 0); + } + + /** + * Sets the timeout in milliseconds used when retrieving a + * {@link org.apache.http.conn.ManagedClientConnection} from the + * {@link org.apache.http.conn.ClientConnectionManager}. + * + * @param timeout the timeout in milliseconds + * + * @deprecated (4.1) use {@link HttpConnectionParams#setConnectionTimeout(HttpParams, int)} + */ + public static void setTimeout(final HttpParams params, long timeout) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setLongParameter(TIMEOUT, timeout); + } + + /** The default maximum number of connections allowed per host */ + private static final ConnPerRoute DEFAULT_CONN_PER_ROUTE = new ConnPerRoute() { + + public int getMaxForRoute(HttpRoute route) { + return ConnPerRouteBean.DEFAULT_MAX_CONNECTIONS_PER_ROUTE; + } + + }; + + /** + * Sets lookup interface for maximum number of connections allowed per route. + * + * @param params HTTP parameters + * @param connPerRoute lookup interface for maximum number of connections allowed + * per route + */ + public static void setMaxConnectionsPerRoute(final HttpParams params, + final ConnPerRoute connPerRoute) { + if (params == null) { + throw new IllegalArgumentException + ("HTTP parameters must not be null."); + } + params.setParameter(MAX_CONNECTIONS_PER_ROUTE, connPerRoute); + } + + /** + * Returns lookup interface for maximum number of connections allowed per route. + * + * @param params HTTP parameters + * + * @return lookup interface for maximum number of connections allowed per route. + */ + public static ConnPerRoute getMaxConnectionsPerRoute(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException + ("HTTP parameters must not be null."); + } + ConnPerRoute connPerRoute = (ConnPerRoute) params.getParameter(MAX_CONNECTIONS_PER_ROUTE); + if (connPerRoute == null) { + connPerRoute = DEFAULT_CONN_PER_ROUTE; + } + return connPerRoute; + } + + /** + * Sets the maximum number of connections allowed. + * + * @param params HTTP parameters + * @param maxTotalConnections The maximum number of connections allowed. + */ + public static void setMaxTotalConnections( + final HttpParams params, + int maxTotalConnections) { + if (params == null) { + throw new IllegalArgumentException + ("HTTP parameters must not be null."); + } + params.setIntParameter(MAX_TOTAL_CONNECTIONS, maxTotalConnections); + } + + /** + * Gets the maximum number of connections allowed. + * + * @param params HTTP parameters + * + * @return The maximum number of connections allowed. + */ + public static int getMaxTotalConnections( + final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException + ("HTTP parameters must not be null."); + } + return params.getIntParameter(MAX_TOTAL_CONNECTIONS, DEFAULT_MAX_TOTAL_CONNECTIONS); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnPerRoute.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnPerRoute.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnPerRoute.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,43 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.params; + +import org.apache.http.conn.routing.HttpRoute; + +/** + * This interface is intended for looking up maximum number of connections + * allowed for a given route. This class can be used by pooling + * {@link org.apache.http.conn.ClientConnectionManager connection managers} for + * a fine-grained control of connections on a per route basis. + * + * @since 4.0 + */ +public interface ConnPerRoute { + + int getMaxForRoute(HttpRoute route); + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnPerRouteBean.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnPerRouteBean.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnPerRouteBean.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,125 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.params; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.http.annotation.ThreadSafe; + +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.pool.ConnPoolControl; + +/** + * This class maintains a map of HTTP routes to maximum number of connections allowed + * for those routes. This class can be used by pooling + * {@link org.apache.http.conn.ClientConnectionManager connection managers} for + * a fine-grained control of connections on a per route basis. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link ConnPoolControl} + */ +@Deprecated +@ThreadSafe +public final class ConnPerRouteBean implements ConnPerRoute { + + /** The default maximum number of connections allowed per host */ + public static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 2; // Per RFC 2616 sec 8.1.4 + + private final ConcurrentHashMap maxPerHostMap; + + private volatile int defaultMax; + + public ConnPerRouteBean(int defaultMax) { + super(); + this.maxPerHostMap = new ConcurrentHashMap(); + setDefaultMaxPerRoute(defaultMax); + } + + public ConnPerRouteBean() { + this(DEFAULT_MAX_CONNECTIONS_PER_ROUTE); + } + + public int getDefaultMax() { + return this.defaultMax; + } + + /** + * @since 4.1 + */ + public int getDefaultMaxPerRoute() { + return this.defaultMax; + } + + public void setDefaultMaxPerRoute(int max) { + if (max < 1) { + throw new IllegalArgumentException + ("The maximum must be greater than 0."); + } + this.defaultMax = max; + } + + public void setMaxForRoute(final HttpRoute route, int max) { + if (route == null) { + throw new IllegalArgumentException + ("HTTP route may not be null."); + } + if (max < 1) { + throw new IllegalArgumentException + ("The maximum must be greater than 0."); + } + this.maxPerHostMap.put(route, Integer.valueOf(max)); + } + + public int getMaxForRoute(final HttpRoute route) { + if (route == null) { + throw new IllegalArgumentException + ("HTTP route may not be null."); + } + Integer max = this.maxPerHostMap.get(route); + if (max != null) { + return max.intValue(); + } else { + return this.defaultMax; + } + } + + public void setMaxForRoutes(final Map map) { + if (map == null) { + return; + } + this.maxPerHostMap.clear(); + this.maxPerHostMap.putAll(map); + } + + @Override + public String toString() { + return this.maxPerHostMap.toString(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnRoutePNames.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnRoutePNames.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnRoutePNames.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,76 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.params; + +/** + * Parameter names for connection routing. + * + * @since 4.0 + */ +public interface ConnRoutePNames { + + /** + * Parameter for the default proxy. + * The default value will be used by some + * {@link org.apache.http.conn.routing.HttpRoutePlanner HttpRoutePlanner} + * implementations, in particular the default implementation. + *

+ * This parameter expects a value of type {@link org.apache.http.HttpHost}. + *

+ */ + public static final String DEFAULT_PROXY = "http.route.default-proxy"; + + /** + * Parameter for the local address. + * On machines with multiple network interfaces, this parameter + * can be used to select the network interface from which the + * connection originates. + * It will be interpreted by the standard + * {@link org.apache.http.conn.routing.HttpRoutePlanner HttpRoutePlanner} + * implementations, in particular the default implementation. + *

+ * This parameter expects a value of type {@link java.net.InetAddress}. + *

+ */ + public static final String LOCAL_ADDRESS = "http.route.local-address"; + + /** + * Parameter for an forced route. + * The forced route will be interpreted by the standard + * {@link org.apache.http.conn.routing.HttpRoutePlanner HttpRoutePlanner} + * implementations. + * Instead of computing a route, the given forced route will be + * returned, even if it points to the wrong target host. + *

+ * This parameter expects a value of type + * {@link org.apache.http.conn.routing.HttpRoute HttpRoute}. + *

+ */ + public static final String FORCED_ROUTE = "http.route.forced-route"; + +} + Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnRouteParamBean.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnRouteParamBean.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnRouteParamBean.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,68 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.params; + +import java.net.InetAddress; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.HttpHost; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.params.HttpAbstractParamBean; +import org.apache.http.params.HttpParams; + +/** + * This is a Java Bean class that can be used to wrap an instance of + * {@link HttpParams} and manipulate connection routing parameters + * using Java Beans conventions. + * + * @since 4.0 + */ +@NotThreadSafe +public class ConnRouteParamBean extends HttpAbstractParamBean { + + public ConnRouteParamBean (final HttpParams params) { + super(params); + } + + /** @see ConnRoutePNames#DEFAULT_PROXY */ + public void setDefaultProxy (final HttpHost defaultProxy) { + params.setParameter(ConnRoutePNames.DEFAULT_PROXY, defaultProxy); + } + + /** @see ConnRoutePNames#LOCAL_ADDRESS */ + public void setLocalAddress (final InetAddress address) { + params.setParameter(ConnRoutePNames.LOCAL_ADDRESS, address); + } + + /** @see ConnRoutePNames#FORCED_ROUTE */ + public void setForcedRoute (final HttpRoute route) { + params.setParameter(ConnRoutePNames.FORCED_ROUTE, route); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnRouteParams.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnRouteParams.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/ConnRouteParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,187 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.params; + +import java.net.InetAddress; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.HttpHost; +import org.apache.http.params.HttpParams; +import org.apache.http.conn.routing.HttpRoute; + +/** + * An adaptor for manipulating HTTP routing parameters + * in {@link HttpParams}. + * + * @since 4.0 + */ +@Immutable +public class ConnRouteParams implements ConnRoutePNames { + + /** + * A special value indicating "no host". + * This relies on a nonsense scheme name to avoid conflicts + * with actual hosts. Note that this is a valid host. + */ + public static final HttpHost NO_HOST = + new HttpHost("127.0.0.255", 0, "no-host"); // Immutable + + /** + * A special value indicating "no route". + * This is a route with {@link #NO_HOST} as the target. + */ + public static final HttpRoute NO_ROUTE = new HttpRoute(NO_HOST); // Immutable + + /** Disabled default constructor. */ + private ConnRouteParams() { + // no body + } + + /** + * Obtains the {@link ConnRoutePNames#DEFAULT_PROXY DEFAULT_PROXY} + * parameter value. + * {@link #NO_HOST} will be mapped to null, + * to allow unsetting in a hierarchy. + * + * @param params the parameters in which to look up + * + * @return the default proxy set in the argument parameters, or + * null if not set + */ + public static HttpHost getDefaultProxy(HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("Parameters must not be null."); + } + HttpHost proxy = (HttpHost) + params.getParameter(DEFAULT_PROXY); + if ((proxy != null) && NO_HOST.equals(proxy)) { + // value is explicitly unset + proxy = null; + } + return proxy; + } + + /** + * Sets the {@link ConnRoutePNames#DEFAULT_PROXY DEFAULT_PROXY} + * parameter value. + * + * @param params the parameters in which to set the value + * @param proxy the value to set, may be null. + * Note that {@link #NO_HOST} will be mapped to + * null by {@link #getDefaultProxy}, + * to allow for explicit unsetting in hierarchies. + */ + public static void setDefaultProxy(HttpParams params, + HttpHost proxy) { + if (params == null) { + throw new IllegalArgumentException("Parameters must not be null."); + } + params.setParameter(DEFAULT_PROXY, proxy); + } + + /** + * Obtains the {@link ConnRoutePNames#FORCED_ROUTE FORCED_ROUTE} + * parameter value. + * {@link #NO_ROUTE} will be mapped to null, + * to allow unsetting in a hierarchy. + * + * @param params the parameters in which to look up + * + * @return the forced route set in the argument parameters, or + * null if not set + */ + public static HttpRoute getForcedRoute(HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("Parameters must not be null."); + } + HttpRoute route = (HttpRoute) + params.getParameter(FORCED_ROUTE); + if ((route != null) && NO_ROUTE.equals(route)) { + // value is explicitly unset + route = null; + } + return route; + } + + /** + * Sets the {@link ConnRoutePNames#FORCED_ROUTE FORCED_ROUTE} + * parameter value. + * + * @param params the parameters in which to set the value + * @param route the value to set, may be null. + * Note that {@link #NO_ROUTE} will be mapped to + * null by {@link #getForcedRoute}, + * to allow for explicit unsetting in hierarchies. + */ + public static void setForcedRoute(HttpParams params, + HttpRoute route) { + if (params == null) { + throw new IllegalArgumentException("Parameters must not be null."); + } + params.setParameter(FORCED_ROUTE, route); + } + + /** + * Obtains the {@link ConnRoutePNames#LOCAL_ADDRESS LOCAL_ADDRESS} + * parameter value. + * There is no special value that would automatically be mapped to + * null. You can use the wildcard address (0.0.0.0 for IPv4, + * :: for IPv6) to override a specific local address in a hierarchy. + * + * @param params the parameters in which to look up + * + * @return the local address set in the argument parameters, or + * null if not set + */ + public static InetAddress getLocalAddress(HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("Parameters must not be null."); + } + InetAddress local = (InetAddress) + params.getParameter(LOCAL_ADDRESS); + // no explicit unsetting + return local; + } + + /** + * Sets the {@link ConnRoutePNames#LOCAL_ADDRESS LOCAL_ADDRESS} + * parameter value. + * + * @param params the parameters in which to set the value + * @param local the value to set, may be null + */ + public static void setLocalAddress(HttpParams params, + InetAddress local) { + if (params == null) { + throw new IllegalArgumentException("Parameters must not be null."); + } + params.setParameter(LOCAL_ADDRESS, local); + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/conn/params/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/params/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/params/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Parameters for configuring HTTP connection and connection management +related classes. + + Index: 3rdParty_sources/httpclient/org/apache/http/conn/routing/BasicRouteDirector.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/routing/BasicRouteDirector.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/routing/BasicRouteDirector.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,168 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.routing; + +import org.apache.http.annotation.Immutable; + +/** + * Basic implementation of an {@link HttpRouteDirector HttpRouteDirector}. + * This implementation is stateless and therefore thread-safe. + * + * @since 4.0 + */ +@Immutable +public class BasicRouteDirector implements HttpRouteDirector { + + /** + * Provides the next step. + * + * @param plan the planned route + * @param fact the currently established route, or + * null if nothing is established + * + * @return one of the constants defined in this class, indicating + * either the next step to perform, or success, or failure. + * 0 is for success, a negative value for failure. + */ + public int nextStep(RouteInfo plan, RouteInfo fact) { + if (plan == null) { + throw new IllegalArgumentException + ("Planned route may not be null."); + } + + int step = UNREACHABLE; + + if ((fact == null) || (fact.getHopCount() < 1)) + step = firstStep(plan); + else if (plan.getHopCount() > 1) + step = proxiedStep(plan, fact); + else + step = directStep(plan, fact); + + return step; + + } // nextStep + + + /** + * Determines the first step to establish a route. + * + * @param plan the planned route + * + * @return the first step + */ + protected int firstStep(RouteInfo plan) { + + return (plan.getHopCount() > 1) ? + CONNECT_PROXY : CONNECT_TARGET; + } + + + /** + * Determines the next step to establish a direct connection. + * + * @param plan the planned route + * @param fact the currently established route + * + * @return one of the constants defined in this class, indicating + * either the next step to perform, or success, or failure + */ + protected int directStep(RouteInfo plan, RouteInfo fact) { + + if (fact.getHopCount() > 1) + return UNREACHABLE; + if (!plan.getTargetHost().equals(fact.getTargetHost())) + return UNREACHABLE; + // If the security is too low, we could now suggest to layer + // a secure protocol on the direct connection. Layering on direct + // connections has not been supported in HttpClient 3.x, we don't + // consider it here until there is a real-life use case for it. + + // Should we tolerate if security is better than planned? + // (plan.isSecure() && !fact.isSecure()) + if (plan.isSecure() != fact.isSecure()) + return UNREACHABLE; + + // Local address has to match only if the plan specifies one. + if ((plan.getLocalAddress() != null) && + !plan.getLocalAddress().equals(fact.getLocalAddress()) + ) + return UNREACHABLE; + + return COMPLETE; + } + + + /** + * Determines the next step to establish a connection via proxy. + * + * @param plan the planned route + * @param fact the currently established route + * + * @return one of the constants defined in this class, indicating + * either the next step to perform, or success, or failure + */ + protected int proxiedStep(RouteInfo plan, RouteInfo fact) { + + if (fact.getHopCount() <= 1) + return UNREACHABLE; + if (!plan.getTargetHost().equals(fact.getTargetHost())) + return UNREACHABLE; + final int phc = plan.getHopCount(); + final int fhc = fact.getHopCount(); + if (phc < fhc) + return UNREACHABLE; + + for (int i=0; i fhc) + return TUNNEL_PROXY; // need to extend the proxy chain + + // proxy chain and target are the same, check tunnelling and layering + if ((fact.isTunnelled() && !plan.isTunnelled()) || + (fact.isLayered() && !plan.isLayered())) + return UNREACHABLE; + + if (plan.isTunnelled() && !fact.isTunnelled()) + return TUNNEL_TARGET; + if (plan.isLayered() && !fact.isLayered()) + return LAYER_PROTOCOL; + + // tunnel and layering are the same, remains to check the security + // Should we tolerate if security is better than planned? + // (plan.isSecure() && !fact.isSecure()) + if (plan.isSecure() != fact.isSecure()) + return UNREACHABLE; + + return COMPLETE; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/routing/HttpRoute.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/routing/HttpRoute.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/routing/HttpRoute.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,406 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.routing; + +import java.net.InetAddress; + +import org.apache.http.annotation.Immutable; +import org.apache.http.util.LangUtils; + +import org.apache.http.HttpHost; + +/** + * The route for a request. + * Instances of this class are unmodifiable and therefore suitable + * for use as lookup keys. + * + * @since 4.0 + */ +@Immutable +public final class HttpRoute implements RouteInfo, Cloneable { + + private static final HttpHost[] EMPTY_HTTP_HOST_ARRAY = new HttpHost[]{}; + + /** The target host to connect to. */ + private final HttpHost targetHost; + + /** + * The local address to connect from. + * null indicates that the default should be used. + */ + private final InetAddress localAddress; + + /** The proxy servers, if any. Never null. */ + private final HttpHost[] proxyChain; + + /** Whether the the route is tunnelled through the proxy. */ + private final TunnelType tunnelled; + + /** Whether the route is layered. */ + private final LayerType layered; + + /** Whether the route is (supposed to be) secure. */ + private final boolean secure; + + + /** + * Internal, fully-specified constructor. + * This constructor does not clone the proxy chain array, + * nor test it for null elements. This conversion and + * check is the responsibility of the public constructors. + * The order of arguments here is different from the similar public + * constructor, as required by Java. + * + * @param local the local address to route from, or + * null for the default + * @param target the host to which to route + * @param proxies the proxy chain to use, or + * null for a direct route + * @param secure true if the route is (to be) secure, + * false otherwise + * @param tunnelled the tunnel type of this route, or + * null for PLAIN + * @param layered the layering type of this route, or + * null for PLAIN + */ + private HttpRoute(InetAddress local, + HttpHost target, HttpHost[] proxies, + boolean secure, + TunnelType tunnelled, LayerType layered) { + if (target == null) { + throw new IllegalArgumentException + ("Target host may not be null."); + } + if (proxies == null) { + throw new IllegalArgumentException + ("Proxies may not be null."); + } + if ((tunnelled == TunnelType.TUNNELLED) && (proxies.length == 0)) { + throw new IllegalArgumentException + ("Proxy required if tunnelled."); + } + + // tunnelled is already checked above, that is in line with the default + if (tunnelled == null) + tunnelled = TunnelType.PLAIN; + if (layered == null) + layered = LayerType.PLAIN; + + this.targetHost = target; + this.localAddress = local; + this.proxyChain = proxies; + this.secure = secure; + this.tunnelled = tunnelled; + this.layered = layered; + } + + + /** + * Creates a new route with all attributes specified explicitly. + * + * @param target the host to which to route + * @param local the local address to route from, or + * null for the default + * @param proxies the proxy chain to use, or + * null for a direct route + * @param secure true if the route is (to be) secure, + * false otherwise + * @param tunnelled the tunnel type of this route + * @param layered the layering type of this route + */ + public HttpRoute(HttpHost target, InetAddress local, HttpHost[] proxies, + boolean secure, TunnelType tunnelled, LayerType layered) { + this(local, target, toChain(proxies), secure, tunnelled, layered); + } + + + /** + * Creates a new route with at most one proxy. + * + * @param target the host to which to route + * @param local the local address to route from, or + * null for the default + * @param proxy the proxy to use, or + * null for a direct route + * @param secure true if the route is (to be) secure, + * false otherwise + * @param tunnelled true if the route is (to be) tunnelled + * via the proxy, + * false otherwise + * @param layered true if the route includes a + * layered protocol, + * false otherwise + */ + public HttpRoute(HttpHost target, InetAddress local, HttpHost proxy, + boolean secure, TunnelType tunnelled, LayerType layered) { + this(local, target, toChain(proxy), secure, tunnelled, layered); + } + + + /** + * Creates a new direct route. + * That is a route without a proxy. + * + * @param target the host to which to route + * @param local the local address to route from, or + * null for the default + * @param secure true if the route is (to be) secure, + * false otherwise + */ + public HttpRoute(HttpHost target, InetAddress local, boolean secure) { + this(local, target, EMPTY_HTTP_HOST_ARRAY, secure, TunnelType.PLAIN, LayerType.PLAIN); + } + + + /** + * Creates a new direct insecure route. + * + * @param target the host to which to route + */ + public HttpRoute(HttpHost target) { + this(null, target, EMPTY_HTTP_HOST_ARRAY, false, TunnelType.PLAIN, LayerType.PLAIN); + } + + + /** + * Creates a new route through a proxy. + * When using this constructor, the proxy MUST be given. + * For convenience, it is assumed that a secure connection will be + * layered over a tunnel through the proxy. + * + * @param target the host to which to route + * @param local the local address to route from, or + * null for the default + * @param proxy the proxy to use + * @param secure true if the route is (to be) secure, + * false otherwise + */ + public HttpRoute(HttpHost target, InetAddress local, HttpHost proxy, + boolean secure) { + this(local, target, toChain(proxy), secure, + secure ? TunnelType.TUNNELLED : TunnelType.PLAIN, + secure ? LayerType.LAYERED : LayerType.PLAIN); + if (proxy == null) { + throw new IllegalArgumentException + ("Proxy host may not be null."); + } + } + + + /** + * Helper to convert a proxy to a proxy chain. + * + * @param proxy the only proxy in the chain, or null + * + * @return a proxy chain array, may be empty (never null) + */ + private static HttpHost[] toChain(HttpHost proxy) { + if (proxy == null) + return EMPTY_HTTP_HOST_ARRAY; + + return new HttpHost[]{ proxy }; + } + + + /** + * Helper to duplicate and check a proxy chain. + * null is converted to an empty proxy chain. + * + * @param proxies the proxy chain to duplicate, or null + * + * @return a new proxy chain array, may be empty (never null) + */ + private static HttpHost[] toChain(HttpHost[] proxies) { + if ((proxies == null) || (proxies.length < 1)) + return EMPTY_HTTP_HOST_ARRAY; + + for (HttpHost proxy : proxies) { + if (proxy == null) + throw new IllegalArgumentException + ("Proxy chain may not contain null elements."); + } + + // copy the proxy chain, the traditional way + HttpHost[] result = new HttpHost[proxies.length]; + System.arraycopy(proxies, 0, result, 0, proxies.length); + + return result; + } + + + + // non-JavaDoc, see interface RouteInfo + public final HttpHost getTargetHost() { + return this.targetHost; + } + + + // non-JavaDoc, see interface RouteInfo + public final InetAddress getLocalAddress() { + return this.localAddress; + } + + + public final int getHopCount() { + return proxyChain.length+1; + } + + + public final HttpHost getHopTarget(int hop) { + if (hop < 0) + throw new IllegalArgumentException + ("Hop index must not be negative: " + hop); + final int hopcount = getHopCount(); + if (hop >= hopcount) + throw new IllegalArgumentException + ("Hop index " + hop + + " exceeds route length " + hopcount); + + HttpHost result = null; + if (hop < hopcount-1) + result = this.proxyChain[hop]; + else + result = this.targetHost; + + return result; + } + + + public final HttpHost getProxyHost() { + return (this.proxyChain.length == 0) ? null : this.proxyChain[0]; + } + + + public final TunnelType getTunnelType() { + return this.tunnelled; + } + + + public final boolean isTunnelled() { + return (this.tunnelled == TunnelType.TUNNELLED); + } + + + public final LayerType getLayerType() { + return this.layered; + } + + + public final boolean isLayered() { + return (this.layered == LayerType.LAYERED); + } + + + public final boolean isSecure() { + return this.secure; + } + + + /** + * Compares this route to another. + * + * @param obj the object to compare with + * + * @return true if the argument is the same route, + * false + */ + @Override + public final boolean equals(Object obj) { + if (this == obj) return true; + if (obj instanceof HttpRoute) { + HttpRoute that = (HttpRoute) obj; + return + // Do the cheapest tests first + (this.secure == that.secure) && + (this.tunnelled == that.tunnelled) && + (this.layered == that.layered) && + LangUtils.equals(this.targetHost, that.targetHost) && + LangUtils.equals(this.localAddress, that.localAddress) && + LangUtils.equals(this.proxyChain, that.proxyChain); + } else { + return false; + } + } + + + /** + * Generates a hash code for this route. + * + * @return the hash code + */ + @Override + public final int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.targetHost); + hash = LangUtils.hashCode(hash, this.localAddress); + for (int i = 0; i < this.proxyChain.length; i++) { + hash = LangUtils.hashCode(hash, this.proxyChain[i]); + } + hash = LangUtils.hashCode(hash, this.secure); + hash = LangUtils.hashCode(hash, this.tunnelled); + hash = LangUtils.hashCode(hash, this.layered); + return hash; + } + + + /** + * Obtains a description of this route. + * + * @return a human-readable representation of this route + */ + @Override + public final String toString() { + StringBuilder cab = new StringBuilder(50 + getHopCount()*30); + if (this.localAddress != null) { + cab.append(this.localAddress); + cab.append("->"); + } + cab.append('{'); + if (this.tunnelled == TunnelType.TUNNELLED) + cab.append('t'); + if (this.layered == LayerType.LAYERED) + cab.append('l'); + if (this.secure) + cab.append('s'); + cab.append("}->"); + for (HttpHost aProxyChain : this.proxyChain) { + cab.append(aProxyChain); + cab.append("->"); + } + cab.append(this.targetHost); + return cab.toString(); + } + + + // default implementation of clone() is sufficient + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/routing/HttpRouteDirector.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/routing/HttpRouteDirector.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/routing/HttpRouteDirector.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.routing; + +/** + * Provides directions on establishing a route. + * Implementations of this interface compare a planned route with + * a tracked route and indicate the next step required. + * + * @since 4.0 + */ +public interface HttpRouteDirector { + + /** Indicates that the route can not be established at all. */ + public final static int UNREACHABLE = -1; + + /** Indicates that the route is complete. */ + public final static int COMPLETE = 0; + + /** Step: open connection to target. */ + public final static int CONNECT_TARGET = 1; + + /** Step: open connection to proxy. */ + public final static int CONNECT_PROXY = 2; + + /** Step: tunnel through proxy to target. */ + public final static int TUNNEL_TARGET = 3; + + /** Step: tunnel through proxy to other proxy. */ + public final static int TUNNEL_PROXY = 4; + + /** Step: layer protocol (over tunnel). */ + public final static int LAYER_PROTOCOL = 5; + + + /** + * Provides the next step. + * + * @param plan the planned route + * @param fact the currently established route, or + * null if nothing is established + * + * @return one of the constants defined in this interface, indicating + * either the next step to perform, or success, or failure. + * 0 is for success, a negative value for failure. + */ + public int nextStep(RouteInfo plan, RouteInfo fact); + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/routing/HttpRoutePlanner.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/routing/HttpRoutePlanner.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/routing/HttpRoutePlanner.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.routing; + +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.protocol.HttpContext; + +/** + * Encapsulates logic to compute a {@link HttpRoute} to a target host. + * Implementations may for example be based on parameters, or on the + * standard Java system properties. + *

+ * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + */ +public interface HttpRoutePlanner { + + /** + * Determines the route for a request. + * + * @param target the target host for the request. + * Implementations may accept null + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * @param context the context to use for the subsequent execution. + * Implementations may accept null. + * + * @return the route that the request should take + * + * @throws HttpException in case of a problem + */ + public HttpRoute determineRoute(HttpHost target, + HttpRequest request, + HttpContext context) throws HttpException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/routing/RouteInfo.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/routing/RouteInfo.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/routing/RouteInfo.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,161 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.routing; + +import java.net.InetAddress; + +import org.apache.http.HttpHost; + +/** + * Read-only interface for route information. + * + * @since 4.0 + */ +public interface RouteInfo { + + /** + * The tunnelling type of a route. + * Plain routes are established by connecting to the target or + * the first proxy. + * Tunnelled routes are established by connecting to the first proxy + * and tunnelling through all proxies to the target. + * Routes without a proxy cannot be tunnelled. + */ + public enum TunnelType { PLAIN, TUNNELLED } + + /** + * The layering type of a route. + * Plain routes are established by connecting or tunnelling. + * Layered routes are established by layering a protocol such as TLS/SSL + * over an existing connection. + * Protocols can only be layered over a tunnel to the target, or + * or over a direct connection without proxies. + *
+ * Layering a protocol + * over a direct connection makes little sense, since the connection + * could be established with the new protocol in the first place. + * But we don't want to exclude that use case. + */ + public enum LayerType { PLAIN, LAYERED } + + /** + * Obtains the target host. + * + * @return the target host + */ + HttpHost getTargetHost(); + + /** + * Obtains the local address to connect from. + * + * @return the local address, + * or null + */ + InetAddress getLocalAddress(); + + /** + * Obtains the number of hops in this route. + * A direct route has one hop. A route through a proxy has two hops. + * A route through a chain of n proxies has n+1 hops. + * + * @return the number of hops in this route + */ + int getHopCount(); + + /** + * Obtains the target of a hop in this route. + * The target of the last hop is the {@link #getTargetHost target host}, + * the target of previous hops is the respective proxy in the chain. + * For a route through exactly one proxy, target of hop 0 is the proxy + * and target of hop 1 is the target host. + * + * @param hop index of the hop for which to get the target, + * 0 for first + * + * @return the target of the given hop + * + * @throws IllegalArgumentException + * if the argument is negative or not less than + * {@link #getHopCount getHopCount()} + */ + HttpHost getHopTarget(int hop); + + /** + * Obtains the first proxy host. + * + * @return the first proxy in the proxy chain, or + * null if this route is direct + */ + HttpHost getProxyHost(); + + /** + * Obtains the tunnel type of this route. + * If there is a proxy chain, only end-to-end tunnels are considered. + * + * @return the tunnelling type + */ + TunnelType getTunnelType(); + + /** + * Checks whether this route is tunnelled through a proxy. + * If there is a proxy chain, only end-to-end tunnels are considered. + * + * @return true if tunnelled end-to-end through at least + * one proxy, + * false otherwise + */ + boolean isTunnelled(); + + /** + * Obtains the layering type of this route. + * In the presence of proxies, only layering over an end-to-end tunnel + * is considered. + * + * @return the layering type + */ + LayerType getLayerType(); + + /** + * Checks whether this route includes a layered protocol. + * In the presence of proxies, only layering over an end-to-end tunnel + * is considered. + * + * @return true if layered, + * false otherwise + */ + boolean isLayered(); + + /** + * Checks whether this route is secure. + * + * @return true if secure, + * false otherwise + */ + boolean isSecure(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/routing/RouteTracker.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/routing/RouteTracker.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/routing/RouteTracker.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,386 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.routing; + +import java.net.InetAddress; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.util.LangUtils; + +import org.apache.http.HttpHost; + +/** + * Helps tracking the steps in establishing a route. + * + * @since 4.0 + */ +@NotThreadSafe +public final class RouteTracker implements RouteInfo, Cloneable { + + /** The target host to connect to. */ + private final HttpHost targetHost; + + /** + * The local address to connect from. + * null indicates that the default should be used. + */ + private final InetAddress localAddress; + + // the attributes above are fixed at construction time + // now follow attributes that indicate the established route + + /** Whether the first hop of the route is established. */ + private boolean connected; + + /** The proxy chain, if any. */ + private HttpHost[] proxyChain; + + /** Whether the the route is tunnelled end-to-end through proxies. */ + private TunnelType tunnelled; + + /** Whether the route is layered over a tunnel. */ + private LayerType layered; + + /** Whether the route is secure. */ + private boolean secure; + + /** + * Creates a new route tracker. + * The target and origin need to be specified at creation time. + * + * @param target the host to which to route + * @param local the local address to route from, or + * null for the default + */ + public RouteTracker(HttpHost target, InetAddress local) { + if (target == null) { + throw new IllegalArgumentException("Target host may not be null."); + } + this.targetHost = target; + this.localAddress = local; + this.tunnelled = TunnelType.PLAIN; + this.layered = LayerType.PLAIN; + } + + /** + * @since 4.2 + */ + public void reset() { + this.connected = false; + this.proxyChain = null; + this.tunnelled = TunnelType.PLAIN; + this.layered = LayerType.PLAIN; + this.secure = false; + } + + /** + * Creates a new tracker for the given route. + * Only target and origin are taken from the route, + * everything else remains to be tracked. + * + * @param route the route to track + */ + public RouteTracker(HttpRoute route) { + this(route.getTargetHost(), route.getLocalAddress()); + } + + /** + * Tracks connecting to the target. + * + * @param secure true if the route is secure, + * false otherwise + */ + public final void connectTarget(boolean secure) { + if (this.connected) { + throw new IllegalStateException("Already connected."); + } + this.connected = true; + this.secure = secure; + } + + /** + * Tracks connecting to the first proxy. + * + * @param proxy the proxy connected to + * @param secure true if the route is secure, + * false otherwise + */ + public final void connectProxy(HttpHost proxy, boolean secure) { + if (proxy == null) { + throw new IllegalArgumentException("Proxy host may not be null."); + } + if (this.connected) { + throw new IllegalStateException("Already connected."); + } + this.connected = true; + this.proxyChain = new HttpHost[]{ proxy }; + this.secure = secure; + } + + /** + * Tracks tunnelling to the target. + * + * @param secure true if the route is secure, + * false otherwise + */ + public final void tunnelTarget(boolean secure) { + if (!this.connected) { + throw new IllegalStateException("No tunnel unless connected."); + } + if (this.proxyChain == null) { + throw new IllegalStateException("No tunnel without proxy."); + } + this.tunnelled = TunnelType.TUNNELLED; + this.secure = secure; + } + + /** + * Tracks tunnelling to a proxy in a proxy chain. + * This will extend the tracked proxy chain, but it does not mark + * the route as tunnelled. Only end-to-end tunnels are considered there. + * + * @param proxy the proxy tunnelled to + * @param secure true if the route is secure, + * false otherwise + */ + public final void tunnelProxy(HttpHost proxy, boolean secure) { + if (proxy == null) { + throw new IllegalArgumentException("Proxy host may not be null."); + } + if (!this.connected) { + throw new IllegalStateException("No tunnel unless connected."); + } + if (this.proxyChain == null) { + throw new IllegalStateException("No proxy tunnel without proxy."); + } + + // prepare an extended proxy chain + HttpHost[] proxies = new HttpHost[this.proxyChain.length+1]; + System.arraycopy(this.proxyChain, 0, + proxies, 0, this.proxyChain.length); + proxies[proxies.length-1] = proxy; + + this.proxyChain = proxies; + this.secure = secure; + } + + /** + * Tracks layering a protocol. + * + * @param secure true if the route is secure, + * false otherwise + */ + public final void layerProtocol(boolean secure) { + // it is possible to layer a protocol over a direct connection, + // although this case is probably not considered elsewhere + if (!this.connected) { + throw new IllegalStateException + ("No layered protocol unless connected."); + } + this.layered = LayerType.LAYERED; + this.secure = secure; + } + + public final HttpHost getTargetHost() { + return this.targetHost; + } + + public final InetAddress getLocalAddress() { + return this.localAddress; + } + + public final int getHopCount() { + int hops = 0; + if (this.connected) { + if (proxyChain == null) + hops = 1; + else + hops = proxyChain.length + 1; + } + return hops; + } + + public final HttpHost getHopTarget(int hop) { + if (hop < 0) + throw new IllegalArgumentException + ("Hop index must not be negative: " + hop); + final int hopcount = getHopCount(); + if (hop >= hopcount) { + throw new IllegalArgumentException + ("Hop index " + hop + + " exceeds tracked route length " + hopcount +"."); + } + + HttpHost result = null; + if (hop < hopcount-1) + result = this.proxyChain[hop]; + else + result = this.targetHost; + + return result; + } + + public final HttpHost getProxyHost() { + return (this.proxyChain == null) ? null : this.proxyChain[0]; + } + + public final boolean isConnected() { + return this.connected; + } + + public final TunnelType getTunnelType() { + return this.tunnelled; + } + + public final boolean isTunnelled() { + return (this.tunnelled == TunnelType.TUNNELLED); + } + + public final LayerType getLayerType() { + return this.layered; + } + + public final boolean isLayered() { + return (this.layered == LayerType.LAYERED); + } + + public final boolean isSecure() { + return this.secure; + } + + /** + * Obtains the tracked route. + * If a route has been tracked, it is {@link #isConnected connected}. + * If not connected, nothing has been tracked so far. + * + * @return the tracked route, or + * null if nothing has been tracked so far + */ + public final HttpRoute toRoute() { + return !this.connected ? + null : new HttpRoute(this.targetHost, this.localAddress, + this.proxyChain, this.secure, + this.tunnelled, this.layered); + } + + /** + * Compares this tracked route to another. + * + * @param o the object to compare with + * + * @return true if the argument is the same tracked route, + * false + */ + @Override + public final boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof RouteTracker)) + return false; + + RouteTracker that = (RouteTracker) o; + return + // Do the cheapest checks first + (this.connected == that.connected) && + (this.secure == that.secure) && + (this.tunnelled == that.tunnelled) && + (this.layered == that.layered) && + LangUtils.equals(this.targetHost, that.targetHost) && + LangUtils.equals(this.localAddress, that.localAddress) && + LangUtils.equals(this.proxyChain, that.proxyChain); + } + + /** + * Generates a hash code for this tracked route. + * Route trackers are modifiable and should therefore not be used + * as lookup keys. Use {@link #toRoute toRoute} to obtain an + * unmodifiable representation of the tracked route. + * + * @return the hash code + */ + @Override + public final int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.targetHost); + hash = LangUtils.hashCode(hash, this.localAddress); + if (this.proxyChain != null) { + for (int i = 0; i < this.proxyChain.length; i++) { + hash = LangUtils.hashCode(hash, this.proxyChain[i]); + } + } + hash = LangUtils.hashCode(hash, this.connected); + hash = LangUtils.hashCode(hash, this.secure); + hash = LangUtils.hashCode(hash, this.tunnelled); + hash = LangUtils.hashCode(hash, this.layered); + return hash; + } + + /** + * Obtains a description of the tracked route. + * + * @return a human-readable representation of the tracked route + */ + @Override + public final String toString() { + StringBuilder cab = new StringBuilder(50 + getHopCount()*30); + + cab.append("RouteTracker["); + if (this.localAddress != null) { + cab.append(this.localAddress); + cab.append("->"); + } + cab.append('{'); + if (this.connected) + cab.append('c'); + if (this.tunnelled == TunnelType.TUNNELLED) + cab.append('t'); + if (this.layered == LayerType.LAYERED) + cab.append('l'); + if (this.secure) + cab.append('s'); + cab.append("}->"); + if (this.proxyChain != null) { + for (int i=0; i"); + } + } + cab.append(this.targetHost); + cab.append(']'); + + return cab.toString(); + } + + + // default implementation of clone() is sufficient + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/routing/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/routing/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/routing/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,53 @@ + + + + + +The client-side route representation and tracking API. +

+An {@link org.apache.http.conn.routing.HttpRoute HttpRoute} +is the path along which a request has to be sent to the server. +The route starts at a local network address and may pass +through one or more proxies before reaching the target. +Routes through proxies can be tunnelled, and a layered protocol (TLS/SSL) +might be put on top of the tunnel. +The {@link org.apache.http.conn.routing.RouteTracker RouteTracker} +helps in tracking the steps for establishing a route, while an +{@link org.apache.http.conn.routing.HttpRouteDirector HttpRouteDirector} +determines the next step to take. +

+

+The {@link org.apache.http.conn.routing.HttpRoutePlanner HttpRoutePlanner} +is responsible for determining a route to a given target host. +Implementations must know about proxies to use, and about exemptions +for hosts that should be contacted directly without a proxy. +

+ + Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/HostNameResolver.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/HostNameResolver.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/HostNameResolver.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,52 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.InetAddress; + +/** + * Hostname to IP address resolver. + * + * @since 4.0 + * + * @deprecated (4.1) Do not use + */ +@Deprecated +public interface HostNameResolver { + + /** + * Resolves given hostname to its IP address + * + * @param hostname the hostname. + * @return IP address. + * @throws IOException + */ + InetAddress resolve (String hostname) throws IOException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/LayeredSchemeSocketFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/LayeredSchemeSocketFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/LayeredSchemeSocketFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,68 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +/** + * Extended {@link SchemeSocketFactory} interface for layered sockets such as SSL/TLS. + * + * @since 4.1 + * + * @deprecated (4.2) use {@link SchemeLayeredSocketFactory} + */ +@Deprecated +public interface LayeredSchemeSocketFactory extends SchemeSocketFactory { + + /** + * Returns a socket connected to the given host that is layered over an + * existing socket. Used primarily for creating secure sockets through + * proxies. + * + * @param socket the existing socket + * @param target the name of the target host. + * @param port the port to connect to on the target host + * @param autoClose a flag for closing the underling socket when the created + * socket is closed + * + * @return Socket a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + * @throws UnknownHostException if the IP address of the host cannot be + * determined + */ + Socket createLayeredSocket( + Socket socket, + String target, + int port, + boolean autoClose + ) throws IOException, UnknownHostException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/LayeredSocketFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/LayeredSocketFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/LayeredSocketFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,69 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +/** + * A {@link SocketFactory SocketFactory} for layered sockets (SSL/TLS). + * See there for things to consider when implementing a socket factory. + * + * @since 4.0 + * + * @deprecated (4.1) use {@link SchemeSocketFactory} + */ +@Deprecated +public interface LayeredSocketFactory extends SocketFactory { + + /** + * Returns a socket connected to the given host that is layered over an + * existing socket. Used primarily for creating secure sockets through + * proxies. + * + * @param socket the existing socket + * @param host the host name/IP + * @param port the port on the host + * @param autoClose a flag for closing the underling socket when the created + * socket is closed + * + * @return Socket a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + * @throws UnknownHostException if the IP address of the host cannot be + * determined + */ + Socket createSocket( + Socket socket, + String host, + int port, + boolean autoClose + ) throws IOException, UnknownHostException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/LayeredSocketFactoryAdaptor.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/LayeredSocketFactoryAdaptor.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/LayeredSocketFactoryAdaptor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,53 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +/** + * @deprecated (4.1) do not use + */ +@Deprecated +class LayeredSocketFactoryAdaptor extends SocketFactoryAdaptor implements LayeredSocketFactory { + + private final LayeredSchemeSocketFactory factory; + + LayeredSocketFactoryAdaptor(final LayeredSchemeSocketFactory factory) { + super(factory); + this.factory = factory; + } + + public Socket createSocket( + final Socket socket, + final String host, int port, boolean autoClose) throws IOException, UnknownHostException { + return this.factory.createLayeredSocket(socket, host, port, autoClose); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/PlainSocketFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/PlainSocketFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/PlainSocketFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,186 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.conn.DnsResolver; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +/** + * The default class for creating plain (unencrypted) sockets. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}
  • + *
+ * + * @since 4.0 + */ +@SuppressWarnings("deprecation") +@Immutable +public class PlainSocketFactory implements SocketFactory, SchemeSocketFactory { + + private final HostNameResolver nameResolver; + + /** + * Gets the default factory. + * + * @return the default factory + */ + public static PlainSocketFactory getSocketFactory() { + return new PlainSocketFactory(); + } + + /** + * @deprecated (4.1) use {@link DnsResolver} + */ + @Deprecated + public PlainSocketFactory(final HostNameResolver nameResolver) { + super(); + this.nameResolver = nameResolver; + } + + public PlainSocketFactory() { + super(); + this.nameResolver = null; + } + + /** + * @param params Optional parameters. Parameters passed to this method will have no effect. + * This method will create a unconnected instance of {@link Socket} class + * using default constructor. + * + * @since 4.1 + */ + public Socket createSocket(final HttpParams params) { + return new Socket(); + } + + public Socket createSocket() { + return new Socket(); + } + + /** + * @since 4.1 + */ + public Socket connectSocket( + final Socket socket, + final InetSocketAddress remoteAddress, + final InetSocketAddress localAddress, + final HttpParams params) throws IOException, ConnectTimeoutException { + if (remoteAddress == null) { + throw new IllegalArgumentException("Remote address may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + Socket sock = socket; + if (sock == null) { + sock = createSocket(); + } + if (localAddress != null) { + sock.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params)); + sock.bind(localAddress); + } + int connTimeout = HttpConnectionParams.getConnectionTimeout(params); + int soTimeout = HttpConnectionParams.getSoTimeout(params); + + try { + sock.setSoTimeout(soTimeout); + sock.connect(remoteAddress, connTimeout); + } catch (SocketTimeoutException ex) { + throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out"); + } + return sock; + } + + /** + * Checks whether a socket connection is secure. + * This factory creates plain socket connections + * which are not considered secure. + * + * @param sock the connected socket + * + * @return false + * + * @throws IllegalArgumentException if the argument is invalid + */ + public final boolean isSecure(Socket sock) + throws IllegalArgumentException { + + if (sock == null) { + throw new IllegalArgumentException("Socket may not be null."); + } + // This check is performed last since it calls a method implemented + // by the argument object. getClass() is final in java.lang.Object. + if (sock.isClosed()) { + throw new IllegalArgumentException("Socket is closed."); + } + return false; + } + + /** + * @deprecated (4.1) Use {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)} + */ + @Deprecated + public Socket connectSocket( + final Socket socket, + final String host, int port, + final InetAddress localAddress, int localPort, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + InetSocketAddress local = null; + if (localAddress != null || localPort > 0) { + // we need to bind explicitly + if (localPort < 0) { + localPort = 0; // indicates "any" + } + local = new InetSocketAddress(localAddress, localPort); + } + InetAddress remoteAddress; + if (this.nameResolver != null) { + remoteAddress = this.nameResolver.resolve(host); + } else { + remoteAddress = InetAddress.getByName(host); + } + InetSocketAddress remote = new InetSocketAddress(remoteAddress, port); + return connectSocket(socket, remote, local, params); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/Scheme.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/Scheme.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/Scheme.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,269 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.conn.scheme; + +import java.util.Locale; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.util.LangUtils; + +/** + * Encapsulates specifics of a protocol scheme such as "http" or "https". Schemes are identified + * by lowercase names. Supported schemes are typically collected in a {@link SchemeRegistry + * SchemeRegistry}. + *

+ * For example, to configure support for "https://" URLs, you could write code like the following: + *

+ * Scheme https = new Scheme("https", 443, new MySecureSocketFactory());
+ * SchemeRegistry.DEFAULT.register(https);
+ * 
+ * + * @since 4.0 + */ +@Immutable +public final class Scheme { + + /** The name of this scheme, in lowercase. (e.g. http, https) */ + private final String name; + + /** The socket factory for this scheme */ + private final SchemeSocketFactory socketFactory; + + /** The default port for this scheme */ + private final int defaultPort; + + /** Indicates whether this scheme allows for layered connections */ + private final boolean layered; + + /** A string representation, for {@link #toString toString}. */ + private String stringRep; + /* + * This is used to cache the result of the toString() method + * Since the method always generates the same value, there's no + * need to synchronize, and it does not affect immutability. + */ + + /** + * Creates a new scheme. + * Whether the created scheme allows for layered connections + * depends on the class of factory. + * + * @param name the scheme name, for example "http". + * The name will be converted to lowercase. + * @param port the default port for this scheme + * @param factory the factory for creating sockets for communication + * with this scheme + * + * @since 4.1 + */ + @SuppressWarnings("deprecation") + public Scheme(final String name, final int port, final SchemeSocketFactory factory) { + if (name == null) { + throw new IllegalArgumentException("Scheme name may not be null"); + } + if ((port <= 0) || (port > 0xffff)) { + throw new IllegalArgumentException("Port is invalid: " + port); + } + if (factory == null) { + throw new IllegalArgumentException("Socket factory may not be null"); + } + this.name = name.toLowerCase(Locale.ENGLISH); + this.defaultPort = port; + if (factory instanceof SchemeLayeredSocketFactory) { + this.layered = true; + this.socketFactory = factory; + } else if (factory instanceof LayeredSchemeSocketFactory) { + this.layered = true; + this.socketFactory = new SchemeLayeredSocketFactoryAdaptor2((LayeredSchemeSocketFactory) factory); + } else { + this.layered = false; + this.socketFactory = factory; + } + } + + /** + * Creates a new scheme. + * Whether the created scheme allows for layered connections + * depends on the class of factory. + * + * @param name the scheme name, for example "http". + * The name will be converted to lowercase. + * @param factory the factory for creating sockets for communication + * with this scheme + * @param port the default port for this scheme + * + * @deprecated (4.1) Use {@link #Scheme(String, int, SchemeSocketFactory)} + */ + @Deprecated + public Scheme(final String name, + final SocketFactory factory, + final int port) { + + if (name == null) { + throw new IllegalArgumentException + ("Scheme name may not be null"); + } + if (factory == null) { + throw new IllegalArgumentException + ("Socket factory may not be null"); + } + if ((port <= 0) || (port > 0xffff)) { + throw new IllegalArgumentException + ("Port is invalid: " + port); + } + + this.name = name.toLowerCase(Locale.ENGLISH); + if (factory instanceof LayeredSocketFactory) { + this.socketFactory = new SchemeLayeredSocketFactoryAdaptor( + (LayeredSocketFactory) factory); + this.layered = true; + } else { + this.socketFactory = new SchemeSocketFactoryAdaptor(factory); + this.layered = false; + } + this.defaultPort = port; + } + + /** + * Obtains the default port. + * + * @return the default port for this scheme + */ + public final int getDefaultPort() { + return defaultPort; + } + + + /** + * Obtains the socket factory. + * If this scheme is {@link #isLayered layered}, the factory implements + * {@link LayeredSocketFactory LayeredSocketFactory}. + * + * @return the socket factory for this scheme + * + * @deprecated (4.1) Use {@link #getSchemeSocketFactory()} + */ + @Deprecated + public final SocketFactory getSocketFactory() { + if (this.socketFactory instanceof SchemeSocketFactoryAdaptor) { + return ((SchemeSocketFactoryAdaptor) this.socketFactory).getFactory(); + } else { + if (this.layered) { + return new LayeredSocketFactoryAdaptor( + (LayeredSchemeSocketFactory) this.socketFactory); + } else { + return new SocketFactoryAdaptor(this.socketFactory); + } + } + } + + /** + * Obtains the socket factory. + * If this scheme is {@link #isLayered layered}, the factory implements + * {@link LayeredSocketFactory LayeredSchemeSocketFactory}. + * + * @return the socket factory for this scheme + * + * @since 4.1 + */ + public final SchemeSocketFactory getSchemeSocketFactory() { + return this.socketFactory; + } + + /** + * Obtains the scheme name. + * + * @return the name of this scheme, in lowercase + */ + public final String getName() { + return name; + } + + /** + * Indicates whether this scheme allows for layered connections. + * + * @return true if layered connections are possible, + * false otherwise + */ + public final boolean isLayered() { + return layered; + } + + /** + * Resolves the correct port for this scheme. + * Returns the given port if it is valid, the default port otherwise. + * + * @param port the port to be resolved, + * a negative number to obtain the default port + * + * @return the given port or the defaultPort + */ + public final int resolvePort(int port) { + return port <= 0 ? defaultPort : port; + } + + /** + * Return a string representation of this object. + * + * @return a human-readable string description of this scheme + */ + @Override + public final String toString() { + if (stringRep == null) { + StringBuilder buffer = new StringBuilder(); + buffer.append(this.name); + buffer.append(':'); + buffer.append(Integer.toString(this.defaultPort)); + stringRep = buffer.toString(); + } + return stringRep; + } + + @Override + public final boolean equals(Object obj) { + if (this == obj) return true; + if (obj instanceof Scheme) { + Scheme that = (Scheme) obj; + return this.name.equals(that.name) + && this.defaultPort == that.defaultPort + && this.layered == that.layered; + } else { + return false; + } + } + + @Override + public int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.defaultPort); + hash = LangUtils.hashCode(hash, this.name); + hash = LangUtils.hashCode(hash, this.layered); + return hash; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeLayeredSocketFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeLayeredSocketFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeLayeredSocketFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,65 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.http.params.HttpParams; + +/** + * Extended {@link SchemeSocketFactory} interface for layered sockets such as SSL/TLS. + * + * @since 4.2 + */ +public interface SchemeLayeredSocketFactory extends SchemeSocketFactory { + + /** + * Returns a socket connected to the given host that is layered over an + * existing socket. Used primarily for creating secure sockets through + * proxies. + * + * @param socket the existing socket + * @param target the name of the target host. + * @param port the port to connect to on the target host + * @param params HTTP parameters + * + * @return Socket a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + * @throws UnknownHostException if the IP address of the host cannot be + * determined + */ + Socket createLayeredSocket( + Socket socket, + String target, + int port, + HttpParams params) throws IOException, UnknownHostException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeLayeredSocketFactoryAdaptor.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeLayeredSocketFactoryAdaptor.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeLayeredSocketFactoryAdaptor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,57 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.http.params.HttpParams; + +/** + * @deprecated (4.2) do not use + */ +@Deprecated +class SchemeLayeredSocketFactoryAdaptor extends SchemeSocketFactoryAdaptor + implements SchemeLayeredSocketFactory { + + private final LayeredSocketFactory factory; + + SchemeLayeredSocketFactoryAdaptor(final LayeredSocketFactory factory) { + super(factory); + this.factory = factory; + } + + public Socket createLayeredSocket( + final Socket socket, + final String target, int port, + final HttpParams params) throws IOException, UnknownHostException { + return this.factory.createSocket(socket, target, port, true); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeLayeredSocketFactoryAdaptor2.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeLayeredSocketFactoryAdaptor2.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeLayeredSocketFactoryAdaptor2.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.params.HttpParams; + +/** + * @deprecated (4.2) do not use + */ +@Deprecated +class SchemeLayeredSocketFactoryAdaptor2 implements SchemeLayeredSocketFactory { + + private final LayeredSchemeSocketFactory factory; + + SchemeLayeredSocketFactoryAdaptor2(final LayeredSchemeSocketFactory factory) { + super(); + this.factory = factory; + } + + public Socket createSocket(final HttpParams params) throws IOException { + return this.factory.createSocket(params); + } + + public Socket connectSocket( + final Socket sock, + final InetSocketAddress remoteAddress, + final InetSocketAddress localAddress, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + return this.factory.connectSocket(sock, remoteAddress, localAddress, params); + } + + public boolean isSecure(Socket sock) throws IllegalArgumentException { + return this.factory.isSecure(sock); + } + + public Socket createLayeredSocket( + final Socket socket, + final String target, int port, + final HttpParams params) throws IOException, UnknownHostException { + return this.factory.createLayeredSocket(socket, target, port, true); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeRegistry.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeRegistry.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeRegistry.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,173 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.conn.scheme; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.http.annotation.ThreadSafe; + +import org.apache.http.HttpHost; + +/** + * A set of supported protocol {@link Scheme}s. + * Schemes are identified by lowercase names. + * + * @since 4.0 + */ +@ThreadSafe +public final class SchemeRegistry { + + /** The available schemes in this registry. */ + private final ConcurrentHashMap registeredSchemes; + + /** + * Creates a new, empty scheme registry. + */ + public SchemeRegistry() { + super(); + registeredSchemes = new ConcurrentHashMap(); + } + + /** + * Obtains a scheme by name. + * + * @param name the name of the scheme to look up (in lowercase) + * + * @return the scheme, never null + * + * @throws IllegalStateException + * if the scheme with the given name is not registered + */ + public final Scheme getScheme(String name) { + Scheme found = get(name); + if (found == null) { + throw new IllegalStateException + ("Scheme '"+name+"' not registered."); + } + return found; + } + + /** + * Obtains the scheme for a host. + * Convenience method for getScheme(host.getSchemeName()) + * + * @param host the host for which to obtain the scheme + * + * @return the scheme for the given host, never null + * + * @throws IllegalStateException + * if a scheme with the respective name is not registered + */ + public final Scheme getScheme(HttpHost host) { + if (host == null) { + throw new IllegalArgumentException("Host must not be null."); + } + return getScheme(host.getSchemeName()); + } + + /** + * Obtains a scheme by name, if registered. + * + * @param name the name of the scheme to look up (in lowercase) + * + * @return the scheme, or + * null if there is none by this name + */ + public final Scheme get(String name) { + if (name == null) + throw new IllegalArgumentException("Name must not be null."); + + // leave it to the caller to use the correct name - all lowercase + //name = name.toLowerCase(); + Scheme found = registeredSchemes.get(name); + return found; + } + + /** + * Registers a scheme. + * The scheme can later be retrieved by its name + * using {@link #getScheme(String) getScheme} or {@link #get get}. + * + * @param sch the scheme to register + * + * @return the scheme previously registered with that name, or + * null if none was registered + */ + public final Scheme register(Scheme sch) { + if (sch == null) + throw new IllegalArgumentException("Scheme must not be null."); + + Scheme old = registeredSchemes.put(sch.getName(), sch); + return old; + } + + /** + * Unregisters a scheme. + * + * @param name the name of the scheme to unregister (in lowercase) + * + * @return the unregistered scheme, or + * null if there was none + */ + public final Scheme unregister(String name) { + if (name == null) + throw new IllegalArgumentException("Name must not be null."); + + // leave it to the caller to use the correct name - all lowercase + //name = name.toLowerCase(); + Scheme gone = registeredSchemes.remove(name); + return gone; + } + + /** + * Obtains the names of the registered schemes. + * + * @return List containing registered scheme names. + */ + public final List getSchemeNames() { + return new ArrayList(registeredSchemes.keySet()); + } + + /** + * Populates the internal collection of registered {@link Scheme protocol schemes} + * with the content of the map passed as a parameter. + * + * @param map protocol schemes + */ + public void setItems(final Map map) { + if (map == null) { + return; + } + registeredSchemes.clear(); + registeredSchemes.putAll(map); + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeSocketFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeSocketFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeSocketFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,127 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.http.HttpHost; +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.conn.HttpInetSocketAddress; +import org.apache.http.params.HttpParams; + +/** + * A factory for creating, initializing and connecting sockets. The factory encapsulates the logic + * for establishing a socket connection. + * + * @since 4.1 + */ +public interface SchemeSocketFactory { + + /** + * Creates a new, unconnected socket. The socket should subsequently be passed to + * {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)}. + * + * @param params Optional {@link HttpParams parameters}. In most cases these parameters + * will not be required and will have no effect, as usually socket + * initialization should take place in the + * {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)} + * method. However, in rare cases one may want to pass additional parameters + * to this method in order to create a customized {@link Socket} instance, + * for instance bound to a SOCKS proxy server. + * + * @return a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + */ + Socket createSocket(HttpParams params) throws IOException; + + /** + * Connects a socket to the target host with the given remote address. + *

+ * Please note that {@link HttpInetSocketAddress} class should be used in order to pass + * the target remote address along with the original {@link HttpHost} value used to resolve + * the address. The use of {@link HttpInetSocketAddress} can also ensure that no reverse + * DNS lookup will be performed if the target remote address was specified as an IP address. + * + * @param sock the socket to connect, as obtained from + * {@link #createSocket(HttpParams) createSocket}. + * null indicates that a new socket + * should be created and connected. + * @param remoteAddress the remote address to connect to. + * @param localAddress the local address to bind the socket to, or + * null for any + * @param params additional {@link HttpParams parameters} for connecting + * + * @return the connected socket. The returned object may be different + * from the sock argument if this factory supports + * a layered protocol. + * + * @throws IOException if an I/O error occurs + * @throws UnknownHostException if the IP address of the target host + * can not be determined + * @throws ConnectTimeoutException if the socket cannot be connected + * within the time limit defined in the params + * + * @see HttpInetSocketAddress + */ + Socket connectSocket( + Socket sock, + InetSocketAddress remoteAddress, + InetSocketAddress localAddress, + HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException; + + /** + * Checks whether a socket provides a secure connection. The socket must be + * {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams) connected} + * by this factory. The factory will not perform I/O operations in this method. + *

+ * As a rule of thumb, plain sockets are not secure and TLS/SSL sockets are secure. However, + * there may be application specific deviations. For example, a plain socket to a host in the + * same intranet ("trusted zone") could be considered secure. On the other hand, a TLS/SSL + * socket could be considered insecure based on the cipher suite chosen for the connection. + * + * @param sock the connected socket to check + * + * @return true if the connection of the socket + * should be considered secure, or + * false if it should not + * + * @throws IllegalArgumentException + * if the argument is invalid, for example because it is + * not a connected socket or was created by a different + * socket factory. + * Note that socket factories are not required to + * check these conditions, they may simply return a default + * value when called with an invalid socket argument. + */ + boolean isSecure(Socket sock) throws IllegalArgumentException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeSocketFactoryAdaptor.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeSocketFactoryAdaptor.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SchemeSocketFactoryAdaptor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,96 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.params.HttpParams; + +/** + * @deprecated (4.1) do not use + */ +@Deprecated +class SchemeSocketFactoryAdaptor implements SchemeSocketFactory { + + private final SocketFactory factory; + + SchemeSocketFactoryAdaptor(final SocketFactory factory) { + super(); + this.factory = factory; + } + + public Socket connectSocket( + final Socket sock, + final InetSocketAddress remoteAddress, + final InetSocketAddress localAddress, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + String host = remoteAddress.getHostName(); + int port = remoteAddress.getPort(); + InetAddress local = null; + int localPort = 0; + if (localAddress != null) { + local = localAddress.getAddress(); + localPort = localAddress.getPort(); + } + return this.factory.connectSocket(sock, host, port, local, localPort, params); + } + + public Socket createSocket(final HttpParams params) throws IOException { + return this.factory.createSocket(); + } + + public boolean isSecure(final Socket sock) throws IllegalArgumentException { + return this.factory.isSecure(sock); + } + + public SocketFactory getFactory() { + return this.factory; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) return false; + if (this == obj) return true; + if (obj instanceof SchemeSocketFactoryAdaptor) { + return this.factory.equals(((SchemeSocketFactoryAdaptor)obj).factory); + } else { + return this.factory.equals(obj); + } + } + + @Override + public int hashCode() { + return this.factory.hashCode(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SocketFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SocketFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SocketFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,127 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.params.HttpParams; + +/** + * A factory for creating, initializing and connecting sockets. + * The factory encapsulates the logic for establishing a socket connection. + * + * @since 4.0 + * + * @deprecated (4.1) use {@link SchemeSocketFactory} + */ +@Deprecated +public interface SocketFactory { + + /** + * Creates a new, unconnected socket. + * The socket should subsequently be passed to + * {@link #connectSocket connectSocket}. + * + * @return a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + */ + Socket createSocket() + throws IOException; + + /** + * Connects a socket to the given host. + * + * @param sock the socket to connect, as obtained from + * {@link #createSocket createSocket}. + * null indicates that a new socket + * should be created and connected. + * @param host the host to connect to + * @param port the port to connect to on the host + * @param localAddress the local address to bind the socket to, or + * null for any + * @param localPort the port on the local machine, + * 0 or a negative number for any + * @param params additional {@link HttpParams parameters} for connecting + * + * @return the connected socket. The returned object may be different + * from the sock argument if this factory supports + * a layered protocol. + * + * @throws IOException if an I/O error occurs + * @throws UnknownHostException if the IP address of the target host + * can not be determined + * @throws ConnectTimeoutException if the socket cannot be connected + * within the time limit defined in the params + */ + Socket connectSocket( + Socket sock, + String host, + int port, + InetAddress localAddress, + int localPort, + HttpParams params + ) throws IOException, UnknownHostException, ConnectTimeoutException; + + /** + * Checks whether a socket provides a secure connection. + * The socket must be {@link #connectSocket connected} + * by this factory. + * The factory will not perform I/O operations + * in this method. + *
+ * As a rule of thumb, plain sockets are not secure and + * TLS/SSL sockets are secure. However, there may be + * application specific deviations. For example, a plain + * socket to a host in the same intranet ("trusted zone") + * could be considered secure. On the other hand, a + * TLS/SSL socket could be considered insecure based on + * the cipher suite chosen for the connection. + * + * @param sock the connected socket to check + * + * @return true if the connection of the socket + * should be considered secure, or + * false if it should not + * + * @throws IllegalArgumentException + * if the argument is invalid, for example because it is + * not a connected socket or was created by a different + * socket factory. + * Note that socket factories are not required to + * check these conditions, they may simply return a default + * value when called with an invalid socket argument. + */ + boolean isSecure(Socket sock) + throws IllegalArgumentException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SocketFactoryAdaptor.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SocketFactoryAdaptor.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/SocketFactoryAdaptor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,100 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.scheme; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpParams; + +/** + * @deprecated (4.1) do not use + */ +@Deprecated +class SocketFactoryAdaptor implements SocketFactory { + + private final SchemeSocketFactory factory; + + SocketFactoryAdaptor(final SchemeSocketFactory factory) { + super(); + this.factory = factory; + } + + public Socket createSocket() throws IOException { + HttpParams params = new BasicHttpParams(); + return this.factory.createSocket(params); + } + + public Socket connectSocket( + final Socket socket, + final String host, int port, + final InetAddress localAddress, int localPort, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + InetSocketAddress local = null; + if (localAddress != null || localPort > 0) { + // we need to bind explicitly + if (localPort < 0) { + localPort = 0; // indicates "any" + } + local = new InetSocketAddress(localAddress, localPort); + } + InetAddress remoteAddress = InetAddress.getByName(host); + InetSocketAddress remote = new InetSocketAddress(remoteAddress, port); + return this.factory.connectSocket(socket, remote, local, params); + } + + public boolean isSecure(final Socket socket) throws IllegalArgumentException { + return this.factory.isSecure(socket); + } + + public SchemeSocketFactory getFactory() { + return this.factory; + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) return false; + if (this == obj) return true; + if (obj instanceof SocketFactoryAdaptor) { + return this.factory.equals(((SocketFactoryAdaptor)obj).factory); + } else { + return this.factory.equals(obj); + } + } + + @Override + public int hashCode() { + return this.factory.hashCode(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/scheme/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/scheme/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/scheme/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,38 @@ + + + + + +{@link org.apache.http.conn.scheme.Scheme} class represents a protocol +scheme such as "http" or "https" and contains a number of protocol properties +such as the default port and the socket factory to be used to creating +{@link java.net.Socket}s for the given protocol + + Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/AbstractVerifier.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/AbstractVerifier.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/AbstractVerifier.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,366 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.ssl; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.conn.util.InetAddressUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.security.cert.Certificate; +import java.security.cert.CertificateParsingException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.StringTokenizer; +import java.util.logging.Logger; +import java.util.logging.Level; + +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; + +/** + * Abstract base class for all standard {@link X509HostnameVerifier} + * implementations. + * + * @since 4.0 + */ +@Immutable +public abstract class AbstractVerifier implements X509HostnameVerifier { + + /** + * This contains a list of 2nd-level domains that aren't allowed to + * have wildcards when combined with country-codes. + * For example: [*.co.uk]. + *

+ * The [*.co.uk] problem is an interesting one. Should we just hope + * that CA's would never foolishly allow such a certificate to happen? + * Looks like we're the only implementation guarding against this. + * Firefox, Curl, Sun Java 1.4, 5, 6 don't bother with this check. + */ + private final static String[] BAD_COUNTRY_2LDS = + { "ac", "co", "com", "ed", "edu", "go", "gouv", "gov", "info", + "lg", "ne", "net", "or", "org" }; + + static { + // Just in case developer forgot to manually sort the array. :-) + Arrays.sort(BAD_COUNTRY_2LDS); + } + + public AbstractVerifier() { + super(); + } + + public final void verify(String host, SSLSocket ssl) + throws IOException { + if(host == null) { + throw new NullPointerException("host to verify is null"); + } + + SSLSession session = ssl.getSession(); + if(session == null) { + // In our experience this only happens under IBM 1.4.x when + // spurious (unrelated) certificates show up in the server' + // chain. Hopefully this will unearth the real problem: + InputStream in = ssl.getInputStream(); + in.available(); + /* + If you're looking at the 2 lines of code above because + you're running into a problem, you probably have two + options: + + #1. Clean up the certificate chain that your server + is presenting (e.g. edit "/etc/apache2/server.crt" + or wherever it is your server's certificate chain + is defined). + + OR + + #2. Upgrade to an IBM 1.5.x or greater JVM, or switch + to a non-IBM JVM. + */ + + // If ssl.getInputStream().available() didn't cause an + // exception, maybe at least now the session is available? + session = ssl.getSession(); + if(session == null) { + // If it's still null, probably a startHandshake() will + // unearth the real problem. + ssl.startHandshake(); + + // Okay, if we still haven't managed to cause an exception, + // might as well go for the NPE. Or maybe we're okay now? + session = ssl.getSession(); + } + } + + Certificate[] certs = session.getPeerCertificates(); + X509Certificate x509 = (X509Certificate) certs[0]; + verify(host, x509); + } + + public final boolean verify(String host, SSLSession session) { + try { + Certificate[] certs = session.getPeerCertificates(); + X509Certificate x509 = (X509Certificate) certs[0]; + verify(host, x509); + return true; + } + catch(SSLException e) { + return false; + } + } + + public final void verify(String host, X509Certificate cert) + throws SSLException { + String[] cns = getCNs(cert); + String[] subjectAlts = getSubjectAlts(cert, host); + verify(host, cns, subjectAlts); + } + + public final void verify(final String host, final String[] cns, + final String[] subjectAlts, + final boolean strictWithSubDomains) + throws SSLException { + + // Build the list of names we're going to check. Our DEFAULT and + // STRICT implementations of the HostnameVerifier only use the + // first CN provided. All other CNs are ignored. + // (Firefox, wget, curl, Sun Java 1.4, 5, 6 all work this way). + LinkedList names = new LinkedList(); + if(cns != null && cns.length > 0 && cns[0] != null) { + names.add(cns[0]); + } + if(subjectAlts != null) { + for (String subjectAlt : subjectAlts) { + if (subjectAlt != null) { + names.add(subjectAlt); + } + } + } + + if(names.isEmpty()) { + String msg = "Certificate for <" + host + "> doesn't contain CN or DNS subjectAlt"; + throw new SSLException(msg); + } + + // StringBuilder for building the error message. + StringBuilder buf = new StringBuilder(); + + // We're can be case-insensitive when comparing the host we used to + // establish the socket to the hostname in the certificate. + String hostName = host.trim().toLowerCase(Locale.ENGLISH); + boolean match = false; + for(Iterator it = names.iterator(); it.hasNext();) { + // Don't trim the CN, though! + String cn = it.next(); + cn = cn.toLowerCase(Locale.ENGLISH); + // Store CN in StringBuilder in case we need to report an error. + buf.append(" <"); + buf.append(cn); + buf.append('>'); + if(it.hasNext()) { + buf.append(" OR"); + } + + // The CN better have at least two dots if it wants wildcard + // action. It also can't be [*.co.uk] or [*.co.jp] or + // [*.org.uk], etc... + String parts[] = cn.split("\\."); + boolean doWildcard = parts.length >= 3 && + parts[0].endsWith("*") && + acceptableCountryWildcard(cn) && + !isIPAddress(host); + + if(doWildcard) { + if (parts[0].length() > 1) { // e.g. server* + String prefix = parts[0].substring(0, parts.length-2); // e.g. server + String suffix = cn.substring(parts[0].length()); // skip wildcard part from cn + String hostSuffix = hostName.substring(prefix.length()); // skip wildcard part from host + match = hostName.startsWith(prefix) && hostSuffix.endsWith(suffix); + } else { + match = hostName.endsWith(cn.substring(1)); + } + if(match && strictWithSubDomains) { + // If we're in strict mode, then [*.foo.com] is not + // allowed to match [a.b.foo.com] + match = countDots(hostName) == countDots(cn); + } + } else { + match = hostName.equals(cn); + } + if(match) { + break; + } + } + if(!match) { + throw new SSLException("hostname in certificate didn't match: <" + host + "> !=" + buf); + } + } + + public static boolean acceptableCountryWildcard(String cn) { + String parts[] = cn.split("\\."); + if (parts.length != 3 || parts[2].length() != 2) { + return true; // it's not an attempt to wildcard a 2TLD within a country code + } + return Arrays.binarySearch(BAD_COUNTRY_2LDS, parts[1]) < 0; + } + + public static String[] getCNs(X509Certificate cert) { + LinkedList cnList = new LinkedList(); + /* + Sebastian Hauer's original StrictSSLProtocolSocketFactory used + getName() and had the following comment: + + Parses a X.500 distinguished name for the value of the + "Common Name" field. This is done a bit sloppy right + now and should probably be done a bit more according to + RFC 2253. + + I've noticed that toString() seems to do a better job than + getName() on these X500Principal objects, so I'm hoping that + addresses Sebastian's concern. + + For example, getName() gives me this: + 1.2.840.113549.1.9.1=#16166a756c6975736461766965734063756362632e636f6d + + whereas toString() gives me this: + EMAILADDRESS=juliusdavies@cucbc.com + + Looks like toString() even works with non-ascii domain names! + I tested it with "花子.co.jp" and it worked fine. + */ + String subjectPrincipal = cert.getSubjectX500Principal().toString(); + StringTokenizer st = new StringTokenizer(subjectPrincipal, ","); + while(st.hasMoreTokens()) { + String tok = st.nextToken(); + int x = tok.indexOf("CN="); + if(x >= 0) { + cnList.add(tok.substring(x + 3)); + } + } + if(!cnList.isEmpty()) { + String[] cns = new String[cnList.size()]; + cnList.toArray(cns); + return cns; + } else { + return null; + } + } + + /** + * Extracts the array of SubjectAlt DNS or IP names from an X509Certificate. + * Returns null if there aren't any. + * + * @param cert X509Certificate + * @param hostname + * @return Array of SubjectALT DNS or IP names stored in the certificate. + */ + private static String[] getSubjectAlts( + final X509Certificate cert, final String hostname) { + int subjectType; + if (isIPAddress(hostname)) { + subjectType = 7; + } else { + subjectType = 2; + } + + LinkedList subjectAltList = new LinkedList(); + Collection> c = null; + try { + c = cert.getSubjectAlternativeNames(); + } + catch(CertificateParsingException cpe) { + Logger.getLogger(AbstractVerifier.class.getName()) + .log(Level.FINE, "Error parsing certificate.", cpe); + } + if(c != null) { + for (List aC : c) { + List list = aC; + int type = ((Integer) list.get(0)).intValue(); + if (type == subjectType) { + String s = (String) list.get(1); + subjectAltList.add(s); + } + } + } + if(!subjectAltList.isEmpty()) { + String[] subjectAlts = new String[subjectAltList.size()]; + subjectAltList.toArray(subjectAlts); + return subjectAlts; + } else { + return null; + } + } + + /** + * Extracts the array of SubjectAlt DNS names from an X509Certificate. + * Returns null if there aren't any. + *

+ * Note: Java doesn't appear able to extract international characters + * from the SubjectAlts. It can only extract international characters + * from the CN field. + *

+ * (Or maybe the version of OpenSSL I'm using to test isn't storing the + * international characters correctly in the SubjectAlts?). + * + * @param cert X509Certificate + * @return Array of SubjectALT DNS names stored in the certificate. + */ + public static String[] getDNSSubjectAlts(X509Certificate cert) { + return getSubjectAlts(cert, null); + } + + /** + * Counts the number of dots "." in a string. + * @param s string to count dots from + * @return number of dots + */ + public static int countDots(final String s) { + int count = 0; + for(int i = 0; i < s.length(); i++) { + if(s.charAt(i) == '.') { + count++; + } + } + return count; + } + + private static boolean isIPAddress(final String hostname) { + return hostname != null && + (InetAddressUtils.isIPv4Address(hostname) || + InetAddressUtils.isIPv6Address(hostname)); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,54 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.ssl; + +import org.apache.http.annotation.Immutable; + +/** + * The ALLOW_ALL HostnameVerifier essentially turns hostname verification + * off. This implementation is a no-op, and never throws the SSLException. + * + * + * @since 4.0 + */ +@Immutable +public class AllowAllHostnameVerifier extends AbstractVerifier { + + public final void verify( + final String host, + final String[] cns, + final String[] subjectAlts) { + // Allow everything - so never blowup. + } + + @Override + public final String toString() { + return "ALLOW_ALL"; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/BrowserCompatHostnameVerifier.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/BrowserCompatHostnameVerifier.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/BrowserCompatHostnameVerifier.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,62 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.ssl; + +import javax.net.ssl.SSLException; + +import org.apache.http.annotation.Immutable; + +/** + * The HostnameVerifier that works the same way as Curl and Firefox. + *

+ * The hostname must match either the first CN, or any of the subject-alts. + * A wildcard can occur in the CN, and in any of the subject-alts. + *

+ * The only difference between BROWSER_COMPATIBLE and STRICT is that a wildcard + * (such as "*.foo.com") with BROWSER_COMPATIBLE matches all subdomains, + * including "a.b.foo.com". + * + * + * @since 4.0 + */ +@Immutable +public class BrowserCompatHostnameVerifier extends AbstractVerifier { + + public final void verify( + final String host, + final String[] cns, + final String[] subjectAlts) throws SSLException { + verify(host, cns, subjectAlts, false); + } + + @Override + public final String toString() { + return "BROWSER_COMPATIBLE"; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/SSLInitializationException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/SSLInitializationException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/SSLInitializationException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,37 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.conn.ssl; + +public class SSLInitializationException extends IllegalStateException { + + private static final long serialVersionUID = -8243587425648536702L; + + public SSLInitializationException(final String message, final Throwable cause) { + super(message, cause); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/SSLSocketFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/SSLSocketFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/SSLSocketFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,717 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.ssl; + +import org.apache.http.HttpHost; +import org.apache.http.annotation.ThreadSafe; + +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.conn.HttpInetSocketAddress; +import org.apache.http.conn.scheme.HostNameResolver; +import org.apache.http.conn.scheme.LayeredSchemeSocketFactory; +import org.apache.http.conn.scheme.LayeredSocketFactory; +import org.apache.http.conn.scheme.SchemeLayeredSocketFactory; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; + +/** + * Layered socket factory for TLS/SSL connections. + *

+ * SSLSocketFactory can be used to validate the identity of the HTTPS server against a list of + * trusted certificates and to authenticate to the HTTPS server using a private key. + *

+ * SSLSocketFactory will enable server authentication when supplied with + * a {@link KeyStore trust-store} file containing one or several trusted certificates. The client + * secure socket will reject the connection during the SSL session handshake if the target HTTPS + * server attempts to authenticate itself with a non-trusted certificate. + *

+ * Use JDK keytool utility to import a trusted certificate and generate a trust-store file: + *

+ *     keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
+ *    
+ *

+ * In special cases the standard trust verification process can be bypassed by using a custom + * {@link TrustStrategy}. This interface is primarily intended for allowing self-signed + * certificates to be accepted as trusted without having to add them to the trust-store file. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}
  • + *
+ *

+ * SSLSocketFactory will enable client authentication when supplied with + * a {@link KeyStore key-store} file containing a private key/public certificate + * pair. The client secure socket will use the private key to authenticate + * itself to the target HTTPS server during the SSL session handshake if + * requested to do so by the server. + * The target HTTPS server will in its turn verify the certificate presented + * by the client in order to establish client's authenticity + *

+ * Use the following sequence of actions to generate a key-store file + *

+ *
    + *
  • + *

    + * Use JDK keytool utility to generate a new key + *

    keytool -genkey -v -alias "my client key" -validity 365 -keystore my.keystore
    + * For simplicity use the same password for the key as that of the key-store + *

    + *
  • + *
  • + *

    + * Issue a certificate signing request (CSR) + *

    keytool -certreq -alias "my client key" -file mycertreq.csr -keystore my.keystore
    + *

    + *
  • + *
  • + *

    + * Send the certificate request to the trusted Certificate Authority for signature. + * One may choose to act as her own CA and sign the certificate request using a PKI + * tool, such as OpenSSL. + *

    + *
  • + *
  • + *

    + * Import the trusted CA root certificate + *

    keytool -import -alias "my trusted ca" -file caroot.crt -keystore my.keystore
    + *

    + *
  • + *
  • + *

    + * Import the PKCS#7 file containg the complete certificate chain + *

    keytool -import -alias "my client key" -file mycert.p7 -keystore my.keystore
    + *

    + *
  • + *
  • + *

    + * Verify the content the resultant keystore file + *

    keytool -list -v -keystore my.keystore
    + *

    + *
  • + *
+ * + * @since 4.0 + */ +@SuppressWarnings("deprecation") +@ThreadSafe +public class SSLSocketFactory implements SchemeLayeredSocketFactory, + LayeredSchemeSocketFactory, LayeredSocketFactory { + + public static final String TLS = "TLS"; + public static final String SSL = "SSL"; + public static final String SSLV2 = "SSLv2"; + + public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER + = new AllowAllHostnameVerifier(); + + public static final X509HostnameVerifier BROWSER_COMPATIBLE_HOSTNAME_VERIFIER + = new BrowserCompatHostnameVerifier(); + + public static final X509HostnameVerifier STRICT_HOSTNAME_VERIFIER + = new StrictHostnameVerifier(); + + private final static char[] EMPTY_PASSWORD = "".toCharArray(); + + /** + * Gets the default factory, which uses the default JSSE settings for initializing + * the SSL context. + * + * @return the default SSL socket factory + */ + public static SSLSocketFactory getSocketFactory() throws SSLInitializationException { + return new SSLSocketFactory(createDefaultSSLContext()); + } + + /** + * Gets the default factory, which uses system properties for initializing the SSL context + * as described in + * + * "JavaTM Secure Socket Extension (JSSE) Reference Guide for the JavaTM 2 Platform + * Standard Edition 5 + *

+ * The following system properties are taken into account by this method: + *

    + *
  • ssl.TrustManagerFactory.algorithm
  • + *
  • javax.net.ssl.trustStoreType
  • + *
  • javax.net.ssl.trustStore
  • + *
  • javax.net.ssl.trustStoreProvider
  • + *
  • javax.net.ssl.trustStorePassword
  • + *
  • java.home
  • + *
  • ssl.KeyManagerFactory.algorithm
  • + *
  • javax.net.ssl.keyStoreType
  • + *
  • javax.net.ssl.keyStore
  • + *
  • javax.net.ssl.keyStoreProvider
  • + *
  • javax.net.ssl.keyStorePassword
  • + *
+ *

+ * + * @return the system SSL socket factory + */ + public static SSLSocketFactory getSystemSocketFactory() throws SSLInitializationException { + return new SSLSocketFactory(createSystemSSLContext()); + } + + private final javax.net.ssl.SSLSocketFactory socketfactory; + private final HostNameResolver nameResolver; + // TODO: make final + private volatile X509HostnameVerifier hostnameVerifier; + + private static SSLContext createSSLContext( + String algorithm, + final KeyStore keystore, + final String keystorePassword, + final KeyStore truststore, + final SecureRandom random, + final TrustStrategy trustStrategy) + throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException { + if (algorithm == null) { + algorithm = TLS; + } + KeyManagerFactory kmfactory = KeyManagerFactory.getInstance( + KeyManagerFactory.getDefaultAlgorithm()); + kmfactory.init(keystore, keystorePassword != null ? keystorePassword.toCharArray(): null); + KeyManager[] keymanagers = kmfactory.getKeyManagers(); + TrustManagerFactory tmfactory = TrustManagerFactory.getInstance( + TrustManagerFactory.getDefaultAlgorithm()); + tmfactory.init(truststore); + TrustManager[] trustmanagers = tmfactory.getTrustManagers(); + if (trustmanagers != null && trustStrategy != null) { + for (int i = 0; i < trustmanagers.length; i++) { + TrustManager tm = trustmanagers[i]; + if (tm instanceof X509TrustManager) { + trustmanagers[i] = new TrustManagerDecorator( + (X509TrustManager) tm, trustStrategy); + } + } + } + + SSLContext sslcontext = SSLContext.getInstance(algorithm); + sslcontext.init(keymanagers, trustmanagers, random); + return sslcontext; + } + + private static SSLContext createSystemSSLContext( + String algorithm, + final SecureRandom random) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, + KeyStoreException, CertificateException, UnrecoverableKeyException, KeyManagementException { + if (algorithm == null) { + algorithm = TLS; + } + TrustManagerFactory tmfactory = null; + + String trustAlgorithm = System.getProperty("ssl.TrustManagerFactory.algorithm"); + if (trustAlgorithm == null) { + trustAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); + } + String trustStoreType = System.getProperty("javax.net.ssl.trustStoreType"); + if (trustStoreType == null) { + trustStoreType = KeyStore.getDefaultType(); + } + if ("none".equalsIgnoreCase(trustStoreType)) { + tmfactory = TrustManagerFactory.getInstance(trustAlgorithm); + } else { + File trustStoreFile = null; + String s = System.getProperty("javax.net.ssl.trustStore"); + if (s != null) { + trustStoreFile = new File(s); + tmfactory = TrustManagerFactory.getInstance(trustAlgorithm); + String trustStoreProvider = System.getProperty("javax.net.ssl.trustStoreProvider"); + KeyStore trustStore; + if (trustStoreProvider != null) { + trustStore = KeyStore.getInstance(trustStoreType, trustStoreProvider); + } else { + trustStore = KeyStore.getInstance(trustStoreType); + } + String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); + FileInputStream instream = new FileInputStream(trustStoreFile); + try { + trustStore.load(instream, trustStorePassword != null ? + trustStorePassword.toCharArray() : EMPTY_PASSWORD); + } finally { + instream.close(); + } + tmfactory.init(trustStore); + } else { + File javaHome = new File(System.getProperty("java.home")); + File file = new File(javaHome, "lib/security/jssecacerts"); + if (!file.exists()) { + file = new File(javaHome, "lib/security/cacerts"); + trustStoreFile = file; + } else { + trustStoreFile = file; + } + tmfactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + String trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); + FileInputStream instream = new FileInputStream(trustStoreFile); + try { + trustStore.load(instream, trustStorePassword != null ? trustStorePassword.toCharArray() : null); + } finally { + instream.close(); + } + tmfactory.init(trustStore); + } + } + + KeyManagerFactory kmfactory = null; + String keyAlgorithm = System.getProperty("ssl.KeyManagerFactory.algorithm"); + if (keyAlgorithm == null) { + keyAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); + } + String keyStoreType = System.getProperty("javax.net.ssl.keyStoreType"); + if (keyStoreType == null) { + keyStoreType = KeyStore.getDefaultType(); + } + if ("none".equalsIgnoreCase(keyStoreType)) { + kmfactory = KeyManagerFactory.getInstance(keyAlgorithm); + } else { + File keyStoreFile = null; + String s = System.getProperty("javax.net.ssl.keyStore"); + if (s != null) { + keyStoreFile = new File(s); + } + if (keyStoreFile != null) { + kmfactory = KeyManagerFactory.getInstance(keyAlgorithm); + String keyStoreProvider = System.getProperty("javax.net.ssl.keyStoreProvider"); + KeyStore keyStore; + if (keyStoreProvider != null) { + keyStore = KeyStore.getInstance(keyStoreType, keyStoreProvider); + } else { + keyStore = KeyStore.getInstance(keyStoreType); + } + String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword"); + FileInputStream instream = new FileInputStream(keyStoreFile); + try { + keyStore.load(instream, keyStorePassword != null ? + keyStorePassword.toCharArray() : EMPTY_PASSWORD); + } finally { + instream.close(); + } + kmfactory.init(keyStore, keyStorePassword != null ? + keyStorePassword.toCharArray() : EMPTY_PASSWORD); + } + } + + SSLContext sslcontext = SSLContext.getInstance(algorithm); + sslcontext.init( + kmfactory != null ? kmfactory.getKeyManagers() : null, + tmfactory != null ? tmfactory.getTrustManagers() : null, + random); + return sslcontext; + } + + private static SSLContext createDefaultSSLContext() throws SSLInitializationException { + try { + return createSSLContext(TLS, null, null, null, null, null); + } catch (Exception ex) { + throw new SSLInitializationException("Failure initializing default SSL context", ex); + } + } + + private static SSLContext createSystemSSLContext() throws SSLInitializationException { + try { + return createSystemSSLContext(TLS, null); + } catch (Exception ex) { + throw new SSLInitializationException("Failure initializing default system SSL context", ex); + } + } + + /** + * @deprecated Use {@link #SSLSocketFactory(String, KeyStore, String, KeyStore, SecureRandom, X509HostnameVerifier)} + */ + @Deprecated + public SSLSocketFactory( + final String algorithm, + final KeyStore keystore, + final String keystorePassword, + final KeyStore truststore, + final SecureRandom random, + final HostNameResolver nameResolver) + throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { + this(createSSLContext( + algorithm, keystore, keystorePassword, truststore, random, null), + nameResolver); + } + + /** + * @since 4.1 + */ + public SSLSocketFactory( + String algorithm, + final KeyStore keystore, + final String keystorePassword, + final KeyStore truststore, + final SecureRandom random, + final X509HostnameVerifier hostnameVerifier) + throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { + this(createSSLContext( + algorithm, keystore, keystorePassword, truststore, random, null), + hostnameVerifier); + } + + /** + * @since 4.1 + */ + public SSLSocketFactory( + String algorithm, + final KeyStore keystore, + final String keystorePassword, + final KeyStore truststore, + final SecureRandom random, + final TrustStrategy trustStrategy, + final X509HostnameVerifier hostnameVerifier) + throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { + this(createSSLContext( + algorithm, keystore, keystorePassword, truststore, random, trustStrategy), + hostnameVerifier); + } + + public SSLSocketFactory( + final KeyStore keystore, + final String keystorePassword, + final KeyStore truststore) + throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { + this(TLS, keystore, keystorePassword, truststore, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + } + + public SSLSocketFactory( + final KeyStore keystore, + final String keystorePassword) + throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException{ + this(TLS, keystore, keystorePassword, null, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + } + + public SSLSocketFactory( + final KeyStore truststore) + throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { + this(TLS, null, null, truststore, null, null, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + } + + /** + * @since 4.1 + */ + public SSLSocketFactory( + final TrustStrategy trustStrategy, + final X509HostnameVerifier hostnameVerifier) + throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { + this(TLS, null, null, null, null, trustStrategy, hostnameVerifier); + } + + /** + * @since 4.1 + */ + public SSLSocketFactory( + final TrustStrategy trustStrategy) + throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException { + this(TLS, null, null, null, null, trustStrategy, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + } + + public SSLSocketFactory(final SSLContext sslContext) { + this(sslContext, BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + } + + /** + * @deprecated Use {@link #SSLSocketFactory(SSLContext)} + */ + @Deprecated + public SSLSocketFactory( + final SSLContext sslContext, final HostNameResolver nameResolver) { + super(); + this.socketfactory = sslContext.getSocketFactory(); + this.hostnameVerifier = BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; + this.nameResolver = nameResolver; + } + + /** + * @since 4.1 + */ + public SSLSocketFactory( + final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) { + super(); + if (sslContext == null) { + throw new IllegalArgumentException("SSL context may not be null"); + } + this.socketfactory = sslContext.getSocketFactory(); + this.hostnameVerifier = hostnameVerifier; + this.nameResolver = null; + } + + /** + * @since 4.2 + */ + public SSLSocketFactory( + final javax.net.ssl.SSLSocketFactory socketfactory, + final X509HostnameVerifier hostnameVerifier) { + if (socketfactory == null) { + throw new IllegalArgumentException("SSL socket factory may not be null"); + } + this.socketfactory = socketfactory; + this.hostnameVerifier = hostnameVerifier; + this.nameResolver = null; + } + + /** + * @param params Optional parameters. Parameters passed to this method will have no effect. + * This method will create a unconnected instance of {@link Socket} class. + * @since 4.1 + */ + public Socket createSocket(final HttpParams params) throws IOException { + SSLSocket sock = (SSLSocket) this.socketfactory.createSocket(); + prepareSocket(sock); + return sock; + } + + @Deprecated + public Socket createSocket() throws IOException { + SSLSocket sock = (SSLSocket) this.socketfactory.createSocket(); + prepareSocket(sock); + return sock; + } + + /** + * @since 4.1 + */ + public Socket connectSocket( + final Socket socket, + final InetSocketAddress remoteAddress, + final InetSocketAddress localAddress, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + if (remoteAddress == null) { + throw new IllegalArgumentException("Remote address may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + Socket sock = socket != null ? socket : this.socketfactory.createSocket(); + if (localAddress != null) { + sock.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params)); + sock.bind(localAddress); + } + + int connTimeout = HttpConnectionParams.getConnectionTimeout(params); + int soTimeout = HttpConnectionParams.getSoTimeout(params); + + try { + sock.setSoTimeout(soTimeout); + sock.connect(remoteAddress, connTimeout); + } catch (SocketTimeoutException ex) { + throw new ConnectTimeoutException("Connect to " + remoteAddress + " timed out"); + } + + String hostname; + if (remoteAddress instanceof HttpInetSocketAddress) { + hostname = ((HttpInetSocketAddress) remoteAddress).getHttpHost().getHostName(); + } else { + hostname = remoteAddress.getHostName(); + } + + SSLSocket sslsock; + // Setup SSL layering if necessary + if (sock instanceof SSLSocket) { + sslsock = (SSLSocket) sock; + } else { + int port = remoteAddress.getPort(); + sslsock = (SSLSocket) this.socketfactory.createSocket(sock, hostname, port, true); + prepareSocket(sslsock); + } + if (this.hostnameVerifier != null) { + try { + this.hostnameVerifier.verify(hostname, sslsock); + // verifyHostName() didn't blowup - good! + } catch (IOException iox) { + // close the socket before re-throwing the exception + try { sslsock.close(); } catch (Exception x) { /*ignore*/ } + throw iox; + } + } + return sslsock; + } + + + /** + * Checks whether a socket connection is secure. + * This factory creates TLS/SSL socket connections + * which, by default, are considered secure. + *
+ * Derived classes may override this method to perform + * runtime checks, for example based on the cypher suite. + * + * @param sock the connected socket + * + * @return true + * + * @throws IllegalArgumentException if the argument is invalid + */ + public boolean isSecure(final Socket sock) throws IllegalArgumentException { + if (sock == null) { + throw new IllegalArgumentException("Socket may not be null"); + } + // This instanceof check is in line with createSocket() above. + if (!(sock instanceof SSLSocket)) { + throw new IllegalArgumentException("Socket not created by this factory"); + } + // This check is performed last since it calls the argument object. + if (sock.isClosed()) { + throw new IllegalArgumentException("Socket is closed"); + } + return true; + } + + /** + * @since 4.2 + */ + public Socket createLayeredSocket( + final Socket socket, + final String host, + final int port, + final HttpParams params) throws IOException, UnknownHostException { + SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket( + socket, + host, + port, + true); + prepareSocket(sslSocket); + if (this.hostnameVerifier != null) { + this.hostnameVerifier.verify(host, sslSocket); + } + // verifyHostName() didn't blowup - good! + return sslSocket; + } + + /** + * @deprecated use {@link #createLayeredSocket(Socket, String, int, HttpParams)} + */ + public Socket createLayeredSocket( + final Socket socket, + final String host, + final int port, + final boolean autoClose) throws IOException, UnknownHostException { + SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket( + socket, + host, + port, + autoClose + ); + prepareSocket(sslSocket); + if (this.hostnameVerifier != null) { + this.hostnameVerifier.verify(host, sslSocket); + } + // verifyHostName() didn't blowup - good! + return sslSocket; + } + + @Deprecated + public void setHostnameVerifier(X509HostnameVerifier hostnameVerifier) { + if ( hostnameVerifier == null ) { + throw new IllegalArgumentException("Hostname verifier may not be null"); + } + this.hostnameVerifier = hostnameVerifier; + } + + public X509HostnameVerifier getHostnameVerifier() { + return this.hostnameVerifier; + } + + /** + * @deprecated Use {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)} + */ + @Deprecated + public Socket connectSocket( + final Socket socket, + final String host, int port, + final InetAddress localAddress, int localPort, + final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + InetSocketAddress local = null; + if (localAddress != null || localPort > 0) { + // we need to bind explicitly + if (localPort < 0) { + localPort = 0; // indicates "any" + } + local = new InetSocketAddress(localAddress, localPort); + } + InetAddress remoteAddress; + if (this.nameResolver != null) { + remoteAddress = this.nameResolver.resolve(host); + } else { + remoteAddress = InetAddress.getByName(host); + } + InetSocketAddress remote = new HttpInetSocketAddress(new HttpHost(host, port), remoteAddress, port); + return connectSocket(socket, remote, local, params); + } + + /** + * @deprecated Use {@link #createLayeredSocket(Socket, String, int, boolean)} + */ + @Deprecated + public Socket createSocket( + final Socket socket, + final String host, int port, + boolean autoClose) throws IOException, UnknownHostException { + return createLayeredSocket(socket, host, port, autoClose); + } + + /** + * Performs any custom initialization for a newly created SSLSocket + * (before the SSL handshake happens). + * + * The default implementation is a no-op, but could be overriden to, e.g., + * call {@link SSLSocket#setEnabledCipherSuites(java.lang.String[])}. + * + * @since 4.2 + */ + protected void prepareSocket(final SSLSocket socket) throws IOException { + } +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/StrictHostnameVerifier.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/StrictHostnameVerifier.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/StrictHostnameVerifier.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,69 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.ssl; + +import javax.net.ssl.SSLException; + +import org.apache.http.annotation.Immutable; + +/** + * The Strict HostnameVerifier works the same way as Sun Java 1.4, Sun + * Java 5, Sun Java 6-rc. It's also pretty close to IE6. This + * implementation appears to be compliant with RFC 2818 for dealing with + * wildcards. + *

+ * The hostname must match either the first CN, or any of the subject-alts. + * A wildcard can occur in the CN, and in any of the subject-alts. The + * one divergence from IE6 is how we only check the first CN. IE6 allows + * a match against any of the CNs present. We decided to follow in + * Sun Java 1.4's footsteps and only check the first CN. (If you need + * to check all the CN's, feel free to write your own implementation!). + *

+ * A wildcard such as "*.foo.com" matches only subdomains in the same + * level, for example "a.foo.com". It does not match deeper subdomains + * such as "a.b.foo.com". + * + * + * @since 4.0 + */ +@Immutable +public class StrictHostnameVerifier extends AbstractVerifier { + + public final void verify( + final String host, + final String[] cns, + final String[] subjectAlts) throws SSLException { + verify(host, cns, subjectAlts, true); + } + + @Override + public final String toString() { + return "STRICT"; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/TrustManagerDecorator.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/TrustManagerDecorator.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/TrustManagerDecorator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,64 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.conn.ssl; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.X509TrustManager; + +/** + * @since 4.1 + */ +class TrustManagerDecorator implements X509TrustManager { + + private final X509TrustManager trustManager; + private final TrustStrategy trustStrategy; + + TrustManagerDecorator(final X509TrustManager trustManager, final TrustStrategy trustStrategy) { + super(); + this.trustManager = trustManager; + this.trustStrategy = trustStrategy; + } + + public void checkClientTrusted( + final X509Certificate[] chain, final String authType) throws CertificateException { + this.trustManager.checkClientTrusted(chain, authType); + } + + public void checkServerTrusted( + final X509Certificate[] chain, final String authType) throws CertificateException { + if (!this.trustStrategy.isTrusted(chain, authType)) { + this.trustManager.checkServerTrusted(chain, authType); + } + } + + public X509Certificate[] getAcceptedIssuers() { + return this.trustManager.getAcceptedIssuers(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/TrustSelfSignedStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/TrustSelfSignedStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/TrustSelfSignedStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,45 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.conn.ssl; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +/** + * A trust strategy that accepts self-signed certificates as trusted. Verification of all other + * certificates is done by the trust manager configured in the SSL context. + * + * @since 4.1 + */ +public class TrustSelfSignedStrategy implements TrustStrategy { + + public boolean isTrusted( + final X509Certificate[] chain, final String authType) throws CertificateException { + return chain.length == 1; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/TrustStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/TrustStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/TrustStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,57 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.conn.ssl; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +/** + * A strategy to establish trustworthiness of certificates without consulting the trust manager + * configured in the actual SSL context. This interface can be used to override the standard + * JSSE certificate verification process. + * + * @since 4.1 + */ +public interface TrustStrategy { + + /** + * Determines whether the certificate chain can be trusted without consulting the trust manager + * configured in the actual SSL context. This method can be used to override the standard JSSE + * certificate verification process. + *

+ * Please note that, if this method returns false, the trust manager configured + * in the actual SSL context can still clear the certificate as trusted. + * + * @param chain the peer certificate chain + * @param authType the authentication type based on the client certificate + * @return true if the certificate can be trusted without verification by + * the trust manager, false otherwise. + * @throws CertificateException thrown if the certificate is not trusted or invalid. + */ + boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/X509HostnameVerifier.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/X509HostnameVerifier.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/X509HostnameVerifier.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,84 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.ssl; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSocket; +import java.io.IOException; +import java.security.cert.X509Certificate; + +/** + * Interface for checking if a hostname matches the names stored inside the + * server's X.509 certificate. This interface extends + * {@link javax.net.ssl.HostnameVerifier}, but it is recommended to use + * methods added by X509HostnameVerifier. + * + * @since 4.0 + */ +public interface X509HostnameVerifier extends HostnameVerifier { + + /** + * Verifies that the host name is an acceptable match with the server's + * authentication scheme based on the given {@link SSLSocket}. + * + * @param host the host. + * @param ssl the SSL socket. + * @throws IOException if an I/O error occurs or the verification process + * fails. + */ + void verify(String host, SSLSocket ssl) throws IOException; + + /** + * Verifies that the host name is an acceptable match with the server's + * authentication scheme based on the given {@link X509Certificate}. + * + * @param host the host. + * @param cert the certificate. + * @throws SSLException if the verification process fails. + */ + void verify(String host, X509Certificate cert) throws SSLException; + + /** + * Checks to see if the supplied hostname matches any of the supplied CNs + * or "DNS" Subject-Alts. Most implementations only look at the first CN, + * and ignore any additional CNs. Most implementations do look at all of + * the "DNS" Subject-Alts. The CNs or Subject-Alts may contain wildcards + * according to RFC 2818. + * + * @param cns CN fields, in order, as extracted from the X.509 + * certificate. + * @param subjectAlts Subject-Alt fields of type 2 ("DNS"), as extracted + * from the X.509 certificate. + * @param host The hostname to verify. + * @throws SSLException if the verification process fails. + */ + void verify(String host, String[] cns, String[] subjectAlts) + throws SSLException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/ssl/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/ssl/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/ssl/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,35 @@ + + + + + +TLS/SSL specific API. + + Index: 3rdParty_sources/httpclient/org/apache/http/conn/util/InetAddressUtils.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/util/InetAddressUtils.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/util/InetAddressUtils.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,73 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.conn.util; + +import java.util.regex.Pattern; + +import org.apache.http.annotation.Immutable; + +/** + * A collection of utilities relating to InetAddresses. + * + * @since 4.0 + */ +@Immutable +public class InetAddressUtils { + + private InetAddressUtils() { + } + + private static final Pattern IPV4_PATTERN = + Pattern.compile( + "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$"); + + private static final Pattern IPV6_STD_PATTERN = + Pattern.compile( + "^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$"); + + private static final Pattern IPV6_HEX_COMPRESSED_PATTERN = + Pattern.compile( + "^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$"); + + public static boolean isIPv4Address(final String input) { + return IPV4_PATTERN.matcher(input).matches(); + } + + public static boolean isIPv6StdAddress(final String input) { + return IPV6_STD_PATTERN.matcher(input).matches(); + } + + public static boolean isIPv6HexCompressedAddress(final String input) { + return IPV6_HEX_COMPRESSED_PATTERN.matcher(input).matches(); + } + + public static boolean isIPv6Address(final String input) { + return isIPv6StdAddress(input) || isIPv6HexCompressedAddress(input); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/conn/util/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/conn/util/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/conn/util/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,35 @@ + + + + + +A collection of HTTP connection utility classes. + + Index: 3rdParty_sources/httpclient/org/apache/http/cookie/ClientCookie.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/ClientCookie.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/ClientCookie.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,62 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +/** + * ClientCookie extends the standard {@link Cookie} interface with + * additional client specific functionality such ability to retrieve + * original cookie attributes exactly as they were specified by the + * origin server. This is important for generating the Cookie + * header because some cookie specifications require that the + * Cookie header should include certain attributes only if + * they were specified in the Set-Cookie header. + * + * + * @since 4.0 + */ +public interface ClientCookie extends Cookie { + + // RFC2109 attributes + public static final String VERSION_ATTR = "version"; + public static final String PATH_ATTR = "path"; + public static final String DOMAIN_ATTR = "domain"; + public static final String MAX_AGE_ATTR = "max-age"; + public static final String SECURE_ATTR = "secure"; + public static final String COMMENT_ATTR = "comment"; + public static final String EXPIRES_ATTR = "expires"; + + // RFC2965 attributes + public static final String PORT_ATTR = "port"; + public static final String COMMENTURL_ATTR = "commenturl"; + public static final String DISCARD_ATTR = "discard"; + + String getAttribute(String name); + + boolean containsAttribute(String name); + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/Cookie.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/Cookie.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/Cookie.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,137 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +import java.util.Date; + +/** + * Cookie interface represents a token or short packet of state information + * (also referred to as "magic-cookie") that the HTTP agent and the target + * server can exchange to maintain a session. In its simples form an HTTP + * cookie is merely a name / value pair. + * + * @since 4.0 + */ +public interface Cookie { + + /** + * Returns the name. + * + * @return String name The name + */ + String getName(); + + /** + * Returns the value. + * + * @return String value The current value. + */ + String getValue(); + + /** + * Returns the comment describing the purpose of this cookie, or + * null if no such comment has been defined. + * + * @return comment + */ + String getComment(); + + /** + * If a user agent (web browser) presents this cookie to a user, the + * cookie's purpose will be described by the information at this URL. + */ + String getCommentURL(); + + /** + * Returns the expiration {@link Date} of the cookie, or null + * if none exists. + *

Note: the object returned by this method is + * considered immutable. Changing it (e.g. using setTime()) could result + * in undefined behaviour. Do so at your peril.

+ * @return Expiration {@link Date}, or null. + */ + Date getExpiryDate(); + + /** + * Returns false if the cookie should be discarded at the end + * of the "session"; true otherwise. + * + * @return false if the cookie should be discarded at the end + * of the "session"; true otherwise + */ + boolean isPersistent(); + + /** + * Returns domain attribute of the cookie. The value of the Domain + * attribute specifies the domain for which the cookie is valid. + * + * @return the value of the domain attribute. + */ + String getDomain(); + + /** + * Returns the path attribute of the cookie. The value of the Path + * attribute specifies the subset of URLs on the origin server to which + * this cookie applies. + * + * @return The value of the path attribute. + */ + String getPath(); + + /** + * Get the Port attribute. It restricts the ports to which a cookie + * may be returned in a Cookie request header. + */ + int[] getPorts(); + + /** + * Indicates whether this cookie requires a secure connection. + * + * @return true if this cookie should only be sent + * over secure connections, false otherwise. + */ + boolean isSecure(); + + /** + * Returns the version of the cookie specification to which this + * cookie conforms. + * + * @return the version of the cookie. + */ + int getVersion(); + + /** + * Returns true if this cookie has expired. + * @param date Current time + * + * @return true if the cookie has expired. + */ + boolean isExpired(final Date date); + +} + Index: 3rdParty_sources/httpclient/org/apache/http/cookie/CookieAttributeHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/CookieAttributeHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/CookieAttributeHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,73 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.cookie; + +/** + * This interface represents a cookie attribute handler responsible + * for parsing, validating, and matching a specific cookie attribute, + * such as path, domain, port, etc. + * + * Different cookie specifications can provide a specific + * implementation for this class based on their cookie handling + * rules. + * + * + * @since 4.0 + */ +public interface CookieAttributeHandler { + + /** + * Parse the given cookie attribute value and update the corresponding + * {@link org.apache.http.cookie.Cookie} property. + * + * @param cookie {@link org.apache.http.cookie.Cookie} to be updated + * @param value cookie attribute value from the cookie response header + */ + void parse(SetCookie cookie, String value) + throws MalformedCookieException; + + /** + * Peforms cookie validation for the given attribute value. + * + * @param cookie {@link org.apache.http.cookie.Cookie} to validate + * @param origin the cookie source to validate against + * @throws MalformedCookieException if cookie validation fails for this attribute + */ + void validate(Cookie cookie, CookieOrigin origin) + throws MalformedCookieException; + + /** + * Matches the given value (property of the destination host where request is being + * submitted) with the corresponding cookie attribute. + * + * @param cookie {@link org.apache.http.cookie.Cookie} to match + * @param origin the cookie source to match against + * @return true if the match is successful; false otherwise + */ + boolean match(Cookie cookie, CookieOrigin origin); + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/CookieIdentityComparator.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/CookieIdentityComparator.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/CookieIdentityComparator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,80 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +import java.io.Serializable; +import java.util.Comparator; + +import org.apache.http.annotation.Immutable; + +/** + * This cookie comparator can be used to compare identity of cookies. + *

+ * Cookies are considered identical if their names are equal and + * their domain attributes match ignoring case. + * + * @since 4.0 + */ +@Immutable +public class CookieIdentityComparator implements Serializable, Comparator { + + private static final long serialVersionUID = 4466565437490631532L; + + public int compare(final Cookie c1, final Cookie c2) { + int res = c1.getName().compareTo(c2.getName()); + if (res == 0) { + // do not differentiate empty and null domains + String d1 = c1.getDomain(); + if (d1 == null) { + d1 = ""; + } else if (d1.indexOf('.') == -1) { + d1 = d1 + ".local"; + } + String d2 = c2.getDomain(); + if (d2 == null) { + d2 = ""; + } else if (d2.indexOf('.') == -1) { + d2 = d2 + ".local"; + } + res = d1.compareToIgnoreCase(d2); + } + if (res == 0) { + String p1 = c1.getPath(); + if (p1 == null) { + p1 = "/"; + } + String p2 = c2.getPath(); + if (p2 == null) { + p2 = "/"; + } + res = p1.compareTo(p2); + } + return res; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/CookieOrigin.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/CookieOrigin.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/CookieOrigin.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,105 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.cookie; + +import java.util.Locale; + +import org.apache.http.annotation.Immutable; + +/** + * CookieOrigin class encapsulates details of an origin server that + * are relevant when parsing, validating or matching HTTP cookies. + * + * @since 4.0 + */ +@Immutable +public final class CookieOrigin { + + private final String host; + private final int port; + private final String path; + private final boolean secure; + + public CookieOrigin(final String host, int port, final String path, boolean secure) { + super(); + if (host == null) { + throw new IllegalArgumentException( + "Host of origin may not be null"); + } + if (host.trim().length() == 0) { + throw new IllegalArgumentException( + "Host of origin may not be blank"); + } + if (port < 0) { + throw new IllegalArgumentException("Invalid port: " + port); + } + if (path == null) { + throw new IllegalArgumentException( + "Path of origin may not be null."); + } + this.host = host.toLowerCase(Locale.ENGLISH); + this.port = port; + if (path.trim().length() != 0) { + this.path = path; + } else { + this.path = "/"; + } + this.secure = secure; + } + + public String getHost() { + return this.host; + } + + public String getPath() { + return this.path; + } + + public int getPort() { + return this.port; + } + + public boolean isSecure() { + return this.secure; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append('['); + if (this.secure) { + buffer.append("(secure)"); + } + buffer.append(this.host); + buffer.append(':'); + buffer.append(Integer.toString(this.port)); + buffer.append(this.path); + buffer.append(']'); + return buffer.toString(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/CookiePathComparator.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/CookiePathComparator.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/CookiePathComparator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,81 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +import java.io.Serializable; +import java.util.Comparator; + +import org.apache.http.annotation.Immutable; + +/** + * This cookie comparator ensures that multiple cookies satisfying + * a common criteria are ordered in the Cookie header such + * that those with more specific Path attributes precede those with + * less specific. + * + *

+ * This comparator assumes that Path attributes of two cookies + * path-match a commmon request-URI. Otherwise, the result of the + * comparison is undefined. + *

+ * + * + * @since 4.0 + */ +@Immutable +public class CookiePathComparator implements Serializable, Comparator { + + private static final long serialVersionUID = 7523645369616405818L; + + private String normalizePath(final Cookie cookie) { + String path = cookie.getPath(); + if (path == null) { + path = "/"; + } + if (!path.endsWith("/")) { + path = path + '/'; + } + return path; + } + + public int compare(final Cookie c1, final Cookie c2) { + String path1 = normalizePath(c1); + String path2 = normalizePath(c2); + if (path1.equals(path2)) { + return 0; + } else if (path1.startsWith(path2)) { + return -1; + } else if (path2.startsWith(path1)) { + return 1; + } else { + // Does not really matter + return 0; + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/CookieRestrictionViolationException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/CookieRestrictionViolationException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/CookieRestrictionViolationException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,61 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +import org.apache.http.annotation.Immutable; + +/** + * Signals that a cookie violates a restriction imposed by the cookie + * specification. + * + * @since 4.1 + */ +@Immutable +public class CookieRestrictionViolationException extends MalformedCookieException { + + private static final long serialVersionUID = 7371235577078589013L; + + /** + * Creates a new CookeFormatViolationException with a null detail + * message. + */ + public CookieRestrictionViolationException() { + super(); + } + + /** + * Creates a new CookeRestrictionViolationException with a specified + * message string. + * + * @param message The exception detail message + */ + public CookieRestrictionViolationException(String message) { + super(message); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/CookieSpec.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/CookieSpec.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/CookieSpec.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,109 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +import java.util.List; + +import org.apache.http.Header; + +/** + * Defines the cookie management specification. + *

Cookie management specification must define + *

    + *
  • rules of parsing "Set-Cookie" header + *
  • rules of validation of parsed cookies + *
  • formatting of "Cookie" header + *
+ * for a given host, port and path of origin + * + * + * @since 4.0 + */ +public interface CookieSpec { + + /** + * Returns version of the state management this cookie specification + * conforms to. + * + * @return version of the state management specification + */ + int getVersion(); + + /** + * Parse the "Set-Cookie" Header into an array of Cookies. + * + *

This method will not perform the validation of the resultant + * {@link Cookie}s

+ * + * @see #validate + * + * @param header the Set-Cookie received from the server + * @param origin details of the cookie origin + * @return an array of Cookies parsed from the header + * @throws MalformedCookieException if an exception occurs during parsing + */ + List parse(Header header, CookieOrigin origin) throws MalformedCookieException; + + /** + * Validate the cookie according to validation rules defined by the + * cookie specification. + * + * @param cookie the Cookie to validate + * @param origin details of the cookie origin + * @throws MalformedCookieException if the cookie is invalid + */ + void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException; + + /** + * Determines if a Cookie matches the target location. + * + * @param cookie the Cookie to be matched + * @param origin the target to test against + * + * @return true if the cookie should be submitted with a request + * with given attributes, false otherwise. + */ + boolean match(Cookie cookie, CookieOrigin origin); + + /** + * Create "Cookie" headers for an array of Cookies. + * + * @param cookies the Cookies format into a Cookie header + * @return a Header for the given Cookies. + * @throws IllegalArgumentException if an input parameter is illegal + */ + List
formatCookies(List cookies); + + /** + * Returns a request header identifying what version of the state management + * specification is understood. May be null if the cookie + * specification does not support Cookie2 header. + */ + Header getVersionHeader(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/CookieSpecFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/CookieSpecFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/CookieSpecFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,48 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +import org.apache.http.params.HttpParams; + +/** + * Factory for {@link CookieSpec} implementations. + * + * @since 4.0 + */ +public interface CookieSpecFactory { + + /** + * Creates an instance of {@link CookieSpec} using given HTTP parameters. + * + * @param params HTTP parameters. + * + * @return cookie spec. + */ + CookieSpec newInstance(HttpParams params); + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/CookieSpecRegistry.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/CookieSpecRegistry.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/CookieSpecRegistry.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,157 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.http.annotation.ThreadSafe; + +import org.apache.http.params.HttpParams; + +/** + * Cookie specification registry that can be used to obtain the corresponding + * cookie specification implementation for a given type of type or version of + * cookie. + * + * + * @since 4.0 + */ +@ThreadSafe +public final class CookieSpecRegistry { + + private final ConcurrentHashMap registeredSpecs; + + public CookieSpecRegistry() { + super(); + this.registeredSpecs = new ConcurrentHashMap(); + } + + /** + * Registers a {@link CookieSpecFactory} with the given identifier. + * If a specification with the given name already exists it will be overridden. + * This nameis the same one used to retrieve the {@link CookieSpecFactory} + * from {@link #getCookieSpec(String)}. + * + * @param name the identifier for this specification + * @param factory the {@link CookieSpecFactory} class to register + * + * @see #getCookieSpec(String) + */ + public void register(final String name, final CookieSpecFactory factory) { + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + if (factory == null) { + throw new IllegalArgumentException("Cookie spec factory may not be null"); + } + registeredSpecs.put(name.toLowerCase(Locale.ENGLISH), factory); + } + + /** + * Unregisters the {@link CookieSpecFactory} with the given ID. + * + * @param id the identifier of the {@link CookieSpec cookie specification} to unregister + */ + public void unregister(final String id) { + if (id == null) { + throw new IllegalArgumentException("Id may not be null"); + } + registeredSpecs.remove(id.toLowerCase(Locale.ENGLISH)); + } + + /** + * Gets the {@link CookieSpec cookie specification} with the given ID. + * + * @param name the {@link CookieSpec cookie specification} identifier + * @param params the {@link HttpParams HTTP parameters} for the cookie + * specification. + * + * @return {@link CookieSpec cookie specification} + * + * @throws IllegalStateException if a policy with the given name cannot be found + */ + public CookieSpec getCookieSpec(final String name, final HttpParams params) + throws IllegalStateException { + + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + CookieSpecFactory factory = registeredSpecs.get(name.toLowerCase(Locale.ENGLISH)); + if (factory != null) { + return factory.newInstance(params); + } else { + throw new IllegalStateException("Unsupported cookie spec: " + name); + } + } + + /** + * Gets the {@link CookieSpec cookie specification} with the given name. + * + * @param name the {@link CookieSpec cookie specification} identifier + * + * @return {@link CookieSpec cookie specification} + * + * @throws IllegalStateException if a policy with the given name cannot be found + */ + public CookieSpec getCookieSpec(final String name) + throws IllegalStateException { + return getCookieSpec(name, null); + } + + /** + * Obtains a list containing the names of all registered {@link CookieSpec cookie + * specs}. + * + * Note that the DEFAULT policy (if present) is likely to be the same + * as one of the other policies, but does not have to be. + * + * @return list of registered cookie spec names + */ + public List getSpecNames(){ + return new ArrayList(registeredSpecs.keySet()); + } + + /** + * Populates the internal collection of registered {@link CookieSpec cookie + * specs} with the content of the map passed as a parameter. + * + * @param map cookie specs + */ + public void setItems(final Map map) { + if (map == null) { + return; + } + registeredSpecs.clear(); + registeredSpecs.putAll(map); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/MalformedCookieException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/MalformedCookieException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/MalformedCookieException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,72 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.ProtocolException; + +/** + * Signals that a cookie is in some way invalid or illegal in a given + * context + * + * + * @since 4.0 + */ +@Immutable +public class MalformedCookieException extends ProtocolException { + + private static final long serialVersionUID = -6695462944287282185L; + + /** + * Creates a new MalformedCookieException with a null detail message. + */ + public MalformedCookieException() { + super(); + } + + /** + * Creates a new MalformedCookieException with a specified message string. + * + * @param message The exception detail message + */ + public MalformedCookieException(String message) { + super(message); + } + + /** + * Creates a new MalformedCookieException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public MalformedCookieException(String message, Throwable cause) { + super(message, cause); + } +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/SM.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/SM.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/SM.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,43 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +/** + * Constants and static helpers related to the HTTP state management. + * + * + * @since 4.0 + */ +public interface SM { + + public static final String COOKIE = "Cookie"; + public static final String COOKIE2 = "Cookie2"; + public static final String SET_COOKIE = "Set-Cookie"; + public static final String SET_COOKIE2 = "Set-Cookie2"; + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/SetCookie.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/SetCookie.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/SetCookie.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,109 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +import java.util.Date; + +/** + * This interface represents a Set-Cookie response header sent by the + * origin server to the HTTP agent in order to maintain a conversational state. + * + * @since 4.0 + */ +public interface SetCookie extends Cookie { + + void setValue(String value); + + /** + * If a user agent (web browser) presents this cookie to a user, the + * cookie's purpose will be described using this comment. + * + * @param comment + * + * @see #getComment() + */ + void setComment(String comment); + + /** + * Sets expiration date. + *

Note: the object returned by this method is considered + * immutable. Changing it (e.g. using setTime()) could result in undefined + * behaviour. Do so at your peril.

+ * + * @param expiryDate the {@link Date} after which this cookie is no longer valid. + * + * @see Cookie#getExpiryDate + * + */ + void setExpiryDate (Date expiryDate); + + /** + * Sets the domain attribute. + * + * @param domain The value of the domain attribute + * + * @see Cookie#getDomain + */ + void setDomain(String domain); + + /** + * Sets the path attribute. + * + * @param path The value of the path attribute + * + * @see Cookie#getPath + * + */ + void setPath(String path); + + /** + * Sets the secure attribute of the cookie. + *

+ * When true the cookie should only be sent + * using a secure protocol (https). This should only be set when + * the cookie's originating server used a secure protocol to set the + * cookie's value. + * + * @param secure The value of the secure attribute + * + * @see #isSecure() + */ + void setSecure (boolean secure); + + /** + * Sets the version of the cookie specification to which this + * cookie conforms. + * + * @param version the version of the cookie. + * + * @see Cookie#getVersion + */ + void setVersion(int version); + +} + Index: 3rdParty_sources/httpclient/org/apache/http/cookie/SetCookie2.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/SetCookie2.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/SetCookie2.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,60 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie; + +/** + * This interface represents a Set-Cookie2 response header sent by the + * origin server to the HTTP agent in order to maintain a conversational state. + * + * @since 4.0 + */ +public interface SetCookie2 extends SetCookie { + + /** + * If a user agent (web browser) presents this cookie to a user, the + * cookie's purpose will be described by the information at this URL. + */ + void setCommentURL(String commentURL); + + /** + * Sets the Port attribute. It restricts the ports to which a cookie + * may be returned in a Cookie request header. + */ + void setPorts(int[] ports); + + /** + * Set the Discard attribute. + * + * Note: Discard attribute overrides Max-age. + * + * @see #isPersistent() + */ + void setDiscard(boolean discard); + +} + Index: 3rdParty_sources/httpclient/org/apache/http/cookie/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,35 @@ + + + + + +The API for client-side state management via cookies. + + Index: 3rdParty_sources/httpclient/org/apache/http/cookie/params/CookieSpecPNames.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/params/CookieSpecPNames.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/params/CookieSpecPNames.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,61 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie.params; + +/** + * Parameter names for HTTP cookie management classes. + * + * @since 4.0 + */ +public interface CookieSpecPNames { + + /** + * Defines valid date patterns to be used for parsing non-standard + * expires attribute. Only required for compatibility + * with non-compliant servers that still use expires + * defined in the Netscape draft instead of the standard + * max-age attribute. + *

+ * This parameter expects a value of type {@link java.util.Collection}. + * The collection elements must be of type {@link String} compatible + * with the syntax of {@link java.text.SimpleDateFormat}. + *

+ */ + public static final String DATE_PATTERNS = "http.protocol.cookie-datepatterns"; + + /** + * Defines whether cookies should be forced into a single + * Cookie request header. Otherwise, each cookie is formatted + * as a separate Cookie header. + *

+ * This parameter expects a value of type {@link Boolean}. + *

+ */ + public static final String SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header"; + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/params/CookieSpecParamBean.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/params/CookieSpecParamBean.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/params/CookieSpecParamBean.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,59 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.cookie.params; + +import java.util.Collection; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.params.HttpAbstractParamBean; +import org.apache.http.params.HttpParams; + +/** + * This is a Java Bean class that can be used to wrap an instance of + * {@link HttpParams} and manipulate HTTP cookie parameters using Java Beans + * conventions. + * + * @since 4.0 + */ +@NotThreadSafe +public class CookieSpecParamBean extends HttpAbstractParamBean { + + public CookieSpecParamBean (final HttpParams params) { + super(params); + } + + public void setDatePatterns (final Collection patterns) { + params.setParameter(CookieSpecPNames.DATE_PATTERNS, patterns); + } + + public void setSingleHeader (final boolean singleHeader) { + params.setBooleanParameter(CookieSpecPNames.SINGLE_COOKIE_HEADER, singleHeader); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/cookie/params/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/cookie/params/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/cookie/params/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,35 @@ + + + + + +Parameters for configuring HTTP state management classes. + + Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/AuthSchemeBase.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/AuthSchemeBase.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/AuthSchemeBase.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,168 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import java.util.Locale; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.FormattedHeader; +import org.apache.http.Header; +import org.apache.http.HttpRequest; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.ChallengeState; +import org.apache.http.auth.ContextAwareAuthScheme; +import org.apache.http.auth.Credentials; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.protocol.HTTP; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.CharArrayBuffer; + +/** + * Abstract authentication scheme class that serves as a basis + * for all authentication schemes supported by HttpClient. This class + * defines the generic way of parsing an authentication challenge. It + * does not make any assumptions regarding the format of the challenge + * nor does it impose any specific way of responding to that challenge. + * + * + * @since 4.0 + */ +@NotThreadSafe +public abstract class AuthSchemeBase implements ContextAwareAuthScheme { + + private ChallengeState challengeState; + + /** + * Creates an instance of AuthSchemeBase with the given challenge + * state. + * + * @since 4.2 + */ + public AuthSchemeBase(final ChallengeState challengeState) { + super(); + this.challengeState = challengeState; + } + + public AuthSchemeBase() { + this(null); + } + + /** + * Processes the given challenge token. Some authentication schemes + * may involve multiple challenge-response exchanges. Such schemes must be able + * to maintain the state information when dealing with sequential challenges + * + * @param header the challenge header + * + * @throws MalformedChallengeException is thrown if the authentication challenge + * is malformed + */ + public void processChallenge(final Header header) throws MalformedChallengeException { + if (header == null) { + throw new IllegalArgumentException("Header may not be null"); + } + String authheader = header.getName(); + if (authheader.equalsIgnoreCase(AUTH.WWW_AUTH)) { + this.challengeState = ChallengeState.TARGET; + } else if (authheader.equalsIgnoreCase(AUTH.PROXY_AUTH)) { + this.challengeState = ChallengeState.PROXY; + } else { + throw new MalformedChallengeException("Unexpected header name: " + authheader); + } + + CharArrayBuffer buffer; + int pos; + if (header instanceof FormattedHeader) { + buffer = ((FormattedHeader) header).getBuffer(); + pos = ((FormattedHeader) header).getValuePos(); + } else { + String s = header.getValue(); + if (s == null) { + throw new MalformedChallengeException("Header value is null"); + } + buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + pos = 0; + } + while (pos < buffer.length() && HTTP.isWhitespace(buffer.charAt(pos))) { + pos++; + } + int beginIndex = pos; + while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) { + pos++; + } + int endIndex = pos; + String s = buffer.substring(beginIndex, endIndex); + if (!s.equalsIgnoreCase(getSchemeName())) { + throw new MalformedChallengeException("Invalid scheme identifier: " + s); + } + + parseChallenge(buffer, pos, buffer.length()); + } + + + @SuppressWarnings("deprecation") + public Header authenticate( + final Credentials credentials, + final HttpRequest request, + final HttpContext context) throws AuthenticationException { + return authenticate(credentials, request); + } + + protected abstract void parseChallenge( + CharArrayBuffer buffer, int beginIndex, int endIndex) throws MalformedChallengeException; + + /** + * Returns true if authenticating against a proxy, false + * otherwise. + */ + public boolean isProxy() { + return this.challengeState != null && this.challengeState == ChallengeState.PROXY; + } + + /** + * Returns {@link ChallengeState} value or null if unchallenged. + * + * @since 4.2 + */ + public ChallengeState getChallengeState() { + return this.challengeState; + } + + @Override + public String toString() { + String name = getSchemeName(); + if (name != null) { + return name.toUpperCase(Locale.US); + } else { + return super.toString(); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/BasicScheme.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/BasicScheme.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/BasicScheme.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,201 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.commons.codec.binary.Base64; +import org.apache.http.Header; +import org.apache.http.HttpRequest; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.ChallengeState; +import org.apache.http.auth.ContextAwareAuthScheme; +import org.apache.http.auth.Credentials; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.InvalidCredentialsException; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.auth.params.AuthParams; +import org.apache.http.message.BufferedHeader; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.CharArrayBuffer; +import org.apache.http.util.EncodingUtils; + +/** + * Basic authentication scheme as defined in RFC 2617. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.auth.params.AuthPNames#CREDENTIAL_CHARSET}
  • + *
+ * + * @since 4.0 + */ +@NotThreadSafe +public class BasicScheme extends RFC2617Scheme { + + /** Whether the basic authentication process is complete */ + private boolean complete; + + /** + * Creates an instance of BasicScheme with the given challenge + * state. + * + * @since 4.2 + */ + public BasicScheme(final ChallengeState challengeState) { + super(challengeState); + this.complete = false; + } + + public BasicScheme() { + this(null); + } + + /** + * Returns textual designation of the basic authentication scheme. + * + * @return basic + */ + public String getSchemeName() { + return "basic"; + } + + /** + * Processes the Basic challenge. + * + * @param header the challenge header + * + * @throws MalformedChallengeException is thrown if the authentication challenge + * is malformed + */ + @Override + public void processChallenge( + final Header header) throws MalformedChallengeException { + super.processChallenge(header); + this.complete = true; + } + + /** + * Tests if the Basic authentication process has been completed. + * + * @return true if Basic authorization has been processed, + * false otherwise. + */ + public boolean isComplete() { + return this.complete; + } + + /** + * Returns false. Basic authentication scheme is request based. + * + * @return false. + */ + public boolean isConnectionBased() { + return false; + } + + /** + * @deprecated (4.2) Use {@link ContextAwareAuthScheme#authenticate(Credentials, HttpRequest, org.apache.http.protocol.HttpContext)} + */ + @Deprecated + public Header authenticate( + final Credentials credentials, final HttpRequest request) throws AuthenticationException { + return authenticate(credentials, request, new BasicHttpContext()); + } + + /** + * Produces basic authorization header for the given set of {@link Credentials}. + * + * @param credentials The set of credentials to be used for authentication + * @param request The request being authenticated + * @throws InvalidCredentialsException if authentication credentials are not + * valid or not applicable for this authentication scheme + * @throws AuthenticationException if authorization string cannot + * be generated due to an authentication failure + * + * @return a basic authorization string + */ + @Override + public Header authenticate( + final Credentials credentials, + final HttpRequest request, + final HttpContext context) throws AuthenticationException { + + if (credentials == null) { + throw new IllegalArgumentException("Credentials may not be null"); + } + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + + String charset = AuthParams.getCredentialCharset(request.getParams()); + return authenticate(credentials, charset, isProxy()); + } + + /** + * Returns a basic Authorization header value for the given + * {@link Credentials} and charset. + * + * @param credentials The credentials to encode. + * @param charset The charset to use for encoding the credentials + * + * @return a basic authorization header + */ + public static Header authenticate( + final Credentials credentials, + final String charset, + boolean proxy) { + if (credentials == null) { + throw new IllegalArgumentException("Credentials may not be null"); + } + if (charset == null) { + throw new IllegalArgumentException("charset may not be null"); + } + + StringBuilder tmp = new StringBuilder(); + tmp.append(credentials.getUserPrincipal().getName()); + tmp.append(":"); + tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword()); + + byte[] base64password = Base64.encodeBase64( + EncodingUtils.getBytes(tmp.toString(), charset)); + + CharArrayBuffer buffer = new CharArrayBuffer(32); + if (proxy) { + buffer.append(AUTH.PROXY_AUTH_RESP); + } else { + buffer.append(AUTH.WWW_AUTH_RESP); + } + buffer.append(": Basic "); + buffer.append(base64password, 0, base64password.length); + + return new BufferedHeader(buffer); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/BasicSchemeFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/BasicSchemeFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/BasicSchemeFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,49 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthSchemeFactory; +import org.apache.http.params.HttpParams; + +/** + * {@link AuthSchemeFactory} implementation that creates and initializes + * {@link BasicScheme} instances. + * + * @since 4.0 + */ +@Immutable +public class BasicSchemeFactory implements AuthSchemeFactory { + + public AuthScheme newInstance(final HttpParams params) { + return new BasicScheme(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/DigestScheme.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/DigestScheme.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/DigestScheme.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,483 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import java.io.IOException; +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Formatter; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.StringTokenizer; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpRequest; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.ChallengeState; +import org.apache.http.auth.ContextAwareAuthScheme; +import org.apache.http.auth.Credentials; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.auth.params.AuthParams; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.message.BasicHeaderValueFormatter; +import org.apache.http.message.BufferedHeader; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.CharArrayBuffer; +import org.apache.http.util.EncodingUtils; + +/** + * Digest authentication scheme as defined in RFC 2617. + * Both MD5 (default) and MD5-sess are supported. + * Currently only qop=auth or no qop is supported. qop=auth-int + * is unsupported. If auth and auth-int are provided, auth is + * used. + *

+ * Credential charset is configured via the + * {@link org.apache.http.auth.params.AuthPNames#CREDENTIAL_CHARSET} + * parameter of the HTTP request. + *

+ * Since the digest username is included as clear text in the generated + * Authentication header, the charset of the username must be compatible + * with the + * {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET + * http element charset}. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.auth.params.AuthPNames#CREDENTIAL_CHARSET}
  • + *
+ * + * @since 4.0 + */ +@NotThreadSafe +public class DigestScheme extends RFC2617Scheme { + + /** + * Hexa values used when creating 32 character long digest in HTTP DigestScheme + * in case of authentication. + * + * @see #encode(byte[]) + */ + private static final char[] HEXADECIMAL = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', + 'e', 'f' + }; + + /** Whether the digest authentication process is complete */ + private boolean complete; + + private static final int QOP_UNKNOWN = -1; + private static final int QOP_MISSING = 0; + private static final int QOP_AUTH_INT = 1; + private static final int QOP_AUTH = 2; + + private String lastNonce; + private long nounceCount; + private String cnonce; + private String a1; + private String a2; + + /** + * Creates an instance of DigestScheme with the given challenge + * state. + * + * @since 4.2 + */ + public DigestScheme(final ChallengeState challengeState) { + super(challengeState); + this.complete = false; + } + + public DigestScheme() { + this(null); + } + + /** + * Processes the Digest challenge. + * + * @param header the challenge header + * + * @throws MalformedChallengeException is thrown if the authentication challenge + * is malformed + */ + @Override + public void processChallenge( + final Header header) throws MalformedChallengeException { + super.processChallenge(header); + this.complete = true; + } + + /** + * Tests if the Digest authentication process has been completed. + * + * @return true if Digest authorization has been processed, + * false otherwise. + */ + public boolean isComplete() { + String s = getParameter("stale"); + if ("true".equalsIgnoreCase(s)) { + return false; + } else { + return this.complete; + } + } + + /** + * Returns textual designation of the digest authentication scheme. + * + * @return digest + */ + public String getSchemeName() { + return "digest"; + } + + /** + * Returns false. Digest authentication scheme is request based. + * + * @return false. + */ + public boolean isConnectionBased() { + return false; + } + + public void overrideParamter(final String name, final String value) { + getParameters().put(name, value); + } + + /** + * @deprecated (4.2) Use {@link ContextAwareAuthScheme#authenticate(Credentials, HttpRequest, org.apache.http.protocol.HttpContext)} + */ + @Deprecated + public Header authenticate( + final Credentials credentials, final HttpRequest request) throws AuthenticationException { + return authenticate(credentials, request, new BasicHttpContext()); + } + + /** + * Produces a digest authorization string for the given set of + * {@link Credentials}, method name and URI. + * + * @param credentials A set of credentials to be used for athentication + * @param request The request being authenticated + * + * @throws org.apache.http.auth.InvalidCredentialsException if authentication credentials + * are not valid or not applicable for this authentication scheme + * @throws AuthenticationException if authorization string cannot + * be generated due to an authentication failure + * + * @return a digest authorization string + */ + @Override + public Header authenticate( + final Credentials credentials, + final HttpRequest request, + final HttpContext context) throws AuthenticationException { + + if (credentials == null) { + throw new IllegalArgumentException("Credentials may not be null"); + } + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (getParameter("realm") == null) { + throw new AuthenticationException("missing realm in challenge"); + } + if (getParameter("nonce") == null) { + throw new AuthenticationException("missing nonce in challenge"); + } + // Add method name and request-URI to the parameter map + getParameters().put("methodname", request.getRequestLine().getMethod()); + getParameters().put("uri", request.getRequestLine().getUri()); + String charset = getParameter("charset"); + if (charset == null) { + charset = AuthParams.getCredentialCharset(request.getParams()); + getParameters().put("charset", charset); + } + return createDigestHeader(credentials, request); + } + + private static MessageDigest createMessageDigest( + final String digAlg) throws UnsupportedDigestAlgorithmException { + try { + return MessageDigest.getInstance(digAlg); + } catch (Exception e) { + throw new UnsupportedDigestAlgorithmException( + "Unsupported algorithm in HTTP Digest authentication: " + + digAlg); + } + } + + /** + * Creates digest-response header as defined in RFC2617. + * + * @param credentials User credentials + * + * @return The digest-response as String. + */ + private Header createDigestHeader( + final Credentials credentials, + final HttpRequest request) throws AuthenticationException { + String uri = getParameter("uri"); + String realm = getParameter("realm"); + String nonce = getParameter("nonce"); + String opaque = getParameter("opaque"); + String method = getParameter("methodname"); + String algorithm = getParameter("algorithm"); + + Set qopset = new HashSet(8); + int qop = QOP_UNKNOWN; + String qoplist = getParameter("qop"); + if (qoplist != null) { + StringTokenizer tok = new StringTokenizer(qoplist, ","); + while (tok.hasMoreTokens()) { + String variant = tok.nextToken().trim(); + qopset.add(variant.toLowerCase(Locale.US)); + } + if (request instanceof HttpEntityEnclosingRequest && qopset.contains("auth-int")) { + qop = QOP_AUTH_INT; + } else if (qopset.contains("auth")) { + qop = QOP_AUTH; + } + } else { + qop = QOP_MISSING; + } + + if (qop == QOP_UNKNOWN) { + throw new AuthenticationException("None of the qop methods is supported: " + qoplist); + } + + // If an algorithm is not specified, default to MD5. + if (algorithm == null) { + algorithm = "MD5"; + } + String charset = getParameter("charset"); + if (charset == null) { + charset = "ISO-8859-1"; + } + + String digAlg = algorithm; + if (digAlg.equalsIgnoreCase("MD5-sess")) { + digAlg = "MD5"; + } + + MessageDigest digester; + try { + digester = createMessageDigest(digAlg); + } catch (UnsupportedDigestAlgorithmException ex) { + throw new AuthenticationException("Unsuppported digest algorithm: " + digAlg); + } + + String uname = credentials.getUserPrincipal().getName(); + String pwd = credentials.getPassword(); + + if (nonce.equals(this.lastNonce)) { + nounceCount++; + } else { + nounceCount = 1; + cnonce = null; + lastNonce = nonce; + } + StringBuilder sb = new StringBuilder(256); + Formatter formatter = new Formatter(sb, Locale.US); + formatter.format("%08x", nounceCount); + String nc = sb.toString(); + + if (cnonce == null) { + cnonce = createCnonce(); + } + + a1 = null; + a2 = null; + // 3.2.2.2: Calculating digest + if (algorithm.equalsIgnoreCase("MD5-sess")) { + // H( unq(username-value) ":" unq(realm-value) ":" passwd ) + // ":" unq(nonce-value) + // ":" unq(cnonce-value) + + // calculated one per session + sb.setLength(0); + sb.append(uname).append(':').append(realm).append(':').append(pwd); + String checksum = encode(digester.digest(EncodingUtils.getBytes(sb.toString(), charset))); + sb.setLength(0); + sb.append(checksum).append(':').append(nonce).append(':').append(cnonce); + a1 = sb.toString(); + } else { + // unq(username-value) ":" unq(realm-value) ":" passwd + sb.setLength(0); + sb.append(uname).append(':').append(realm).append(':').append(pwd); + a1 = sb.toString(); + } + + String hasha1 = encode(digester.digest(EncodingUtils.getBytes(a1, charset))); + + if (qop == QOP_AUTH) { + // Method ":" digest-uri-value + a2 = method + ':' + uri; + } else if (qop == QOP_AUTH_INT) { + // Method ":" digest-uri-value ":" H(entity-body) + HttpEntity entity = null; + if (request instanceof HttpEntityEnclosingRequest) { + entity = ((HttpEntityEnclosingRequest) request).getEntity(); + } + if (entity != null && !entity.isRepeatable()) { + // If the entity is not repeatable, try falling back onto QOP_AUTH + if (qopset.contains("auth")) { + qop = QOP_AUTH; + a2 = method + ':' + uri; + } else { + throw new AuthenticationException("Qop auth-int cannot be used with " + + "a non-repeatable entity"); + } + } else { + HttpEntityDigester entityDigester = new HttpEntityDigester(digester); + try { + if (entity != null) { + entity.writeTo(entityDigester); + } + entityDigester.close(); + } catch (IOException ex) { + throw new AuthenticationException("I/O error reading entity content", ex); + } + a2 = method + ':' + uri + ':' + encode(entityDigester.getDigest()); + } + } else { + a2 = method + ':' + uri; + } + + String hasha2 = encode(digester.digest(EncodingUtils.getBytes(a2, charset))); + + // 3.2.2.1 + + String digestValue; + if (qop == QOP_MISSING) { + sb.setLength(0); + sb.append(hasha1).append(':').append(nonce).append(':').append(hasha2); + digestValue = sb.toString(); + } else { + sb.setLength(0); + sb.append(hasha1).append(':').append(nonce).append(':').append(nc).append(':') + .append(cnonce).append(':').append(qop == QOP_AUTH_INT ? "auth-int" : "auth") + .append(':').append(hasha2); + digestValue = sb.toString(); + } + + String digest = encode(digester.digest(EncodingUtils.getAsciiBytes(digestValue))); + + CharArrayBuffer buffer = new CharArrayBuffer(128); + if (isProxy()) { + buffer.append(AUTH.PROXY_AUTH_RESP); + } else { + buffer.append(AUTH.WWW_AUTH_RESP); + } + buffer.append(": Digest "); + + List params = new ArrayList(20); + params.add(new BasicNameValuePair("username", uname)); + params.add(new BasicNameValuePair("realm", realm)); + params.add(new BasicNameValuePair("nonce", nonce)); + params.add(new BasicNameValuePair("uri", uri)); + params.add(new BasicNameValuePair("response", digest)); + + if (qop != QOP_MISSING) { + params.add(new BasicNameValuePair("qop", qop == QOP_AUTH_INT ? "auth-int" : "auth")); + params.add(new BasicNameValuePair("nc", nc)); + params.add(new BasicNameValuePair("cnonce", cnonce)); + } + if (algorithm != null) { + params.add(new BasicNameValuePair("algorithm", algorithm)); + } + if (opaque != null) { + params.add(new BasicNameValuePair("opaque", opaque)); + } + + for (int i = 0; i < params.size(); i++) { + BasicNameValuePair param = params.get(i); + if (i > 0) { + buffer.append(", "); + } + boolean noQuotes = "nc".equals(param.getName()) || "qop".equals(param.getName()); + BasicHeaderValueFormatter.DEFAULT.formatNameValuePair(buffer, param, !noQuotes); + } + return new BufferedHeader(buffer); + } + + String getCnonce() { + return cnonce; + } + + String getA1() { + return a1; + } + + String getA2() { + return a2; + } + + /** + * Encodes the 128 bit (16 bytes) MD5 digest into a 32 characters long + * String according to RFC 2617. + * + * @param binaryData array containing the digest + * @return encoded MD5, or null if encoding failed + */ + static String encode(byte[] binaryData) { + int n = binaryData.length; + char[] buffer = new char[n * 2]; + for (int i = 0; i < n; i++) { + int low = (binaryData[i] & 0x0f); + int high = ((binaryData[i] & 0xf0) >> 4); + buffer[i * 2] = HEXADECIMAL[high]; + buffer[(i * 2) + 1] = HEXADECIMAL[low]; + } + + return new String(buffer); + } + + + /** + * Creates a random cnonce value based on the current time. + * + * @return The cnonce value as String. + */ + public static String createCnonce() { + SecureRandom rnd = new SecureRandom(); + byte[] tmp = new byte[8]; + rnd.nextBytes(tmp); + return encode(tmp); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/DigestSchemeFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/DigestSchemeFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/DigestSchemeFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,49 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthSchemeFactory; +import org.apache.http.params.HttpParams; + +/** + * {@link AuthSchemeFactory} implementation that creates and initializes + * {@link DigestScheme} instances. + * + * @since 4.0 + */ +@Immutable +public class DigestSchemeFactory implements AuthSchemeFactory { + + public AuthScheme newInstance(final HttpParams params) { + return new DigestScheme(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/GGSSchemeBase.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/GGSSchemeBase.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/GGSSchemeBase.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,199 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.http.impl.auth; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.ContextAwareAuthScheme; +import org.apache.http.auth.Credentials; +import org.apache.http.auth.InvalidCredentialsException; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.ExecutionContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.CharArrayBuffer; +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.GSSManager; +import org.ietf.jgss.GSSName; +import org.ietf.jgss.Oid; + +/** + * @since 4.2 + */ +public abstract class GGSSchemeBase extends AuthSchemeBase { + + enum State { + UNINITIATED, + CHALLENGE_RECEIVED, + TOKEN_GENERATED, + FAILED, + } + + private final Log log = LogFactory.getLog(getClass()); + + private final boolean stripPort; + private final Base64 base64codec; + + /** Authentication process state */ + private State state; + + /** base64 decoded challenge **/ + private byte[] token; + + GGSSchemeBase(boolean stripPort) { + super(); + this.base64codec = new Base64(); + this.state = State.UNINITIATED; + this.stripPort = stripPort; + } + + GGSSchemeBase() { + this(false); + } + + protected GSSManager getManager() { + return GSSManager.getInstance(); + } + + protected byte[] generateGSSToken( + final byte[] input, final Oid oid, final String authServer) throws GSSException { + byte[] token = input; + if (token == null) { + token = new byte[0]; + } + GSSManager manager = getManager(); + GSSName serverName = manager.createName("HTTP@" + authServer, GSSName.NT_HOSTBASED_SERVICE); + GSSContext gssContext = manager.createContext( + serverName.canonicalize(oid), oid, null, GSSContext.DEFAULT_LIFETIME); + gssContext.requestMutualAuth(true); + gssContext.requestCredDeleg(true); + return gssContext.initSecContext(token, 0, token.length); + } + + protected abstract byte[] generateToken( + byte[] input, final String authServer) throws GSSException; + + public boolean isComplete() { + return this.state == State.TOKEN_GENERATED || this.state == State.FAILED; + } + + /** + * @deprecated (4.2) Use {@link ContextAwareAuthScheme#authenticate(Credentials, HttpRequest, org.apache.http.protocol.HttpContext)} + */ + @Deprecated + public Header authenticate( + final Credentials credentials, + final HttpRequest request) throws AuthenticationException { + return authenticate(credentials, request, null); + } + + @Override + public Header authenticate( + final Credentials credentials, + final HttpRequest request, + final HttpContext context) throws AuthenticationException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + switch (state) { + case UNINITIATED: + throw new AuthenticationException(getSchemeName() + " authentication has not been initiated"); + case FAILED: + throw new AuthenticationException(getSchemeName() + " authentication has failed"); + case CHALLENGE_RECEIVED: + try { + String key = null; + if (isProxy()) { + key = ExecutionContext.HTTP_PROXY_HOST; + } else { + key = ExecutionContext.HTTP_TARGET_HOST; + } + HttpHost host = (HttpHost) context.getAttribute(key); + if (host == null) { + throw new AuthenticationException("Authentication host is not set " + + "in the execution context"); + } + String authServer; + if (!this.stripPort && host.getPort() > 0) { + authServer = host.toHostString(); + } else { + authServer = host.getHostName(); + } + + if (log.isDebugEnabled()) { + log.debug("init " + authServer); + } + token = generateToken(token, authServer); + state = State.TOKEN_GENERATED; + } catch (GSSException gsse) { + state = State.FAILED; + if (gsse.getMajor() == GSSException.DEFECTIVE_CREDENTIAL + || gsse.getMajor() == GSSException.CREDENTIALS_EXPIRED) + throw new InvalidCredentialsException(gsse.getMessage(), gsse); + if (gsse.getMajor() == GSSException.NO_CRED ) + throw new InvalidCredentialsException(gsse.getMessage(), gsse); + if (gsse.getMajor() == GSSException.DEFECTIVE_TOKEN + || gsse.getMajor() == GSSException.DUPLICATE_TOKEN + || gsse.getMajor() == GSSException.OLD_TOKEN) + throw new AuthenticationException(gsse.getMessage(), gsse); + // other error + throw new AuthenticationException(gsse.getMessage()); + } + case TOKEN_GENERATED: + String tokenstr = new String(base64codec.encode(token)); + if (log.isDebugEnabled()) { + log.debug("Sending response '" + tokenstr + "' back to the auth server"); + } + return new BasicHeader("Authorization", "Negotiate " + tokenstr); + default: + throw new IllegalStateException("Illegal state: " + state); + } + } + + @Override + protected void parseChallenge( + final CharArrayBuffer buffer, + int beginIndex, int endIndex) throws MalformedChallengeException { + String challenge = buffer.substringTrimmed(beginIndex, endIndex); + if (log.isDebugEnabled()) { + log.debug("Received challenge '" + challenge + "' from the auth server"); + } + if (state == State.UNINITIATED) { + token = base64codec.decode(challenge.getBytes()); + state = State.CHALLENGE_RECEIVED; + } else { + log.debug("Authentication already attempted"); + state = State.FAILED; + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/HttpEntityDigester.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/HttpEntityDigester.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/HttpEntityDigester.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,75 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import java.io.IOException; +import java.io.OutputStream; +import java.security.MessageDigest; + +class HttpEntityDigester extends OutputStream { + + private final MessageDigest digester; + private boolean closed; + private byte[] digest; + + HttpEntityDigester(final MessageDigest digester) { + super(); + this.digester = digester; + this.digester.reset(); + } + + @Override + public void write(int b) throws IOException { + if (this.closed) { + throw new IOException("Stream has been already closed"); + } + this.digester.update((byte) b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + if (this.closed) { + throw new IOException("Stream has been already closed"); + } + this.digester.update(b, off, len); + } + + @Override + public void close() throws IOException { + if (this.closed) { + return; + } + this.closed = true; + this.digest = this.digester.digest(); + super.close(); + } + + public byte[] getDigest() { + return this.digest; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/KerberosScheme.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/KerberosScheme.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/KerberosScheme.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,114 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.http.impl.auth; + +import org.apache.http.Header; +import org.apache.http.HttpRequest; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.Credentials; +import org.apache.http.protocol.HttpContext; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.Oid; + +/** + * KERBEROS authentication scheme. + * + * @since 4.2 + */ +public class KerberosScheme extends GGSSchemeBase { + + private static final String KERBEROS_OID = "1.2.840.113554.1.2.2"; + + public KerberosScheme(boolean stripPort) { + super(stripPort); + } + + public KerberosScheme() { + super(false); + } + + public String getSchemeName() { + return "Kerberos"; + } + + /** + * Produces KERBEROS authorization Header based on token created by + * processChallenge. + * + * @param credentials not used by the KERBEROS scheme. + * @param request The request being authenticated + * + * @throws AuthenticationException if authentication string cannot + * be generated due to an authentication failure + * + * @return KERBEROS authentication Header + */ + @Override + public Header authenticate( + final Credentials credentials, + final HttpRequest request, + final HttpContext context) throws AuthenticationException { + return super.authenticate(credentials, request, context); + } + + @Override + protected byte[] generateToken(final byte[] input, final String authServer) throws GSSException { + return generateGSSToken(input, new Oid(KERBEROS_OID), authServer); + } + + /** + * There are no valid parameters for KERBEROS authentication so this + * method always returns null. + * + * @return null + */ + public String getParameter(String name) { + if (name == null) { + throw new IllegalArgumentException("Parameter name may not be null"); + } + return null; + } + + /** + * The concept of an authentication realm is not supported by the Negotiate + * authentication scheme. Always returns null. + * + * @return null + */ + public String getRealm() { + return null; + } + + /** + * Returns true. KERBEROS authentication scheme is connection based. + * + * @return true. + */ + public boolean isConnectionBased() { + return true; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/KerberosSchemeFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/KerberosSchemeFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/KerberosSchemeFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,61 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthSchemeFactory; +import org.apache.http.params.HttpParams; + +/** + * Kerberos authentication scheme factory. + * + * @since 4.2 + */ +@Immutable +public class KerberosSchemeFactory implements AuthSchemeFactory { + + private final boolean stripPort; + + public KerberosSchemeFactory(boolean stripPort) { + super(); + this.stripPort = stripPort; + } + + public KerberosSchemeFactory() { + this(false); + } + + public AuthScheme newInstance(final HttpParams params) { + return new KerberosScheme(this.stripPort); + } + + public boolean isStripPort() { + return stripPort; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMEngine.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMEngine.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMEngine.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,70 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +/** + * Abstract NTLM authentication engine. The engine can be used to + * generate Type1 messages and Type3 messages in response to a + * Type2 challenge. + * + * @since 4.0 + */ +public interface NTLMEngine { + + /** + * Generates a Type1 message given the domain and workstation. + * + * @param domain Optional Windows domain name. Can be null. + * @param workstation Optional Windows workstation name. Can be + * null. + * @return Type1 message + * @throws NTLMEngineException + */ + String generateType1Msg( + String domain, + String workstation) throws NTLMEngineException; + + /** + * Generates a Type3 message given the user credentials and the + * authentication challenge. + * + * @param username Windows user name + * @param password Password + * @param domain Windows domain name + * @param workstation Windows workstation name + * @param challenge Type2 challenge. + * @return Type3 response. + * @throws NTLMEngineException + */ + String generateType3Msg( + String username, + String password, + String domain, + String workstation, + String challenge) throws NTLMEngineException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMEngineException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMEngineException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMEngineException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,68 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.auth.AuthenticationException; + +/** + * Signals NTLM protocol failure. + * + * + * @since 4.0 + */ +@Immutable +public class NTLMEngineException extends AuthenticationException { + + private static final long serialVersionUID = 6027981323731768824L; + + public NTLMEngineException() { + super(); + } + + /** + * Creates a new NTLMEngineException with the specified message. + * + * @param message the exception detail message + */ + public NTLMEngineException(String message) { + super(message); + } + + /** + * Creates a new NTLMEngineException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public NTLMEngineException(String message, Throwable cause) { + super(message, cause); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMEngineImpl.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMEngineImpl.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMEngineImpl.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,1319 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import java.security.Key; +import java.security.MessageDigest; +import java.util.Arrays; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +import org.apache.commons.codec.binary.Base64; +import org.apache.http.util.EncodingUtils; + +/** + * Provides an implementation for NTLMv1, NTLMv2, and NTLM2 Session forms of the NTLM + * authentication protocol. + * + * @since 4.1 + */ +final class NTLMEngineImpl implements NTLMEngine { + + // Flags we use + protected final static int FLAG_UNICODE_ENCODING = 0x00000001; + protected final static int FLAG_TARGET_DESIRED = 0x00000004; + protected final static int FLAG_NEGOTIATE_SIGN = 0x00000010; + protected final static int FLAG_NEGOTIATE_SEAL = 0x00000020; + protected final static int FLAG_NEGOTIATE_NTLM = 0x00000200; + protected final static int FLAG_NEGOTIATE_ALWAYS_SIGN = 0x00008000; + protected final static int FLAG_NEGOTIATE_NTLM2 = 0x00080000; + protected final static int FLAG_NEGOTIATE_128 = 0x20000000; + protected final static int FLAG_NEGOTIATE_KEY_EXCH = 0x40000000; + + /** Secure random generator */ + private static final java.security.SecureRandom RND_GEN; + static { + java.security.SecureRandom rnd = null; + try { + rnd = java.security.SecureRandom.getInstance("SHA1PRNG"); + } catch (Exception e) { + } + RND_GEN = rnd; + } + + /** Character encoding */ + static final String DEFAULT_CHARSET = "ASCII"; + + /** The character set to use for encoding the credentials */ + private String credentialCharset = DEFAULT_CHARSET; + + /** The signature string as bytes in the default encoding */ + private static byte[] SIGNATURE; + + static { + byte[] bytesWithoutNull = EncodingUtils.getBytes("NTLMSSP", "ASCII"); + SIGNATURE = new byte[bytesWithoutNull.length + 1]; + System.arraycopy(bytesWithoutNull, 0, SIGNATURE, 0, bytesWithoutNull.length); + SIGNATURE[bytesWithoutNull.length] = (byte) 0x00; + } + + /** + * Returns the response for the given message. + * + * @param message + * the message that was received from the server. + * @param username + * the username to authenticate with. + * @param password + * the password to authenticate with. + * @param host + * The host. + * @param domain + * the NT domain to authenticate in. + * @return The response. + * @throws HttpException + * If the messages cannot be retrieved. + */ + final String getResponseFor(String message, String username, String password, + String host, String domain) throws NTLMEngineException { + + final String response; + if (message == null || message.trim().equals("")) { + response = getType1Message(host, domain); + } else { + Type2Message t2m = new Type2Message(message); + response = getType3Message(username, password, host, domain, t2m.getChallenge(), t2m + .getFlags(), t2m.getTarget(), t2m.getTargetInfo()); + } + return response; + } + + /** + * Creates the first message (type 1 message) in the NTLM authentication + * sequence. This message includes the user name, domain and host for the + * authentication session. + * + * @param host + * the computer name of the host requesting authentication. + * @param domain + * The domain to authenticate with. + * @return String the message to add to the HTTP request header. + */ + String getType1Message(String host, String domain) throws NTLMEngineException { + return new Type1Message(domain, host).getResponse(); + } + + /** + * Creates the type 3 message using the given server nonce. The type 3 + * message includes all the information for authentication, host, domain, + * username and the result of encrypting the nonce sent by the server using + * the user's password as the key. + * + * @param user + * The user name. This should not include the domain name. + * @param password + * The password. + * @param host + * The host that is originating the authentication request. + * @param domain + * The domain to authenticate within. + * @param nonce + * the 8 byte array the server sent. + * @return The type 3 message. + * @throws NTLMEngineException + * If {@encrypt(byte[],byte[])} fails. + */ + String getType3Message(String user, String password, String host, String domain, + byte[] nonce, int type2Flags, String target, byte[] targetInformation) + throws NTLMEngineException { + return new Type3Message(domain, host, user, password, nonce, type2Flags, target, + targetInformation).getResponse(); + } + + /** + * @return Returns the credentialCharset. + */ + String getCredentialCharset() { + return credentialCharset; + } + + /** + * @param credentialCharset + * The credentialCharset to set. + */ + void setCredentialCharset(String credentialCharset) { + this.credentialCharset = credentialCharset; + } + + /** Strip dot suffix from a name */ + private static String stripDotSuffix(String value) { + int index = value.indexOf("."); + if (index != -1) + return value.substring(0, index); + return value; + } + + /** Convert host to standard form */ + private static String convertHost(String host) { + return stripDotSuffix(host); + } + + /** Convert domain to standard form */ + private static String convertDomain(String domain) { + return stripDotSuffix(domain); + } + + private static int readULong(byte[] src, int index) throws NTLMEngineException { + if (src.length < index + 4) + throw new NTLMEngineException("NTLM authentication - buffer too small for DWORD"); + return (src[index] & 0xff) | ((src[index + 1] & 0xff) << 8) + | ((src[index + 2] & 0xff) << 16) | ((src[index + 3] & 0xff) << 24); + } + + private static int readUShort(byte[] src, int index) throws NTLMEngineException { + if (src.length < index + 2) + throw new NTLMEngineException("NTLM authentication - buffer too small for WORD"); + return (src[index] & 0xff) | ((src[index + 1] & 0xff) << 8); + } + + private static byte[] readSecurityBuffer(byte[] src, int index) throws NTLMEngineException { + int length = readUShort(src, index); + int offset = readULong(src, index + 4); + if (src.length < offset + length) + throw new NTLMEngineException( + "NTLM authentication - buffer too small for data item"); + byte[] buffer = new byte[length]; + System.arraycopy(src, offset, buffer, 0, length); + return buffer; + } + + /** Calculate a challenge block */ + private static byte[] makeRandomChallenge() throws NTLMEngineException { + if (RND_GEN == null) { + throw new NTLMEngineException("Random generator not available"); + } + byte[] rval = new byte[8]; + synchronized (RND_GEN) { + RND_GEN.nextBytes(rval); + } + return rval; + } + + /** Calculate an NTLM2 challenge block */ + private static byte[] makeNTLM2RandomChallenge() throws NTLMEngineException { + if (RND_GEN == null) { + throw new NTLMEngineException("Random generator not available"); + } + byte[] rval = new byte[24]; + synchronized (RND_GEN) { + RND_GEN.nextBytes(rval); + } + // 8-byte challenge, padded with zeros to 24 bytes. + Arrays.fill(rval, 8, 24, (byte) 0x00); + return rval; + } + + /** + * Calculates the LM Response for the given challenge, using the specified + * password. + * + * @param password + * The user's password. + * @param challenge + * The Type 2 challenge from the server. + * + * @return The LM Response. + */ + static byte[] getLMResponse(String password, byte[] challenge) + throws NTLMEngineException { + byte[] lmHash = lmHash(password); + return lmResponse(lmHash, challenge); + } + + /** + * Calculates the NTLM Response for the given challenge, using the specified + * password. + * + * @param password + * The user's password. + * @param challenge + * The Type 2 challenge from the server. + * + * @return The NTLM Response. + */ + static byte[] getNTLMResponse(String password, byte[] challenge) + throws NTLMEngineException { + byte[] ntlmHash = ntlmHash(password); + return lmResponse(ntlmHash, challenge); + } + + /** + * Calculates the NTLMv2 Response for the given challenge, using the + * specified authentication target, username, password, target information + * block, and client challenge. + * + * @param target + * The authentication target (i.e., domain). + * @param user + * The username. + * @param password + * The user's password. + * @param targetInformation + * The target information block from the Type 2 message. + * @param challenge + * The Type 2 challenge from the server. + * @param clientChallenge + * The random 8-byte client challenge. + * + * @return The NTLMv2 Response. + */ + static byte[] getNTLMv2Response(String target, String user, String password, + byte[] challenge, byte[] clientChallenge, byte[] targetInformation) + throws NTLMEngineException { + byte[] ntlmv2Hash = ntlmv2Hash(target, user, password); + byte[] blob = createBlob(clientChallenge, targetInformation); + return lmv2Response(ntlmv2Hash, challenge, blob); + } + + /** + * Calculates the LMv2 Response for the given challenge, using the specified + * authentication target, username, password, and client challenge. + * + * @param target + * The authentication target (i.e., domain). + * @param user + * The username. + * @param password + * The user's password. + * @param challenge + * The Type 2 challenge from the server. + * @param clientChallenge + * The random 8-byte client challenge. + * + * @return The LMv2 Response. + */ + static byte[] getLMv2Response(String target, String user, String password, + byte[] challenge, byte[] clientChallenge) throws NTLMEngineException { + byte[] ntlmv2Hash = ntlmv2Hash(target, user, password); + return lmv2Response(ntlmv2Hash, challenge, clientChallenge); + } + + /** + * Calculates the NTLM2 Session Response for the given challenge, using the + * specified password and client challenge. + * + * @param password + * The user's password. + * @param challenge + * The Type 2 challenge from the server. + * @param clientChallenge + * The random 8-byte client challenge. + * + * @return The NTLM2 Session Response. This is placed in the NTLM response + * field of the Type 3 message; the LM response field contains the + * client challenge, null-padded to 24 bytes. + */ + static byte[] getNTLM2SessionResponse(String password, byte[] challenge, + byte[] clientChallenge) throws NTLMEngineException { + try { + byte[] ntlmHash = ntlmHash(password); + + // Look up MD5 algorithm (was necessary on jdk 1.4.2) + // This used to be needed, but java 1.5.0_07 includes the MD5 + // algorithm (finally) + // Class x = Class.forName("gnu.crypto.hash.MD5"); + // Method updateMethod = x.getMethod("update",new + // Class[]{byte[].class}); + // Method digestMethod = x.getMethod("digest",new Class[0]); + // Object mdInstance = x.newInstance(); + // updateMethod.invoke(mdInstance,new Object[]{challenge}); + // updateMethod.invoke(mdInstance,new Object[]{clientChallenge}); + // byte[] digest = (byte[])digestMethod.invoke(mdInstance,new + // Object[0]); + + MessageDigest md5 = MessageDigest.getInstance("MD5"); + md5.update(challenge); + md5.update(clientChallenge); + byte[] digest = md5.digest(); + + byte[] sessionHash = new byte[8]; + System.arraycopy(digest, 0, sessionHash, 0, 8); + return lmResponse(ntlmHash, sessionHash); + } catch (Exception e) { + if (e instanceof NTLMEngineException) + throw (NTLMEngineException) e; + throw new NTLMEngineException(e.getMessage(), e); + } + } + + /** + * Creates the LM Hash of the user's password. + * + * @param password + * The password. + * + * @return The LM Hash of the given password, used in the calculation of the + * LM Response. + */ + private static byte[] lmHash(String password) throws NTLMEngineException { + try { + byte[] oemPassword = password.toUpperCase().getBytes("US-ASCII"); + int length = Math.min(oemPassword.length, 14); + byte[] keyBytes = new byte[14]; + System.arraycopy(oemPassword, 0, keyBytes, 0, length); + Key lowKey = createDESKey(keyBytes, 0); + Key highKey = createDESKey(keyBytes, 7); + byte[] magicConstant = "KGS!@#$%".getBytes("US-ASCII"); + Cipher des = Cipher.getInstance("DES/ECB/NoPadding"); + des.init(Cipher.ENCRYPT_MODE, lowKey); + byte[] lowHash = des.doFinal(magicConstant); + des.init(Cipher.ENCRYPT_MODE, highKey); + byte[] highHash = des.doFinal(magicConstant); + byte[] lmHash = new byte[16]; + System.arraycopy(lowHash, 0, lmHash, 0, 8); + System.arraycopy(highHash, 0, lmHash, 8, 8); + return lmHash; + } catch (Exception e) { + throw new NTLMEngineException(e.getMessage(), e); + } + } + + /** + * Creates the NTLM Hash of the user's password. + * + * @param password + * The password. + * + * @return The NTLM Hash of the given password, used in the calculation of + * the NTLM Response and the NTLMv2 and LMv2 Hashes. + */ + private static byte[] ntlmHash(String password) throws NTLMEngineException { + try { + byte[] unicodePassword = password.getBytes("UnicodeLittleUnmarked"); + MD4 md4 = new MD4(); + md4.update(unicodePassword); + return md4.getOutput(); + } catch (java.io.UnsupportedEncodingException e) { + throw new NTLMEngineException("Unicode not supported: " + e.getMessage(), e); + } + } + + /** + * Creates the NTLMv2 Hash of the user's password. + * + * @param target + * The authentication target (i.e., domain). + * @param user + * The username. + * @param password + * The password. + * + * @return The NTLMv2 Hash, used in the calculation of the NTLMv2 and LMv2 + * Responses. + */ + private static byte[] ntlmv2Hash(String target, String user, String password) + throws NTLMEngineException { + try { + byte[] ntlmHash = ntlmHash(password); + HMACMD5 hmacMD5 = new HMACMD5(ntlmHash); + // Upper case username, mixed case target!! + hmacMD5.update(user.toUpperCase().getBytes("UnicodeLittleUnmarked")); + hmacMD5.update(target.getBytes("UnicodeLittleUnmarked")); + return hmacMD5.getOutput(); + } catch (java.io.UnsupportedEncodingException e) { + throw new NTLMEngineException("Unicode not supported! " + e.getMessage(), e); + } + } + + /** + * Creates the LM Response from the given hash and Type 2 challenge. + * + * @param hash + * The LM or NTLM Hash. + * @param challenge + * The server challenge from the Type 2 message. + * + * @return The response (either LM or NTLM, depending on the provided hash). + */ + private static byte[] lmResponse(byte[] hash, byte[] challenge) throws NTLMEngineException { + try { + byte[] keyBytes = new byte[21]; + System.arraycopy(hash, 0, keyBytes, 0, 16); + Key lowKey = createDESKey(keyBytes, 0); + Key middleKey = createDESKey(keyBytes, 7); + Key highKey = createDESKey(keyBytes, 14); + Cipher des = Cipher.getInstance("DES/ECB/NoPadding"); + des.init(Cipher.ENCRYPT_MODE, lowKey); + byte[] lowResponse = des.doFinal(challenge); + des.init(Cipher.ENCRYPT_MODE, middleKey); + byte[] middleResponse = des.doFinal(challenge); + des.init(Cipher.ENCRYPT_MODE, highKey); + byte[] highResponse = des.doFinal(challenge); + byte[] lmResponse = new byte[24]; + System.arraycopy(lowResponse, 0, lmResponse, 0, 8); + System.arraycopy(middleResponse, 0, lmResponse, 8, 8); + System.arraycopy(highResponse, 0, lmResponse, 16, 8); + return lmResponse; + } catch (Exception e) { + throw new NTLMEngineException(e.getMessage(), e); + } + } + + /** + * Creates the LMv2 Response from the given hash, client data, and Type 2 + * challenge. + * + * @param hash + * The NTLMv2 Hash. + * @param clientData + * The client data (blob or client challenge). + * @param challenge + * The server challenge from the Type 2 message. + * + * @return The response (either NTLMv2 or LMv2, depending on the client + * data). + */ + private static byte[] lmv2Response(byte[] hash, byte[] challenge, byte[] clientData) + throws NTLMEngineException { + HMACMD5 hmacMD5 = new HMACMD5(hash); + hmacMD5.update(challenge); + hmacMD5.update(clientData); + byte[] mac = hmacMD5.getOutput(); + byte[] lmv2Response = new byte[mac.length + clientData.length]; + System.arraycopy(mac, 0, lmv2Response, 0, mac.length); + System.arraycopy(clientData, 0, lmv2Response, mac.length, clientData.length); + return lmv2Response; + } + + /** + * Creates the NTLMv2 blob from the given target information block and + * client challenge. + * + * @param targetInformation + * The target information block from the Type 2 message. + * @param clientChallenge + * The random 8-byte client challenge. + * + * @return The blob, used in the calculation of the NTLMv2 Response. + */ + private static byte[] createBlob(byte[] clientChallenge, byte[] targetInformation) { + byte[] blobSignature = new byte[] { (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00 }; + byte[] reserved = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; + byte[] unknown1 = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; + long time = System.currentTimeMillis(); + time += 11644473600000l; // milliseconds from January 1, 1601 -> epoch. + time *= 10000; // tenths of a microsecond. + // convert to little-endian byte array. + byte[] timestamp = new byte[8]; + for (int i = 0; i < 8; i++) { + timestamp[i] = (byte) time; + time >>>= 8; + } + byte[] blob = new byte[blobSignature.length + reserved.length + timestamp.length + 8 + + unknown1.length + targetInformation.length]; + int offset = 0; + System.arraycopy(blobSignature, 0, blob, offset, blobSignature.length); + offset += blobSignature.length; + System.arraycopy(reserved, 0, blob, offset, reserved.length); + offset += reserved.length; + System.arraycopy(timestamp, 0, blob, offset, timestamp.length); + offset += timestamp.length; + System.arraycopy(clientChallenge, 0, blob, offset, 8); + offset += 8; + System.arraycopy(unknown1, 0, blob, offset, unknown1.length); + offset += unknown1.length; + System.arraycopy(targetInformation, 0, blob, offset, targetInformation.length); + return blob; + } + + /** + * Creates a DES encryption key from the given key material. + * + * @param bytes + * A byte array containing the DES key material. + * @param offset + * The offset in the given byte array at which the 7-byte key + * material starts. + * + * @return A DES encryption key created from the key material starting at + * the specified offset in the given byte array. + */ + private static Key createDESKey(byte[] bytes, int offset) { + byte[] keyBytes = new byte[7]; + System.arraycopy(bytes, offset, keyBytes, 0, 7); + byte[] material = new byte[8]; + material[0] = keyBytes[0]; + material[1] = (byte) (keyBytes[0] << 7 | (keyBytes[1] & 0xff) >>> 1); + material[2] = (byte) (keyBytes[1] << 6 | (keyBytes[2] & 0xff) >>> 2); + material[3] = (byte) (keyBytes[2] << 5 | (keyBytes[3] & 0xff) >>> 3); + material[4] = (byte) (keyBytes[3] << 4 | (keyBytes[4] & 0xff) >>> 4); + material[5] = (byte) (keyBytes[4] << 3 | (keyBytes[5] & 0xff) >>> 5); + material[6] = (byte) (keyBytes[5] << 2 | (keyBytes[6] & 0xff) >>> 6); + material[7] = (byte) (keyBytes[6] << 1); + oddParity(material); + return new SecretKeySpec(material, "DES"); + } + + /** + * Applies odd parity to the given byte array. + * + * @param bytes + * The data whose parity bits are to be adjusted for odd parity. + */ + private static void oddParity(byte[] bytes) { + for (int i = 0; i < bytes.length; i++) { + byte b = bytes[i]; + boolean needsParity = (((b >>> 7) ^ (b >>> 6) ^ (b >>> 5) ^ (b >>> 4) ^ (b >>> 3) + ^ (b >>> 2) ^ (b >>> 1)) & 0x01) == 0; + if (needsParity) { + bytes[i] |= (byte) 0x01; + } else { + bytes[i] &= (byte) 0xfe; + } + } + } + + /** NTLM message generation, base class */ + static class NTLMMessage { + /** The current response */ + private byte[] messageContents = null; + + /** The current output position */ + private int currentOutputPosition = 0; + + /** Constructor to use when message contents are not yet known */ + NTLMMessage() { + } + + /** Constructor to use when message contents are known */ + NTLMMessage(String messageBody, int expectedType) throws NTLMEngineException { + messageContents = Base64.decodeBase64(EncodingUtils.getBytes(messageBody, + DEFAULT_CHARSET)); + // Look for NTLM message + if (messageContents.length < SIGNATURE.length) + throw new NTLMEngineException("NTLM message decoding error - packet too short"); + int i = 0; + while (i < SIGNATURE.length) { + if (messageContents[i] != SIGNATURE[i]) + throw new NTLMEngineException( + "NTLM message expected - instead got unrecognized bytes"); + i++; + } + + // Check to be sure there's a type 2 message indicator next + int type = readULong(SIGNATURE.length); + if (type != expectedType) + throw new NTLMEngineException("NTLM type " + Integer.toString(expectedType) + + " message expected - instead got type " + Integer.toString(type)); + + currentOutputPosition = messageContents.length; + } + + /** + * Get the length of the signature and flags, so calculations can adjust + * offsets accordingly. + */ + protected int getPreambleLength() { + return SIGNATURE.length + 4; + } + + /** Get the message length */ + protected int getMessageLength() { + return currentOutputPosition; + } + + /** Read a byte from a position within the message buffer */ + protected byte readByte(int position) throws NTLMEngineException { + if (messageContents.length < position + 1) + throw new NTLMEngineException("NTLM: Message too short"); + return messageContents[position]; + } + + /** Read a bunch of bytes from a position in the message buffer */ + protected void readBytes(byte[] buffer, int position) throws NTLMEngineException { + if (messageContents.length < position + buffer.length) + throw new NTLMEngineException("NTLM: Message too short"); + System.arraycopy(messageContents, position, buffer, 0, buffer.length); + } + + /** Read a ushort from a position within the message buffer */ + protected int readUShort(int position) throws NTLMEngineException { + return NTLMEngineImpl.readUShort(messageContents, position); + } + + /** Read a ulong from a position within the message buffer */ + protected int readULong(int position) throws NTLMEngineException { + return NTLMEngineImpl.readULong(messageContents, position); + } + + /** Read a security buffer from a position within the message buffer */ + protected byte[] readSecurityBuffer(int position) throws NTLMEngineException { + return NTLMEngineImpl.readSecurityBuffer(messageContents, position); + } + + /** + * Prepares the object to create a response of the given length. + * + * @param length + * the maximum length of the response to prepare, not + * including the type and the signature (which this method + * adds). + */ + protected void prepareResponse(int maxlength, int messageType) { + messageContents = new byte[maxlength]; + currentOutputPosition = 0; + addBytes(SIGNATURE); + addULong(messageType); + } + + /** + * Adds the given byte to the response. + * + * @param b + * the byte to add. + */ + protected void addByte(byte b) { + messageContents[currentOutputPosition] = b; + currentOutputPosition++; + } + + /** + * Adds the given bytes to the response. + * + * @param bytes + * the bytes to add. + */ + protected void addBytes(byte[] bytes) { + for (int i = 0; i < bytes.length; i++) { + messageContents[currentOutputPosition] = bytes[i]; + currentOutputPosition++; + } + } + + /** Adds a USHORT to the response */ + protected void addUShort(int value) { + addByte((byte) (value & 0xff)); + addByte((byte) (value >> 8 & 0xff)); + } + + /** Adds a ULong to the response */ + protected void addULong(int value) { + addByte((byte) (value & 0xff)); + addByte((byte) (value >> 8 & 0xff)); + addByte((byte) (value >> 16 & 0xff)); + addByte((byte) (value >> 24 & 0xff)); + } + + /** + * Returns the response that has been generated after shrinking the + * array if required and base64 encodes the response. + * + * @return The response as above. + */ + String getResponse() { + byte[] resp; + if (messageContents.length > currentOutputPosition) { + byte[] tmp = new byte[currentOutputPosition]; + for (int i = 0; i < currentOutputPosition; i++) { + tmp[i] = messageContents[i]; + } + resp = tmp; + } else { + resp = messageContents; + } + return EncodingUtils.getAsciiString(Base64.encodeBase64(resp)); + } + + } + + /** Type 1 message assembly class */ + static class Type1Message extends NTLMMessage { + protected byte[] hostBytes; + protected byte[] domainBytes; + + /** Constructor. Include the arguments the message will need */ + Type1Message(String domain, String host) throws NTLMEngineException { + super(); + try { + // Strip off domain name from the host! + host = convertHost(host); + // Use only the base domain name! + domain = convertDomain(domain); + + hostBytes = host.getBytes("UnicodeLittleUnmarked"); + domainBytes = domain.toUpperCase().getBytes("UnicodeLittleUnmarked"); + } catch (java.io.UnsupportedEncodingException e) { + throw new NTLMEngineException("Unicode unsupported: " + e.getMessage(), e); + } + } + + /** + * Getting the response involves building the message before returning + * it + */ + @Override + String getResponse() { + // Now, build the message. Calculate its length first, including + // signature or type. + int finalLength = 32 + hostBytes.length + domainBytes.length; + + // Set up the response. This will initialize the signature, message + // type, and flags. + prepareResponse(finalLength, 1); + + // Flags. These are the complete set of flags we support. + addULong(FLAG_NEGOTIATE_NTLM | FLAG_NEGOTIATE_NTLM2 | FLAG_NEGOTIATE_SIGN + | FLAG_NEGOTIATE_SEAL | + /* + * FLAG_NEGOTIATE_ALWAYS_SIGN | FLAG_NEGOTIATE_KEY_EXCH | + */ + FLAG_UNICODE_ENCODING | FLAG_TARGET_DESIRED | FLAG_NEGOTIATE_128); + + // Domain length (two times). + addUShort(domainBytes.length); + addUShort(domainBytes.length); + + // Domain offset. + addULong(hostBytes.length + 32); + + // Host length (two times). + addUShort(hostBytes.length); + addUShort(hostBytes.length); + + // Host offset (always 32). + addULong(32); + + // Host String. + addBytes(hostBytes); + + // Domain String. + addBytes(domainBytes); + + return super.getResponse(); + } + + } + + /** Type 2 message class */ + static class Type2Message extends NTLMMessage { + protected byte[] challenge; + protected String target; + protected byte[] targetInfo; + protected int flags; + + Type2Message(String message) throws NTLMEngineException { + super(message, 2); + + // Parse out the rest of the info we need from the message + // The nonce is the 8 bytes starting from the byte in position 24. + challenge = new byte[8]; + readBytes(challenge, 24); + + flags = readULong(20); + if ((flags & FLAG_UNICODE_ENCODING) == 0) + throw new NTLMEngineException( + "NTLM type 2 message has flags that make no sense: " + + Integer.toString(flags)); + // Do the target! + target = null; + // The TARGET_DESIRED flag is said to not have understood semantics + // in Type2 messages, so use the length of the packet to decide + // how to proceed instead + if (getMessageLength() >= 12 + 8) { + byte[] bytes = readSecurityBuffer(12); + if (bytes.length != 0) { + try { + target = new String(bytes, "UnicodeLittleUnmarked"); + } catch (java.io.UnsupportedEncodingException e) { + throw new NTLMEngineException(e.getMessage(), e); + } + } + } + + // Do the target info! + targetInfo = null; + // TARGET_DESIRED flag cannot be relied on, so use packet length + if (getMessageLength() >= 40 + 8) { + byte[] bytes = readSecurityBuffer(40); + if (bytes.length != 0) { + targetInfo = bytes; + } + } + } + + /** Retrieve the challenge */ + byte[] getChallenge() { + return challenge; + } + + /** Retrieve the target */ + String getTarget() { + return target; + } + + /** Retrieve the target info */ + byte[] getTargetInfo() { + return targetInfo; + } + + /** Retrieve the response flags */ + int getFlags() { + return flags; + } + + } + + /** Type 3 message assembly class */ + static class Type3Message extends NTLMMessage { + // Response flags from the type2 message + protected int type2Flags; + + protected byte[] domainBytes; + protected byte[] hostBytes; + protected byte[] userBytes; + + protected byte[] lmResp; + protected byte[] ntResp; + + /** Constructor. Pass the arguments we will need */ + Type3Message(String domain, String host, String user, String password, byte[] nonce, + int type2Flags, String target, byte[] targetInformation) + throws NTLMEngineException { + // Save the flags + this.type2Flags = type2Flags; + + // Strip off domain name from the host! + host = convertHost(host); + // Use only the base domain name! + domain = convertDomain(domain); + + // Use the new code to calculate the responses, including v2 if that + // seems warranted. + try { + if (targetInformation != null && target != null) { + byte[] clientChallenge = makeRandomChallenge(); + ntResp = getNTLMv2Response(target, user, password, nonce, clientChallenge, + targetInformation); + lmResp = getLMv2Response(target, user, password, nonce, clientChallenge); + } else { + if ((type2Flags & FLAG_NEGOTIATE_NTLM2) != 0) { + // NTLM2 session stuff is requested + byte[] clientChallenge = makeNTLM2RandomChallenge(); + + ntResp = getNTLM2SessionResponse(password, nonce, clientChallenge); + lmResp = clientChallenge; + + // All the other flags we send (signing, sealing, key + // exchange) are supported, but they don't do anything + // at all in an + // NTLM2 context! So we're done at this point. + } else { + ntResp = getNTLMResponse(password, nonce); + lmResp = getLMResponse(password, nonce); + } + } + } catch (NTLMEngineException e) { + // This likely means we couldn't find the MD4 hash algorithm - + // fail back to just using LM + ntResp = new byte[0]; + lmResp = getLMResponse(password, nonce); + } + + try { + domainBytes = domain.toUpperCase().getBytes("UnicodeLittleUnmarked"); + hostBytes = host.getBytes("UnicodeLittleUnmarked"); + userBytes = user.getBytes("UnicodeLittleUnmarked"); + } catch (java.io.UnsupportedEncodingException e) { + throw new NTLMEngineException("Unicode not supported: " + e.getMessage(), e); + } + } + + /** Assemble the response */ + @Override + String getResponse() { + int ntRespLen = ntResp.length; + int lmRespLen = lmResp.length; + + int domainLen = domainBytes.length; + int hostLen = hostBytes.length; + int userLen = userBytes.length; + + // Calculate the layout within the packet + int lmRespOffset = 64; + int ntRespOffset = lmRespOffset + lmRespLen; + int domainOffset = ntRespOffset + ntRespLen; + int userOffset = domainOffset + domainLen; + int hostOffset = userOffset + userLen; + int sessionKeyOffset = hostOffset + hostLen; + int finalLength = sessionKeyOffset + 0; + + // Start the response. Length includes signature and type + prepareResponse(finalLength, 3); + + // LM Resp Length (twice) + addUShort(lmRespLen); + addUShort(lmRespLen); + + // LM Resp Offset + addULong(lmRespOffset); + + // NT Resp Length (twice) + addUShort(ntRespLen); + addUShort(ntRespLen); + + // NT Resp Offset + addULong(ntRespOffset); + + // Domain length (twice) + addUShort(domainLen); + addUShort(domainLen); + + // Domain offset. + addULong(domainOffset); + + // User Length (twice) + addUShort(userLen); + addUShort(userLen); + + // User offset + addULong(userOffset); + + // Host length (twice) + addUShort(hostLen); + addUShort(hostLen); + + // Host offset + addULong(hostOffset); + + // 4 bytes of zeros - not sure what this is + addULong(0); + + // Message length + addULong(finalLength); + + // Flags. Currently: NEGOTIATE_NTLM + UNICODE_ENCODING + + // TARGET_DESIRED + NEGOTIATE_128 + addULong(FLAG_NEGOTIATE_NTLM | FLAG_UNICODE_ENCODING | FLAG_TARGET_DESIRED + | FLAG_NEGOTIATE_128 | (type2Flags & FLAG_NEGOTIATE_NTLM2) + | (type2Flags & FLAG_NEGOTIATE_SIGN) | (type2Flags & FLAG_NEGOTIATE_SEAL) + | (type2Flags & FLAG_NEGOTIATE_KEY_EXCH) + | (type2Flags & FLAG_NEGOTIATE_ALWAYS_SIGN)); + + // Add the actual data + addBytes(lmResp); + addBytes(ntResp); + addBytes(domainBytes); + addBytes(userBytes); + addBytes(hostBytes); + + return super.getResponse(); + } + } + + static void writeULong(byte[] buffer, int value, int offset) { + buffer[offset] = (byte) (value & 0xff); + buffer[offset + 1] = (byte) (value >> 8 & 0xff); + buffer[offset + 2] = (byte) (value >> 16 & 0xff); + buffer[offset + 3] = (byte) (value >> 24 & 0xff); + } + + static int F(int x, int y, int z) { + return ((x & y) | (~x & z)); + } + + static int G(int x, int y, int z) { + return ((x & y) | (x & z) | (y & z)); + } + + static int H(int x, int y, int z) { + return (x ^ y ^ z); + } + + static int rotintlft(int val, int numbits) { + return ((val << numbits) | (val >>> (32 - numbits))); + } + + /** + * Cryptography support - MD4. The following class was based loosely on the + * RFC and on code found at http://www.cs.umd.edu/~harry/jotp/src/md.java. + * Code correctness was verified by looking at MD4.java from the jcifs + * library (http://jcifs.samba.org). It was massaged extensively to the + * final form found here by Karl Wright (kwright@metacarta.com). + */ + static class MD4 { + protected int A = 0x67452301; + protected int B = 0xefcdab89; + protected int C = 0x98badcfe; + protected int D = 0x10325476; + protected long count = 0L; + protected byte[] dataBuffer = new byte[64]; + + MD4() { + } + + void update(byte[] input) { + // We always deal with 512 bits at a time. Correspondingly, there is + // a buffer 64 bytes long that we write data into until it gets + // full. + int curBufferPos = (int) (count & 63L); + int inputIndex = 0; + while (input.length - inputIndex + curBufferPos >= dataBuffer.length) { + // We have enough data to do the next step. Do a partial copy + // and a transform, updating inputIndex and curBufferPos + // accordingly + int transferAmt = dataBuffer.length - curBufferPos; + System.arraycopy(input, inputIndex, dataBuffer, curBufferPos, transferAmt); + count += transferAmt; + curBufferPos = 0; + inputIndex += transferAmt; + processBuffer(); + } + + // If there's anything left, copy it into the buffer and leave it. + // We know there's not enough left to process. + if (inputIndex < input.length) { + int transferAmt = input.length - inputIndex; + System.arraycopy(input, inputIndex, dataBuffer, curBufferPos, transferAmt); + count += transferAmt; + curBufferPos += transferAmt; + } + } + + byte[] getOutput() { + // Feed pad/length data into engine. This must round out the input + // to a multiple of 512 bits. + int bufferIndex = (int) (count & 63L); + int padLen = (bufferIndex < 56) ? (56 - bufferIndex) : (120 - bufferIndex); + byte[] postBytes = new byte[padLen + 8]; + // Leading 0x80, specified amount of zero padding, then length in + // bits. + postBytes[0] = (byte) 0x80; + // Fill out the last 8 bytes with the length + for (int i = 0; i < 8; i++) { + postBytes[padLen + i] = (byte) ((count * 8) >>> (8 * i)); + } + + // Update the engine + update(postBytes); + + // Calculate final result + byte[] result = new byte[16]; + writeULong(result, A, 0); + writeULong(result, B, 4); + writeULong(result, C, 8); + writeULong(result, D, 12); + return result; + } + + protected void processBuffer() { + // Convert current buffer to 16 ulongs + int[] d = new int[16]; + + for (int i = 0; i < 16; i++) { + d[i] = (dataBuffer[i * 4] & 0xff) + ((dataBuffer[i * 4 + 1] & 0xff) << 8) + + ((dataBuffer[i * 4 + 2] & 0xff) << 16) + + ((dataBuffer[i * 4 + 3] & 0xff) << 24); + } + + // Do a round of processing + int AA = A; + int BB = B; + int CC = C; + int DD = D; + round1(d); + round2(d); + round3(d); + A += AA; + B += BB; + C += CC; + D += DD; + + } + + protected void round1(int[] d) { + A = rotintlft((A + F(B, C, D) + d[0]), 3); + D = rotintlft((D + F(A, B, C) + d[1]), 7); + C = rotintlft((C + F(D, A, B) + d[2]), 11); + B = rotintlft((B + F(C, D, A) + d[3]), 19); + + A = rotintlft((A + F(B, C, D) + d[4]), 3); + D = rotintlft((D + F(A, B, C) + d[5]), 7); + C = rotintlft((C + F(D, A, B) + d[6]), 11); + B = rotintlft((B + F(C, D, A) + d[7]), 19); + + A = rotintlft((A + F(B, C, D) + d[8]), 3); + D = rotintlft((D + F(A, B, C) + d[9]), 7); + C = rotintlft((C + F(D, A, B) + d[10]), 11); + B = rotintlft((B + F(C, D, A) + d[11]), 19); + + A = rotintlft((A + F(B, C, D) + d[12]), 3); + D = rotintlft((D + F(A, B, C) + d[13]), 7); + C = rotintlft((C + F(D, A, B) + d[14]), 11); + B = rotintlft((B + F(C, D, A) + d[15]), 19); + } + + protected void round2(int[] d) { + A = rotintlft((A + G(B, C, D) + d[0] + 0x5a827999), 3); + D = rotintlft((D + G(A, B, C) + d[4] + 0x5a827999), 5); + C = rotintlft((C + G(D, A, B) + d[8] + 0x5a827999), 9); + B = rotintlft((B + G(C, D, A) + d[12] + 0x5a827999), 13); + + A = rotintlft((A + G(B, C, D) + d[1] + 0x5a827999), 3); + D = rotintlft((D + G(A, B, C) + d[5] + 0x5a827999), 5); + C = rotintlft((C + G(D, A, B) + d[9] + 0x5a827999), 9); + B = rotintlft((B + G(C, D, A) + d[13] + 0x5a827999), 13); + + A = rotintlft((A + G(B, C, D) + d[2] + 0x5a827999), 3); + D = rotintlft((D + G(A, B, C) + d[6] + 0x5a827999), 5); + C = rotintlft((C + G(D, A, B) + d[10] + 0x5a827999), 9); + B = rotintlft((B + G(C, D, A) + d[14] + 0x5a827999), 13); + + A = rotintlft((A + G(B, C, D) + d[3] + 0x5a827999), 3); + D = rotintlft((D + G(A, B, C) + d[7] + 0x5a827999), 5); + C = rotintlft((C + G(D, A, B) + d[11] + 0x5a827999), 9); + B = rotintlft((B + G(C, D, A) + d[15] + 0x5a827999), 13); + + } + + protected void round3(int[] d) { + A = rotintlft((A + H(B, C, D) + d[0] + 0x6ed9eba1), 3); + D = rotintlft((D + H(A, B, C) + d[8] + 0x6ed9eba1), 9); + C = rotintlft((C + H(D, A, B) + d[4] + 0x6ed9eba1), 11); + B = rotintlft((B + H(C, D, A) + d[12] + 0x6ed9eba1), 15); + + A = rotintlft((A + H(B, C, D) + d[2] + 0x6ed9eba1), 3); + D = rotintlft((D + H(A, B, C) + d[10] + 0x6ed9eba1), 9); + C = rotintlft((C + H(D, A, B) + d[6] + 0x6ed9eba1), 11); + B = rotintlft((B + H(C, D, A) + d[14] + 0x6ed9eba1), 15); + + A = rotintlft((A + H(B, C, D) + d[1] + 0x6ed9eba1), 3); + D = rotintlft((D + H(A, B, C) + d[9] + 0x6ed9eba1), 9); + C = rotintlft((C + H(D, A, B) + d[5] + 0x6ed9eba1), 11); + B = rotintlft((B + H(C, D, A) + d[13] + 0x6ed9eba1), 15); + + A = rotintlft((A + H(B, C, D) + d[3] + 0x6ed9eba1), 3); + D = rotintlft((D + H(A, B, C) + d[11] + 0x6ed9eba1), 9); + C = rotintlft((C + H(D, A, B) + d[7] + 0x6ed9eba1), 11); + B = rotintlft((B + H(C, D, A) + d[15] + 0x6ed9eba1), 15); + + } + + } + + /** + * Cryptography support - HMACMD5 - algorithmically based on various web + * resources by Karl Wright + */ + static class HMACMD5 { + protected byte[] ipad; + protected byte[] opad; + protected MessageDigest md5; + + HMACMD5(byte[] key) throws NTLMEngineException { + try { + md5 = MessageDigest.getInstance("MD5"); + } catch (Exception ex) { + // Umm, the algorithm doesn't exist - throw an + // NTLMEngineException! + throw new NTLMEngineException( + "Error getting md5 message digest implementation: " + ex.getMessage(), ex); + } + + // Initialize the pad buffers with the key + ipad = new byte[64]; + opad = new byte[64]; + + int keyLength = key.length; + if (keyLength > 64) { + // Use MD5 of the key instead, as described in RFC 2104 + md5.update(key); + key = md5.digest(); + keyLength = key.length; + } + int i = 0; + while (i < keyLength) { + ipad[i] = (byte) (key[i] ^ (byte) 0x36); + opad[i] = (byte) (key[i] ^ (byte) 0x5c); + i++; + } + while (i < 64) { + ipad[i] = (byte) 0x36; + opad[i] = (byte) 0x5c; + i++; + } + + // Very important: update the digest with the ipad buffer + md5.reset(); + md5.update(ipad); + + } + + /** Grab the current digest. This is the "answer". */ + byte[] getOutput() { + byte[] digest = md5.digest(); + md5.update(opad); + return md5.digest(digest); + } + + /** Update by adding a complete array */ + void update(byte[] input) { + md5.update(input); + } + + /** Update the algorithm */ + void update(byte[] input, int offset, int length) { + md5.update(input, offset, length); + } + + } + + public String generateType1Msg( + final String domain, + final String workstation) throws NTLMEngineException { + return getType1Message(workstation, domain); + } + + public String generateType3Msg( + final String username, + final String password, + final String domain, + final String workstation, + final String challenge) throws NTLMEngineException { + Type2Message t2m = new Type2Message(challenge); + return getType3Message( + username, + password, + workstation, + domain, + t2m.getChallenge(), + t2m.getFlags(), + t2m.getTarget(), + t2m.getTargetInfo()); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMScheme.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMScheme.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMScheme.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,155 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.Header; +import org.apache.http.HttpRequest; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.Credentials; +import org.apache.http.auth.InvalidCredentialsException; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.auth.NTCredentials; +import org.apache.http.impl.auth.AuthSchemeBase; +import org.apache.http.message.BufferedHeader; +import org.apache.http.util.CharArrayBuffer; + +/** + * NTLM is a proprietary authentication scheme developed by Microsoft + * and optimized for Windows platforms. + * + * @since 4.0 + */ +@NotThreadSafe +public class NTLMScheme extends AuthSchemeBase { + + enum State { + UNINITIATED, + CHALLENGE_RECEIVED, + MSG_TYPE1_GENERATED, + MSG_TYPE2_RECEVIED, + MSG_TYPE3_GENERATED, + FAILED, + } + + private final NTLMEngine engine; + + private State state; + private String challenge; + + public NTLMScheme(final NTLMEngine engine) { + super(); + if (engine == null) { + throw new IllegalArgumentException("NTLM engine may not be null"); + } + this.engine = engine; + this.state = State.UNINITIATED; + this.challenge = null; + } + + public String getSchemeName() { + return "ntlm"; + } + + public String getParameter(String name) { + // String parameters not supported + return null; + } + + public String getRealm() { + // NTLM does not support the concept of an authentication realm + return null; + } + + public boolean isConnectionBased() { + return true; + } + + @Override + protected void parseChallenge( + final CharArrayBuffer buffer, + int beginIndex, int endIndex) throws MalformedChallengeException { + String challenge = buffer.substringTrimmed(beginIndex, endIndex); + if (challenge.length() == 0) { + if (this.state == State.UNINITIATED) { + this.state = State.CHALLENGE_RECEIVED; + } else { + this.state = State.FAILED; + } + this.challenge = null; + } else { + this.state = State.MSG_TYPE2_RECEVIED; + this.challenge = challenge; + } + } + + public Header authenticate( + final Credentials credentials, + final HttpRequest request) throws AuthenticationException { + NTCredentials ntcredentials = null; + try { + ntcredentials = (NTCredentials) credentials; + } catch (ClassCastException e) { + throw new InvalidCredentialsException( + "Credentials cannot be used for NTLM authentication: " + + credentials.getClass().getName()); + } + String response = null; + if (this.state == State.CHALLENGE_RECEIVED || this.state == State.FAILED) { + response = this.engine.generateType1Msg( + ntcredentials.getDomain(), + ntcredentials.getWorkstation()); + this.state = State.MSG_TYPE1_GENERATED; + } else if (this.state == State.MSG_TYPE2_RECEVIED) { + response = this.engine.generateType3Msg( + ntcredentials.getUserName(), + ntcredentials.getPassword(), + ntcredentials.getDomain(), + ntcredentials.getWorkstation(), + this.challenge); + this.state = State.MSG_TYPE3_GENERATED; + } else { + throw new AuthenticationException("Unexpected state: " + this.state); + } + CharArrayBuffer buffer = new CharArrayBuffer(32); + if (isProxy()) { + buffer.append(AUTH.PROXY_AUTH_RESP); + } else { + buffer.append(AUTH.WWW_AUTH_RESP); + } + buffer.append(": NTLM "); + buffer.append(response); + return new BufferedHeader(buffer); + } + + public boolean isComplete() { + return this.state == State.MSG_TYPE3_GENERATED || this.state == State.FAILED; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMSchemeFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMSchemeFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/NTLMSchemeFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,50 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthSchemeFactory; +import org.apache.http.params.HttpParams; + +/** + * {@link AuthSchemeFactory} implementation that creates and initializes + * {@link NTLMScheme} instances configured to use the default {@link NTLMEngine} + * implementation. + * + * @since 4.1 + */ +@Immutable +public class NTLMSchemeFactory implements AuthSchemeFactory { + + public AuthScheme newInstance(final HttpParams params) { + return new NTLMScheme(new NTLMEngineImpl()); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/NegotiateScheme.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/NegotiateScheme.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/NegotiateScheme.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,203 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.http.impl.auth; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpRequest; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.Credentials; +import org.apache.http.protocol.HttpContext; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.Oid; + +/** + * SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) authentication + * scheme. + * + * @since 4.1 + * + * @deprecated (4.2) use {@link SPNegoScheme} or {@link KerberosScheme}. + */ +@Deprecated +public class NegotiateScheme extends GGSSchemeBase { + + private final Log log = LogFactory.getLog(getClass()); + + private static final String SPNEGO_OID = "1.3.6.1.5.5.2"; + private static final String KERBEROS_OID = "1.2.840.113554.1.2.2"; + + private final SpnegoTokenGenerator spengoGenerator; + + /** + * Default constructor for the Negotiate authentication scheme. + * + */ + public NegotiateScheme(final SpnegoTokenGenerator spengoGenerator, boolean stripPort) { + super(stripPort); + this.spengoGenerator = spengoGenerator; + } + + public NegotiateScheme(final SpnegoTokenGenerator spengoGenerator) { + this(spengoGenerator, false); + } + + public NegotiateScheme() { + this(null, false); + } + + /** + * Returns textual designation of the Negotiate authentication scheme. + * + * @return Negotiate + */ + public String getSchemeName() { + return "Negotiate"; + } + + public Header authenticate( + final Credentials credentials, + final HttpRequest request) throws AuthenticationException { + return authenticate(credentials, request, null); + } + + /** + * Produces Negotiate authorization Header based on token created by + * processChallenge. + * + * @param credentials Never used be the Negotiate scheme but must be provided to + * satisfy common-httpclient API. Credentials from JAAS will be used instead. + * @param request The request being authenticated + * + * @throws AuthenticationException if authorisation string cannot + * be generated due to an authentication failure + * + * @return an Negotiate authorisation Header + */ + @Override + public Header authenticate( + final Credentials credentials, + final HttpRequest request, + final HttpContext context) throws AuthenticationException { + return super.authenticate(credentials, request, context); + } + + @Override + protected byte[] generateToken(final byte[] input, final String authServer) throws GSSException { + /* Using the SPNEGO OID is the correct method. + * Kerberos v5 works for IIS but not JBoss. Unwrapping + * the initial token when using SPNEGO OID looks like what is + * described here... + * + * http://msdn.microsoft.com/en-us/library/ms995330.aspx + * + * Another helpful URL... + * + * http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.express.doc/info/exp/ae/tsec_SPNEGO_token.html + * + * Unfortunately SPNEGO is JRE >=1.6. + */ + + /** Try SPNEGO by default, fall back to Kerberos later if error */ + Oid negotiationOid = new Oid(SPNEGO_OID); + + byte[] token = input; + boolean tryKerberos = false; + try { + token = generateGSSToken(token, negotiationOid, authServer); + } catch (GSSException ex){ + // BAD MECH means we are likely to be using 1.5, fall back to Kerberos MECH. + // Rethrow any other exception. + if (ex.getMajor() == GSSException.BAD_MECH ){ + log.debug("GSSException BAD_MECH, retry with Kerberos MECH"); + tryKerberos = true; + } else { + throw ex; + } + + } + if (tryKerberos){ + /* Kerberos v5 GSS-API mechanism defined in RFC 1964.*/ + log.debug("Using Kerberos MECH " + KERBEROS_OID); + negotiationOid = new Oid(KERBEROS_OID); + token = generateGSSToken(token, negotiationOid, authServer); + + /* + * IIS accepts Kerberos and SPNEGO tokens. Some other servers Jboss, Glassfish? + * seem to only accept SPNEGO. Below wraps Kerberos into SPNEGO token. + */ + if (token != null && spengoGenerator != null) { + try { + token = spengoGenerator.generateSpnegoDERObject(token); + } catch (IOException ex) { + log.error(ex.getMessage(), ex); + } + } + } + return token; + } + + /** + * Returns the authentication parameter with the given name, if available. + * + *

There are no valid parameters for Negotiate authentication so this + * method always returns null.

+ * + * @param name The name of the parameter to be returned + * + * @return the parameter with the given name + */ + public String getParameter(String name) { + if (name == null) { + throw new IllegalArgumentException("Parameter name may not be null"); + } + return null; + } + + /** + * The concept of an authentication realm is not supported by the Negotiate + * authentication scheme. Always returns null. + * + * @return null + */ + public String getRealm() { + return null; + } + + /** + * Returns true. + * Negotiate authentication scheme is connection based. + * + * @return true. + */ + public boolean isConnectionBased() { + return true; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/NegotiateSchemeFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/NegotiateSchemeFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/NegotiateSchemeFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,73 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthSchemeFactory; +import org.apache.http.params.HttpParams; + +/** + * SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) authentication + * scheme factory. + * + * @since 4.1 + * + * @deprecated (4.2) use {@link SPNegoSchemeFactory} or {@link KerberosSchemeFactory}. + */ +@Deprecated +public class NegotiateSchemeFactory implements AuthSchemeFactory { + + private final SpnegoTokenGenerator spengoGenerator; + private final boolean stripPort; + + public NegotiateSchemeFactory(final SpnegoTokenGenerator spengoGenerator, boolean stripPort) { + super(); + this.spengoGenerator = spengoGenerator; + this.stripPort = stripPort; + } + + public NegotiateSchemeFactory(final SpnegoTokenGenerator spengoGenerator) { + this(spengoGenerator, false); + } + + public NegotiateSchemeFactory() { + this(null, false); + } + + public AuthScheme newInstance(final HttpParams params) { + return new NegotiateScheme(this.spengoGenerator, this.stripPort); + } + + public boolean isStripPort() { + return stripPort; + } + + public SpnegoTokenGenerator getSpengoGenerator() { + return spengoGenerator; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/RFC2617Scheme.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/RFC2617Scheme.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/RFC2617Scheme.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,120 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.HeaderElement; +import org.apache.http.auth.ChallengeState; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.message.BasicHeaderValueParser; +import org.apache.http.message.HeaderValueParser; +import org.apache.http.message.ParserCursor; +import org.apache.http.util.CharArrayBuffer; + +/** + * Abstract authentication scheme class that lays foundation for all + * RFC 2617 compliant authentication schemes and provides capabilities common + * to all authentication schemes defined in RFC 2617. + * + * @since 4.0 + */ +@NotThreadSafe // AuthSchemeBase, params +public abstract class RFC2617Scheme extends AuthSchemeBase { + + /** + * Authentication parameter map. + */ + private final Map params; + + /** + * Creates an instance of RFC2617Scheme with the given challenge + * state. + * + * @since 4.2 + */ + public RFC2617Scheme(final ChallengeState challengeState) { + super(challengeState); + this.params = new HashMap(); + } + + public RFC2617Scheme() { + this(null); + } + + @Override + protected void parseChallenge( + final CharArrayBuffer buffer, int pos, int len) throws MalformedChallengeException { + HeaderValueParser parser = BasicHeaderValueParser.DEFAULT; + ParserCursor cursor = new ParserCursor(pos, buffer.length()); + HeaderElement[] elements = parser.parseElements(buffer, cursor); + if (elements.length == 0) { + throw new MalformedChallengeException("Authentication challenge is empty"); + } + this.params.clear(); + for (HeaderElement element : elements) { + this.params.put(element.getName(), element.getValue()); + } + } + + /** + * Returns authentication parameters map. Keys in the map are lower-cased. + * + * @return the map of authentication parameters + */ + protected Map getParameters() { + return this.params; + } + + /** + * Returns authentication parameter with the given name, if available. + * + * @param name The name of the parameter to be returned + * + * @return the parameter with the given name + */ + public String getParameter(final String name) { + if (name == null) { + return null; + } + return this.params.get(name.toLowerCase(Locale.ENGLISH)); + } + + /** + * Returns authentication realm. The realm may not be null. + * + * @return the authentication realm + */ + public String getRealm() { + return getParameter("realm"); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/SPNegoScheme.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/SPNegoScheme.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/SPNegoScheme.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,115 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.http.impl.auth; + +import org.apache.http.Header; +import org.apache.http.HttpRequest; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.Credentials; +import org.apache.http.protocol.HttpContext; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.Oid; + +/** + * SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) authentication + * scheme. + * + * @since 4.2 + */ +public class SPNegoScheme extends GGSSchemeBase { + + private static final String SPNEGO_OID = "1.3.6.1.5.5.2"; + + public SPNegoScheme(boolean stripPort) { + super(stripPort); + } + + public SPNegoScheme() { + super(false); + } + + public String getSchemeName() { + return "Negotiate"; + } + + /** + * Produces SPNEGO authorization Header based on token created by + * processChallenge. + * + * @param credentials not used by the SPNEGO scheme. + * @param request The request being authenticated + * + * @throws AuthenticationException if authentication string cannot + * be generated due to an authentication failure + * + * @return SPNEGO authentication Header + */ + @Override + public Header authenticate( + final Credentials credentials, + final HttpRequest request, + final HttpContext context) throws AuthenticationException { + return super.authenticate(credentials, request, context); + } + + @Override + protected byte[] generateToken(final byte[] input, final String authServer) throws GSSException { + return generateGSSToken(input, new Oid(SPNEGO_OID), authServer); + } + + /** + * There are no valid parameters for SPNEGO authentication so this + * method always returns null. + * + * @return null + */ + public String getParameter(String name) { + if (name == null) { + throw new IllegalArgumentException("Parameter name may not be null"); + } + return null; + } + + /** + * The concept of an authentication realm is not supported by the Negotiate + * authentication scheme. Always returns null. + * + * @return null + */ + public String getRealm() { + return null; + } + + /** + * Returns true. SPNEGO authentication scheme is connection based. + * + * @return true. + */ + public boolean isConnectionBased() { + return true; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/SPNegoSchemeFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/SPNegoSchemeFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/SPNegoSchemeFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,62 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthSchemeFactory; +import org.apache.http.params.HttpParams; + +/** + * SPNEGO (Simple and Protected GSSAPI Negotiation Mechanism) authentication + * scheme factory. + * + * @since 4.2 + */ +@Immutable +public class SPNegoSchemeFactory implements AuthSchemeFactory { + + private final boolean stripPort; + + public SPNegoSchemeFactory(boolean stripPort) { + super(); + this.stripPort = stripPort; + } + + public SPNegoSchemeFactory() { + this(false); + } + + public AuthScheme newInstance(final HttpParams params) { + return new SPNegoScheme(this.stripPort); + } + + public boolean isStripPort() { + return stripPort; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/SpnegoTokenGenerator.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/SpnegoTokenGenerator.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/SpnegoTokenGenerator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,47 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import java.io.IOException; + +/** + * Abstract SPNEGO token generator. Implementations should take an Kerberos ticket and transform + * into a SPNEGO token. + *

+ * Implementations of this interface are expected to be thread-safe. + * + * @since 4.1 + * + * @deprecated (4.2) subclass {@link KerberosScheme} and override + * {@link KerberosScheme#generateGSSToken(byte[], org.ietf.jgss.Oid, String)} + */ +@Deprecated +public interface SpnegoTokenGenerator { + + byte [] generateSpnegoDERObject(byte [] kerberosTicket) throws IOException; + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/UnsupportedDigestAlgorithmException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/UnsupportedDigestAlgorithmException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/UnsupportedDigestAlgorithmException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,69 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.auth; + +import org.apache.http.annotation.Immutable; + +/** + * Authentication credentials required to respond to a authentication + * challenge are invalid + * + * + * @since 4.0 + */ +@Immutable +public class UnsupportedDigestAlgorithmException extends RuntimeException { + + private static final long serialVersionUID = 319558534317118022L; + + /** + * Creates a new UnsupportedAuthAlgoritmException with a null detail message. + */ + public UnsupportedDigestAlgorithmException() { + super(); + } + + /** + * Creates a new UnsupportedAuthAlgoritmException with the specified message. + * + * @param message the exception detail message + */ + public UnsupportedDigestAlgorithmException(String message) { + super(message); + } + + /** + * Creates a new UnsupportedAuthAlgoritmException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public UnsupportedDigestAlgorithmException(String message, Throwable cause) { + super(message, cause); + } +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/auth/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/auth/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/auth/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Default implementations for interfaces in +{@link org.apache.http.auth org.apache.http.auth}. + + Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/AIMDBackoffManager.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/AIMDBackoffManager.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/AIMDBackoffManager.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,161 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.client; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.http.client.BackoffManager; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.pool.ConnPoolControl; + +/** + *

The AIMDBackoffManager applies an additive increase, + * multiplicative decrease (AIMD) to managing a dynamic limit to + * the number of connections allowed to a given host. You may want + * to experiment with the settings for the cooldown periods and the + * backoff factor to get the adaptive behavior you want.

+ * + *

Generally speaking, shorter cooldowns will lead to more steady-state + * variability but faster reaction times, while longer cooldowns + * will lead to more stable equilibrium behavior but slower reaction + * times.

+ * + *

Similarly, higher backoff factors promote greater + * utilization of available capacity at the expense of fairness + * among clients. Lower backoff factors allow equal distribution of + * capacity among clients (fairness) to happen faster, at the + * expense of having more server capacity unused in the short term.

+ * + * @since 4.2 + */ +public class AIMDBackoffManager implements BackoffManager { + + private final ConnPoolControl connPerRoute; + private final Clock clock; + private final Map lastRouteProbes; + private final Map lastRouteBackoffs; + private long coolDown = 5 * 1000L; + private double backoffFactor = 0.5; + private int cap = 2; // Per RFC 2616 sec 8.1.4 + + /** + * Creates an AIMDBackoffManager to manage + * per-host connection pool sizes represented by the + * given {@link ConnPoolControl}. + * @param connPerRoute per-host routing maximums to + * be managed + */ + public AIMDBackoffManager(ConnPoolControl connPerRoute) { + this(connPerRoute, new SystemClock()); + } + + AIMDBackoffManager(ConnPoolControl connPerRoute, Clock clock) { + this.clock = clock; + this.connPerRoute = connPerRoute; + this.lastRouteProbes = new HashMap(); + this.lastRouteBackoffs = new HashMap(); + } + + public void backOff(HttpRoute route) { + synchronized(connPerRoute) { + int curr = connPerRoute.getMaxPerRoute(route); + Long lastUpdate = getLastUpdate(lastRouteBackoffs, route); + long now = clock.getCurrentTime(); + if (now - lastUpdate.longValue() < coolDown) return; + connPerRoute.setMaxPerRoute(route, getBackedOffPoolSize(curr)); + lastRouteBackoffs.put(route, Long.valueOf(now)); + } + } + + private int getBackedOffPoolSize(int curr) { + if (curr <= 1) return 1; + return (int)(Math.floor(backoffFactor * curr)); + } + + public void probe(HttpRoute route) { + synchronized(connPerRoute) { + int curr = connPerRoute.getMaxPerRoute(route); + int max = (curr >= cap) ? cap : curr + 1; + Long lastProbe = getLastUpdate(lastRouteProbes, route); + Long lastBackoff = getLastUpdate(lastRouteBackoffs, route); + long now = clock.getCurrentTime(); + if (now - lastProbe.longValue() < coolDown || now - lastBackoff.longValue() < coolDown) + return; + connPerRoute.setMaxPerRoute(route, max); + lastRouteProbes.put(route, Long.valueOf(now)); + } + } + + private Long getLastUpdate(Map updates, HttpRoute route) { + Long lastUpdate = updates.get(route); + if (lastUpdate == null) lastUpdate = Long.valueOf(0L); + return lastUpdate; + } + + /** + * Sets the factor to use when backing off; the new + * per-host limit will be roughly the current max times + * this factor. Math.floor is applied in the + * case of non-integer outcomes to ensure we actually + * decrease the pool size. Pool sizes are never decreased + * below 1, however. Defaults to 0.5. + * @param d must be between 0.0 and 1.0, exclusive. + */ + public void setBackoffFactor(double d) { + if (d <= 0.0 || d >= 1.0) { + throw new IllegalArgumentException("backoffFactor must be 0.0 < f < 1.0"); + } + backoffFactor = d; + } + + /** + * Sets the amount of time, in milliseconds, to wait between + * adjustments in pool sizes for a given host, to allow + * enough time for the adjustments to take effect. Defaults + * to 5000L (5 seconds). + * @param l must be positive + */ + public void setCooldownMillis(long l) { + if (coolDown <= 0) { + throw new IllegalArgumentException("cooldownMillis must be positive"); + } + coolDown = l; + } + + /** + * Sets the absolute maximum per-host connection pool size to + * probe up to; defaults to 2 (the default per-host max). + * @param cap must be >= 1 + */ + public void setPerHostConnectionCap(int cap) { + if (cap < 1) { + throw new IllegalArgumentException("perHostConnectionCap must be >= 1"); + } + this.cap = cap; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/AbstractAuthenticationHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/AbstractAuthenticationHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/AbstractAuthenticationHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,192 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.FormattedHeader; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthSchemeRegistry; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.client.AuthenticationHandler; +import org.apache.http.client.AuthenticationStrategy; +import org.apache.http.client.params.AuthPolicy; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.protocol.HTTP; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.CharArrayBuffer; + +/** + * Base class for {@link AuthenticationHandler} implementations. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link AuthenticationStrategy} + */ +@Deprecated +@Immutable +public abstract class AbstractAuthenticationHandler implements AuthenticationHandler { + + private final Log log = LogFactory.getLog(getClass()); + + private static final List DEFAULT_SCHEME_PRIORITY = + Collections.unmodifiableList(Arrays.asList(new String[] { + AuthPolicy.SPNEGO, + AuthPolicy.NTLM, + AuthPolicy.DIGEST, + AuthPolicy.BASIC + })); + + public AbstractAuthenticationHandler() { + super(); + } + + protected Map parseChallenges( + final Header[] headers) throws MalformedChallengeException { + + Map map = new HashMap(headers.length); + for (Header header : headers) { + CharArrayBuffer buffer; + int pos; + if (header instanceof FormattedHeader) { + buffer = ((FormattedHeader) header).getBuffer(); + pos = ((FormattedHeader) header).getValuePos(); + } else { + String s = header.getValue(); + if (s == null) { + throw new MalformedChallengeException("Header value is null"); + } + buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + pos = 0; + } + while (pos < buffer.length() && HTTP.isWhitespace(buffer.charAt(pos))) { + pos++; + } + int beginIndex = pos; + while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) { + pos++; + } + int endIndex = pos; + String s = buffer.substring(beginIndex, endIndex); + map.put(s.toLowerCase(Locale.US), header); + } + return map; + } + + /** + * Returns default list of auth scheme names in their order of preference. + * + * @return list of auth scheme names + */ + protected List getAuthPreferences() { + return DEFAULT_SCHEME_PRIORITY; + } + + /** + * Returns default list of auth scheme names in their order of preference + * based on the HTTP response and the current execution context. + * + * @param response HTTP response. + * @param context HTTP execution context. + * + * @since 4.1 + */ + protected List getAuthPreferences( + final HttpResponse response, + final HttpContext context) { + return getAuthPreferences(); + } + + public AuthScheme selectScheme( + final Map challenges, + final HttpResponse response, + final HttpContext context) throws AuthenticationException { + + AuthSchemeRegistry registry = (AuthSchemeRegistry) context.getAttribute( + ClientContext.AUTHSCHEME_REGISTRY); + if (registry == null) { + throw new IllegalStateException("AuthScheme registry not set in HTTP context"); + } + + Collection authPrefs = getAuthPreferences(response, context); + if (authPrefs == null) { + authPrefs = DEFAULT_SCHEME_PRIORITY; + } + + if (this.log.isDebugEnabled()) { + this.log.debug("Authentication schemes in the order of preference: " + + authPrefs); + } + + AuthScheme authScheme = null; + for (String id: authPrefs) { + Header challenge = challenges.get(id.toLowerCase(Locale.ENGLISH)); + + if (challenge != null) { + if (this.log.isDebugEnabled()) { + this.log.debug(id + " authentication scheme selected"); + } + try { + authScheme = registry.getAuthScheme(id, response.getParams()); + break; + } catch (IllegalStateException e) { + if (this.log.isWarnEnabled()) { + this.log.warn("Authentication scheme " + id + " not supported"); + // Try again + } + } + } else { + if (this.log.isDebugEnabled()) { + this.log.debug("Challenge for " + id + " authentication scheme not available"); + // Try again + } + } + } + if (authScheme == null) { + // If none selected, something is wrong + throw new AuthenticationException( + "Unable to respond to any of these challenges: " + + challenges); + } + return authScheme; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/AbstractHttpClient.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/AbstractHttpClient.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/AbstractHttpClient.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,1096 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.io.IOException; +import java.lang.reflect.UndeclaredThrowableException; +import java.net.URI; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.annotation.GuardedBy; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.auth.AuthSchemeRegistry; +import org.apache.http.client.AuthenticationHandler; +import org.apache.http.client.AuthenticationStrategy; +import org.apache.http.client.BackoffManager; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.ConnectionBackoffStrategy; +import org.apache.http.client.CookieStore; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.HttpClient; +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.client.RedirectHandler; +import org.apache.http.client.RedirectStrategy; +import org.apache.http.client.RequestDirector; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.UserTokenHandler; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.params.AuthPolicy; +import org.apache.http.client.params.ClientPNames; +import org.apache.http.client.params.CookiePolicy; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.client.utils.URIUtils; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionManagerFactory; +import org.apache.http.conn.ConnectionKeepAliveStrategy; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.cookie.CookieSpecRegistry; +import org.apache.http.impl.DefaultConnectionReuseStrategy; +import org.apache.http.impl.auth.BasicSchemeFactory; +import org.apache.http.impl.auth.DigestSchemeFactory; +import org.apache.http.impl.auth.KerberosSchemeFactory; +import org.apache.http.impl.auth.NTLMSchemeFactory; +import org.apache.http.impl.auth.SPNegoSchemeFactory; +import org.apache.http.impl.conn.BasicClientConnectionManager; +import org.apache.http.impl.conn.DefaultHttpRoutePlanner; +import org.apache.http.impl.conn.SchemeRegistryFactory; +import org.apache.http.impl.cookie.BestMatchSpecFactory; +import org.apache.http.impl.cookie.BrowserCompatSpecFactory; +import org.apache.http.impl.cookie.IgnoreSpecFactory; +import org.apache.http.impl.cookie.NetscapeDraftSpecFactory; +import org.apache.http.impl.cookie.RFC2109SpecFactory; +import org.apache.http.impl.cookie.RFC2965SpecFactory; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.BasicHttpProcessor; +import org.apache.http.protocol.DefaultedHttpContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpProcessor; +import org.apache.http.protocol.HttpRequestExecutor; +import org.apache.http.protocol.ImmutableHttpProcessor; +import org.apache.http.util.EntityUtils; + +/** + * Base class for {@link HttpClient} implementations. This class acts as + * a facade to a number of special purpose handler or strategy + * implementations responsible for handling of a particular aspect of + * the HTTP protocol such as redirect or authentication handling or + * making decision about connection persistence and keep alive duration. + * This enables the users to selectively replace default implementation + * of those aspects with custom, application specific ones. This class + * also provides factory methods to instantiate those objects: + *
    + *
  • {@link HttpRequestExecutor}
  • object used to transmit messages + * over HTTP connections. The {@link #createRequestExecutor()} must be + * implemented by concrete super classes to instantiate this object. + *
  • {@link BasicHttpProcessor}
  • object to manage a list of protocol + * interceptors and apply cross-cutting protocol logic to all incoming + * and outgoing HTTP messages. The {@link #createHttpProcessor()} must be + * implemented by concrete super classes to instantiate this object. + *
  • {@link HttpRequestRetryHandler}
  • object used to decide whether + * or not a failed HTTP request is safe to retry automatically. + * The {@link #createHttpRequestRetryHandler()} must be + * implemented by concrete super classes to instantiate this object. + *
  • {@link ClientConnectionManager}
  • object used to manage + * persistent HTTP connections. + *
  • {@link ConnectionReuseStrategy}
  • object used to decide whether + * or not a HTTP connection can be kept alive and re-used for subsequent + * HTTP requests. The {@link #createConnectionReuseStrategy()} must be + * implemented by concrete super classes to instantiate this object. + *
  • {@link ConnectionKeepAliveStrategy}
  • object used to decide how + * long a persistent HTTP connection can be kept alive. + * The {@link #createConnectionKeepAliveStrategy()} must be + * implemented by concrete super classes to instantiate this object. + *
  • {@link CookieSpecRegistry}
  • object used to maintain a list of + * supported cookie specifications. + * The {@link #createCookieSpecRegistry()} must be implemented by concrete + * super classes to instantiate this object. + *
  • {@link CookieStore}
  • object used to maintain a collection of + * cookies. The {@link #createCookieStore()} must be implemented by + * concrete super classes to instantiate this object. + *
  • {@link AuthSchemeRegistry}
  • object used to maintain a list of + * supported authentication schemes. + * The {@link #createAuthSchemeRegistry()} must be implemented by concrete + * super classes to instantiate this object. + *
  • {@link CredentialsProvider}
  • object used to maintain + * a collection user credentials. The {@link #createCredentialsProvider()} + * must be implemented by concrete super classes to instantiate + * this object. + *
  • {@link AuthenticationStrategy}
  • object used to authenticate + * against the target host. + * The {@link #createTargetAuthenticationStrategy()} must be implemented + * by concrete super classes to instantiate this object. + *
  • {@link AuthenticationStrategy}
  • object used to authenticate + * against the proxy host. + * The {@link #createProxyAuthenticationStrategy()} must be implemented + * by concrete super classes to instantiate this object. + *
  • {@link HttpRoutePlanner}
  • object used to calculate a route + * for establishing a connection to the target host. The route + * may involve multiple intermediate hops. + * The {@link #createHttpRoutePlanner()} must be implemented + * by concrete super classes to instantiate this object. + *
  • {@link RedirectStrategy}
  • object used to determine if an HTTP + * request should be redirected to a new location in response to an HTTP + * response received from the target server. + *
  • {@link UserTokenHandler}
  • object used to determine if the + * execution context is user identity specific. + * The {@link #createUserTokenHandler()} must be implemented by + * concrete super classes to instantiate this object. + *
+ *

+ * This class also maintains a list of protocol interceptors intended + * for processing outgoing requests and incoming responses and provides + * methods for managing those interceptors. New protocol interceptors can be + * introduced to the protocol processor chain or removed from it if needed. + * Internally protocol interceptors are stored in a simple + * {@link java.util.ArrayList}. They are executed in the same natural order + * as they are added to the list. + *

+ * AbstractHttpClient is thread safe. It is recommended that the same + * instance of this class is reused for multiple request executions. + * When an instance of DefaultHttpClient is no longer needed and is about + * to go out of scope the connection manager associated with it must be + * shut down by calling {@link ClientConnectionManager#shutdown()}! + * + * @since 4.0 + */ +@SuppressWarnings("deprecation") +@ThreadSafe +public abstract class AbstractHttpClient implements HttpClient { + + private final Log log = LogFactory.getLog(getClass()); + + /** The parameters. */ + @GuardedBy("this") + private HttpParams defaultParams; + + /** The request executor. */ + @GuardedBy("this") + private HttpRequestExecutor requestExec; + + /** The connection manager. */ + @GuardedBy("this") + private ClientConnectionManager connManager; + + /** The connection re-use strategy. */ + @GuardedBy("this") + private ConnectionReuseStrategy reuseStrategy; + + /** The connection keep-alive strategy. */ + @GuardedBy("this") + private ConnectionKeepAliveStrategy keepAliveStrategy; + + /** The cookie spec registry. */ + @GuardedBy("this") + private CookieSpecRegistry supportedCookieSpecs; + + /** The authentication scheme registry. */ + @GuardedBy("this") + private AuthSchemeRegistry supportedAuthSchemes; + + /** The HTTP protocol processor and its immutable copy. */ + @GuardedBy("this") + private BasicHttpProcessor mutableProcessor; + + @GuardedBy("this") + private ImmutableHttpProcessor protocolProcessor; + + /** The request retry handler. */ + @GuardedBy("this") + private HttpRequestRetryHandler retryHandler; + + /** The redirect handler. */ + @GuardedBy("this") + private RedirectStrategy redirectStrategy; + + /** The target authentication handler. */ + @GuardedBy("this") + private AuthenticationStrategy targetAuthStrategy; + + /** The proxy authentication handler. */ + @GuardedBy("this") + private AuthenticationStrategy proxyAuthStrategy; + + /** The cookie store. */ + @GuardedBy("this") + private CookieStore cookieStore; + + /** The credentials provider. */ + @GuardedBy("this") + private CredentialsProvider credsProvider; + + /** The route planner. */ + @GuardedBy("this") + private HttpRoutePlanner routePlanner; + + /** The user token handler. */ + @GuardedBy("this") + private UserTokenHandler userTokenHandler; + + /** The connection backoff strategy. */ + @GuardedBy("this") + private ConnectionBackoffStrategy connectionBackoffStrategy; + + /** The backoff manager. */ + @GuardedBy("this") + private BackoffManager backoffManager; + + /** + * Creates a new HTTP client. + * + * @param conman the connection manager + * @param params the parameters + */ + protected AbstractHttpClient( + final ClientConnectionManager conman, + final HttpParams params) { + defaultParams = params; + connManager = conman; + } // constructor + + + protected abstract HttpParams createHttpParams(); + + + protected abstract BasicHttpProcessor createHttpProcessor(); + + + protected HttpContext createHttpContext() { + HttpContext context = new BasicHttpContext(); + context.setAttribute( + ClientContext.SCHEME_REGISTRY, + getConnectionManager().getSchemeRegistry()); + context.setAttribute( + ClientContext.AUTHSCHEME_REGISTRY, + getAuthSchemes()); + context.setAttribute( + ClientContext.COOKIESPEC_REGISTRY, + getCookieSpecs()); + context.setAttribute( + ClientContext.COOKIE_STORE, + getCookieStore()); + context.setAttribute( + ClientContext.CREDS_PROVIDER, + getCredentialsProvider()); + return context; + } + + + protected ClientConnectionManager createClientConnectionManager() { + SchemeRegistry registry = SchemeRegistryFactory.createDefault(); + + ClientConnectionManager connManager = null; + HttpParams params = getParams(); + + ClientConnectionManagerFactory factory = null; + + String className = (String) params.getParameter( + ClientPNames.CONNECTION_MANAGER_FACTORY_CLASS_NAME); + if (className != null) { + try { + Class clazz = Class.forName(className); + factory = (ClientConnectionManagerFactory) clazz.newInstance(); + } catch (ClassNotFoundException ex) { + throw new IllegalStateException("Invalid class name: " + className); + } catch (IllegalAccessException ex) { + throw new IllegalAccessError(ex.getMessage()); + } catch (InstantiationException ex) { + throw new InstantiationError(ex.getMessage()); + } + } + if (factory != null) { + connManager = factory.newInstance(params, registry); + } else { + connManager = new BasicClientConnectionManager(registry); + } + + return connManager; + } + + + protected AuthSchemeRegistry createAuthSchemeRegistry() { + AuthSchemeRegistry registry = new AuthSchemeRegistry(); + registry.register( + AuthPolicy.BASIC, + new BasicSchemeFactory()); + registry.register( + AuthPolicy.DIGEST, + new DigestSchemeFactory()); + registry.register( + AuthPolicy.NTLM, + new NTLMSchemeFactory()); + registry.register( + AuthPolicy.SPNEGO, + new SPNegoSchemeFactory()); + registry.register( + AuthPolicy.KERBEROS, + new KerberosSchemeFactory()); + return registry; + } + + + protected CookieSpecRegistry createCookieSpecRegistry() { + CookieSpecRegistry registry = new CookieSpecRegistry(); + registry.register( + CookiePolicy.BEST_MATCH, + new BestMatchSpecFactory()); + registry.register( + CookiePolicy.BROWSER_COMPATIBILITY, + new BrowserCompatSpecFactory()); + registry.register( + CookiePolicy.NETSCAPE, + new NetscapeDraftSpecFactory()); + registry.register( + CookiePolicy.RFC_2109, + new RFC2109SpecFactory()); + registry.register( + CookiePolicy.RFC_2965, + new RFC2965SpecFactory()); + registry.register( + CookiePolicy.IGNORE_COOKIES, + new IgnoreSpecFactory()); + return registry; + } + + protected HttpRequestExecutor createRequestExecutor() { + return new HttpRequestExecutor(); + } + + protected ConnectionReuseStrategy createConnectionReuseStrategy() { + return new DefaultConnectionReuseStrategy(); + } + + protected ConnectionKeepAliveStrategy createConnectionKeepAliveStrategy() { + return new DefaultConnectionKeepAliveStrategy(); + } + + protected HttpRequestRetryHandler createHttpRequestRetryHandler() { + return new DefaultHttpRequestRetryHandler(); + } + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + protected RedirectHandler createRedirectHandler() { + return new DefaultRedirectHandler(); + } + + protected AuthenticationStrategy createTargetAuthenticationStrategy() { + return new TargetAuthenticationStrategy(); + } + + /** + * @deprecated (4.2) do not use + */ + @Deprecated + protected AuthenticationHandler createTargetAuthenticationHandler() { + return new DefaultTargetAuthenticationHandler(); + } + + protected AuthenticationStrategy createProxyAuthenticationStrategy() { + return new ProxyAuthenticationStrategy(); + } + + /** + * @deprecated (4.2) do not use + */ + @Deprecated + protected AuthenticationHandler createProxyAuthenticationHandler() { + return new DefaultProxyAuthenticationHandler(); + } + + protected CookieStore createCookieStore() { + return new BasicCookieStore(); + } + + protected CredentialsProvider createCredentialsProvider() { + return new BasicCredentialsProvider(); + } + + protected HttpRoutePlanner createHttpRoutePlanner() { + return new DefaultHttpRoutePlanner(getConnectionManager().getSchemeRegistry()); + } + + protected UserTokenHandler createUserTokenHandler() { + return new DefaultUserTokenHandler(); + } + + // non-javadoc, see interface HttpClient + public synchronized final HttpParams getParams() { + if (defaultParams == null) { + defaultParams = createHttpParams(); + } + return defaultParams; + } + + /** + * Replaces the parameters. + * The implementation here does not update parameters of dependent objects. + * + * @param params the new default parameters + */ + public synchronized void setParams(HttpParams params) { + defaultParams = params; + } + + + public synchronized final ClientConnectionManager getConnectionManager() { + if (connManager == null) { + connManager = createClientConnectionManager(); + } + return connManager; + } + + + public synchronized final HttpRequestExecutor getRequestExecutor() { + if (requestExec == null) { + requestExec = createRequestExecutor(); + } + return requestExec; + } + + + public synchronized final AuthSchemeRegistry getAuthSchemes() { + if (supportedAuthSchemes == null) { + supportedAuthSchemes = createAuthSchemeRegistry(); + } + return supportedAuthSchemes; + } + + public synchronized void setAuthSchemes(final AuthSchemeRegistry registry) { + supportedAuthSchemes = registry; + } + + public synchronized final ConnectionBackoffStrategy getConnectionBackoffStrategy() { + return connectionBackoffStrategy; + } + + public synchronized void setConnectionBackoffStrategy(final ConnectionBackoffStrategy strategy) { + connectionBackoffStrategy = strategy; + } + + public synchronized final CookieSpecRegistry getCookieSpecs() { + if (supportedCookieSpecs == null) { + supportedCookieSpecs = createCookieSpecRegistry(); + } + return supportedCookieSpecs; + } + + public synchronized final BackoffManager getBackoffManager() { + return backoffManager; + } + + public synchronized void setBackoffManager(final BackoffManager manager) { + backoffManager = manager; + } + + public synchronized void setCookieSpecs(final CookieSpecRegistry registry) { + supportedCookieSpecs = registry; + } + + public synchronized final ConnectionReuseStrategy getConnectionReuseStrategy() { + if (reuseStrategy == null) { + reuseStrategy = createConnectionReuseStrategy(); + } + return reuseStrategy; + } + + + public synchronized void setReuseStrategy(final ConnectionReuseStrategy strategy) { + this.reuseStrategy = strategy; + } + + + public synchronized final ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy() { + if (keepAliveStrategy == null) { + keepAliveStrategy = createConnectionKeepAliveStrategy(); + } + return keepAliveStrategy; + } + + + public synchronized void setKeepAliveStrategy(final ConnectionKeepAliveStrategy strategy) { + this.keepAliveStrategy = strategy; + } + + + public synchronized final HttpRequestRetryHandler getHttpRequestRetryHandler() { + if (retryHandler == null) { + retryHandler = createHttpRequestRetryHandler(); + } + return retryHandler; + } + + public synchronized void setHttpRequestRetryHandler(final HttpRequestRetryHandler handler) { + this.retryHandler = handler; + } + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + public synchronized final RedirectHandler getRedirectHandler() { + return createRedirectHandler(); + } + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + public synchronized void setRedirectHandler(final RedirectHandler handler) { + this.redirectStrategy = new DefaultRedirectStrategyAdaptor(handler); + } + + /** + * @since 4.1 + */ + public synchronized final RedirectStrategy getRedirectStrategy() { + if (redirectStrategy == null) { + redirectStrategy = new DefaultRedirectStrategy(); + } + return redirectStrategy; + } + + /** + * @since 4.1 + */ + public synchronized void setRedirectStrategy(final RedirectStrategy strategy) { + this.redirectStrategy = strategy; + } + + /** + * @deprecated (4.2) do not use + */ + @Deprecated + public synchronized final AuthenticationHandler getTargetAuthenticationHandler() { + return createTargetAuthenticationHandler(); + } + + /** + * @deprecated (4.2) do not use + */ + @Deprecated + public synchronized void setTargetAuthenticationHandler(final AuthenticationHandler handler) { + this.targetAuthStrategy = new AuthenticationStrategyAdaptor(handler); + } + + /** + * @since 4.2 + */ + public synchronized final AuthenticationStrategy getTargetAuthenticationStrategy() { + if (targetAuthStrategy == null) { + targetAuthStrategy = createTargetAuthenticationStrategy(); + } + return targetAuthStrategy; + } + + /** + * @since 4.2 + */ + public synchronized void setTargetAuthenticationStrategy(final AuthenticationStrategy strategy) { + this.targetAuthStrategy = strategy; + } + + /** + * @deprecated (4.2) do not use + */ + @Deprecated + public synchronized final AuthenticationHandler getProxyAuthenticationHandler() { + return createProxyAuthenticationHandler(); + } + + /** + * @deprecated (4.2) do not use + */ + @Deprecated + public synchronized void setProxyAuthenticationHandler(final AuthenticationHandler handler) { + this.proxyAuthStrategy = new AuthenticationStrategyAdaptor(handler); + } + + /** + * @since 4.2 + */ + public synchronized final AuthenticationStrategy getProxyAuthenticationStrategy() { + if (proxyAuthStrategy == null) { + proxyAuthStrategy = createProxyAuthenticationStrategy(); + } + return proxyAuthStrategy; + } + + /** + * @since 4.2 + */ + public synchronized void setProxyAuthenticationStrategy(final AuthenticationStrategy strategy) { + this.proxyAuthStrategy = strategy; + } + + public synchronized final CookieStore getCookieStore() { + if (cookieStore == null) { + cookieStore = createCookieStore(); + } + return cookieStore; + } + + public synchronized void setCookieStore(final CookieStore cookieStore) { + this.cookieStore = cookieStore; + } + + public synchronized final CredentialsProvider getCredentialsProvider() { + if (credsProvider == null) { + credsProvider = createCredentialsProvider(); + } + return credsProvider; + } + + public synchronized void setCredentialsProvider(final CredentialsProvider credsProvider) { + this.credsProvider = credsProvider; + } + + public synchronized final HttpRoutePlanner getRoutePlanner() { + if (this.routePlanner == null) { + this.routePlanner = createHttpRoutePlanner(); + } + return this.routePlanner; + } + + public synchronized void setRoutePlanner(final HttpRoutePlanner routePlanner) { + this.routePlanner = routePlanner; + } + + public synchronized final UserTokenHandler getUserTokenHandler() { + if (this.userTokenHandler == null) { + this.userTokenHandler = createUserTokenHandler(); + } + return this.userTokenHandler; + } + + public synchronized void setUserTokenHandler(final UserTokenHandler handler) { + this.userTokenHandler = handler; + } + + protected synchronized final BasicHttpProcessor getHttpProcessor() { + if (mutableProcessor == null) { + mutableProcessor = createHttpProcessor(); + } + return mutableProcessor; + } + + private synchronized final HttpProcessor getProtocolProcessor() { + if (protocolProcessor == null) { + // Get mutable HTTP processor + BasicHttpProcessor proc = getHttpProcessor(); + // and create an immutable copy of it + int reqc = proc.getRequestInterceptorCount(); + HttpRequestInterceptor[] reqinterceptors = new HttpRequestInterceptor[reqc]; + for (int i = 0; i < reqc; i++) { + reqinterceptors[i] = proc.getRequestInterceptor(i); + } + int resc = proc.getResponseInterceptorCount(); + HttpResponseInterceptor[] resinterceptors = new HttpResponseInterceptor[resc]; + for (int i = 0; i < resc; i++) { + resinterceptors[i] = proc.getResponseInterceptor(i); + } + protocolProcessor = new ImmutableHttpProcessor(reqinterceptors, resinterceptors); + } + return protocolProcessor; + } + + public synchronized int getResponseInterceptorCount() { + return getHttpProcessor().getResponseInterceptorCount(); + } + + public synchronized HttpResponseInterceptor getResponseInterceptor(int index) { + return getHttpProcessor().getResponseInterceptor(index); + } + + public synchronized HttpRequestInterceptor getRequestInterceptor(int index) { + return getHttpProcessor().getRequestInterceptor(index); + } + + public synchronized int getRequestInterceptorCount() { + return getHttpProcessor().getRequestInterceptorCount(); + } + + public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp) { + getHttpProcessor().addInterceptor(itcp); + protocolProcessor = null; + } + + public synchronized void addResponseInterceptor(final HttpResponseInterceptor itcp, int index) { + getHttpProcessor().addInterceptor(itcp, index); + protocolProcessor = null; + } + + public synchronized void clearResponseInterceptors() { + getHttpProcessor().clearResponseInterceptors(); + protocolProcessor = null; + } + + public synchronized void removeResponseInterceptorByClass(Class clazz) { + getHttpProcessor().removeResponseInterceptorByClass(clazz); + protocolProcessor = null; + } + + public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp) { + getHttpProcessor().addInterceptor(itcp); + protocolProcessor = null; + } + + public synchronized void addRequestInterceptor(final HttpRequestInterceptor itcp, int index) { + getHttpProcessor().addInterceptor(itcp, index); + protocolProcessor = null; + } + + public synchronized void clearRequestInterceptors() { + getHttpProcessor().clearRequestInterceptors(); + protocolProcessor = null; + } + + public synchronized void removeRequestInterceptorByClass(Class clazz) { + getHttpProcessor().removeRequestInterceptorByClass(clazz); + protocolProcessor = null; + } + + public final HttpResponse execute(HttpUriRequest request) + throws IOException, ClientProtocolException { + + return execute(request, (HttpContext) null); + } + + /** + * Maps to {@link HttpClient#execute(HttpHost,HttpRequest,HttpContext) + * execute(target, request, context)}. + * The target is determined from the URI of the request. + * + * @param request the request to execute + * @param context the request-specific execution context, + * or null to use a default context + */ + public final HttpResponse execute(HttpUriRequest request, + HttpContext context) + throws IOException, ClientProtocolException { + + if (request == null) { + throw new IllegalArgumentException + ("Request must not be null."); + } + + return execute(determineTarget(request), request, context); + } + + private static HttpHost determineTarget(HttpUriRequest request) throws ClientProtocolException { + // A null target may be acceptable if there is a default target. + // Otherwise, the null target is detected in the director. + HttpHost target = null; + + URI requestURI = request.getURI(); + if (requestURI.isAbsolute()) { + target = URIUtils.extractHost(requestURI); + if (target == null) { + throw new ClientProtocolException( + "URI does not specify a valid host name: " + requestURI); + } + } + return target; + } + + public final HttpResponse execute(HttpHost target, HttpRequest request) + throws IOException, ClientProtocolException { + + return execute(target, request, (HttpContext) null); + } + + public final HttpResponse execute(HttpHost target, HttpRequest request, + HttpContext context) + throws IOException, ClientProtocolException { + + if (request == null) { + throw new IllegalArgumentException + ("Request must not be null."); + } + // a null target may be acceptable, this depends on the route planner + // a null context is acceptable, default context created below + + HttpContext execContext = null; + RequestDirector director = null; + HttpRoutePlanner routePlanner = null; + ConnectionBackoffStrategy connectionBackoffStrategy = null; + BackoffManager backoffManager = null; + + // Initialize the request execution context making copies of + // all shared objects that are potentially threading unsafe. + synchronized (this) { + + HttpContext defaultContext = createHttpContext(); + if (context == null) { + execContext = defaultContext; + } else { + execContext = new DefaultedHttpContext(context, defaultContext); + } + // Create a director for this request + director = createClientRequestDirector( + getRequestExecutor(), + getConnectionManager(), + getConnectionReuseStrategy(), + getConnectionKeepAliveStrategy(), + getRoutePlanner(), + getProtocolProcessor(), + getHttpRequestRetryHandler(), + getRedirectStrategy(), + getTargetAuthenticationStrategy(), + getProxyAuthenticationStrategy(), + getUserTokenHandler(), + determineParams(request)); + routePlanner = getRoutePlanner(); + connectionBackoffStrategy = getConnectionBackoffStrategy(); + backoffManager = getBackoffManager(); + } + + try { + if (connectionBackoffStrategy != null && backoffManager != null) { + HttpHost targetForRoute = (target != null) ? target + : (HttpHost) determineParams(request).getParameter( + ClientPNames.DEFAULT_HOST); + HttpRoute route = routePlanner.determineRoute(targetForRoute, request, execContext); + + HttpResponse out; + try { + out = director.execute(target, request, execContext); + } catch (RuntimeException re) { + if (connectionBackoffStrategy.shouldBackoff(re)) { + backoffManager.backOff(route); + } + throw re; + } catch (Exception e) { + if (connectionBackoffStrategy.shouldBackoff(e)) { + backoffManager.backOff(route); + } + if (e instanceof HttpException) throw (HttpException)e; + if (e instanceof IOException) throw (IOException)e; + throw new UndeclaredThrowableException(e); + } + if (connectionBackoffStrategy.shouldBackoff(out)) { + backoffManager.backOff(route); + } else { + backoffManager.probe(route); + } + return out; + } else { + return director.execute(target, request, execContext); + } + } catch(HttpException httpException) { + throw new ClientProtocolException(httpException); + } + } + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + protected RequestDirector createClientRequestDirector( + final HttpRequestExecutor requestExec, + final ClientConnectionManager conman, + final ConnectionReuseStrategy reustrat, + final ConnectionKeepAliveStrategy kastrat, + final HttpRoutePlanner rouplan, + final HttpProcessor httpProcessor, + final HttpRequestRetryHandler retryHandler, + final RedirectHandler redirectHandler, + final AuthenticationHandler targetAuthHandler, + final AuthenticationHandler proxyAuthHandler, + final UserTokenHandler userTokenHandler, + final HttpParams params) { + return new DefaultRequestDirector( + requestExec, + conman, + reustrat, + kastrat, + rouplan, + httpProcessor, + retryHandler, + redirectHandler, + targetAuthHandler, + proxyAuthHandler, + userTokenHandler, + params); + } + + /** + * @deprecated (4.2) do not use + */ + @Deprecated + protected RequestDirector createClientRequestDirector( + final HttpRequestExecutor requestExec, + final ClientConnectionManager conman, + final ConnectionReuseStrategy reustrat, + final ConnectionKeepAliveStrategy kastrat, + final HttpRoutePlanner rouplan, + final HttpProcessor httpProcessor, + final HttpRequestRetryHandler retryHandler, + final RedirectStrategy redirectStrategy, + final AuthenticationHandler targetAuthHandler, + final AuthenticationHandler proxyAuthHandler, + final UserTokenHandler userTokenHandler, + final HttpParams params) { + return new DefaultRequestDirector( + log, + requestExec, + conman, + reustrat, + kastrat, + rouplan, + httpProcessor, + retryHandler, + redirectStrategy, + targetAuthHandler, + proxyAuthHandler, + userTokenHandler, + params); + } + + + /** + * @since 4.2 + */ + protected RequestDirector createClientRequestDirector( + final HttpRequestExecutor requestExec, + final ClientConnectionManager conman, + final ConnectionReuseStrategy reustrat, + final ConnectionKeepAliveStrategy kastrat, + final HttpRoutePlanner rouplan, + final HttpProcessor httpProcessor, + final HttpRequestRetryHandler retryHandler, + final RedirectStrategy redirectStrategy, + final AuthenticationStrategy targetAuthStrategy, + final AuthenticationStrategy proxyAuthStrategy, + final UserTokenHandler userTokenHandler, + final HttpParams params) { + return new DefaultRequestDirector( + log, + requestExec, + conman, + reustrat, + kastrat, + rouplan, + httpProcessor, + retryHandler, + redirectStrategy, + targetAuthStrategy, + proxyAuthStrategy, + userTokenHandler, + params); + } + + /** + * Obtains parameters for executing a request. + * The default implementation in this class creates a new + * {@link ClientParamsStack} from the request parameters + * and the client parameters. + *
+ * This method is called by the default implementation of + * {@link #execute(HttpHost,HttpRequest,HttpContext)} + * to obtain the parameters for the + * {@link DefaultRequestDirector}. + * + * @param req the request that will be executed + * + * @return the parameters to use + */ + protected HttpParams determineParams(HttpRequest req) { + return new ClientParamsStack + (null, getParams(), req.getParams(), null); + } + + public T execute( + final HttpUriRequest request, + final ResponseHandler responseHandler) + throws IOException, ClientProtocolException { + return execute(request, responseHandler, null); + } + + public T execute( + final HttpUriRequest request, + final ResponseHandler responseHandler, + final HttpContext context) + throws IOException, ClientProtocolException { + HttpHost target = determineTarget(request); + return execute(target, request, responseHandler, context); + } + + public T execute( + final HttpHost target, + final HttpRequest request, + final ResponseHandler responseHandler) + throws IOException, ClientProtocolException { + return execute(target, request, responseHandler, null); + } + + public T execute( + final HttpHost target, + final HttpRequest request, + final ResponseHandler responseHandler, + final HttpContext context) + throws IOException, ClientProtocolException { + if (responseHandler == null) { + throw new IllegalArgumentException + ("Response handler must not be null."); + } + + HttpResponse response = execute(target, request, context); + + T result; + try { + result = responseHandler.handleResponse(response); + } catch (Exception t) { + HttpEntity entity = response.getEntity(); + try { + EntityUtils.consume(entity); + } catch (Exception t2) { + // Log this exception. The original exception is more + // important and will be thrown to the caller. + this.log.warn("Error consuming content after an exception.", t2); + } + if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } + if (t instanceof IOException) { + throw (IOException) t; + } + throw new UndeclaredThrowableException(t); + } + + // Handling the response was successful. Ensure that the content has + // been fully consumed. + HttpEntity entity = response.getEntity(); + EntityUtils.consume(entity); + return result; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/AuthenticationStrategyAdaptor.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/AuthenticationStrategyAdaptor.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/AuthenticationStrategyAdaptor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,179 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.LinkedList; +import java.util.Locale; +import java.util.Map; +import java.util.Queue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AuthOption; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.Credentials; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.client.AuthCache; +import org.apache.http.client.AuthenticationHandler; +import org.apache.http.client.AuthenticationStrategy; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.params.AuthPolicy; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.protocol.HttpContext; + +/** + * @deprecated (4.2) do not use + */ +@Immutable +@Deprecated +class AuthenticationStrategyAdaptor implements AuthenticationStrategy { + + private final Log log = LogFactory.getLog(getClass()); + + private final AuthenticationHandler handler; + + public AuthenticationStrategyAdaptor(final AuthenticationHandler handler) { + super(); + this.handler = handler; + } + + public boolean isAuthenticationRequested( + final HttpHost authhost, + final HttpResponse response, + final HttpContext context) { + return this.handler.isAuthenticationRequested(response, context); + } + + public Map getChallenges( + final HttpHost authhost, + final HttpResponse response, + final HttpContext context) throws MalformedChallengeException { + return this.handler.getChallenges(response, context); + } + + public Queue select( + final Map challenges, + final HttpHost authhost, + final HttpResponse response, + final HttpContext context) throws MalformedChallengeException { + if (challenges == null) { + throw new IllegalArgumentException("Map of auth challenges may not be null"); + } + if (authhost == null) { + throw new IllegalArgumentException("Host may not be null"); + } + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + Queue options = new LinkedList(); + CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute( + ClientContext.CREDS_PROVIDER); + if (credsProvider == null) { + this.log.debug("Credentials provider not set in the context"); + return options; + } + + AuthScheme authScheme; + try { + authScheme = this.handler.selectScheme(challenges, response, context); + } catch (AuthenticationException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn(ex.getMessage(), ex); + } + return options; + } + String id = authScheme.getSchemeName(); + Header challenge = challenges.get(id.toLowerCase(Locale.US)); + authScheme.processChallenge(challenge); + + AuthScope authScope = new AuthScope( + authhost.getHostName(), + authhost.getPort(), + authScheme.getRealm(), + authScheme.getSchemeName()); + + Credentials credentials = credsProvider.getCredentials(authScope); + if (credentials != null) { + options.add(new AuthOption(authScheme, credentials)); + } + return options; + } + + public void authSucceeded( + final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) { + AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE); + if (isCachable(authScheme)) { + if (authCache == null) { + authCache = new BasicAuthCache(); + context.setAttribute(ClientContext.AUTH_CACHE, authCache); + } + if (this.log.isDebugEnabled()) { + this.log.debug("Caching '" + authScheme.getSchemeName() + + "' auth scheme for " + authhost); + } + authCache.put(authhost, authScheme); + } + } + + public void authFailed( + final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) { + AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE); + if (authCache == null) { + return; + } + if (this.log.isDebugEnabled()) { + this.log.debug("Removing from cache '" + authScheme.getSchemeName() + + "' auth scheme for " + authhost); + } + authCache.remove(authhost); + } + + private boolean isCachable(final AuthScheme authScheme) { + if (authScheme == null || !authScheme.isComplete()) { + return false; + } + String schemeName = authScheme.getSchemeName(); + return schemeName.equalsIgnoreCase(AuthPolicy.BASIC) || + schemeName.equalsIgnoreCase(AuthPolicy.DIGEST); + } + + public AuthenticationHandler getHandler() { + return this.handler; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/AuthenticationStrategyImpl.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/AuthenticationStrategyImpl.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/AuthenticationStrategyImpl.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,260 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Queue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.FormattedHeader; +import org.apache.http.Header; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AuthOption; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthSchemeRegistry; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.client.AuthCache; +import org.apache.http.client.AuthenticationStrategy; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.params.AuthPolicy; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.protocol.HTTP; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.CharArrayBuffer; + +@Immutable +class AuthenticationStrategyImpl implements AuthenticationStrategy { + + private final Log log = LogFactory.getLog(getClass()); + + private static final List DEFAULT_SCHEME_PRIORITY = + Collections.unmodifiableList(Arrays.asList(new String[] { + AuthPolicy.SPNEGO, + AuthPolicy.KERBEROS, + AuthPolicy.NTLM, + AuthPolicy.DIGEST, + AuthPolicy.BASIC + })); + + private final int challengeCode; + private final String headerName; + private final String prefParamName; + + AuthenticationStrategyImpl(int challengeCode, final String headerName, final String prefParamName) { + super(); + this.challengeCode = challengeCode; + this.headerName = headerName; + this.prefParamName = prefParamName; + } + + public boolean isAuthenticationRequested( + final HttpHost authhost, + final HttpResponse response, + final HttpContext context) { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + int status = response.getStatusLine().getStatusCode(); + return status == this.challengeCode; + } + + public Map getChallenges( + final HttpHost authhost, + final HttpResponse response, + final HttpContext context) throws MalformedChallengeException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + Header[] headers = response.getHeaders(this.headerName); + Map map = new HashMap(headers.length); + for (Header header : headers) { + CharArrayBuffer buffer; + int pos; + if (header instanceof FormattedHeader) { + buffer = ((FormattedHeader) header).getBuffer(); + pos = ((FormattedHeader) header).getValuePos(); + } else { + String s = header.getValue(); + if (s == null) { + throw new MalformedChallengeException("Header value is null"); + } + buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + pos = 0; + } + while (pos < buffer.length() && HTTP.isWhitespace(buffer.charAt(pos))) { + pos++; + } + int beginIndex = pos; + while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) { + pos++; + } + int endIndex = pos; + String s = buffer.substring(beginIndex, endIndex); + map.put(s.toLowerCase(Locale.US), header); + } + return map; + } + + public Queue select( + final Map challenges, + final HttpHost authhost, + final HttpResponse response, + final HttpContext context) throws MalformedChallengeException { + if (challenges == null) { + throw new IllegalArgumentException("Map of auth challenges may not be null"); + } + if (authhost == null) { + throw new IllegalArgumentException("Host may not be null"); + } + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + Queue options = new LinkedList(); + AuthSchemeRegistry registry = (AuthSchemeRegistry) context.getAttribute( + ClientContext.AUTHSCHEME_REGISTRY); + if (registry == null) { + this.log.debug("Auth scheme registry not set in the context"); + return options; + } + CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute( + ClientContext.CREDS_PROVIDER); + if (credsProvider == null) { + this.log.debug("Credentials provider not set in the context"); + return options; + } + + @SuppressWarnings("unchecked") + List authPrefs = (List) response.getParams().getParameter(this.prefParamName); + if (authPrefs == null) { + authPrefs = DEFAULT_SCHEME_PRIORITY; + } + if (this.log.isDebugEnabled()) { + this.log.debug("Authentication schemes in the order of preference: " + authPrefs); + } + + for (String id: authPrefs) { + Header challenge = challenges.get(id.toLowerCase(Locale.US)); + if (challenge != null) { + try { + AuthScheme authScheme = registry.getAuthScheme(id, response.getParams()); + authScheme.processChallenge(challenge); + + AuthScope authScope = new AuthScope( + authhost.getHostName(), + authhost.getPort(), + authScheme.getRealm(), + authScheme.getSchemeName()); + + Credentials credentials = credsProvider.getCredentials(authScope); + if (credentials != null) { + options.add(new AuthOption(authScheme, credentials)); + } + } catch (IllegalStateException e) { + if (this.log.isWarnEnabled()) { + this.log.warn("Authentication scheme " + id + " not supported"); + // Try again + } + } + } else { + if (this.log.isDebugEnabled()) { + this.log.debug("Challenge for " + id + " authentication scheme not available"); + // Try again + } + } + } + return options; + } + + public void authSucceeded( + final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) { + if (authhost == null) { + throw new IllegalArgumentException("Host may not be null"); + } + if (authScheme == null) { + throw new IllegalArgumentException("Auth scheme may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + if (isCachable(authScheme)) { + AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE); + if (authCache == null) { + authCache = new BasicAuthCache(); + context.setAttribute(ClientContext.AUTH_CACHE, authCache); + } + if (this.log.isDebugEnabled()) { + this.log.debug("Caching '" + authScheme.getSchemeName() + + "' auth scheme for " + authhost); + } + authCache.put(authhost, authScheme); + } + } + + protected boolean isCachable(final AuthScheme authScheme) { + if (authScheme == null || !authScheme.isComplete()) { + return false; + } + String schemeName = authScheme.getSchemeName(); + return schemeName.equalsIgnoreCase(AuthPolicy.BASIC) || + schemeName.equalsIgnoreCase(AuthPolicy.DIGEST); + } + + public void authFailed( + final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) { + if (authhost == null) { + throw new IllegalArgumentException("Host may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE); + if (authCache != null) { + if (this.log.isDebugEnabled()) { + this.log.debug("Clearing cached auth scheme for " + authhost); + } + authCache.remove(authhost); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/AutoRetryHttpClient.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/AutoRetryHttpClient.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/AutoRetryHttpClient.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,179 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.URI; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.client.HttpClient; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.ServiceUnavailableRetryStrategy; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; + +/** + * {@link HttpClient} implementation that can automatically retry the request in case of + * a non-2xx response using the {@link ServiceUnavailableRetryStrategy} interface. + * + * @since 4.2 + */ +@ThreadSafe +public class AutoRetryHttpClient implements HttpClient { + + private final HttpClient backend; + + private final ServiceUnavailableRetryStrategy retryStrategy; + + private final Log log = LogFactory.getLog(getClass()); + + public AutoRetryHttpClient( + final HttpClient client, final ServiceUnavailableRetryStrategy retryStrategy) { + super(); + if (client == null) { + throw new IllegalArgumentException("HttpClient may not be null"); + } + if (retryStrategy == null) { + throw new IllegalArgumentException( + "ServiceUnavailableRetryStrategy may not be null"); + } + this.backend = client; + this.retryStrategy = retryStrategy; + } + + /** + * Constructs a {@code AutoRetryHttpClient} with default caching settings that + * stores cache entries in memory and uses a vanilla + * {@link DefaultHttpClient} for backend requests. + */ + public AutoRetryHttpClient() { + this(new DefaultHttpClient(), new DefaultServiceUnavailableRetryStrategy()); + } + + /** + * Constructs a {@code AutoRetryHttpClient} with the given caching options that + * stores cache entries in memory and uses a vanilla + * {@link DefaultHttpClient} for backend requests. + * + * @param config + * retry configuration module options + */ + public AutoRetryHttpClient(ServiceUnavailableRetryStrategy config) { + this(new DefaultHttpClient(), config); + } + + /** + * Constructs a {@code AutoRetryHttpClient} with default caching settings that + * stores cache entries in memory and uses the given {@link HttpClient} for + * backend requests. + * + * @param client + * used to make origin requests + */ + public AutoRetryHttpClient(HttpClient client) { + this(client, new DefaultServiceUnavailableRetryStrategy()); + } + + public HttpResponse execute(HttpHost target, HttpRequest request) + throws IOException { + HttpContext defaultContext = null; + return execute(target, request, defaultContext); + } + + public T execute(HttpHost target, HttpRequest request, + ResponseHandler responseHandler) throws IOException { + return execute(target, request, responseHandler, null); + } + + public T execute(HttpHost target, HttpRequest request, + ResponseHandler responseHandler, HttpContext context) + throws IOException { + HttpResponse resp = execute(target, request, context); + return responseHandler.handleResponse(resp); + } + + public HttpResponse execute(HttpUriRequest request) throws IOException { + HttpContext context = null; + return execute(request, context); + } + + public HttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException { + URI uri = request.getURI(); + HttpHost httpHost = new HttpHost(uri.getHost(), uri.getPort(), + uri.getScheme()); + return execute(httpHost, request, context); + } + + public T execute(HttpUriRequest request, + ResponseHandler responseHandler) throws IOException { + return execute(request, responseHandler, null); + } + + public T execute(HttpUriRequest request, + ResponseHandler responseHandler, HttpContext context) + throws IOException { + HttpResponse resp = execute(request, context); + return responseHandler.handleResponse(resp); + } + + public HttpResponse execute(HttpHost target, HttpRequest request, + HttpContext context) throws IOException { + for (int c = 1;; c++) { + HttpResponse response = backend.execute(target, request, context); + if (retryStrategy.retryRequest(response, c, context)) { + long nextInterval = retryStrategy.getRetryInterval(); + try { + log.trace("Wait for " + nextInterval); + Thread.sleep(nextInterval); + } catch (InterruptedException e) { + throw new InterruptedIOException(e.getMessage()); + } + } else { + return response; + } + } + } + + public ClientConnectionManager getConnectionManager() { + return backend.getConnectionManager(); + } + + public HttpParams getParams() { + return backend.getParams(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicAuthCache.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicAuthCache.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicAuthCache.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,84 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.HashMap; + +import org.apache.http.HttpHost; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.auth.AuthScheme; +import org.apache.http.client.AuthCache; + +/** + * Default implementation of {@link AuthCache}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicAuthCache implements AuthCache { + + private final HashMap map; + + /** + * Default constructor. + */ + public BasicAuthCache() { + super(); + this.map = new HashMap(); + } + + public void put(final HttpHost host, final AuthScheme authScheme) { + if (host == null) { + throw new IllegalArgumentException("HTTP host may not be null"); + } + this.map.put(host, authScheme); + } + + public AuthScheme get(final HttpHost host) { + if (host == null) { + throw new IllegalArgumentException("HTTP host may not be null"); + } + return this.map.get(host); + } + + public void remove(final HttpHost host) { + if (host == null) { + throw new IllegalArgumentException("HTTP host may not be null"); + } + this.map.remove(host); + } + + public void clear() { + this.map.clear(); + } + + @Override + public String toString() { + return this.map.toString(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicCookieStore.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicCookieStore.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicCookieStore.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,145 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.TreeSet; + +import org.apache.http.annotation.GuardedBy; +import org.apache.http.annotation.ThreadSafe; + +import org.apache.http.client.CookieStore; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieIdentityComparator; + +/** + * Default implementation of {@link CookieStore} + * + * + * @since 4.0 + */ +@ThreadSafe +public class BasicCookieStore implements CookieStore, Serializable { + + private static final long serialVersionUID = -7581093305228232025L; + + @GuardedBy("this") + private final TreeSet cookies; + + public BasicCookieStore() { + super(); + this.cookies = new TreeSet(new CookieIdentityComparator()); + } + + /** + * Adds an {@link Cookie HTTP cookie}, replacing any existing equivalent cookies. + * If the given cookie has already expired it will not be added, but existing + * values will still be removed. + * + * @param cookie the {@link Cookie cookie} to be added + * + * @see #addCookies(Cookie[]) + * + */ + public synchronized void addCookie(Cookie cookie) { + if (cookie != null) { + // first remove any old cookie that is equivalent + cookies.remove(cookie); + if (!cookie.isExpired(new Date())) { + cookies.add(cookie); + } + } + } + + /** + * Adds an array of {@link Cookie HTTP cookies}. Cookies are added individually and + * in the given array order. If any of the given cookies has already expired it will + * not be added, but existing values will still be removed. + * + * @param cookies the {@link Cookie cookies} to be added + * + * @see #addCookie(Cookie) + * + */ + public synchronized void addCookies(Cookie[] cookies) { + if (cookies != null) { + for (Cookie cooky : cookies) { + this.addCookie(cooky); + } + } + } + + /** + * Returns an immutable array of {@link Cookie cookies} that this HTTP + * state currently contains. + * + * @return an array of {@link Cookie cookies}. + */ + public synchronized List getCookies() { + //create defensive copy so it won't be concurrently modified + return new ArrayList(cookies); + } + + /** + * Removes all of {@link Cookie cookies} in this HTTP state + * that have expired by the specified {@link java.util.Date date}. + * + * @return true if any cookies were purged. + * + * @see Cookie#isExpired(Date) + */ + public synchronized boolean clearExpired(final Date date) { + if (date == null) { + return false; + } + boolean removed = false; + for (Iterator it = cookies.iterator(); it.hasNext();) { + if (it.next().isExpired(date)) { + it.remove(); + removed = true; + } + } + return removed; + } + + /** + * Clears all cookies. + */ + public synchronized void clear() { + cookies.clear(); + } + + @Override + public synchronized String toString() { + return cookies.toString(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicCredentialsProvider.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicCredentialsProvider.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicCredentialsProvider.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,113 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.http.annotation.ThreadSafe; + +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.Credentials; +import org.apache.http.client.CredentialsProvider; + +/** + * Default implementation of {@link CredentialsProvider}. + * + * @since 4.0 + */ +@ThreadSafe +public class BasicCredentialsProvider implements CredentialsProvider { + + private final ConcurrentHashMap credMap; + + /** + * Default constructor. + */ + public BasicCredentialsProvider() { + super(); + this.credMap = new ConcurrentHashMap(); + } + + public void setCredentials( + final AuthScope authscope, + final Credentials credentials) { + if (authscope == null) { + throw new IllegalArgumentException("Authentication scope may not be null"); + } + credMap.put(authscope, credentials); + } + + /** + * Find matching {@link Credentials credentials} for the given authentication scope. + * + * @param map the credentials hash map + * @param authscope the {@link AuthScope authentication scope} + * @return the credentials + * + */ + private static Credentials matchCredentials( + final Map map, + final AuthScope authscope) { + // see if we get a direct hit + Credentials creds = map.get(authscope); + if (creds == null) { + // Nope. + // Do a full scan + int bestMatchFactor = -1; + AuthScope bestMatch = null; + for (AuthScope current: map.keySet()) { + int factor = authscope.match(current); + if (factor > bestMatchFactor) { + bestMatchFactor = factor; + bestMatch = current; + } + } + if (bestMatch != null) { + creds = map.get(bestMatch); + } + } + return creds; + } + + public Credentials getCredentials(final AuthScope authscope) { + if (authscope == null) { + throw new IllegalArgumentException("Authentication scope may not be null"); + } + return matchCredentials(this.credMap, authscope); + } + + public void clear() { + this.credMap.clear(); + } + + @Override + public String toString() { + return credMap.toString(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicResponseHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicResponseHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/BasicResponseHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.io.IOException; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.HttpResponseException; +import org.apache.http.util.EntityUtils; + +/** + * A {@link ResponseHandler} that returns the response body as a String + * for successful (2xx) responses. If the response code was >= 300, the response + * body is consumed and an {@link HttpResponseException} is thrown. + *

+ * If this is used with + * {@link org.apache.http.client.HttpClient#execute( + * org.apache.http.client.methods.HttpUriRequest, ResponseHandler)}, + * HttpClient may handle redirects (3xx responses) internally. + * + * @since 4.0 + */ +@Immutable +public class BasicResponseHandler implements ResponseHandler { + + /** + * Returns the response body as a String if the response was successful (a + * 2xx status code). If no response body exists, this returns null. If the + * response was unsuccessful (>= 300 status code), throws an + * {@link HttpResponseException}. + */ + public String handleResponse(final HttpResponse response) + throws HttpResponseException, IOException { + StatusLine statusLine = response.getStatusLine(); + HttpEntity entity = response.getEntity(); + if (statusLine.getStatusCode() >= 300) { + EntityUtils.consume(entity); + throw new HttpResponseException(statusLine.getStatusCode(), + statusLine.getReasonPhrase()); + } + return entity == null ? null : EntityUtils.toString(entity); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/ClientParamsStack.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/ClientParamsStack.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/ClientParamsStack.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,270 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.params.HttpParams; +import org.apache.http.params.AbstractHttpParams; + +/** + * Represents a stack of parameter collections. + * When retrieving a parameter, the stack is searched in a fixed order + * and the first match returned. Setting parameters via the stack is + * not supported. To minimize overhead, the stack has a fixed size and + * does not maintain an internal array. + * The supported stack entries, sorted by increasing priority, are: + *

    + *
  1. Application parameters: + * expected to be the same for all clients used by an application. + * These provide "global", that is application-wide, defaults. + *
  2. + *
  3. Client parameters: + * specific to an instance of + * {@link org.apache.http.client.HttpClient HttpClient}. + * These provide client specific defaults. + *
  4. + *
  5. Request parameters: + * specific to a single request execution. + * For overriding client and global defaults. + *
  6. + *
  7. Override parameters: + * specific to an instance of + * {@link org.apache.http.client.HttpClient HttpClient}. + * These can be used to set parameters that cannot be overridden + * on a per-request basis. + *
  8. + *
+ * Each stack entry may be null. That is preferable over + * an empty params collection, since it avoids searching the empty collection + * when looking up parameters. + * + * + * + * @since 4.0 + */ +@NotThreadSafe +public class ClientParamsStack extends AbstractHttpParams { + + /** The application parameter collection, or null. */ + protected final HttpParams applicationParams; + + /** The client parameter collection, or null. */ + protected final HttpParams clientParams; + + /** The request parameter collection, or null. */ + protected final HttpParams requestParams; + + /** The override parameter collection, or null. */ + protected final HttpParams overrideParams; + + + /** + * Creates a new parameter stack from elements. + * The arguments will be stored as-is, there is no copying to + * prevent modification. + * + * @param aparams application parameters, or null + * @param cparams client parameters, or null + * @param rparams request parameters, or null + * @param oparams override parameters, or null + */ + public ClientParamsStack(HttpParams aparams, HttpParams cparams, + HttpParams rparams, HttpParams oparams) { + applicationParams = aparams; + clientParams = cparams; + requestParams = rparams; + overrideParams = oparams; + } + + + /** + * Creates a copy of a parameter stack. + * The new stack will have the exact same entries as the argument stack. + * There is no copying of parameters. + * + * @param stack the stack to copy + */ + public ClientParamsStack(ClientParamsStack stack) { + this(stack.getApplicationParams(), + stack.getClientParams(), + stack.getRequestParams(), + stack.getOverrideParams()); + } + + + /** + * Creates a modified copy of a parameter stack. + * The new stack will contain the explicitly passed elements. + * For elements where the explicit argument is null, + * the corresponding element from the argument stack is used. + * There is no copying of parameters. + * + * @param stack the stack to modify + * @param aparams application parameters, or null + * @param cparams client parameters, or null + * @param rparams request parameters, or null + * @param oparams override parameters, or null + */ + public ClientParamsStack(ClientParamsStack stack, + HttpParams aparams, HttpParams cparams, + HttpParams rparams, HttpParams oparams) { + this((aparams != null) ? aparams : stack.getApplicationParams(), + (cparams != null) ? cparams : stack.getClientParams(), + (rparams != null) ? rparams : stack.getRequestParams(), + (oparams != null) ? oparams : stack.getOverrideParams()); + } + + + /** + * Obtains the application parameters of this stack. + * + * @return the application parameters, or null + */ + public final HttpParams getApplicationParams() { + return applicationParams; + } + + /** + * Obtains the client parameters of this stack. + * + * @return the client parameters, or null + */ + public final HttpParams getClientParams() { + return clientParams; + } + + /** + * Obtains the request parameters of this stack. + * + * @return the request parameters, or null + */ + public final HttpParams getRequestParams() { + return requestParams; + } + + /** + * Obtains the override parameters of this stack. + * + * @return the override parameters, or null + */ + public final HttpParams getOverrideParams() { + return overrideParams; + } + + + /** + * Obtains a parameter from this stack. + * See class comment for search order. + * + * @param name the name of the parameter to obtain + * + * @return the highest-priority value for that parameter, or + * null if it is not set anywhere in this stack + */ + public Object getParameter(String name) { + if (name == null) { + throw new IllegalArgumentException + ("Parameter name must not be null."); + } + + Object result = null; + + if (overrideParams != null) { + result = overrideParams.getParameter(name); + } + if ((result == null) && (requestParams != null)) { + result = requestParams.getParameter(name); + } + if ((result == null) && (clientParams != null)) { + result = clientParams.getParameter(name); + } + if ((result == null) && (applicationParams != null)) { + result = applicationParams.getParameter(name); + } + return result; + } + + /** + * Does not set a parameter. + * Parameter stacks are read-only. It is possible, though discouraged, + * to access and modify specific stack entries. + * Derived classes may change this behavior. + * + * @param name ignored + * @param value ignored + * + * @return nothing + * + * @throws UnsupportedOperationException always + */ + public HttpParams setParameter(String name, Object value) + throws UnsupportedOperationException { + + throw new UnsupportedOperationException + ("Setting parameters in a stack is not supported."); + } + + + /** + * Does not remove a parameter. + * Parameter stacks are read-only. It is possible, though discouraged, + * to access and modify specific stack entries. + * Derived classes may change this behavior. + * + * @param name ignored + * + * @return nothing + * + * @throws UnsupportedOperationException always + */ + public boolean removeParameter(String name) { + throw new UnsupportedOperationException + ("Removing parameters in a stack is not supported."); + } + + + /** + * Does not copy parameters. + * Parameter stacks are lightweight objects, expected to be instantiated + * as needed and to be used only in a very specific context. On top of + * that, they are read-only. The typical copy operation to prevent + * accidental modification of parameters passed by the application to + * a framework object is therefore pointless and disabled. + * Create a new stack if you really need a copy. + *
+ * Derived classes may change this behavior. + * + * @return this parameter stack + */ + public HttpParams copy() { + return this; + } + + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/Clock.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/Clock.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/Clock.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,42 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.client; + +/** + * Interface used to enable easier testing of time-related behavior. + * + * @since 4.2 + * + */ +interface Clock { + + /** + * Returns the current time, expressed as the number of + * milliseconds since the epoch. + * @return current time + */ + long getCurrentTime(); +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/ContentEncodingHttpClient.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/ContentEncodingHttpClient.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/ContentEncodingHttpClient.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,92 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.http.impl.client; + +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.client.HttpClient; +import org.apache.http.client.protocol.RequestAcceptEncoding; +import org.apache.http.client.protocol.ResponseContentEncoding; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.BasicHttpProcessor; + +/** + * {@link DefaultHttpClient} sub-class which includes a {@link RequestAcceptEncoding} + * for the request and response. + * + * Deprecation note: due to the way this class modifies a response body + * without changing the response headers to reflect the entity changes, it cannot + * be used as the "backend" for a caching {@link HttpClient} and still + * have uncompressed responses be cached. Users are encouraged to use the + * {@link DecompressingHttpClient} instead of this class, which can be wired in + * either before or after caching, depending on whether you want to cache + * responses in compressed or uncompressed form. + * + * @since 4.1 + */ +@Deprecated +@ThreadSafe // since DefaultHttpClient is +public class ContentEncodingHttpClient extends DefaultHttpClient { + + /** + * Creates a new HTTP client from parameters and a connection manager. + * + * @param params the parameters + * @param conman the connection manager + */ + public ContentEncodingHttpClient(ClientConnectionManager conman, HttpParams params) { + super(conman, params); + } + + /** + * @param params + */ + public ContentEncodingHttpClient(HttpParams params) { + this(null, params); + } + + /** + * + */ + public ContentEncodingHttpClient() { + this(null); + } + + /** + * {@inheritDoc} + */ + @Override + protected BasicHttpProcessor createHttpProcessor() { + BasicHttpProcessor result = super.createHttpProcessor(); + + result.addRequestInterceptor(new RequestAcceptEncoding()); + result.addResponseInterceptor(new ResponseContentEncoding()); + + return result; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DecompressingHttpClient.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DecompressingHttpClient.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DecompressingHttpClient.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,180 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.http.impl.client; + +import java.io.IOException; +import java.net.URI; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.protocol.RequestAcceptEncoding; +import org.apache.http.client.protocol.ResponseContentEncoding; +import org.apache.http.client.utils.URIUtils; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.EntityUtils; + +/** + *

Decorator adding support for compressed responses. This class sets + * the Accept-Encoding header on requests to indicate + * support for the gzip and deflate + * compression schemes; it then checks the Content-Encoding + * header on the response to uncompress any compressed response bodies. + * The {@link java.io.InputStream} of the entity will contain the uncompressed + * content.

+ * + *

N.B. Any upstream clients of this class need to be aware that + * this effectively obscures visibility into the length of a server + * response body, since the Content-Length header will + * correspond to the compressed entity length received from the server, + * but the content length experienced by reading the response body may + * be different (hopefully higher!).

+ * + *

That said, this decorator is compatible with the + * CachingHttpClient in that the two decorators can be added + * in either order and still have cacheable responses be cached.

+ * + * @since 4.2 + */ +public class DecompressingHttpClient implements HttpClient { + + private HttpClient backend; + private HttpRequestInterceptor acceptEncodingInterceptor; + private HttpResponseInterceptor contentEncodingInterceptor; + + /** + * Constructs a decorator to ask for and handle compressed + * entities on the fly. + * @param backend the {@link HttpClient} to use for actually + * issuing requests + */ + public DecompressingHttpClient(HttpClient backend) { + this(backend, new RequestAcceptEncoding(), new ResponseContentEncoding()); + } + + DecompressingHttpClient(HttpClient backend, + HttpRequestInterceptor requestInterceptor, + HttpResponseInterceptor responseInterceptor) { + this.backend = backend; + this.acceptEncodingInterceptor = requestInterceptor; + this.contentEncodingInterceptor = responseInterceptor; + } + + public HttpParams getParams() { + return backend.getParams(); + } + + public ClientConnectionManager getConnectionManager() { + return backend.getConnectionManager(); + } + + public HttpResponse execute(HttpUriRequest request) throws IOException, + ClientProtocolException { + return execute(getHttpHost(request), request, (HttpContext)null); + } + + HttpHost getHttpHost(HttpUriRequest request) { + URI uri = request.getURI(); + return URIUtils.extractHost(uri); + } + + public HttpResponse execute(HttpUriRequest request, HttpContext context) + throws IOException, ClientProtocolException { + return execute(getHttpHost(request), request, context); + } + + public HttpResponse execute(HttpHost target, HttpRequest request) + throws IOException, ClientProtocolException { + return execute(target, request, (HttpContext)null); + } + + public HttpResponse execute(HttpHost target, HttpRequest request, + HttpContext context) throws IOException, ClientProtocolException { + try { + if (context == null) context = new BasicHttpContext(); + HttpRequest wrapped; + if (request instanceof HttpEntityEnclosingRequest) { + wrapped = new EntityEnclosingRequestWrapper((HttpEntityEnclosingRequest) request); + } else { + wrapped = new RequestWrapper(request); + } + acceptEncodingInterceptor.process(wrapped, context); + HttpResponse response = backend.execute(target, wrapped, context); + contentEncodingInterceptor.process(response, context); + if (Boolean.TRUE.equals(context.getAttribute(ResponseContentEncoding.UNCOMPRESSED))) { + response.removeHeaders("Content-Length"); + response.removeHeaders("Content-Encoding"); + response.removeHeaders("Content-MD5"); + } + return response; + } catch (HttpException e) { + throw new ClientProtocolException(e); + } + } + + public T execute(HttpUriRequest request, + ResponseHandler responseHandler) throws IOException, + ClientProtocolException { + return execute(getHttpHost(request), request, responseHandler); + } + + public T execute(HttpUriRequest request, + ResponseHandler responseHandler, HttpContext context) + throws IOException, ClientProtocolException { + return execute(getHttpHost(request), request, responseHandler, context); + } + + public T execute(HttpHost target, HttpRequest request, + ResponseHandler responseHandler) throws IOException, + ClientProtocolException { + return execute(target, request, responseHandler, null); + } + + public T execute(HttpHost target, HttpRequest request, + ResponseHandler responseHandler, HttpContext context) + throws IOException, ClientProtocolException { + HttpResponse response = execute(target, request, context); + try { + return responseHandler.handleResponse(response); + } finally { + HttpEntity entity = response.getEntity(); + if (entity != null) EntityUtils.consume(entity); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultBackoffStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultBackoffStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultBackoffStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,53 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.client; + +import java.net.ConnectException; +import java.net.SocketTimeoutException; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.ConnectionBackoffStrategy; + +/** + * This {@link ConnectionBackoffStrategy} backs off either for a raw + * network socket or connection timeout or if the server explicitly + * sends a 503 (Service Unavailable) response. + * + * @since 4.2 + */ +public class DefaultBackoffStrategy implements ConnectionBackoffStrategy { + + public boolean shouldBackoff(Throwable t) { + return (t instanceof SocketTimeoutException + || t instanceof ConnectException); + } + + public boolean shouldBackoff(HttpResponse resp) { + return (resp.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultConnectionKeepAliveStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultConnectionKeepAliveStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultConnectionKeepAliveStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,71 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.client; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.HeaderElement; +import org.apache.http.HeaderElementIterator; +import org.apache.http.HttpResponse; +import org.apache.http.conn.ConnectionKeepAliveStrategy; +import org.apache.http.message.BasicHeaderElementIterator; +import org.apache.http.protocol.HTTP; +import org.apache.http.protocol.HttpContext; + +/** + * Default implementation of a strategy deciding duration + * that a connection can remain idle. + * + * The default implementation looks solely at the 'Keep-Alive' + * header's timeout token. + * + * @since 4.0 + */ +@Immutable +public class DefaultConnectionKeepAliveStrategy implements ConnectionKeepAliveStrategy { + + public long getKeepAliveDuration(HttpResponse response, HttpContext context) { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + HeaderElementIterator it = new BasicHeaderElementIterator( + response.headerIterator(HTTP.CONN_KEEP_ALIVE)); + while (it.hasNext()) { + HeaderElement he = it.nextElement(); + String param = he.getName(); + String value = he.getValue(); + if (value != null && param.equalsIgnoreCase("timeout")) { + try { + return Long.parseLong(value) * 1000; + } catch(NumberFormatException ignore) { + } + } + } + return -1; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultHttpClient.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultHttpClient.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultHttpClient.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,227 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import org.apache.http.HttpVersion; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.client.HttpClient; +import org.apache.http.client.protocol.RequestAddCookies; +import org.apache.http.client.protocol.RequestAuthCache; +import org.apache.http.client.protocol.RequestClientConnControl; +import org.apache.http.client.protocol.RequestDefaultHeaders; +import org.apache.http.client.protocol.RequestProxyAuthentication; +import org.apache.http.client.protocol.RequestTargetAuthentication; +import org.apache.http.client.protocol.ResponseProcessCookies; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.params.CoreConnectionPNames; +import org.apache.http.params.CoreProtocolPNames; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.params.SyncBasicHttpParams; +import org.apache.http.protocol.BasicHttpProcessor; +import org.apache.http.protocol.HTTP; +import org.apache.http.protocol.RequestContent; +import org.apache.http.protocol.RequestExpectContinue; +import org.apache.http.protocol.RequestTargetHost; +import org.apache.http.protocol.RequestUserAgent; +import org.apache.http.util.VersionInfo; + +/** + * Default implementation of {@link HttpClient} pre-configured for most common use scenarios. + *

+ * Please see the Javadoc for {@link #createHttpProcessor()} for the details of the interceptors + * that are set up by default. + *

+ * Additional interceptors can be added as follows, but + * take care not to add the same interceptor more than once. + *

+ * DefaultHttpClient httpclient = new DefaultHttpClient();
+ * httpclient.addRequestInterceptor(new RequestAcceptEncoding());
+ * httpclient.addResponseInterceptor(new ResponseContentEncoding());
+ * 
+ *

+ * This class sets up the following parameters if not explicitly set: + *

    + *
  • Version: HttpVersion.HTTP_1_1
  • + *
  • ContentCharset: HTTP.DEFAULT_CONTENT_CHARSET
  • + *
  • NoTcpDelay: true
  • + *
  • SocketBufferSize: 8192
  • + *
  • UserAgent: Apache-HttpClient/release (java 1.5)
  • + *
+ *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.params.CoreProtocolPNames#PROTOCOL_VERSION}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#USE_EXPECT_CONTINUE}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#WAIT_FOR_CONTINUE}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#USER_AGENT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#STALE_CONNECTION_CHECK}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY}
  • + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}
  • + *
  • {@link org.apache.http.auth.params.AuthPNames#CREDENTIAL_CHARSET}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#COOKIE_POLICY}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_AUTHENTICATION}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_REDIRECTS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#MAX_REDIRECTS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#ALLOW_CIRCULAR_REDIRECTS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#VIRTUAL_HOST}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HOST}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HEADERS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#CONN_MANAGER_TIMEOUT}
  • + *
+ * + * @since 4.0 + */ +@ThreadSafe +public class DefaultHttpClient extends AbstractHttpClient { + + /** + * Creates a new HTTP client from parameters and a connection manager. + * + * @param params the parameters + * @param conman the connection manager + */ + public DefaultHttpClient( + final ClientConnectionManager conman, + final HttpParams params) { + super(conman, params); + } + + + /** + * @since 4.1 + */ + public DefaultHttpClient( + final ClientConnectionManager conman) { + super(conman, null); + } + + + public DefaultHttpClient(final HttpParams params) { + super(null, params); + } + + + public DefaultHttpClient() { + super(null, null); + } + + + /** + * Creates the default set of HttpParams by invoking {@link DefaultHttpClient#setDefaultHttpParams(HttpParams)} + * + * @return a new instance of {@link SyncBasicHttpParams} with the defaults applied to it. + */ + @Override + protected HttpParams createHttpParams() { + HttpParams params = new SyncBasicHttpParams(); + setDefaultHttpParams(params); + return params; + } + + /** + * Saves the default set of HttpParams in the provided parameter. + * These are: + *
    + *
  • {@link CoreProtocolPNames#PROTOCOL_VERSION}: 1.1
  • + *
  • {@link CoreProtocolPNames#HTTP_CONTENT_CHARSET}: ISO-8859-1
  • + *
  • {@link CoreConnectionPNames#TCP_NODELAY}: true
  • + *
  • {@link CoreConnectionPNames#SOCKET_BUFFER_SIZE}: 8192
  • + *
  • {@link CoreProtocolPNames#USER_AGENT}: Apache-HttpClient/ (java 1.5)
  • + *
+ */ + public static void setDefaultHttpParams(HttpParams params) { + HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); + HttpProtocolParams.setContentCharset(params, HTTP.DEF_CONTENT_CHARSET.name()); + HttpConnectionParams.setTcpNoDelay(params, true); + HttpConnectionParams.setSocketBufferSize(params, 8192); + + // determine the release version from packaged version info + final VersionInfo vi = VersionInfo.loadVersionInfo + ("org.apache.http.client", DefaultHttpClient.class.getClassLoader()); + final String release = (vi != null) ? + vi.getRelease() : VersionInfo.UNAVAILABLE; + HttpProtocolParams.setUserAgent(params, + "Apache-HttpClient/" + release + " (java 1.5)"); + } + + /** + * Create the processor with the following interceptors: + *
    + *
  • {@link RequestDefaultHeaders}
  • + *
  • {@link RequestContent}
  • + *
  • {@link RequestTargetHost}
  • + *
  • {@link RequestClientConnControl}
  • + *
  • {@link RequestUserAgent}
  • + *
  • {@link RequestExpectContinue}
  • + *
  • {@link RequestAddCookies}
  • + *
  • {@link ResponseProcessCookies}
  • + *
  • {@link RequestAuthCache}
  • + *
  • {@link RequestTargetAuthentication}
  • + *
  • {@link RequestProxyAuthentication}
  • + *
+ *

+ * @return the processor with the added interceptors. + */ + @Override + protected BasicHttpProcessor createHttpProcessor() { + BasicHttpProcessor httpproc = new BasicHttpProcessor(); + httpproc.addInterceptor(new RequestDefaultHeaders()); + // Required protocol interceptors + httpproc.addInterceptor(new RequestContent()); + httpproc.addInterceptor(new RequestTargetHost()); + // Recommended protocol interceptors + httpproc.addInterceptor(new RequestClientConnControl()); + httpproc.addInterceptor(new RequestUserAgent()); + httpproc.addInterceptor(new RequestExpectContinue()); + // HTTP state management interceptors + httpproc.addInterceptor(new RequestAddCookies()); + httpproc.addInterceptor(new ResponseProcessCookies()); + // HTTP authentication interceptors + httpproc.addInterceptor(new RequestAuthCache()); + httpproc.addInterceptor(new RequestTargetAuthentication()); + httpproc.addInterceptor(new RequestProxyAuthentication()); + return httpproc; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultHttpRequestRetryHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultHttpRequestRetryHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultHttpRequestRetryHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,169 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.ConnectException; +import java.net.UnknownHostException; + +import javax.net.ssl.SSLException; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpRequest; +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.ExecutionContext; +import org.apache.http.client.methods.HttpUriRequest; + +/** + * The default {@link HttpRequestRetryHandler} used by request executors. + * + * + * @since 4.0 + */ +@Immutable +public class DefaultHttpRequestRetryHandler implements HttpRequestRetryHandler { + + /** the number of times a method will be retried */ + private final int retryCount; + + /** Whether or not methods that have successfully sent their request will be retried */ + private final boolean requestSentRetryEnabled; + + /** + * Default constructor + */ + public DefaultHttpRequestRetryHandler(int retryCount, boolean requestSentRetryEnabled) { + super(); + this.retryCount = retryCount; + this.requestSentRetryEnabled = requestSentRetryEnabled; + } + + /** + * Default constructor + */ + public DefaultHttpRequestRetryHandler() { + this(3, false); + } + /** + * Used retryCount and requestSentRetryEnabled to determine + * if the given method should be retried. + */ + public boolean retryRequest( + final IOException exception, + int executionCount, + final HttpContext context) { + if (exception == null) { + throw new IllegalArgumentException("Exception parameter may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + if (executionCount > this.retryCount) { + // Do not retry if over max retry count + return false; + } + if (exception instanceof InterruptedIOException) { + // Timeout + return false; + } + if (exception instanceof UnknownHostException) { + // Unknown host + return false; + } + if (exception instanceof ConnectException) { + // Connection refused + return false; + } + if (exception instanceof SSLException) { + // SSL handshake exception + return false; + } + + HttpRequest request = (HttpRequest) + context.getAttribute(ExecutionContext.HTTP_REQUEST); + + if(requestIsAborted(request)){ + return false; + } + + if (handleAsIdempotent(request)) { + // Retry if the request is considered idempotent + return true; + } + + Boolean b = (Boolean) + context.getAttribute(ExecutionContext.HTTP_REQ_SENT); + boolean sent = (b != null && b.booleanValue()); + + if (!sent || this.requestSentRetryEnabled) { + // Retry if the request has not been sent fully or + // if it's OK to retry methods that have been sent + return true; + } + // otherwise do not retry + return false; + } + + /** + * @return true if this handler will retry methods that have + * successfully sent their request, false otherwise + */ + public boolean isRequestSentRetryEnabled() { + return requestSentRetryEnabled; + } + + /** + * @return the maximum number of times a method will be retried + */ + public int getRetryCount() { + return retryCount; + } + + /** + * @since 4.2 + */ + protected boolean handleAsIdempotent(final HttpRequest request) { + return !(request instanceof HttpEntityEnclosingRequest); + } + + /** + * @since 4.2 + */ + protected boolean requestIsAborted(final HttpRequest request) { + HttpRequest req = request; + if (request instanceof RequestWrapper) { // does not forward request to original + req = ((RequestWrapper) request).getOriginal(); + } + return (req instanceof HttpUriRequest && ((HttpUriRequest)req).isAborted()); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultProxyAuthenticationHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultProxyAuthenticationHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultProxyAuthenticationHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,94 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.List; +import java.util.Map; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.auth.params.AuthPNames; +import org.apache.http.client.AuthenticationHandler; +import org.apache.http.protocol.HttpContext; + +/** + * Default {@link AuthenticationHandler} implementation for proxy host + * authentication. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link ProxyAuthenticationStrategy} + */ +@Deprecated +@Immutable +public class DefaultProxyAuthenticationHandler extends AbstractAuthenticationHandler { + + public DefaultProxyAuthenticationHandler() { + super(); + } + + public boolean isAuthenticationRequested( + final HttpResponse response, + final HttpContext context) { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + int status = response.getStatusLine().getStatusCode(); + return status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED; + } + + public Map getChallenges( + final HttpResponse response, + final HttpContext context) throws MalformedChallengeException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + Header[] headers = response.getHeaders(AUTH.PROXY_AUTH); + return parseChallenges(headers); + } + + @Override + protected List getAuthPreferences( + final HttpResponse response, + final HttpContext context) { + @SuppressWarnings("unchecked") + List authpref = (List) response.getParams().getParameter( + AuthPNames.PROXY_AUTH_PREF); + if (authpref != null) { + return authpref; + } else { + return super.getAuthPreferences(response, context); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRedirectHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRedirectHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRedirectHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,186 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.http.annotation.Immutable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.ProtocolException; +import org.apache.http.client.CircularRedirectException; +import org.apache.http.client.RedirectHandler; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.params.ClientPNames; +import org.apache.http.client.utils.URIUtils; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.ExecutionContext; + +/** + * Default implementation of {@link RedirectHandler}. + * + * @since 4.0 + * + * @deprecated (4.1) use {@link DefaultRedirectStrategy}. + */ +@Immutable +@Deprecated +public class DefaultRedirectHandler implements RedirectHandler { + + private final Log log = LogFactory.getLog(getClass()); + + private static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations"; + + public DefaultRedirectHandler() { + super(); + } + + public boolean isRedirectRequested( + final HttpResponse response, + final HttpContext context) { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + + int statusCode = response.getStatusLine().getStatusCode(); + switch (statusCode) { + case HttpStatus.SC_MOVED_TEMPORARILY: + case HttpStatus.SC_MOVED_PERMANENTLY: + case HttpStatus.SC_TEMPORARY_REDIRECT: + HttpRequest request = (HttpRequest) context.getAttribute( + ExecutionContext.HTTP_REQUEST); + String method = request.getRequestLine().getMethod(); + return method.equalsIgnoreCase(HttpGet.METHOD_NAME) + || method.equalsIgnoreCase(HttpHead.METHOD_NAME); + case HttpStatus.SC_SEE_OTHER: + return true; + default: + return false; + } //end of switch + } + + public URI getLocationURI( + final HttpResponse response, + final HttpContext context) throws ProtocolException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + //get the location header to find out where to redirect to + Header locationHeader = response.getFirstHeader("location"); + if (locationHeader == null) { + // got a redirect response, but no location header + throw new ProtocolException( + "Received redirect response " + response.getStatusLine() + + " but no location header"); + } + String location = locationHeader.getValue(); + if (this.log.isDebugEnabled()) { + this.log.debug("Redirect requested to location '" + location + "'"); + } + + URI uri; + try { + uri = new URI(location); + } catch (URISyntaxException ex) { + throw new ProtocolException("Invalid redirect URI: " + location, ex); + } + + HttpParams params = response.getParams(); + // rfc2616 demands the location value be a complete URI + // Location = "Location" ":" absoluteURI + if (!uri.isAbsolute()) { + if (params.isParameterTrue(ClientPNames.REJECT_RELATIVE_REDIRECT)) { + throw new ProtocolException("Relative redirect location '" + + uri + "' not allowed"); + } + // Adjust location URI + HttpHost target = (HttpHost) context.getAttribute( + ExecutionContext.HTTP_TARGET_HOST); + if (target == null) { + throw new IllegalStateException("Target host not available " + + "in the HTTP context"); + } + + HttpRequest request = (HttpRequest) context.getAttribute( + ExecutionContext.HTTP_REQUEST); + + try { + URI requestURI = new URI(request.getRequestLine().getUri()); + URI absoluteRequestURI = URIUtils.rewriteURI(requestURI, target, true); + uri = URIUtils.resolve(absoluteRequestURI, uri); + } catch (URISyntaxException ex) { + throw new ProtocolException(ex.getMessage(), ex); + } + } + + if (params.isParameterFalse(ClientPNames.ALLOW_CIRCULAR_REDIRECTS)) { + + RedirectLocations redirectLocations = (RedirectLocations) context.getAttribute( + REDIRECT_LOCATIONS); + + if (redirectLocations == null) { + redirectLocations = new RedirectLocations(); + context.setAttribute(REDIRECT_LOCATIONS, redirectLocations); + } + + URI redirectURI; + if (uri.getFragment() != null) { + try { + HttpHost target = new HttpHost( + uri.getHost(), + uri.getPort(), + uri.getScheme()); + redirectURI = URIUtils.rewriteURI(uri, target, true); + } catch (URISyntaxException ex) { + throw new ProtocolException(ex.getMessage(), ex); + } + } else { + redirectURI = uri; + } + + if (redirectLocations.contains(redirectURI)) { + throw new CircularRedirectException("Circular redirect to '" + + redirectURI + "'"); + } else { + redirectLocations.add(redirectURI); + } + } + + return uri; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRedirectStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRedirectStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRedirectStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,218 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.http.annotation.Immutable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.ProtocolException; +import org.apache.http.client.CircularRedirectException; +import org.apache.http.client.RedirectStrategy; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.params.ClientPNames; +import org.apache.http.client.utils.URIUtils; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.ExecutionContext; + +/** + * Default implementation of {@link RedirectStrategy}. This strategy honors the restrictions + * on automatic redirection of entity enclosing methods such as POST and PUT imposed by the + * HTTP specification. 302 Moved Temporarily, 301 Moved Permanently and + * 307 Temporary Redirect status codes will result in an automatic redirect of + * HEAD and GET methods only. POST and PUT methods will not be automatically redirected + * as requiring user confirmation. + *

+ * The restriction on automatic redirection of POST methods can be relaxed by using + * {@link LaxRedirectStrategy} instead of {@link DefaultRedirectStrategy}. + * + * @see LaxRedirectStrategy + * @since 4.1 + */ +@Immutable +public class DefaultRedirectStrategy implements RedirectStrategy { + + private final Log log = LogFactory.getLog(getClass()); + + public static final String REDIRECT_LOCATIONS = "http.protocol.redirect-locations"; + + /** + * Redirectable methods. + */ + private static final String[] REDIRECT_METHODS = new String[] { + HttpGet.METHOD_NAME, + HttpHead.METHOD_NAME + }; + + public DefaultRedirectStrategy() { + super(); + } + + public boolean isRedirected( + final HttpRequest request, + final HttpResponse response, + final HttpContext context) throws ProtocolException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + + int statusCode = response.getStatusLine().getStatusCode(); + String method = request.getRequestLine().getMethod(); + Header locationHeader = response.getFirstHeader("location"); + switch (statusCode) { + case HttpStatus.SC_MOVED_TEMPORARILY: + return isRedirectable(method) && locationHeader != null; + case HttpStatus.SC_MOVED_PERMANENTLY: + case HttpStatus.SC_TEMPORARY_REDIRECT: + return isRedirectable(method); + case HttpStatus.SC_SEE_OTHER: + return true; + default: + return false; + } //end of switch + } + + public URI getLocationURI( + final HttpRequest request, + final HttpResponse response, + final HttpContext context) throws ProtocolException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + //get the location header to find out where to redirect to + Header locationHeader = response.getFirstHeader("location"); + if (locationHeader == null) { + // got a redirect response, but no location header + throw new ProtocolException( + "Received redirect response " + response.getStatusLine() + + " but no location header"); + } + String location = locationHeader.getValue(); + if (this.log.isDebugEnabled()) { + this.log.debug("Redirect requested to location '" + location + "'"); + } + + URI uri = createLocationURI(location); + + HttpParams params = request.getParams(); + // rfc2616 demands the location value be a complete URI + // Location = "Location" ":" absoluteURI + try { + // Drop fragment + uri = URIUtils.rewriteURI(uri); + if (!uri.isAbsolute()) { + if (params.isParameterTrue(ClientPNames.REJECT_RELATIVE_REDIRECT)) { + throw new ProtocolException("Relative redirect location '" + + uri + "' not allowed"); + } + // Adjust location URI + HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); + if (target == null) { + throw new IllegalStateException("Target host not available " + + "in the HTTP context"); + } + URI requestURI = new URI(request.getRequestLine().getUri()); + URI absoluteRequestURI = URIUtils.rewriteURI(requestURI, target, true); + uri = URIUtils.resolve(absoluteRequestURI, uri); + } + } catch (URISyntaxException ex) { + throw new ProtocolException(ex.getMessage(), ex); + } + + RedirectLocations redirectLocations = (RedirectLocations) context.getAttribute( + REDIRECT_LOCATIONS); + if (redirectLocations == null) { + redirectLocations = new RedirectLocations(); + context.setAttribute(REDIRECT_LOCATIONS, redirectLocations); + } + if (params.isParameterFalse(ClientPNames.ALLOW_CIRCULAR_REDIRECTS)) { + if (redirectLocations.contains(uri)) { + throw new CircularRedirectException("Circular redirect to '" + uri + "'"); + } + } + redirectLocations.add(uri); + return uri; + } + + /** + * @since 4.1 + */ + protected URI createLocationURI(final String location) throws ProtocolException { + try { + return new URI(location).normalize(); + } catch (URISyntaxException ex) { + throw new ProtocolException("Invalid redirect URI: " + location, ex); + } + } + + /** + * @since 4.2 + */ + protected boolean isRedirectable(final String method) { + for (String m: REDIRECT_METHODS) { + if (m.equalsIgnoreCase(method)) { + return true; + } + } + return false; + } + + public HttpUriRequest getRedirect( + final HttpRequest request, + final HttpResponse response, + final HttpContext context) throws ProtocolException { + URI uri = getLocationURI(request, response, context); + String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) { + return new HttpHead(uri); + } else { + return new HttpGet(uri); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRedirectStrategyAdaptor.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRedirectStrategyAdaptor.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRedirectStrategyAdaptor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,81 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.net.URI; + +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolException; +import org.apache.http.annotation.Immutable; +import org.apache.http.client.RedirectHandler; +import org.apache.http.client.RedirectStrategy; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.protocol.HttpContext; + +/** + * @deprecated (4.1) do not use + */ +@Immutable +@Deprecated +class DefaultRedirectStrategyAdaptor implements RedirectStrategy { + + private final RedirectHandler handler; + + public DefaultRedirectStrategyAdaptor(final RedirectHandler handler) { + super(); + this.handler = handler; + } + + public boolean isRedirected( + final HttpRequest request, + final HttpResponse response, + final HttpContext context) throws ProtocolException { + return this.handler.isRedirectRequested(response, context); + } + + public HttpUriRequest getRedirect( + final HttpRequest request, + final HttpResponse response, + final HttpContext context) throws ProtocolException { + URI uri = this.handler.getLocationURI(response, context); + String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) { + return new HttpHead(uri); + } else { + return new HttpGet(uri); + } + } + + public RedirectHandler getHandler() { + return this.handler; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRequestDirector.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRequestDirector.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultRequestDirector.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,1170 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolException; +import org.apache.http.ProtocolVersion; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.auth.AuthProtocolState; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthState; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.AuthenticationHandler; +import org.apache.http.client.AuthenticationStrategy; +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.client.NonRepeatableRequestException; +import org.apache.http.client.RedirectException; +import org.apache.http.client.RedirectHandler; +import org.apache.http.client.RedirectStrategy; +import org.apache.http.client.RequestDirector; +import org.apache.http.client.UserTokenHandler; +import org.apache.http.client.methods.AbortableHttpRequest; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.params.ClientPNames; +import org.apache.http.client.params.HttpClientParams; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.client.utils.URIUtils; +import org.apache.http.conn.BasicManagedEntity; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionRequest; +import org.apache.http.conn.ConnectionKeepAliveStrategy; +import org.apache.http.conn.ManagedClientConnection; +import org.apache.http.conn.routing.BasicRouteDirector; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.routing.HttpRouteDirector; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.entity.BufferedHttpEntity; +import org.apache.http.impl.auth.BasicScheme; +import org.apache.http.impl.conn.ConnectionShutdownException; +import org.apache.http.message.BasicHttpRequest; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.ExecutionContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpProcessor; +import org.apache.http.protocol.HttpRequestExecutor; +import org.apache.http.util.EntityUtils; + +/** + * Default implementation of {@link RequestDirector}. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.params.CoreProtocolPNames#PROTOCOL_VERSION}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#USE_EXPECT_CONTINUE}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#WAIT_FOR_CONTINUE}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#USER_AGENT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#STALE_CONNECTION_CHECK}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY}
  • + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}
  • + *
  • {@link org.apache.http.auth.params.AuthPNames#CREDENTIAL_CHARSET}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#COOKIE_POLICY}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_AUTHENTICATION}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_REDIRECTS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#MAX_REDIRECTS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#ALLOW_CIRCULAR_REDIRECTS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#VIRTUAL_HOST}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HOST}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HEADERS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#CONN_MANAGER_TIMEOUT}
  • + *
+ * + * @since 4.0 + */ +@SuppressWarnings("deprecation") +@NotThreadSafe // e.g. managedConn +public class DefaultRequestDirector implements RequestDirector { + + private final Log log; + + /** The connection manager. */ + protected final ClientConnectionManager connManager; + + /** The route planner. */ + protected final HttpRoutePlanner routePlanner; + + /** The connection re-use strategy. */ + protected final ConnectionReuseStrategy reuseStrategy; + + /** The keep-alive duration strategy. */ + protected final ConnectionKeepAliveStrategy keepAliveStrategy; + + /** The request executor. */ + protected final HttpRequestExecutor requestExec; + + /** The HTTP protocol processor. */ + protected final HttpProcessor httpProcessor; + + /** The request retry handler. */ + protected final HttpRequestRetryHandler retryHandler; + + /** The redirect handler. */ + @Deprecated + protected final RedirectHandler redirectHandler; + + /** The redirect strategy. */ + protected final RedirectStrategy redirectStrategy; + + /** The target authentication handler. */ + @Deprecated + protected final AuthenticationHandler targetAuthHandler; + + /** The target authentication handler. */ + protected final AuthenticationStrategy targetAuthStrategy; + + /** The proxy authentication handler. */ + @Deprecated + protected final AuthenticationHandler proxyAuthHandler; + + /** The proxy authentication handler. */ + protected final AuthenticationStrategy proxyAuthStrategy; + + /** The user token handler. */ + protected final UserTokenHandler userTokenHandler; + + /** The HTTP parameters. */ + protected final HttpParams params; + + /** The currently allocated connection. */ + protected ManagedClientConnection managedConn; + + protected final AuthState targetAuthState; + + protected final AuthState proxyAuthState; + + private final HttpAuthenticator authenticator; + + private int execCount; + + private int redirectCount; + + private int maxRedirects; + + private HttpHost virtualHost; + + @Deprecated + public DefaultRequestDirector( + final HttpRequestExecutor requestExec, + final ClientConnectionManager conman, + final ConnectionReuseStrategy reustrat, + final ConnectionKeepAliveStrategy kastrat, + final HttpRoutePlanner rouplan, + final HttpProcessor httpProcessor, + final HttpRequestRetryHandler retryHandler, + final RedirectHandler redirectHandler, + final AuthenticationHandler targetAuthHandler, + final AuthenticationHandler proxyAuthHandler, + final UserTokenHandler userTokenHandler, + final HttpParams params) { + this(LogFactory.getLog(DefaultRequestDirector.class), + requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, + new DefaultRedirectStrategyAdaptor(redirectHandler), + new AuthenticationStrategyAdaptor(targetAuthHandler), + new AuthenticationStrategyAdaptor(proxyAuthHandler), + userTokenHandler, + params); + } + + + @Deprecated + public DefaultRequestDirector( + final Log log, + final HttpRequestExecutor requestExec, + final ClientConnectionManager conman, + final ConnectionReuseStrategy reustrat, + final ConnectionKeepAliveStrategy kastrat, + final HttpRoutePlanner rouplan, + final HttpProcessor httpProcessor, + final HttpRequestRetryHandler retryHandler, + final RedirectStrategy redirectStrategy, + final AuthenticationHandler targetAuthHandler, + final AuthenticationHandler proxyAuthHandler, + final UserTokenHandler userTokenHandler, + final HttpParams params) { + this(LogFactory.getLog(DefaultRequestDirector.class), + requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, + redirectStrategy, + new AuthenticationStrategyAdaptor(targetAuthHandler), + new AuthenticationStrategyAdaptor(proxyAuthHandler), + userTokenHandler, + params); + } + + /** + * @since 4.2 + */ + public DefaultRequestDirector( + final Log log, + final HttpRequestExecutor requestExec, + final ClientConnectionManager conman, + final ConnectionReuseStrategy reustrat, + final ConnectionKeepAliveStrategy kastrat, + final HttpRoutePlanner rouplan, + final HttpProcessor httpProcessor, + final HttpRequestRetryHandler retryHandler, + final RedirectStrategy redirectStrategy, + final AuthenticationStrategy targetAuthStrategy, + final AuthenticationStrategy proxyAuthStrategy, + final UserTokenHandler userTokenHandler, + final HttpParams params) { + + if (log == null) { + throw new IllegalArgumentException + ("Log may not be null."); + } + if (requestExec == null) { + throw new IllegalArgumentException + ("Request executor may not be null."); + } + if (conman == null) { + throw new IllegalArgumentException + ("Client connection manager may not be null."); + } + if (reustrat == null) { + throw new IllegalArgumentException + ("Connection reuse strategy may not be null."); + } + if (kastrat == null) { + throw new IllegalArgumentException + ("Connection keep alive strategy may not be null."); + } + if (rouplan == null) { + throw new IllegalArgumentException + ("Route planner may not be null."); + } + if (httpProcessor == null) { + throw new IllegalArgumentException + ("HTTP protocol processor may not be null."); + } + if (retryHandler == null) { + throw new IllegalArgumentException + ("HTTP request retry handler may not be null."); + } + if (redirectStrategy == null) { + throw new IllegalArgumentException + ("Redirect strategy may not be null."); + } + if (targetAuthStrategy == null) { + throw new IllegalArgumentException + ("Target authentication strategy may not be null."); + } + if (proxyAuthStrategy == null) { + throw new IllegalArgumentException + ("Proxy authentication strategy may not be null."); + } + if (userTokenHandler == null) { + throw new IllegalArgumentException + ("User token handler may not be null."); + } + if (params == null) { + throw new IllegalArgumentException + ("HTTP parameters may not be null"); + } + this.log = log; + this.authenticator = new HttpAuthenticator(log); + this.requestExec = requestExec; + this.connManager = conman; + this.reuseStrategy = reustrat; + this.keepAliveStrategy = kastrat; + this.routePlanner = rouplan; + this.httpProcessor = httpProcessor; + this.retryHandler = retryHandler; + this.redirectStrategy = redirectStrategy; + this.targetAuthStrategy = targetAuthStrategy; + this.proxyAuthStrategy = proxyAuthStrategy; + this.userTokenHandler = userTokenHandler; + this.params = params; + + if (redirectStrategy instanceof DefaultRedirectStrategyAdaptor) { + this.redirectHandler = ((DefaultRedirectStrategyAdaptor) redirectStrategy).getHandler(); + } else { + this.redirectHandler = null; + } + if (targetAuthStrategy instanceof AuthenticationStrategyAdaptor) { + this.targetAuthHandler = ((AuthenticationStrategyAdaptor) targetAuthStrategy).getHandler(); + } else { + this.targetAuthHandler = null; + } + if (proxyAuthStrategy instanceof AuthenticationStrategyAdaptor) { + this.proxyAuthHandler = ((AuthenticationStrategyAdaptor) proxyAuthStrategy).getHandler(); + } else { + this.proxyAuthHandler = null; + } + + this.managedConn = null; + + this.execCount = 0; + this.redirectCount = 0; + this.targetAuthState = new AuthState(); + this.proxyAuthState = new AuthState(); + this.maxRedirects = this.params.getIntParameter(ClientPNames.MAX_REDIRECTS, 100); + } + + + private RequestWrapper wrapRequest( + final HttpRequest request) throws ProtocolException { + if (request instanceof HttpEntityEnclosingRequest) { + return new EntityEnclosingRequestWrapper( + (HttpEntityEnclosingRequest) request); + } else { + return new RequestWrapper( + request); + } + } + + + protected void rewriteRequestURI( + final RequestWrapper request, + final HttpRoute route) throws ProtocolException { + try { + + URI uri = request.getURI(); + if (route.getProxyHost() != null && !route.isTunnelled()) { + // Make sure the request URI is absolute + if (!uri.isAbsolute()) { + HttpHost target = route.getTargetHost(); + uri = URIUtils.rewriteURI(uri, target, true); + } else { + uri = URIUtils.rewriteURI(uri); + } + } else { + // Make sure the request URI is relative + if (uri.isAbsolute()) { + uri = URIUtils.rewriteURI(uri, null); + } else { + uri = URIUtils.rewriteURI(uri); + } + } + request.setURI(uri); + + } catch (URISyntaxException ex) { + throw new ProtocolException("Invalid URI: " + + request.getRequestLine().getUri(), ex); + } + } + + + // non-javadoc, see interface ClientRequestDirector + public HttpResponse execute(HttpHost target, HttpRequest request, + HttpContext context) + throws HttpException, IOException { + + context.setAttribute(ClientContext.TARGET_AUTH_STATE, targetAuthState); + context.setAttribute(ClientContext.PROXY_AUTH_STATE, proxyAuthState); + + HttpRequest orig = request; + RequestWrapper origWrapper = wrapRequest(orig); + origWrapper.setParams(params); + HttpRoute origRoute = determineRoute(target, origWrapper, context); + + virtualHost = (HttpHost) origWrapper.getParams().getParameter(ClientPNames.VIRTUAL_HOST); + + // HTTPCLIENT-1092 - add the port if necessary + if (virtualHost != null && virtualHost.getPort() == -1) { + int port = target.getPort(); + if (port != -1){ + virtualHost = new HttpHost(virtualHost.getHostName(), port, virtualHost.getSchemeName()); + } + } + + RoutedRequest roureq = new RoutedRequest(origWrapper, origRoute); + + boolean reuse = false; + boolean done = false; + try { + HttpResponse response = null; + while (!done) { + // In this loop, the RoutedRequest may be replaced by a + // followup request and route. The request and route passed + // in the method arguments will be replaced. The original + // request is still available in 'orig'. + + RequestWrapper wrapper = roureq.getRequest(); + HttpRoute route = roureq.getRoute(); + response = null; + + // See if we have a user token bound to the execution context + Object userToken = context.getAttribute(ClientContext.USER_TOKEN); + + // Allocate connection if needed + if (managedConn == null) { + ClientConnectionRequest connRequest = connManager.requestConnection( + route, userToken); + if (orig instanceof AbortableHttpRequest) { + ((AbortableHttpRequest) orig).setConnectionRequest(connRequest); + } + + long timeout = HttpClientParams.getConnectionManagerTimeout(params); + try { + managedConn = connRequest.getConnection(timeout, TimeUnit.MILLISECONDS); + } catch(InterruptedException interrupted) { + InterruptedIOException iox = new InterruptedIOException(); + iox.initCause(interrupted); + throw iox; + } + + if (HttpConnectionParams.isStaleCheckingEnabled(params)) { + // validate connection + if (managedConn.isOpen()) { + this.log.debug("Stale connection check"); + if (managedConn.isStale()) { + this.log.debug("Stale connection detected"); + managedConn.close(); + } + } + } + } + + if (orig instanceof AbortableHttpRequest) { + ((AbortableHttpRequest) orig).setReleaseTrigger(managedConn); + } + + try { + tryConnect(roureq, context); + } catch (TunnelRefusedException ex) { + if (this.log.isDebugEnabled()) { + this.log.debug(ex.getMessage()); + } + response = ex.getResponse(); + break; + } + + String userinfo = wrapper.getURI().getUserInfo(); + if (userinfo != null) { + targetAuthState.update( + new BasicScheme(), new UsernamePasswordCredentials(userinfo)); + } + + // Reset headers on the request wrapper + wrapper.resetHeaders(); + + // Re-write request URI if needed + rewriteRequestURI(wrapper, route); + + // Use virtual host if set + target = virtualHost; + + if (target == null) { + target = route.getTargetHost(); + } + + HttpHost proxy = route.getProxyHost(); + + // Populate the execution context + context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target); + context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy); + context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn); + + // Run request protocol interceptors + requestExec.preProcess(wrapper, httpProcessor, context); + + response = tryExecute(roureq, context); + if (response == null) { + // Need to start over + continue; + } + + // Run response protocol interceptors + response.setParams(params); + requestExec.postProcess(response, httpProcessor, context); + + + // The connection is in or can be brought to a re-usable state. + reuse = reuseStrategy.keepAlive(response, context); + if (reuse) { + // Set the idle duration of this connection + long duration = keepAliveStrategy.getKeepAliveDuration(response, context); + if (this.log.isDebugEnabled()) { + String s; + if (duration > 0) { + s = "for " + duration + " " + TimeUnit.MILLISECONDS; + } else { + s = "indefinitely"; + } + this.log.debug("Connection can be kept alive " + s); + } + managedConn.setIdleDuration(duration, TimeUnit.MILLISECONDS); + } + + RoutedRequest followup = handleResponse(roureq, response, context); + if (followup == null) { + done = true; + } else { + if (reuse) { + // Make sure the response body is fully consumed, if present + HttpEntity entity = response.getEntity(); + EntityUtils.consume(entity); + // entity consumed above is not an auto-release entity, + // need to mark the connection re-usable explicitly + managedConn.markReusable(); + } else { + managedConn.close(); + if (proxyAuthState.getState() == AuthProtocolState.SUCCESS + && proxyAuthState.getAuthScheme() != null + && proxyAuthState.getAuthScheme().isConnectionBased()) { + this.log.debug("Resetting proxy auth state"); + proxyAuthState.reset(); + } + if (targetAuthState.getState() == AuthProtocolState.SUCCESS + && targetAuthState.getAuthScheme() != null + && targetAuthState.getAuthScheme().isConnectionBased()) { + this.log.debug("Resetting target auth state"); + targetAuthState.reset(); + } + } + // check if we can use the same connection for the followup + if (!followup.getRoute().equals(roureq.getRoute())) { + releaseConnection(); + } + roureq = followup; + } + + if (managedConn != null) { + if (userToken == null) { + userToken = userTokenHandler.getUserToken(context); + context.setAttribute(ClientContext.USER_TOKEN, userToken); + } + if (userToken != null) { + managedConn.setState(userToken); + } + } + + } // while not done + + + // check for entity, release connection if possible + if ((response == null) || (response.getEntity() == null) || + !response.getEntity().isStreaming()) { + // connection not needed and (assumed to be) in re-usable state + if (reuse) + managedConn.markReusable(); + releaseConnection(); + } else { + // install an auto-release entity + HttpEntity entity = response.getEntity(); + entity = new BasicManagedEntity(entity, managedConn, reuse); + response.setEntity(entity); + } + + return response; + + } catch (ConnectionShutdownException ex) { + InterruptedIOException ioex = new InterruptedIOException( + "Connection has been shut down"); + ioex.initCause(ex); + throw ioex; + } catch (HttpException ex) { + abortConnection(); + throw ex; + } catch (IOException ex) { + abortConnection(); + throw ex; + } catch (RuntimeException ex) { + abortConnection(); + throw ex; + } + } // execute + + /** + * Establish connection either directly or through a tunnel and retry in case of + * a recoverable I/O failure + */ + private void tryConnect( + final RoutedRequest req, final HttpContext context) throws HttpException, IOException { + HttpRoute route = req.getRoute(); + HttpRequest wrapper = req.getRequest(); + + int connectCount = 0; + for (;;) { + context.setAttribute(ExecutionContext.HTTP_REQUEST, wrapper); + // Increment connect count + connectCount++; + try { + if (!managedConn.isOpen()) { + managedConn.open(route, context, params); + } else { + managedConn.setSocketTimeout(HttpConnectionParams.getSoTimeout(params)); + } + establishRoute(route, context); + break; + } catch (IOException ex) { + try { + managedConn.close(); + } catch (IOException ignore) { + } + if (retryHandler.retryRequest(ex, connectCount, context)) { + if (this.log.isInfoEnabled()) { + this.log.info("I/O exception ("+ ex.getClass().getName() + + ") caught when connecting to the target host: " + + ex.getMessage()); + if (this.log.isDebugEnabled()) { + this.log.debug(ex.getMessage(), ex); + } + this.log.info("Retrying connect"); + } + } else { + throw ex; + } + } + } + } + + /** + * Execute request and retry in case of a recoverable I/O failure + */ + private HttpResponse tryExecute( + final RoutedRequest req, final HttpContext context) throws HttpException, IOException { + RequestWrapper wrapper = req.getRequest(); + HttpRoute route = req.getRoute(); + HttpResponse response = null; + + Exception retryReason = null; + for (;;) { + // Increment total exec count (with redirects) + execCount++; + // Increment exec count for this particular request + wrapper.incrementExecCount(); + if (!wrapper.isRepeatable()) { + this.log.debug("Cannot retry non-repeatable request"); + if (retryReason != null) { + throw new NonRepeatableRequestException("Cannot retry request " + + "with a non-repeatable request entity. The cause lists the " + + "reason the original request failed.", retryReason); + } else { + throw new NonRepeatableRequestException("Cannot retry request " + + "with a non-repeatable request entity."); + } + } + + try { + if (!managedConn.isOpen()) { + // If we have a direct route to the target host + // just re-open connection and re-try the request + if (!route.isTunnelled()) { + this.log.debug("Reopening the direct connection."); + managedConn.open(route, context, params); + } else { + // otherwise give up + this.log.debug("Proxied connection. Need to start over."); + break; + } + } + + if (this.log.isDebugEnabled()) { + this.log.debug("Attempt " + execCount + " to execute request"); + } + response = requestExec.execute(wrapper, managedConn, context); + break; + + } catch (IOException ex) { + this.log.debug("Closing the connection."); + try { + managedConn.close(); + } catch (IOException ignore) { + } + if (retryHandler.retryRequest(ex, wrapper.getExecCount(), context)) { + if (this.log.isInfoEnabled()) { + this.log.info("I/O exception ("+ ex.getClass().getName() + + ") caught when processing request: " + + ex.getMessage()); + } + if (this.log.isDebugEnabled()) { + this.log.debug(ex.getMessage(), ex); + } + this.log.info("Retrying request"); + retryReason = ex; + } else { + throw ex; + } + } + } + return response; + } + + /** + * Returns the connection back to the connection manager + * and prepares for retrieving a new connection during + * the next request. + */ + protected void releaseConnection() { + // Release the connection through the ManagedConnection instead of the + // ConnectionManager directly. This lets the connection control how + // it is released. + try { + managedConn.releaseConnection(); + } catch(IOException ignored) { + this.log.debug("IOException releasing connection", ignored); + } + managedConn = null; + } + + /** + * Determines the route for a request. + * Called by {@link #execute} + * to determine the route for either the original or a followup request. + * + * @param target the target host for the request. + * Implementations may accept null + * if they can still determine a route, for example + * to a default target or by inspecting the request. + * @param request the request to execute + * @param context the context to use for the execution, + * never null + * + * @return the route the request should take + * + * @throws HttpException in case of a problem + */ + protected HttpRoute determineRoute(HttpHost target, + HttpRequest request, + HttpContext context) + throws HttpException { + + if (target == null) { + target = (HttpHost) request.getParams().getParameter( + ClientPNames.DEFAULT_HOST); + } + if (target == null) { + throw new IllegalStateException + ("Target host must not be null, or set in parameters."); + } + + return this.routePlanner.determineRoute(target, request, context); + } + + + /** + * Establishes the target route. + * + * @param route the route to establish + * @param context the context for the request execution + * + * @throws HttpException in case of a problem + * @throws IOException in case of an IO problem + */ + protected void establishRoute(HttpRoute route, HttpContext context) + throws HttpException, IOException { + + HttpRouteDirector rowdy = new BasicRouteDirector(); + int step; + do { + HttpRoute fact = managedConn.getRoute(); + step = rowdy.nextStep(route, fact); + + switch (step) { + + case HttpRouteDirector.CONNECT_TARGET: + case HttpRouteDirector.CONNECT_PROXY: + managedConn.open(route, context, this.params); + break; + + case HttpRouteDirector.TUNNEL_TARGET: { + boolean secure = createTunnelToTarget(route, context); + this.log.debug("Tunnel to target created."); + managedConn.tunnelTarget(secure, this.params); + } break; + + case HttpRouteDirector.TUNNEL_PROXY: { + // The most simple example for this case is a proxy chain + // of two proxies, where P1 must be tunnelled to P2. + // route: Source -> P1 -> P2 -> Target (3 hops) + // fact: Source -> P1 -> Target (2 hops) + final int hop = fact.getHopCount()-1; // the hop to establish + boolean secure = createTunnelToProxy(route, hop, context); + this.log.debug("Tunnel to proxy created."); + managedConn.tunnelProxy(route.getHopTarget(hop), + secure, this.params); + } break; + + + case HttpRouteDirector.LAYER_PROTOCOL: + managedConn.layerProtocol(context, this.params); + break; + + case HttpRouteDirector.UNREACHABLE: + throw new HttpException("Unable to establish route: " + + "planned = " + route + "; current = " + fact); + case HttpRouteDirector.COMPLETE: + // do nothing + break; + default: + throw new IllegalStateException("Unknown step indicator " + + step + " from RouteDirector."); + } + + } while (step > HttpRouteDirector.COMPLETE); + + } // establishConnection + + + /** + * Creates a tunnel to the target server. + * The connection must be established to the (last) proxy. + * A CONNECT request for tunnelling through the proxy will + * be created and sent, the response received and checked. + * This method does not update the connection with + * information about the tunnel, that is left to the caller. + * + * @param route the route to establish + * @param context the context for request execution + * + * @return true if the tunnelled route is secure, + * false otherwise. + * The implementation here always returns false, + * but derived classes may override. + * + * @throws HttpException in case of a problem + * @throws IOException in case of an IO problem + */ + protected boolean createTunnelToTarget(HttpRoute route, + HttpContext context) + throws HttpException, IOException { + + HttpHost proxy = route.getProxyHost(); + HttpHost target = route.getTargetHost(); + HttpResponse response = null; + + for (;;) { + if (!this.managedConn.isOpen()) { + this.managedConn.open(route, context, this.params); + } + + HttpRequest connect = createConnectRequest(route, context); + connect.setParams(this.params); + + // Populate the execution context + context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target); + context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy); + context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn); + context.setAttribute(ExecutionContext.HTTP_REQUEST, connect); + + this.requestExec.preProcess(connect, this.httpProcessor, context); + + response = this.requestExec.execute(connect, this.managedConn, context); + + response.setParams(this.params); + this.requestExec.postProcess(response, this.httpProcessor, context); + + int status = response.getStatusLine().getStatusCode(); + if (status < 200) { + throw new HttpException("Unexpected response to CONNECT request: " + + response.getStatusLine()); + } + + if (HttpClientParams.isAuthenticating(this.params)) { + if (this.authenticator.isAuthenticationRequested(proxy, response, + this.proxyAuthStrategy, this.proxyAuthState, context)) { + if (this.authenticator.authenticate(proxy, response, + this.proxyAuthStrategy, this.proxyAuthState, context)) { + // Retry request + if (this.reuseStrategy.keepAlive(response, context)) { + this.log.debug("Connection kept alive"); + // Consume response content + HttpEntity entity = response.getEntity(); + EntityUtils.consume(entity); + } else { + this.managedConn.close(); + } + } else { + break; + } + } else { + break; + } + } + } + + int status = response.getStatusLine().getStatusCode(); + + if (status > 299) { + + // Buffer response content + HttpEntity entity = response.getEntity(); + if (entity != null) { + response.setEntity(new BufferedHttpEntity(entity)); + } + + this.managedConn.close(); + throw new TunnelRefusedException("CONNECT refused by proxy: " + + response.getStatusLine(), response); + } + + this.managedConn.markReusable(); + + // How to decide on security of the tunnelled connection? + // The socket factory knows only about the segment to the proxy. + // Even if that is secure, the hop to the target may be insecure. + // Leave it to derived classes, consider insecure by default here. + return false; + + } // createTunnelToTarget + + + + /** + * Creates a tunnel to an intermediate proxy. + * This method is not implemented in this class. + * It just throws an exception here. + * + * @param route the route to establish + * @param hop the hop in the route to establish now. + * route.getHopTarget(hop) + * will return the proxy to tunnel to. + * @param context the context for request execution + * + * @return true if the partially tunnelled connection + * is secure, false otherwise. + * + * @throws HttpException in case of a problem + * @throws IOException in case of an IO problem + */ + protected boolean createTunnelToProxy(HttpRoute route, int hop, + HttpContext context) + throws HttpException, IOException { + + // Have a look at createTunnelToTarget and replicate the parts + // you need in a custom derived class. If your proxies don't require + // authentication, it is not too hard. But for the stock version of + // HttpClient, we cannot make such simplifying assumptions and would + // have to include proxy authentication code. The HttpComponents team + // is currently not in a position to support rarely used code of this + // complexity. Feel free to submit patches that refactor the code in + // createTunnelToTarget to facilitate re-use for proxy tunnelling. + + throw new HttpException("Proxy chains are not supported."); + } + + + + /** + * Creates the CONNECT request for tunnelling. + * Called by {@link #createTunnelToTarget createTunnelToTarget}. + * + * @param route the route to establish + * @param context the context for request execution + * + * @return the CONNECT request for tunnelling + */ + protected HttpRequest createConnectRequest(HttpRoute route, + HttpContext context) { + // see RFC 2817, section 5.2 and + // INTERNET-DRAFT: Tunneling TCP based protocols through + // Web proxy servers + + HttpHost target = route.getTargetHost(); + + String host = target.getHostName(); + int port = target.getPort(); + if (port < 0) { + Scheme scheme = connManager.getSchemeRegistry(). + getScheme(target.getSchemeName()); + port = scheme.getDefaultPort(); + } + + StringBuilder buffer = new StringBuilder(host.length() + 6); + buffer.append(host); + buffer.append(':'); + buffer.append(Integer.toString(port)); + + String authority = buffer.toString(); + ProtocolVersion ver = HttpProtocolParams.getVersion(params); + HttpRequest req = new BasicHttpRequest + ("CONNECT", authority, ver); + + return req; + } + + + /** + * Analyzes a response to check need for a followup. + * + * @param roureq the request and route. + * @param response the response to analayze + * @param context the context used for the current request execution + * + * @return the followup request and route if there is a followup, or + * null if the response should be returned as is + * + * @throws HttpException in case of a problem + * @throws IOException in case of an IO problem + */ + protected RoutedRequest handleResponse(RoutedRequest roureq, + HttpResponse response, + HttpContext context) + throws HttpException, IOException { + + HttpRoute route = roureq.getRoute(); + RequestWrapper request = roureq.getRequest(); + + HttpParams params = request.getParams(); + if (HttpClientParams.isRedirecting(params) && + this.redirectStrategy.isRedirected(request, response, context)) { + + if (redirectCount >= maxRedirects) { + throw new RedirectException("Maximum redirects (" + + maxRedirects + ") exceeded"); + } + redirectCount++; + + // Virtual host cannot be used any longer + virtualHost = null; + + HttpUriRequest redirect = redirectStrategy.getRedirect(request, response, context); + HttpRequest orig = request.getOriginal(); + redirect.setHeaders(orig.getAllHeaders()); + + URI uri = redirect.getURI(); + if (uri.getHost() == null) { + throw new ProtocolException("Redirect URI does not specify a valid host name: " + uri); + } + + HttpHost newTarget = new HttpHost( + uri.getHost(), + uri.getPort(), + uri.getScheme()); + + // Reset auth states if redirecting to another host + if (!route.getTargetHost().equals(newTarget)) { + this.log.debug("Resetting target auth state"); + targetAuthState.reset(); + AuthScheme authScheme = proxyAuthState.getAuthScheme(); + if (authScheme != null && authScheme.isConnectionBased()) { + this.log.debug("Resetting proxy auth state"); + proxyAuthState.reset(); + } + } + + RequestWrapper wrapper = wrapRequest(redirect); + wrapper.setParams(params); + + HttpRoute newRoute = determineRoute(newTarget, wrapper, context); + RoutedRequest newRequest = new RoutedRequest(wrapper, newRoute); + + if (this.log.isDebugEnabled()) { + this.log.debug("Redirecting to '" + uri + "' via " + newRoute); + } + + return newRequest; + } + + if (HttpClientParams.isAuthenticating(params)) { + HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST); + if (target == null) { + target = route.getTargetHost(); + } + if (target.getPort() < 0) { + Scheme scheme = connManager.getSchemeRegistry().getScheme(target); + target = new HttpHost(target.getHostName(), scheme.getDefaultPort(), target.getSchemeName()); + } + if (this.authenticator.isAuthenticationRequested(target, response, + this.targetAuthStrategy, this.targetAuthState, context)) { + if (this.authenticator.authenticate(target, response, + this.targetAuthStrategy, this.targetAuthState, context)) { + // Re-try the same request via the same route + return roureq; + } else { + return null; + } + } + + HttpHost proxy = route.getProxyHost(); + if (this.authenticator.isAuthenticationRequested(proxy, response, + this.proxyAuthStrategy, this.proxyAuthState, context)) { + if (this.authenticator.authenticate(proxy, response, + this.proxyAuthStrategy, this.proxyAuthState, context)) { + // Re-try the same request via the same route + return roureq; + } else { + return null; + } + } + } + return null; + } // handleResponse + + + /** + * Shuts down the connection. + * This method is called from a catch block in + * {@link #execute execute} during exception handling. + */ + private void abortConnection() { + ManagedClientConnection mcc = managedConn; + if (mcc != null) { + // we got here as the result of an exception + // no response will be returned, release the connection + managedConn = null; + try { + mcc.abortConnection(); + } catch (IOException ex) { + if (this.log.isDebugEnabled()) { + this.log.debug(ex.getMessage(), ex); + } + } + // ensure the connection manager properly releases this connection + try { + mcc.releaseConnection(); + } catch(IOException ignored) { + this.log.debug("Error releasing connection", ignored); + } + } + } // abortConnection + + +} // class DefaultClientRequestDirector Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultServiceUnavailableRetryStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,83 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.annotation.Immutable; +import org.apache.http.client.ServiceUnavailableRetryStrategy; +import org.apache.http.protocol.HttpContext; + +/** + * Default implementation of the {@link ServiceUnavailableRetryStrategy} interface. + * that retries 503 (Service Unavailable) responses for a fixed number of times + * at a fixed interval. + * + * @since 4.2 + */ +@Immutable +public class DefaultServiceUnavailableRetryStrategy implements ServiceUnavailableRetryStrategy { + + /** + * Maximum number of allowed retries if the server responds with a HTTP code + * in our retry code list. Default value is 1. + */ + private final int maxRetries; + + /** + * Retry interval between subsequent requests, in milliseconds. Default + * value is 1 second. + */ + private final long retryInterval; + + public DefaultServiceUnavailableRetryStrategy(int maxRetries, int retryInterval) { + super(); + if (maxRetries < 1) { + throw new IllegalArgumentException("MaxRetries must be greater than 1"); + } + if (retryInterval < 1) { + throw new IllegalArgumentException("Retry interval must be greater than 1"); + } + this.maxRetries = maxRetries; + this.retryInterval = retryInterval; + } + + public DefaultServiceUnavailableRetryStrategy() { + this(1, 1000); + } + + public boolean retryRequest(final HttpResponse response, int executionCount, final HttpContext context) { + return executionCount <= maxRetries && + response.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE; + } + + public long getRetryInterval() { + return retryInterval; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultTargetAuthenticationHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultTargetAuthenticationHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultTargetAuthenticationHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,95 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.List; +import java.util.Map; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.auth.params.AuthPNames; +import org.apache.http.client.AuthenticationHandler; +import org.apache.http.protocol.HttpContext; + +/** + * Default {@link AuthenticationHandler} implementation for target host + * authentication. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link TargetAuthenticationStrategy} + */ +@Deprecated +@Immutable +public class DefaultTargetAuthenticationHandler extends AbstractAuthenticationHandler { + + public DefaultTargetAuthenticationHandler() { + super(); + } + + public boolean isAuthenticationRequested( + final HttpResponse response, + final HttpContext context) { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + int status = response.getStatusLine().getStatusCode(); + return status == HttpStatus.SC_UNAUTHORIZED; + } + + public Map getChallenges( + final HttpResponse response, + final HttpContext context) throws MalformedChallengeException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + Header[] headers = response.getHeaders(AUTH.WWW_AUTH); + return parseChallenges(headers); + } + + @Override + protected List getAuthPreferences( + final HttpResponse response, + final HttpContext context) { + @SuppressWarnings("unchecked") + List authpref = (List) response.getParams().getParameter( + AuthPNames.TARGET_AUTH_PREF); + if (authpref != null) { + return authpref; + } else { + return super.getAuthPreferences(response, context); + } + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultUserTokenHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultUserTokenHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/DefaultUserTokenHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,101 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.security.Principal; + +import javax.net.ssl.SSLSession; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthState; +import org.apache.http.auth.Credentials; +import org.apache.http.client.UserTokenHandler; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.conn.HttpRoutedConnection; +import org.apache.http.protocol.ExecutionContext; +import org.apache.http.protocol.HttpContext; + +/** + * Default implementation of {@link UserTokenHandler}. This class will use + * an instance of {@link Principal} as a state object for HTTP connections, + * if it can be obtained from the given execution context. This helps ensure + * persistent connections created with a particular user identity within + * a particular security context can be reused by the same user only. + *

+ * DefaultUserTokenHandler will use the user principle of connection + * based authentication schemes such as NTLM or that of the SSL session + * with the client authentication turned on. If both are unavailable, + * null token will be returned. + * + * @since 4.0 + */ +@Immutable +public class DefaultUserTokenHandler implements UserTokenHandler { + + public Object getUserToken(final HttpContext context) { + + Principal userPrincipal = null; + + AuthState targetAuthState = (AuthState) context.getAttribute( + ClientContext.TARGET_AUTH_STATE); + if (targetAuthState != null) { + userPrincipal = getAuthPrincipal(targetAuthState); + if (userPrincipal == null) { + AuthState proxyAuthState = (AuthState) context.getAttribute( + ClientContext.PROXY_AUTH_STATE); + userPrincipal = getAuthPrincipal(proxyAuthState); + } + } + + if (userPrincipal == null) { + HttpRoutedConnection conn = (HttpRoutedConnection) context.getAttribute( + ExecutionContext.HTTP_CONNECTION); + if (conn.isOpen()) { + SSLSession sslsession = conn.getSSLSession(); + if (sslsession != null) { + userPrincipal = sslsession.getLocalPrincipal(); + } + } + } + + return userPrincipal; + } + + private static Principal getAuthPrincipal(final AuthState authState) { + AuthScheme scheme = authState.getAuthScheme(); + if (scheme != null && scheme.isComplete() && scheme.isConnectionBased()) { + Credentials creds = authState.getCredentials(); + if (creds != null) { + return creds.getUserPrincipal(); + } + } + return null; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/EntityEnclosingRequestWrapper.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/EntityEnclosingRequestWrapper.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/EntityEnclosingRequestWrapper.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,113 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.entity.HttpEntityWrapper; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.ProtocolException; +import org.apache.http.protocol.HTTP; + +/** + * A wrapper class for {@link HttpEntityEnclosingRequest}s that can + * be used to change properties of the current request without + * modifying the original object. + *

+ * This class is also capable of resetting the request headers to + * the state of the original request. + * + * + * @since 4.0 + */ +@NotThreadSafe // e.g. [gs]etEntity() +public class EntityEnclosingRequestWrapper extends RequestWrapper + implements HttpEntityEnclosingRequest { + + private HttpEntity entity; + private boolean consumed; + + public EntityEnclosingRequestWrapper(final HttpEntityEnclosingRequest request) + throws ProtocolException { + super(request); + setEntity(request.getEntity()); + } + + public HttpEntity getEntity() { + return this.entity; + } + + public void setEntity(final HttpEntity entity) { + this.entity = entity != null ? new EntityWrapper(entity) : null; + this.consumed = false; + } + + public boolean expectContinue() { + Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE); + return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue()); + } + + @Override + public boolean isRepeatable() { + return this.entity == null || this.entity.isRepeatable() || !this.consumed; + } + + class EntityWrapper extends HttpEntityWrapper { + + EntityWrapper(final HttpEntity entity) { + super(entity); + } + + @SuppressWarnings("deprecation") + @Override + public void consumeContent() throws IOException { + consumed = true; + super.consumeContent(); + } + + @Override + public InputStream getContent() throws IOException { + consumed = true; + return super.getContent(); + } + + @Override + public void writeTo(final OutputStream outstream) throws IOException { + consumed = true; + super.writeTo(outstream); + } + + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/HttpAuthenticator.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/HttpAuthenticator.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/HttpAuthenticator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,159 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.Locale; +import java.util.Map; +import java.util.Queue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthProtocolState; +import org.apache.http.auth.AuthOption; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthState; +import org.apache.http.auth.MalformedChallengeException; +import org.apache.http.client.AuthenticationStrategy; +import org.apache.http.protocol.HttpContext; + +public class HttpAuthenticator { + + private final Log log; + + public HttpAuthenticator(final Log log) { + super(); + this.log = log != null ? log : LogFactory.getLog(getClass()); + } + + public HttpAuthenticator() { + this(null); + } + + public boolean isAuthenticationRequested( + final HttpHost host, + final HttpResponse response, + final AuthenticationStrategy authStrategy, + final AuthState authState, + final HttpContext context) { + if (authStrategy.isAuthenticationRequested(host, response, context)) { + return true; + } else { + switch (authState.getState()) { + case CHALLENGED: + case HANDSHAKE: + authState.setState(AuthProtocolState.SUCCESS); + authStrategy.authSucceeded(host, authState.getAuthScheme(), context); + break; + case SUCCESS: + break; + default: + authState.setState(AuthProtocolState.UNCHALLENGED); + } + return false; + } + } + + public boolean authenticate( + final HttpHost host, + final HttpResponse response, + final AuthenticationStrategy authStrategy, + final AuthState authState, + final HttpContext context) { + try { + if (this.log.isDebugEnabled()) { + this.log.debug(host.toHostString() + " requested authentication"); + } + Map challenges = authStrategy.getChallenges(host, response, context); + if (challenges.isEmpty()) { + this.log.debug("Response contains no authentication challenges"); + return false; + } + + AuthScheme authScheme = authState.getAuthScheme(); + switch (authState.getState()) { + case FAILURE: + return false; + case SUCCESS: + authState.reset(); + break; + case CHALLENGED: + case HANDSHAKE: + if (authScheme == null) { + this.log.debug("Auth scheme is null"); + authStrategy.authFailed(host, null, context); + authState.reset(); + authState.setState(AuthProtocolState.FAILURE); + return false; + } + case UNCHALLENGED: + if (authScheme != null) { + String id = authScheme.getSchemeName(); + Header challenge = challenges.get(id.toLowerCase(Locale.US)); + if (challenge != null) { + this.log.debug("Authorization challenge processed"); + authScheme.processChallenge(challenge); + if (authScheme.isComplete()) { + this.log.debug("Authentication failed"); + authStrategy.authFailed(host, authState.getAuthScheme(), context); + authState.reset(); + authState.setState(AuthProtocolState.FAILURE); + return false; + } else { + authState.setState(AuthProtocolState.HANDSHAKE); + return true; + } + } else { + authState.reset(); + // Retry authentication with a different scheme + } + } + } + Queue authOptions = authStrategy.select(challenges, host, response, context); + if (authOptions != null && !authOptions.isEmpty()) { + if (this.log.isDebugEnabled()) { + this.log.debug("Selected authentication options: " + authOptions); + } + authState.setState(AuthProtocolState.CHALLENGED); + authState.update(authOptions); + return true; + } else { + return false; + } + } catch (MalformedChallengeException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn("Malformed challenge: " + ex.getMessage()); + } + authState.reset(); + return false; + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/LaxRedirectStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/LaxRedirectStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/LaxRedirectStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,65 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import org.apache.http.annotation.Immutable; +import org.apache.http.client.RedirectStrategy; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.methods.HttpPost; + +/** + * Lax {@link RedirectStrategy} implementation that automatically redirects all HEAD, GET and POST + * requests. This strategy relaxes restrictions on automatic redirection of POST methods imposed + * by the HTTP specification. + * + * @since 4.2 + */ +@Immutable +public class LaxRedirectStrategy extends DefaultRedirectStrategy { + + /** + * Redirectable methods. + */ + private static final String[] REDIRECT_METHODS = new String[] { + HttpGet.METHOD_NAME, + HttpPost.METHOD_NAME, + HttpHead.METHOD_NAME + }; + + @Override + protected boolean isRedirectable(String method) { + for (String m: REDIRECT_METHODS) { + if (m.equalsIgnoreCase(method)) { + return true; + } + } + return false; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/NullBackoffStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/NullBackoffStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/NullBackoffStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,46 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.client; + +import org.apache.http.HttpResponse; +import org.apache.http.client.ConnectionBackoffStrategy; + +/** + * This is a {@link ConnectionBackoffStrategy} that never backs off, + * for compatibility with existing behavior. + * + * @since 4.2 + */ +public class NullBackoffStrategy implements ConnectionBackoffStrategy { + + public boolean shouldBackoff(Throwable t) { + return false; + } + + public boolean shouldBackoff(HttpResponse resp) { + return false; + } +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/ProxyAuthenticationStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/ProxyAuthenticationStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/ProxyAuthenticationStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,48 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import org.apache.http.HttpStatus; +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.params.AuthPNames; +import org.apache.http.client.AuthenticationStrategy; + +/** + * Default {@link AuthenticationStrategy} implementation for proxy host authentication. + * + * @since 4.2 + */ +@Immutable +public class ProxyAuthenticationStrategy extends AuthenticationStrategyImpl { + + public ProxyAuthenticationStrategy() { + super(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, AUTH.PROXY_AUTH, AuthPNames.PROXY_AUTH_PREF); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/ProxyClient.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/ProxyClient.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/ProxyClient.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,247 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.io.IOException; +import java.net.Socket; + +import javax.net.ssl.SSLSession; + +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.auth.AuthSchemeRegistry; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.AuthState; +import org.apache.http.auth.Credentials; +import org.apache.http.client.params.AuthPolicy; +import org.apache.http.client.params.HttpClientParams; +import org.apache.http.client.protocol.ClientContext; +import org.apache.http.client.protocol.RequestClientConnControl; +import org.apache.http.client.protocol.RequestProxyAuthentication; +import org.apache.http.conn.HttpRoutedConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.entity.BufferedHttpEntity; +import org.apache.http.impl.DefaultConnectionReuseStrategy; +import org.apache.http.impl.DefaultHttpClientConnection; +import org.apache.http.impl.auth.BasicSchemeFactory; +import org.apache.http.impl.auth.DigestSchemeFactory; +import org.apache.http.impl.auth.KerberosSchemeFactory; +import org.apache.http.impl.auth.NTLMSchemeFactory; +import org.apache.http.impl.auth.SPNegoSchemeFactory; +import org.apache.http.message.BasicHttpRequest; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.ExecutionContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpProcessor; +import org.apache.http.protocol.HttpRequestExecutor; +import org.apache.http.protocol.ImmutableHttpProcessor; +import org.apache.http.protocol.RequestContent; +import org.apache.http.protocol.RequestTargetHost; +import org.apache.http.protocol.RequestUserAgent; +import org.apache.http.util.EntityUtils; + +public class ProxyClient { + + private final HttpProcessor httpProcessor; + private final HttpRequestExecutor requestExec; + private final ProxyAuthenticationStrategy proxyAuthStrategy; + private final HttpAuthenticator authenticator; + private final AuthState proxyAuthState; + private final AuthSchemeRegistry authSchemeRegistry; + private final ConnectionReuseStrategy reuseStrategy; + private final HttpParams params; + + public ProxyClient(final HttpParams params) { + super(); + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + this.httpProcessor = new ImmutableHttpProcessor(new HttpRequestInterceptor[] { + new RequestContent(), + new RequestTargetHost(), + new RequestClientConnControl(), + new RequestUserAgent(), + new RequestProxyAuthentication() + } ); + this.requestExec = new HttpRequestExecutor(); + this.proxyAuthStrategy = new ProxyAuthenticationStrategy(); + this.authenticator = new HttpAuthenticator(); + this.proxyAuthState = new AuthState(); + this.authSchemeRegistry = new AuthSchemeRegistry(); + this.authSchemeRegistry.register(AuthPolicy.BASIC, new BasicSchemeFactory()); + this.authSchemeRegistry.register(AuthPolicy.DIGEST, new DigestSchemeFactory()); + this.authSchemeRegistry.register(AuthPolicy.NTLM, new NTLMSchemeFactory()); + this.authSchemeRegistry.register(AuthPolicy.SPNEGO, new SPNegoSchemeFactory()); + this.authSchemeRegistry.register(AuthPolicy.KERBEROS, new KerberosSchemeFactory()); + this.reuseStrategy = new DefaultConnectionReuseStrategy(); + this.params = params; + } + + public ProxyClient() { + this(new BasicHttpParams()); + } + + public HttpParams getParams() { + return this.params; + } + + public AuthSchemeRegistry getAuthSchemeRegistry() { + return this.authSchemeRegistry; + } + + public Socket tunnel( + final HttpHost proxy, + final HttpHost target, + final Credentials credentials) throws IOException, HttpException { + ProxyConnection conn = new ProxyConnection(new HttpRoute(proxy)); + HttpContext context = new BasicHttpContext(); + HttpResponse response = null; + + for (;;) { + if (!conn.isOpen()) { + Socket socket = new Socket(proxy.getHostName(), proxy.getPort()); + conn.bind(socket, this.params); + } + String host = target.getHostName(); + int port = target.getPort(); + if (port < 0) { + port = 80; + } + + StringBuilder buffer = new StringBuilder(host.length() + 6); + buffer.append(host); + buffer.append(':'); + buffer.append(Integer.toString(port)); + + String authority = buffer.toString(); + ProtocolVersion ver = HttpProtocolParams.getVersion(this.params); + HttpRequest connect = new BasicHttpRequest("CONNECT", authority, ver); + connect.setParams(this.params); + + BasicCredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials(new AuthScope(proxy), credentials); + + // Populate the execution context + context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target); + context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy); + context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn); + context.setAttribute(ExecutionContext.HTTP_REQUEST, connect); + context.setAttribute(ClientContext.PROXY_AUTH_STATE, this.proxyAuthState); + context.setAttribute(ClientContext.CREDS_PROVIDER, credsProvider); + context.setAttribute(ClientContext.AUTHSCHEME_REGISTRY, this.authSchemeRegistry); + + this.requestExec.preProcess(connect, this.httpProcessor, context); + + response = this.requestExec.execute(connect, conn, context); + + response.setParams(this.params); + this.requestExec.postProcess(response, this.httpProcessor, context); + + int status = response.getStatusLine().getStatusCode(); + if (status < 200) { + throw new HttpException("Unexpected response to CONNECT request: " + + response.getStatusLine()); + } + + if (HttpClientParams.isAuthenticating(this.params)) { + if (this.authenticator.isAuthenticationRequested(proxy, response, + this.proxyAuthStrategy, this.proxyAuthState, context)) { + if (this.authenticator.authenticate(proxy, response, + this.proxyAuthStrategy, this.proxyAuthState, context)) { + // Retry request + if (this.reuseStrategy.keepAlive(response, context)) { + // Consume response content + HttpEntity entity = response.getEntity(); + EntityUtils.consume(entity); + } else { + conn.close(); + } + } else { + break; + } + } else { + break; + } + } + } + + int status = response.getStatusLine().getStatusCode(); + + if (status > 299) { + + // Buffer response content + HttpEntity entity = response.getEntity(); + if (entity != null) { + response.setEntity(new BufferedHttpEntity(entity)); + } + + conn.close(); + throw new TunnelRefusedException("CONNECT refused by proxy: " + + response.getStatusLine(), response); + } + return conn.getSocket(); + } + + static class ProxyConnection extends DefaultHttpClientConnection implements HttpRoutedConnection { + + private final HttpRoute route; + + ProxyConnection(final HttpRoute route) { + super(); + this.route = route; + } + + public HttpRoute getRoute() { + return this.route; + } + + public boolean isSecure() { + return false; + } + + public SSLSession getSSLSession() { + return null; + } + + @Override + public Socket getSocket() { + return super.getSocket(); + } + + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/RedirectLocations.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/RedirectLocations.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/RedirectLocations.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,99 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * This class represents a collection of {@link URI}s used as redirect locations. + * + * @since 4.0 + */ +@NotThreadSafe // HashSet is not synch. +public class RedirectLocations { + + private final Set unique; + private final List all; + + public RedirectLocations() { + super(); + this.unique = new HashSet(); + this.all = new ArrayList(); + } + + /** + * Test if the URI is present in the collection. + */ + public boolean contains(final URI uri) { + return this.unique.contains(uri); + } + + /** + * Adds a new URI to the collection. + */ + public void add(final URI uri) { + this.unique.add(uri); + this.all.add(uri); + } + + /** + * Removes a URI from the collection. + */ + public boolean remove(final URI uri) { + boolean removed = this.unique.remove(uri); + if (removed) { + Iterator it = this.all.iterator(); + while (it.hasNext()) { + URI current = it.next(); + if (current.equals(uri)) { + it.remove(); + } + } + } + return removed; + } + + /** + * Returns all redirect {@link URI}s in the order they were added to the collection. + * + * @return list of all URIs + * + * @since 4.1 + */ + public List getAll() { + return new ArrayList(this.all); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/RequestWrapper.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/RequestWrapper.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/RequestWrapper.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,166 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.HttpRequest; +import org.apache.http.ProtocolException; +import org.apache.http.ProtocolVersion; +import org.apache.http.RequestLine; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.message.AbstractHttpMessage; +import org.apache.http.message.BasicRequestLine; +import org.apache.http.params.HttpProtocolParams; + +/** + * A wrapper class for {@link HttpRequest}s that can be used to change + * properties of the current request without modifying the original + * object. + *

+ * This class is also capable of resetting the request headers to + * the state of the original request. + * + * + * @since 4.0 + */ +@NotThreadSafe +public class RequestWrapper extends AbstractHttpMessage implements HttpUriRequest { + + private final HttpRequest original; + + private URI uri; + private String method; + private ProtocolVersion version; + private int execCount; + + public RequestWrapper(final HttpRequest request) throws ProtocolException { + super(); + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + this.original = request; + setParams(request.getParams()); + setHeaders(request.getAllHeaders()); + // Make a copy of the original URI + if (request instanceof HttpUriRequest) { + this.uri = ((HttpUriRequest) request).getURI(); + this.method = ((HttpUriRequest) request).getMethod(); + this.version = null; + } else { + RequestLine requestLine = request.getRequestLine(); + try { + this.uri = new URI(requestLine.getUri()); + } catch (URISyntaxException ex) { + throw new ProtocolException("Invalid request URI: " + + requestLine.getUri(), ex); + } + this.method = requestLine.getMethod(); + this.version = request.getProtocolVersion(); + } + this.execCount = 0; + } + + public void resetHeaders() { + // Make a copy of original headers + this.headergroup.clear(); + setHeaders(this.original.getAllHeaders()); + } + + public String getMethod() { + return this.method; + } + + public void setMethod(final String method) { + if (method == null) { + throw new IllegalArgumentException("Method name may not be null"); + } + this.method = method; + } + + public ProtocolVersion getProtocolVersion() { + if (this.version == null) { + this.version = HttpProtocolParams.getVersion(getParams()); + } + return this.version; + } + + public void setProtocolVersion(final ProtocolVersion version) { + this.version = version; + } + + + public URI getURI() { + return this.uri; + } + + public void setURI(final URI uri) { + this.uri = uri; + } + + public RequestLine getRequestLine() { + String method = getMethod(); + ProtocolVersion ver = getProtocolVersion(); + String uritext = null; + if (uri != null) { + uritext = uri.toASCIIString(); + } + if (uritext == null || uritext.length() == 0) { + uritext = "/"; + } + return new BasicRequestLine(method, uritext, ver); + } + + public void abort() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + public boolean isAborted() { + return false; + } + + public HttpRequest getOriginal() { + return this.original; + } + + public boolean isRepeatable() { + return true; + } + + public int getExecCount() { + return this.execCount; + } + + public void incrementExecCount() { + this.execCount++; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/RoutedRequest.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/RoutedRequest.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/RoutedRequest.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,65 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.conn.routing.HttpRoute; + +/** + * A request with the route along which it should be sent. + * + * @since 4.0 + */ +@NotThreadSafe // RequestWrapper is @NotThreadSafe +public class RoutedRequest { + + protected final RequestWrapper request; // @NotThreadSafe + protected final HttpRoute route; // @Immutable + + /** + * Creates a new routed request. + * + * @param req the request + * @param route the route + */ + public RoutedRequest(final RequestWrapper req, final HttpRoute route) { + super(); + this.request = req; + this.route = route; + } + + public final RequestWrapper getRequest() { + return request; + } + + public final HttpRoute getRoute() { + return route; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/StandardHttpRequestRetryHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/StandardHttpRequestRetryHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/StandardHttpRequestRetryHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,81 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.http.HttpRequest; +import org.apache.http.annotation.Immutable; +import org.apache.http.client.HttpRequestRetryHandler; + +/** + * A {@link HttpRequestRetryHandler} which assumes that all requested + * HTTP methods which should be idempotent according to RFC-2616 are + * in fact idempotent and can be retried. + * + * According to RFC-2616 section 9.1.2 the idempotent HTTP methods are: + * GET, HEAD, PUT, DELETE, OPTIONS, and TRACE + * + * @since 4.2 + */ +@Immutable +public class StandardHttpRequestRetryHandler extends DefaultHttpRequestRetryHandler { + + private final Map idempotentMethods; + + /** + * Default constructor + */ + public StandardHttpRequestRetryHandler(int retryCount, boolean requestSentRetryEnabled) { + super(retryCount, requestSentRetryEnabled); + this.idempotentMethods = new ConcurrentHashMap(); + this.idempotentMethods.put("GET", Boolean.TRUE); + this.idempotentMethods.put("HEAD", Boolean.TRUE); + this.idempotentMethods.put("PUT", Boolean.TRUE); + this.idempotentMethods.put("DELETE", Boolean.TRUE); + this.idempotentMethods.put("OPTIONS", Boolean.TRUE); + this.idempotentMethods.put("TRACE", Boolean.TRUE); + } + + /** + * Default constructor + */ + public StandardHttpRequestRetryHandler() { + this(3, false); + } + + @Override + protected boolean handleAsIdempotent(final HttpRequest request) { + String method = request.getRequestLine().getMethod().toUpperCase(Locale.US); + Boolean b = this.idempotentMethods.get(method); + return b != null && b.booleanValue(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/SystemClock.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/SystemClock.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/SystemClock.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,39 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.client; + +/** + * The actual system clock. + * + * @since 4.2 + */ +class SystemClock implements Clock { + + public long getCurrentTime() { + return System.currentTimeMillis(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/SystemDefaultHttpClient.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/SystemDefaultHttpClient.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/SystemDefaultHttpClient.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,146 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import java.net.ProxySelector; + +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.impl.DefaultConnectionReuseStrategy; +import org.apache.http.impl.NoConnectionReuseStrategy; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.impl.conn.ProxySelectorRoutePlanner; +import org.apache.http.impl.conn.SchemeRegistryFactory; +import org.apache.http.params.HttpParams; + +/** + * An extension of {@link DefaultHttpClient} pre-configured using system properties. + *

+ * The following system properties are taken into account by this class: + *

    + *
  • ssl.TrustManagerFactory.algorithm
  • + *
  • javax.net.ssl.trustStoreType
  • + *
  • javax.net.ssl.trustStore
  • + *
  • javax.net.ssl.trustStoreProvider
  • + *
  • javax.net.ssl.trustStorePassword
  • + *
  • java.home
  • + *
  • ssl.KeyManagerFactory.algorithm
  • + *
  • javax.net.ssl.keyStoreType
  • + *
  • javax.net.ssl.keyStore
  • + *
  • javax.net.ssl.keyStoreProvider
  • + *
  • javax.net.ssl.keyStorePassword
  • + *
  • http.proxyHost
  • + *
  • http.proxyPort
  • + *
  • http.nonProxyHosts
  • + *
  • http.keepAlive
  • + *
  • http.maxConnections
  • + *
+ *

+ *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.params.CoreProtocolPNames#PROTOCOL_VERSION}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#USE_EXPECT_CONTINUE}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#WAIT_FOR_CONTINUE}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#USER_AGENT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#STALE_CONNECTION_CHECK}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY}
  • + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}
  • + *
  • {@link org.apache.http.auth.params.AuthPNames#CREDENTIAL_CHARSET}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#COOKIE_POLICY}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_AUTHENTICATION}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#HANDLE_REDIRECTS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#MAX_REDIRECTS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#ALLOW_CIRCULAR_REDIRECTS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#VIRTUAL_HOST}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HOST}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#DEFAULT_HEADERS}
  • + *
  • {@link org.apache.http.client.params.ClientPNames#CONN_MANAGER_TIMEOUT}
  • + *
+ *

+ * + * @since 4.2 + */ +@ThreadSafe +public class SystemDefaultHttpClient extends DefaultHttpClient { + + public SystemDefaultHttpClient(final HttpParams params) { + super(null, params); + } + + public SystemDefaultHttpClient() { + super(null, null); + } + + @Override + protected ClientConnectionManager createClientConnectionManager() { + PoolingClientConnectionManager connmgr = new PoolingClientConnectionManager( + SchemeRegistryFactory.createSystemDefault()); + String s = System.getProperty("http.keepAlive"); + if ("true".equalsIgnoreCase(s)) { + s = System.getProperty("http.maxConnections", "5"); + int max = Integer.parseInt(s); + connmgr.setDefaultMaxPerRoute(max); + connmgr.setMaxTotal(2 * max); + } + return connmgr; + } + + @Override + protected HttpRoutePlanner createHttpRoutePlanner() { + return new ProxySelectorRoutePlanner(getConnectionManager().getSchemeRegistry(), + ProxySelector.getDefault()); + } + + @Override + protected ConnectionReuseStrategy createConnectionReuseStrategy() { + String s = System.getProperty("http.keepAlive"); + if ("true".equalsIgnoreCase(s)) { + return new DefaultConnectionReuseStrategy(); + } else { + return new NoConnectionReuseStrategy(); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/TargetAuthenticationStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/TargetAuthenticationStrategy.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/TargetAuthenticationStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,48 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import org.apache.http.HttpStatus; +import org.apache.http.annotation.Immutable; +import org.apache.http.auth.AUTH; +import org.apache.http.auth.params.AuthPNames; +import org.apache.http.client.AuthenticationStrategy; + +/** + * Default {@link AuthenticationStrategy} implementation for proxy host authentication. + * + * @since 4.2 + */ +@Immutable +public class TargetAuthenticationStrategy extends AuthenticationStrategyImpl { + + public TargetAuthenticationStrategy() { + super(HttpStatus.SC_UNAUTHORIZED, AUTH.WWW_AUTH, AuthPNames.TARGET_AUTH_PREF); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/TunnelRefusedException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/TunnelRefusedException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/TunnelRefusedException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,56 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.client; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; + +/** + * Signals that the tunnel request was rejected by the proxy host. + * + * @since 4.0 + */ +@Immutable +public class TunnelRefusedException extends HttpException { + + private static final long serialVersionUID = -8646722842745617323L; + + private final HttpResponse response; + + public TunnelRefusedException(final String message, final HttpResponse response) { + super(message); + this.response = response; + } + + public HttpResponse getResponse() { + return this.response; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/client/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/client/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/client/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Default implementations for interfaces in +{@link org.apache.http.auth org.apache.http.client}. + + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/AbstractClientConnAdapter.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/AbstractClientConnAdapter.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/AbstractClientConnAdapter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,351 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.InetAddress; +import java.net.Socket; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSession; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpConnectionMetrics; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.conn.ManagedClientConnection; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.protocol.HttpContext; + +/** + * Abstract adapter from {@link OperatedClientConnection operated} to + * {@link ManagedClientConnection managed} client connections. + * Read and write methods are delegated to the wrapped connection. + * Operations affecting the connection state have to be implemented + * by derived classes. Operations for querying the connection state + * are delegated to the wrapped connection if there is one, or + * return a default value if there is none. + *

+ * This adapter tracks the checkpoints for reusable communication states, + * as indicated by {@link #markReusable markReusable} and queried by + * {@link #isMarkedReusable isMarkedReusable}. + * All send and receive operations will automatically clear the mark. + *

+ * Connection release calls are delegated to the connection manager, + * if there is one. {@link #abortConnection abortConnection} will + * clear the reusability mark first. The connection manager is + * expected to tolerate multiple calls to the release method. + * + * @since 4.0 + * + * @deprecated (4.2) do not use + */ +@Deprecated +@NotThreadSafe +public abstract class AbstractClientConnAdapter implements ManagedClientConnection, HttpContext { + + /** + * The connection manager. + */ + private final ClientConnectionManager connManager; + + /** The wrapped connection. */ + private volatile OperatedClientConnection wrappedConnection; + + /** The reusability marker. */ + private volatile boolean markedReusable; + + /** True if the connection has been shut down or released. */ + private volatile boolean released; + + /** The duration this is valid for while idle (in ms). */ + private volatile long duration; + + /** + * Creates a new connection adapter. + * The adapter is initially not + * {@link #isMarkedReusable marked} as reusable. + * + * @param mgr the connection manager, or null + * @param conn the connection to wrap, or null + */ + protected AbstractClientConnAdapter(ClientConnectionManager mgr, + OperatedClientConnection conn) { + super(); + connManager = mgr; + wrappedConnection = conn; + markedReusable = false; + released = false; + duration = Long.MAX_VALUE; + } + + /** + * Detaches this adapter from the wrapped connection. + * This adapter becomes useless. + */ + protected synchronized void detach() { + wrappedConnection = null; + duration = Long.MAX_VALUE; + } + + protected OperatedClientConnection getWrappedConnection() { + return wrappedConnection; + } + + protected ClientConnectionManager getManager() { + return connManager; + } + + /** + * @deprecated (4.1) use {@link #assertValid(OperatedClientConnection)} + */ + protected final void assertNotAborted() throws InterruptedIOException { + if (isReleased()) { + throw new InterruptedIOException("Connection has been shut down"); + } + } + + /** + * @since 4.1 + * @return value of released flag + */ + protected boolean isReleased() { + return released; + } + + /** + * Asserts that there is a valid wrapped connection to delegate to. + * + * @throws ConnectionShutdownException if there is no wrapped connection + * or connection has been aborted + */ + protected final void assertValid( + final OperatedClientConnection wrappedConn) throws ConnectionShutdownException { + if (isReleased() || wrappedConn == null) { + throw new ConnectionShutdownException(); + } + } + + public boolean isOpen() { + OperatedClientConnection conn = getWrappedConnection(); + if (conn == null) + return false; + + return conn.isOpen(); + } + + public boolean isStale() { + if (isReleased()) + return true; + OperatedClientConnection conn = getWrappedConnection(); + if (conn == null) + return true; + + return conn.isStale(); + } + + public void setSocketTimeout(int timeout) { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + conn.setSocketTimeout(timeout); + } + + public int getSocketTimeout() { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + return conn.getSocketTimeout(); + } + + public HttpConnectionMetrics getMetrics() { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + return conn.getMetrics(); + } + + public void flush() throws IOException { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + conn.flush(); + } + + public boolean isResponseAvailable(int timeout) throws IOException { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + return conn.isResponseAvailable(timeout); + } + + public void receiveResponseEntity(HttpResponse response) + throws HttpException, IOException { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + unmarkReusable(); + conn.receiveResponseEntity(response); + } + + public HttpResponse receiveResponseHeader() + throws HttpException, IOException { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + unmarkReusable(); + return conn.receiveResponseHeader(); + } + + public void sendRequestEntity(HttpEntityEnclosingRequest request) + throws HttpException, IOException { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + unmarkReusable(); + conn.sendRequestEntity(request); + } + + public void sendRequestHeader(HttpRequest request) + throws HttpException, IOException { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + unmarkReusable(); + conn.sendRequestHeader(request); + } + + public InetAddress getLocalAddress() { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + return conn.getLocalAddress(); + } + + public int getLocalPort() { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + return conn.getLocalPort(); + } + + public InetAddress getRemoteAddress() { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + return conn.getRemoteAddress(); + } + + public int getRemotePort() { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + return conn.getRemotePort(); + } + + public boolean isSecure() { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + return conn.isSecure(); + } + + public SSLSession getSSLSession() { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + if (!isOpen()) + return null; + + SSLSession result = null; + Socket sock = conn.getSocket(); + if (sock instanceof SSLSocket) { + result = ((SSLSocket)sock).getSession(); + } + return result; + } + + public void markReusable() { + markedReusable = true; + } + + public void unmarkReusable() { + markedReusable = false; + } + + public boolean isMarkedReusable() { + return markedReusable; + } + + public void setIdleDuration(long duration, TimeUnit unit) { + if(duration > 0) { + this.duration = unit.toMillis(duration); + } else { + this.duration = -1; + } + } + + public synchronized void releaseConnection() { + if (released) { + return; + } + released = true; + connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS); + } + + public synchronized void abortConnection() { + if (released) { + return; + } + released = true; + unmarkReusable(); + try { + shutdown(); + } catch (IOException ignore) { + } + connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS); + } + + public Object getAttribute(final String id) { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + if (conn instanceof HttpContext) { + return ((HttpContext) conn).getAttribute(id); + } else { + return null; + } + } + + public Object removeAttribute(final String id) { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + if (conn instanceof HttpContext) { + return ((HttpContext) conn).removeAttribute(id); + } else { + return null; + } + } + + public void setAttribute(final String id, final Object obj) { + OperatedClientConnection conn = getWrappedConnection(); + assertValid(conn); + if (conn instanceof HttpContext) { + ((HttpContext) conn).setAttribute(id, obj); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/AbstractPoolEntry.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/AbstractPoolEntry.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/AbstractPoolEntry.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,298 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.io.InterruptedIOException; + +import org.apache.http.HttpHost; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.routing.RouteTracker; +import org.apache.http.conn.ClientConnectionOperator; +import org.apache.http.conn.OperatedClientConnection; + +/** + * A pool entry for use by connection manager implementations. + * Pool entries work in conjunction with an + * {@link AbstractClientConnAdapter adapter}. + * The adapter is handed out to applications that obtain a connection. + * The pool entry stores the underlying connection and tracks the + * {@link HttpRoute route} established. + * The adapter delegates methods for establishing the route to + * its pool entry. + *

+ * If the managed connections is released or revoked, the adapter + * gets disconnected, but the pool entry still contains the + * underlying connection and the established route. + * + * @since 4.0 + * + * @deprecated (4.2) do not use + */ +@Deprecated +public abstract class AbstractPoolEntry { + + /** The connection operator. */ + protected final ClientConnectionOperator connOperator; + + /** The underlying connection being pooled or used. */ + protected final OperatedClientConnection connection; + + /** The route for which this entry gets allocated. */ + //@@@ currently accessed from connection manager(s) as attribute + //@@@ avoid that, derived classes should decide whether update is allowed + //@@@ SCCM: yes, TSCCM: no + protected volatile HttpRoute route; + + /** Connection state object */ + protected volatile Object state; + + /** The tracked route, or null before tracking starts. */ + protected volatile RouteTracker tracker; + + + /** + * Creates a new pool entry. + * + * @param connOperator the Connection Operator for this entry + * @param route the planned route for the connection, + * or null + */ + protected AbstractPoolEntry(ClientConnectionOperator connOperator, + HttpRoute route) { + super(); + if (connOperator == null) { + throw new IllegalArgumentException("Connection operator may not be null"); + } + this.connOperator = connOperator; + this.connection = connOperator.createConnection(); + this.route = route; + this.tracker = null; + } + + /** + * Returns the state object associated with this pool entry. + * + * @return The state object + */ + public Object getState() { + return state; + } + + /** + * Assigns a state object to this pool entry. + * + * @param state The state object + */ + public void setState(final Object state) { + this.state = state; + } + + /** + * Opens the underlying connection. + * + * @param route the route along which to open the connection + * @param context the context for opening the connection + * @param params the parameters for opening the connection + * + * @throws IOException in case of a problem + */ + public void open(HttpRoute route, + HttpContext context, HttpParams params) + throws IOException { + + if (route == null) { + throw new IllegalArgumentException + ("Route must not be null."); + } + if (params == null) { + throw new IllegalArgumentException + ("Parameters must not be null."); + } + if ((this.tracker != null) && this.tracker.isConnected()) { + throw new IllegalStateException("Connection already open."); + } + + // - collect the arguments + // - call the operator + // - update the tracking data + // In this order, we can be sure that only a successful + // opening of the connection will be tracked. + + this.tracker = new RouteTracker(route); + final HttpHost proxy = route.getProxyHost(); + + connOperator.openConnection + (this.connection, + (proxy != null) ? proxy : route.getTargetHost(), + route.getLocalAddress(), + context, params); + + RouteTracker localTracker = tracker; // capture volatile + + // If this tracker was reset while connecting, + // fail early. + if (localTracker == null) { + throw new InterruptedIOException("Request aborted"); + } + + if (proxy == null) { + localTracker.connectTarget(this.connection.isSecure()); + } else { + localTracker.connectProxy(proxy, this.connection.isSecure()); + } + + } + + /** + * Tracks tunnelling of the connection to the target. + * The tunnel has to be established outside by sending a CONNECT + * request to the (last) proxy. + * + * @param secure true if the tunnel should be + * considered secure, false otherwise + * @param params the parameters for tunnelling the connection + * + * @throws IOException in case of a problem + */ + public void tunnelTarget(boolean secure, HttpParams params) + throws IOException { + + if (params == null) { + throw new IllegalArgumentException + ("Parameters must not be null."); + } + + if ((this.tracker == null) || !this.tracker.isConnected()) { + throw new IllegalStateException("Connection not open."); + } + if (this.tracker.isTunnelled()) { + throw new IllegalStateException + ("Connection is already tunnelled."); + } + + this.connection.update(null, tracker.getTargetHost(), + secure, params); + this.tracker.tunnelTarget(secure); + } + + /** + * Tracks tunnelling of the connection to a chained proxy. + * The tunnel has to be established outside by sending a CONNECT + * request to the previous proxy. + * + * @param next the proxy to which the tunnel was established. + * See {@link org.apache.http.conn.ManagedClientConnection#tunnelProxy + * ManagedClientConnection.tunnelProxy} + * for details. + * @param secure true if the tunnel should be + * considered secure, false otherwise + * @param params the parameters for tunnelling the connection + * + * @throws IOException in case of a problem + */ + public void tunnelProxy(HttpHost next, boolean secure, HttpParams params) + throws IOException { + + if (next == null) { + throw new IllegalArgumentException + ("Next proxy must not be null."); + } + if (params == null) { + throw new IllegalArgumentException + ("Parameters must not be null."); + } + + //@@@ check for proxy in planned route? + if ((this.tracker == null) || !this.tracker.isConnected()) { + throw new IllegalStateException("Connection not open."); + } + + this.connection.update(null, next, secure, params); + this.tracker.tunnelProxy(next, secure); + } + + /** + * Layers a protocol on top of an established tunnel. + * + * @param context the context for layering + * @param params the parameters for layering + * + * @throws IOException in case of a problem + */ + public void layerProtocol(HttpContext context, HttpParams params) + throws IOException { + + //@@@ is context allowed to be null? depends on operator? + if (params == null) { + throw new IllegalArgumentException + ("Parameters must not be null."); + } + + if ((this.tracker == null) || !this.tracker.isConnected()) { + throw new IllegalStateException("Connection not open."); + } + if (!this.tracker.isTunnelled()) { + //@@@ allow this? + throw new IllegalStateException + ("Protocol layering without a tunnel not supported."); + } + if (this.tracker.isLayered()) { + throw new IllegalStateException + ("Multiple protocol layering not supported."); + } + + // - collect the arguments + // - call the operator + // - update the tracking data + // In this order, we can be sure that only a successful + // layering on top of the connection will be tracked. + + final HttpHost target = tracker.getTargetHost(); + + connOperator.updateSecureConnection(this.connection, target, + context, params); + + this.tracker.layerProtocol(this.connection.isSecure()); + + } + + /** + * Shuts down the entry. + * + * If {@link #open(HttpRoute, HttpContext, HttpParams)} is in progress, + * this will cause that open to possibly throw an {@link IOException}. + */ + protected void shutdownEntry() { + tracker = null; + state = null; + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/AbstractPooledConnAdapter.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/AbstractPooledConnAdapter.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/AbstractPooledConnAdapter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,183 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; + +import org.apache.http.HttpHost; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.OperatedClientConnection; + +/** + * Abstract adapter from pool {@link AbstractPoolEntry entries} to + * {@link org.apache.http.conn.ManagedClientConnection managed} + * client connections. + * The connection in the pool entry is used to initialize the base class. + * In addition, methods to establish a route are delegated to the + * pool entry. {@link #shutdown shutdown} and {@link #close close} + * will clear the tracked route in the pool entry and call the + * respective method of the wrapped connection. + * + * @since 4.0 + * + * @deprecated (4.2) do not use + */ +@Deprecated +public abstract class AbstractPooledConnAdapter extends AbstractClientConnAdapter { + + /** The wrapped pool entry. */ + protected volatile AbstractPoolEntry poolEntry; + + /** + * Creates a new connection adapter. + * + * @param manager the connection manager + * @param entry the pool entry for the connection being wrapped + */ + protected AbstractPooledConnAdapter(ClientConnectionManager manager, + AbstractPoolEntry entry) { + super(manager, entry.connection); + this.poolEntry = entry; + } + + /** + * Obtains the pool entry. + * + * @return the pool entry, or null if detached + * + * @deprecated (4.0.1) + */ + protected AbstractPoolEntry getPoolEntry() { + return this.poolEntry; + } + + /** + * Asserts that there is a valid pool entry. + * + * @throws ConnectionShutdownException if there is no pool entry + * or connection has been aborted + * + * @see #assertValid(OperatedClientConnection) + */ + protected void assertValid(final AbstractPoolEntry entry) { + if (isReleased() || entry == null) { + throw new ConnectionShutdownException(); + } + } + + /** + * @deprecated (4.1) use {@link #assertValid(AbstractPoolEntry)} + */ + protected final void assertAttached() { + if (poolEntry == null) { + throw new ConnectionShutdownException(); + } + } + + /** + * Detaches this adapter from the wrapped connection. + * This adapter becomes useless. + */ + @Override + protected synchronized void detach() { + poolEntry = null; + super.detach(); + } + + public HttpRoute getRoute() { + AbstractPoolEntry entry = getPoolEntry(); + assertValid(entry); + return (entry.tracker == null) ? null : entry.tracker.toRoute(); + } + + public void open(HttpRoute route, + HttpContext context, HttpParams params) + throws IOException { + AbstractPoolEntry entry = getPoolEntry(); + assertValid(entry); + entry.open(route, context, params); + } + + public void tunnelTarget(boolean secure, HttpParams params) + throws IOException { + AbstractPoolEntry entry = getPoolEntry(); + assertValid(entry); + entry.tunnelTarget(secure, params); + } + + public void tunnelProxy(HttpHost next, boolean secure, HttpParams params) + throws IOException { + AbstractPoolEntry entry = getPoolEntry(); + assertValid(entry); + entry.tunnelProxy(next, secure, params); + } + + public void layerProtocol(HttpContext context, HttpParams params) + throws IOException { + AbstractPoolEntry entry = getPoolEntry(); + assertValid(entry); + entry.layerProtocol(context, params); + } + + public void close() throws IOException { + AbstractPoolEntry entry = getPoolEntry(); + if (entry != null) + entry.shutdownEntry(); + + OperatedClientConnection conn = getWrappedConnection(); + if (conn != null) { + conn.close(); + } + } + + public void shutdown() throws IOException { + AbstractPoolEntry entry = getPoolEntry(); + if (entry != null) + entry.shutdownEntry(); + + OperatedClientConnection conn = getWrappedConnection(); + if (conn != null) { + conn.shutdown(); + } + } + + public Object getState() { + AbstractPoolEntry entry = getPoolEntry(); + assertValid(entry); + return entry.getState(); + } + + public void setState(final Object state) { + AbstractPoolEntry entry = getPoolEntry(); + assertValid(entry); + entry.setState(state); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/BasicClientConnectionManager.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/BasicClientConnectionManager.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/BasicClientConnectionManager.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,275 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.annotation.GuardedBy; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionOperator; +import org.apache.http.conn.ClientConnectionRequest; +import org.apache.http.conn.ManagedClientConnection; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.scheme.SchemeRegistry; + +/** + * A connection manager for a single connection. This connection manager maintains only one active + * connection at a time. Even though this class is thread-safe it ought to be used by one execution + * thread only. + *

+ * BasicClientConnManager will make an effort to reuse the connection for subsequent requests + * with the same {@link HttpRoute route}. It will, however, close the existing connection and + * open it for the given route, if the route of the persistent connection does not match that + * of the connection request. If the connection has been already been allocated + * {@link IllegalStateException} is thrown. + *

+ * This connection manager implementation can be used inside a EJB container instead of + * {@link PoolingClientConnectionManager}. + * + * @since 4.2 + */ +@ThreadSafe +public class BasicClientConnectionManager implements ClientConnectionManager { + + private final Log log = LogFactory.getLog(getClass()); + + private static final AtomicLong COUNTER = new AtomicLong(); + + /** The message to be logged on multiple allocation. */ + public final static String MISUSE_MESSAGE = + "Invalid use of BasicClientConnManager: connection still allocated.\n" + + "Make sure to release the connection before allocating another one."; + + /** The schemes supported by this connection manager. */ + private final SchemeRegistry schemeRegistry; + + /** The operator for opening and updating connections. */ + private final ClientConnectionOperator connOperator; + + /** The one and only entry in this pool. */ + @GuardedBy("this") + private HttpPoolEntry poolEntry; + + /** The currently issued managed connection, if any. */ + @GuardedBy("this") + private ManagedClientConnectionImpl conn; + + /** Indicates whether this connection manager is shut down. */ + @GuardedBy("this") + private volatile boolean shutdown; + + /** + * Creates a new simple connection manager. + * + * @param schreg the scheme registry + */ + public BasicClientConnectionManager(final SchemeRegistry schreg) { + if (schreg == null) { + throw new IllegalArgumentException("Scheme registry may not be null"); + } + this.schemeRegistry = schreg; + this.connOperator = createConnectionOperator(schreg); + } + + public BasicClientConnectionManager() { + this(SchemeRegistryFactory.createDefault()); + } + + @Override + protected void finalize() throws Throwable { + try { + shutdown(); + } finally { // Make sure we call overridden method even if shutdown barfs + super.finalize(); + } + } + + public SchemeRegistry getSchemeRegistry() { + return this.schemeRegistry; + } + + protected ClientConnectionOperator createConnectionOperator(final SchemeRegistry schreg) { + return new DefaultClientConnectionOperator(schreg); + } + + public final ClientConnectionRequest requestConnection( + final HttpRoute route, + final Object state) { + + return new ClientConnectionRequest() { + + public void abortRequest() { + // Nothing to abort, since requests are immediate. + } + + public ManagedClientConnection getConnection( + long timeout, TimeUnit tunit) { + return BasicClientConnectionManager.this.getConnection( + route, state); + } + + }; + } + + private void assertNotShutdown() { + if (this.shutdown) { + throw new IllegalStateException("Connection manager has been shut down"); + } + } + + ManagedClientConnection getConnection(final HttpRoute route, final Object state) { + if (route == null) { + throw new IllegalArgumentException("Route may not be null."); + } + assertNotShutdown(); + if (this.log.isDebugEnabled()) { + this.log.debug("Get connection for route " + route); + } + synchronized (this) { + if (this.conn != null) { + throw new IllegalStateException(MISUSE_MESSAGE); + } + if (this.poolEntry != null && !this.poolEntry.getPlannedRoute().equals(route)) { + this.poolEntry.close(); + this.poolEntry = null; + } + if (this.poolEntry == null) { + String id = Long.toString(COUNTER.getAndIncrement()); + OperatedClientConnection conn = this.connOperator.createConnection(); + this.poolEntry = new HttpPoolEntry(this.log, id, route, conn, 0, TimeUnit.MILLISECONDS); + } + long now = System.currentTimeMillis(); + if (this.poolEntry.isExpired(now)) { + this.poolEntry.close(); + this.poolEntry.getTracker().reset(); + } + this.conn = new ManagedClientConnectionImpl(this, this.connOperator, this.poolEntry); + return this.conn; + } + } + + public void releaseConnection(final ManagedClientConnection conn, long keepalive, TimeUnit tunit) { + assertNotShutdown(); + if (!(conn instanceof ManagedClientConnectionImpl)) { + throw new IllegalArgumentException("Connection class mismatch, " + + "connection not obtained from this manager"); + } + if (this.log.isDebugEnabled()) { + this.log.debug("Releasing connection " + conn); + } + ManagedClientConnectionImpl managedConn = (ManagedClientConnectionImpl) conn; + synchronized (managedConn) { + if (managedConn.getPoolEntry() == null) { + return; // already released + } + ClientConnectionManager manager = managedConn.getManager(); + if (manager != null && manager != this) { + throw new IllegalStateException("Connection not obtained from this manager"); + } + synchronized (this) { + try { + if (managedConn.isOpen() && !managedConn.isMarkedReusable()) { + try { + managedConn.shutdown(); + } catch (IOException iox) { + if (this.log.isDebugEnabled()) { + this.log.debug("I/O exception shutting down released connection", iox); + } + } + } + this.poolEntry.updateExpiry(keepalive, tunit != null ? tunit : TimeUnit.MILLISECONDS); + if (this.log.isDebugEnabled()) { + String s; + if (keepalive > 0) { + s = "for " + keepalive + " " + tunit; + } else { + s = "indefinitely"; + } + this.log.debug("Connection can be kept alive " + s); + } + } finally { + managedConn.detach(); + this.conn = null; + if (this.poolEntry.isClosed()) { + this.poolEntry = null; + } + } + } + } + } + + public void closeExpiredConnections() { + assertNotShutdown(); + synchronized (this) { + long now = System.currentTimeMillis(); + if (this.poolEntry != null && this.poolEntry.isExpired(now)) { + this.poolEntry.close(); + this.poolEntry.getTracker().reset(); + } + } + } + + public void closeIdleConnections(long idletime, TimeUnit tunit) { + if (tunit == null) { + throw new IllegalArgumentException("Time unit must not be null."); + } + assertNotShutdown(); + synchronized (this) { + long time = tunit.toMillis(idletime); + if (time < 0) { + time = 0; + } + long deadline = System.currentTimeMillis() - time; + if (this.poolEntry != null && this.poolEntry.getUpdated() <= deadline) { + this.poolEntry.close(); + this.poolEntry.getTracker().reset(); + } + } + } + + public void shutdown() { + this.shutdown = true; + synchronized (this) { + try { + if (this.poolEntry != null) { + this.poolEntry.close(); + } + } finally { + this.poolEntry = null; + this.conn = null; + } + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/ConnectionShutdownException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/ConnectionShutdownException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/ConnectionShutdownException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,50 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import org.apache.http.annotation.Immutable; + +/** + * Signals that the connection has been shut down or released back to the + * the connection pool + * + * @since 4.1 + */ +@Immutable +public class ConnectionShutdownException extends IllegalStateException { + + private static final long serialVersionUID = 5868657401162844497L; + + /** + * Creates a new ConnectionShutdownException with a null detail message. + */ + public ConnectionShutdownException() { + super(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultClientConnection.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultClientConnection.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultClientConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,293 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.Socket; +import java.util.HashMap; +import java.util.Map; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.Header; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseFactory; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.HttpContext; +import org.apache.http.impl.SocketHttpClientConnection; +import org.apache.http.io.HttpMessageParser; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.io.SessionOutputBuffer; + +import org.apache.http.conn.OperatedClientConnection; + +/** + * Default implementation of an operated client connection. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
  • + *
  • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
  • + *
+ * + * @since 4.0 + */ +@NotThreadSafe // connSecure, targetHost +public class DefaultClientConnection extends SocketHttpClientConnection + implements OperatedClientConnection, HttpContext { + + private final Log log = LogFactory.getLog(getClass()); + private final Log headerLog = LogFactory.getLog("org.apache.http.headers"); + private final Log wireLog = LogFactory.getLog("org.apache.http.wire"); + + /** The unconnected socket */ + private volatile Socket socket; + + /** The target host of this connection. */ + private HttpHost targetHost; + + /** Whether this connection is secure. */ + private boolean connSecure; + + /** True if this connection was shutdown. */ + private volatile boolean shutdown; + + /** connection specific attributes */ + private final Map attributes; + + public DefaultClientConnection() { + super(); + this.attributes = new HashMap(); + } + + public final HttpHost getTargetHost() { + return this.targetHost; + } + + public final boolean isSecure() { + return this.connSecure; + } + + @Override + public final Socket getSocket() { + return this.socket; + } + + public void opening(Socket sock, HttpHost target) throws IOException { + assertNotOpen(); + this.socket = sock; + this.targetHost = target; + + // Check for shutdown after assigning socket, so that + if (this.shutdown) { + sock.close(); // allow this to throw... + // ...but if it doesn't, explicitly throw one ourselves. + throw new InterruptedIOException("Connection already shutdown"); + } + } + + public void openCompleted(boolean secure, HttpParams params) throws IOException { + assertNotOpen(); + if (params == null) { + throw new IllegalArgumentException + ("Parameters must not be null."); + } + this.connSecure = secure; + bind(this.socket, params); + } + + /** + * Force-closes this connection. + * If the connection is still in the process of being open (the method + * {@link #opening opening} was already called but + * {@link #openCompleted openCompleted} was not), the associated + * socket that is being connected to a remote address will be closed. + * That will interrupt a thread that is blocked on connecting + * the socket. + * If the connection is not yet open, this will prevent the connection + * from being opened. + * + * @throws IOException in case of a problem + */ + @Override + public void shutdown() throws IOException { + shutdown = true; + try { + super.shutdown(); + if (log.isDebugEnabled()) { + log.debug("Connection " + this + " shut down"); + } + Socket sock = this.socket; // copy volatile attribute + if (sock != null) + sock.close(); + } catch (IOException ex) { + log.debug("I/O error shutting down connection", ex); + } + } + + @Override + public void close() throws IOException { + try { + super.close(); + if (log.isDebugEnabled()) { + log.debug("Connection " + this + " closed"); + } + } catch (IOException ex) { + log.debug("I/O error closing connection", ex); + } + } + + @Override + protected SessionInputBuffer createSessionInputBuffer( + final Socket socket, + int buffersize, + final HttpParams params) throws IOException { + if (buffersize == -1) { + buffersize = 8192; + } + SessionInputBuffer inbuffer = super.createSessionInputBuffer( + socket, + buffersize, + params); + if (wireLog.isDebugEnabled()) { + inbuffer = new LoggingSessionInputBuffer( + inbuffer, + new Wire(wireLog), + HttpProtocolParams.getHttpElementCharset(params)); + } + return inbuffer; + } + + @Override + protected SessionOutputBuffer createSessionOutputBuffer( + final Socket socket, + int buffersize, + final HttpParams params) throws IOException { + if (buffersize == -1) { + buffersize = 8192; + } + SessionOutputBuffer outbuffer = super.createSessionOutputBuffer( + socket, + buffersize, + params); + if (wireLog.isDebugEnabled()) { + outbuffer = new LoggingSessionOutputBuffer( + outbuffer, + new Wire(wireLog), + HttpProtocolParams.getHttpElementCharset(params)); + } + return outbuffer; + } + + @Override + protected HttpMessageParser createResponseParser( + final SessionInputBuffer buffer, + final HttpResponseFactory responseFactory, + final HttpParams params) { + // override in derived class to specify a line parser + return new DefaultHttpResponseParser + (buffer, null, responseFactory, params); + } + + public void update(Socket sock, HttpHost target, + boolean secure, HttpParams params) + throws IOException { + + assertOpen(); + if (target == null) { + throw new IllegalArgumentException + ("Target host must not be null."); + } + if (params == null) { + throw new IllegalArgumentException + ("Parameters must not be null."); + } + + if (sock != null) { + this.socket = sock; + bind(sock, params); + } + targetHost = target; + connSecure = secure; + } + + @Override + public HttpResponse receiveResponseHeader() throws HttpException, IOException { + HttpResponse response = super.receiveResponseHeader(); + if (log.isDebugEnabled()) { + log.debug("Receiving response: " + response.getStatusLine()); + } + if (headerLog.isDebugEnabled()) { + headerLog.debug("<< " + response.getStatusLine().toString()); + Header[] headers = response.getAllHeaders(); + for (Header header : headers) { + headerLog.debug("<< " + header.toString()); + } + } + return response; + } + + @Override + public void sendRequestHeader(HttpRequest request) throws HttpException, IOException { + if (log.isDebugEnabled()) { + log.debug("Sending request: " + request.getRequestLine()); + } + super.sendRequestHeader(request); + if (headerLog.isDebugEnabled()) { + headerLog.debug(">> " + request.getRequestLine().toString()); + Header[] headers = request.getAllHeaders(); + for (Header header : headers) { + headerLog.debug(">> " + header.toString()); + } + } + } + + public Object getAttribute(final String id) { + return this.attributes.get(id); + } + + public Object removeAttribute(final String id) { + return this.attributes.remove(id); + } + + public void setAttribute(final String id, final Object obj) { + this.attributes.put(id, obj); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultClientConnectionOperator.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultClientConnectionOperator.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultClientConnectionOperator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,282 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.net.ConnectException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.annotation.ThreadSafe; + +import org.apache.http.HttpHost; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.protocol.HttpContext; + +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.conn.HttpHostConnectException; +import org.apache.http.conn.HttpInetSocketAddress; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.conn.ClientConnectionOperator; +import org.apache.http.conn.scheme.SchemeLayeredSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.scheme.SchemeSocketFactory; + +import org.apache.http.conn.DnsResolver; + +/** + * Default implementation of a {@link ClientConnectionOperator}. It uses a {@link SchemeRegistry} + * to look up {@link SchemeSocketFactory} objects. + *

+ * This connection operator is multihome network aware and will attempt to retry failed connects + * against all known IP addresses sequentially until the connect is successful or all known + * addresses fail to respond. Please note the same + * {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT} value will be used + * for each connection attempt, so in the worst case the total elapsed time before timeout + * can be CONNECTION_TIMEOUT * n where n is the number of IP addresses + * of the given host. One can disable multihome support by overriding + * the {@link #resolveHostname(String)} method and returning only one IP address for the given + * host name. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SO_REUSEADDR}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#CONNECTION_TIMEOUT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • + *
+ * + * @since 4.0 + */ +@ThreadSafe +public class DefaultClientConnectionOperator implements ClientConnectionOperator { + + private final Log log = LogFactory.getLog(getClass()); + + /** The scheme registry for looking up socket factories. */ + protected final SchemeRegistry schemeRegistry; // @ThreadSafe + + /** the custom-configured DNS lookup mechanism. */ + protected final DnsResolver dnsResolver; + + /** + * Creates a new client connection operator for the given scheme registry. + * + * @param schemes the scheme registry + * + * @since 4.2 + */ + public DefaultClientConnectionOperator(final SchemeRegistry schemes) { + if (schemes == null) { + throw new IllegalArgumentException("Scheme registry amy not be null"); + } + this.schemeRegistry = schemes; + this.dnsResolver = new SystemDefaultDnsResolver(); + } + + /** + * Creates a new client connection operator for the given scheme registry + * and the given custom DNS lookup mechanism. + * + * @param schemes + * the scheme registry + * @param dnsResolver + * the custom DNS lookup mechanism + */ + public DefaultClientConnectionOperator(final SchemeRegistry schemes,final DnsResolver dnsResolver) { + if (schemes == null) { + throw new IllegalArgumentException( + "Scheme registry may not be null"); + } + + if(dnsResolver == null){ + throw new IllegalArgumentException("DNS resolver may not be null"); + } + + this.schemeRegistry = schemes; + this.dnsResolver = dnsResolver; + } + + public OperatedClientConnection createConnection() { + return new DefaultClientConnection(); + } + + public void openConnection( + final OperatedClientConnection conn, + final HttpHost target, + final InetAddress local, + final HttpContext context, + final HttpParams params) throws IOException { + if (conn == null) { + throw new IllegalArgumentException("Connection may not be null"); + } + if (target == null) { + throw new IllegalArgumentException("Target host may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + if (conn.isOpen()) { + throw new IllegalStateException("Connection must not be open"); + } + + Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); + SchemeSocketFactory sf = schm.getSchemeSocketFactory(); + + InetAddress[] addresses = resolveHostname(target.getHostName()); + int port = schm.resolvePort(target.getPort()); + for (int i = 0; i < addresses.length; i++) { + InetAddress address = addresses[i]; + boolean last = i == addresses.length - 1; + + Socket sock = sf.createSocket(params); + conn.opening(sock, target); + + InetSocketAddress remoteAddress = new HttpInetSocketAddress(target, address, port); + InetSocketAddress localAddress = null; + if (local != null) { + localAddress = new InetSocketAddress(local, 0); + } + if (this.log.isDebugEnabled()) { + this.log.debug("Connecting to " + remoteAddress); + } + try { + Socket connsock = sf.connectSocket(sock, remoteAddress, localAddress, params); + if (sock != connsock) { + sock = connsock; + conn.opening(sock, target); + } + prepareSocket(sock, context, params); + conn.openCompleted(sf.isSecure(sock), params); + return; + } catch (ConnectException ex) { + if (last) { + throw new HttpHostConnectException(target, ex); + } + } catch (ConnectTimeoutException ex) { + if (last) { + throw ex; + } + } + if (this.log.isDebugEnabled()) { + this.log.debug("Connect to " + remoteAddress + " timed out. " + + "Connection will be retried using another IP address"); + } + } + } + + public void updateSecureConnection( + final OperatedClientConnection conn, + final HttpHost target, + final HttpContext context, + final HttpParams params) throws IOException { + if (conn == null) { + throw new IllegalArgumentException("Connection may not be null"); + } + if (target == null) { + throw new IllegalArgumentException("Target host may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + if (!conn.isOpen()) { + throw new IllegalStateException("Connection must be open"); + } + + final Scheme schm = schemeRegistry.getScheme(target.getSchemeName()); + if (!(schm.getSchemeSocketFactory() instanceof SchemeLayeredSocketFactory)) { + throw new IllegalArgumentException + ("Target scheme (" + schm.getName() + + ") must have layered socket factory."); + } + + SchemeLayeredSocketFactory lsf = (SchemeLayeredSocketFactory) schm.getSchemeSocketFactory(); + Socket sock; + try { + sock = lsf.createLayeredSocket( + conn.getSocket(), target.getHostName(), target.getPort(), params); + } catch (ConnectException ex) { + throw new HttpHostConnectException(target, ex); + } + prepareSocket(sock, context, params); + conn.update(sock, target, lsf.isSecure(sock), params); + } + + /** + * Performs standard initializations on a newly created socket. + * + * @param sock the socket to prepare + * @param context the context for the connection + * @param params the parameters from which to prepare the socket + * + * @throws IOException in case of an IO problem + */ + protected void prepareSocket( + final Socket sock, + final HttpContext context, + final HttpParams params) throws IOException { + sock.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params)); + sock.setSoTimeout(HttpConnectionParams.getSoTimeout(params)); + + int linger = HttpConnectionParams.getLinger(params); + if (linger >= 0) { + sock.setSoLinger(linger > 0, linger); + } + } + + /** + * Resolves the given host name to an array of corresponding IP addresses, based on the + * configured name service on the provided DNS resolver. If one wasn't provided, the system + * configuration is used. + * + * @param host host name to resolve + * @return array of IP addresses + * @exception UnknownHostException if no IP address for the host could be determined. + * + * @see DnsResolver + * @see SystemDefaultDnsResolver + * + * @since 4.1 + */ + protected InetAddress[] resolveHostname(final String host) throws UnknownHostException { + return dnsResolver.resolve(host); + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultHttpResponseParser.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultHttpResponseParser.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultHttpResponseParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,120 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; + +import org.apache.http.annotation.ThreadSafe; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseFactory; +import org.apache.http.NoHttpResponseException; +import org.apache.http.ProtocolException; +import org.apache.http.StatusLine; +import org.apache.http.impl.io.AbstractMessageParser; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.message.LineParser; +import org.apache.http.message.ParserCursor; +import org.apache.http.params.HttpParams; +import org.apache.http.util.CharArrayBuffer; + +/** + * Default HTTP response parser implementation. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • + *
+ * + * @since 4.2 + */ +@ThreadSafe // no public methods +public class DefaultHttpResponseParser extends AbstractMessageParser { + + private final Log log = LogFactory.getLog(getClass()); + + private final HttpResponseFactory responseFactory; + private final CharArrayBuffer lineBuf; + + public DefaultHttpResponseParser( + final SessionInputBuffer buffer, + final LineParser parser, + final HttpResponseFactory responseFactory, + final HttpParams params) { + super(buffer, parser, params); + if (responseFactory == null) { + throw new IllegalArgumentException + ("Response factory may not be null"); + } + this.responseFactory = responseFactory; + this.lineBuf = new CharArrayBuffer(128); + } + + @Override + protected HttpResponse parseHead( + final SessionInputBuffer sessionBuffer) throws IOException, HttpException { + //read out the HTTP status string + int count = 0; + ParserCursor cursor = null; + do { + // clear the buffer + this.lineBuf.clear(); + int i = sessionBuffer.readLine(this.lineBuf); + if (i == -1 && count == 0) { + // The server just dropped connection on us + throw new NoHttpResponseException("The target server failed to respond"); + } + cursor = new ParserCursor(0, this.lineBuf.length()); + if (lineParser.hasProtocolVersion(this.lineBuf, cursor)) { + // Got one + break; + } else if (i == -1 || reject(this.lineBuf, count)) { + // Giving up + throw new ProtocolException("The server failed to respond with a " + + "valid HTTP response"); + } + if (this.log.isDebugEnabled()) { + this.log.debug("Garbage in response: " + this.lineBuf.toString()); + } + count++; + } while(true); + //create the status line from the status string + StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor); + return this.responseFactory.newHttpResponse(statusline, null); + } + + protected boolean reject(CharArrayBuffer line, int count) { + return false; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultHttpRoutePlanner.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultHttpRoutePlanner.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultHttpRoutePlanner.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,129 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + + +import java.net.InetAddress; + +import org.apache.http.annotation.ThreadSafe; + +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.protocol.HttpContext; + +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; + +import org.apache.http.conn.params.ConnRouteParams; + +/** + * Default implementation of an {@link HttpRoutePlanner}. This implementation + * is based on {@link org.apache.http.conn.params.ConnRoutePNames parameters}. + * It will not make use of any Java system properties, nor of system or + * browser proxy settings. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}
  • + *
+ * + * @since 4.0 + */ +@ThreadSafe +public class DefaultHttpRoutePlanner implements HttpRoutePlanner { + + /** The scheme registry. */ + protected final SchemeRegistry schemeRegistry; // class is @ThreadSafe + + /** + * Creates a new default route planner. + * + * @param schreg the scheme registry + */ + public DefaultHttpRoutePlanner(SchemeRegistry schreg) { + if (schreg == null) { + throw new IllegalArgumentException + ("SchemeRegistry must not be null."); + } + schemeRegistry = schreg; + } + + public HttpRoute determineRoute(HttpHost target, + HttpRequest request, + HttpContext context) + throws HttpException { + + if (request == null) { + throw new IllegalStateException + ("Request must not be null."); + } + + // If we have a forced route, we can do without a target. + HttpRoute route = + ConnRouteParams.getForcedRoute(request.getParams()); + if (route != null) + return route; + + // If we get here, there is no forced route. + // So we need a target to compute a route. + + if (target == null) { + throw new IllegalStateException + ("Target host must not be null."); + } + + final InetAddress local = + ConnRouteParams.getLocalAddress(request.getParams()); + final HttpHost proxy = + ConnRouteParams.getDefaultProxy(request.getParams()); + + final Scheme schm; + try { + schm = schemeRegistry.getScheme(target.getSchemeName()); + } catch (IllegalStateException ex) { + throw new HttpException(ex.getMessage()); + } + // as it is typically used for TLS/SSL, we assume that + // a layered scheme implies a secure connection + final boolean secure = schm.isLayered(); + + if (proxy == null) { + route = new HttpRoute(target, local, secure); + } else { + route = new HttpRoute(target, local, proxy, secure); + } + return route; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultResponseParser.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultResponseParser.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/DefaultResponseParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,127 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; + +import org.apache.http.annotation.ThreadSafe; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.HttpResponseFactory; +import org.apache.http.NoHttpResponseException; +import org.apache.http.ProtocolException; +import org.apache.http.StatusLine; +import org.apache.http.impl.io.AbstractMessageParser; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.message.LineParser; +import org.apache.http.message.ParserCursor; +import org.apache.http.params.HttpParams; +import org.apache.http.util.CharArrayBuffer; + +/** + * Default HTTP response parser implementation. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
  • + *
  • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
  • + *
  • {@link org.apache.http.conn.params.ConnConnectionPNames#MAX_STATUS_LINE_GARBAGE}
  • + *
+ * + * @since 4.0 + * + * @deprecated (4.2) use {@link DefaultHttpResponseParser} + */ +@ThreadSafe // no public methods +public class DefaultResponseParser extends AbstractMessageParser { + + private final Log log = LogFactory.getLog(getClass()); + + private final HttpResponseFactory responseFactory; + private final CharArrayBuffer lineBuf; + private final int maxGarbageLines; + + public DefaultResponseParser( + final SessionInputBuffer buffer, + final LineParser parser, + final HttpResponseFactory responseFactory, + final HttpParams params) { + super(buffer, parser, params); + if (responseFactory == null) { + throw new IllegalArgumentException + ("Response factory may not be null"); + } + this.responseFactory = responseFactory; + this.lineBuf = new CharArrayBuffer(128); + this.maxGarbageLines = getMaxGarbageLines(params); + } + + protected int getMaxGarbageLines(final HttpParams params) { + return params.getIntParameter( + org.apache.http.conn.params.ConnConnectionPNames.MAX_STATUS_LINE_GARBAGE, + Integer.MAX_VALUE); + } + + @Override + protected HttpMessage parseHead( + final SessionInputBuffer sessionBuffer) throws IOException, HttpException { + //read out the HTTP status string + int count = 0; + ParserCursor cursor = null; + do { + // clear the buffer + this.lineBuf.clear(); + int i = sessionBuffer.readLine(this.lineBuf); + if (i == -1 && count == 0) { + // The server just dropped connection on us + throw new NoHttpResponseException("The target server failed to respond"); + } + cursor = new ParserCursor(0, this.lineBuf.length()); + if (lineParser.hasProtocolVersion(this.lineBuf, cursor)) { + // Got one + break; + } else if (i == -1 || count >= this.maxGarbageLines) { + // Giving up + throw new ProtocolException("The server failed to respond with a " + + "valid HTTP response"); + } + if (this.log.isDebugEnabled()) { + this.log.debug("Garbage in response: " + this.lineBuf.toString()); + } + count++; + } while(true); + //create the status line from the status string + StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor); + return this.responseFactory.newHttpResponse(statusline, null); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/HttpConnPool.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/HttpConnPool.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/HttpConnPool.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,73 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.commons.logging.Log; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.pool.AbstractConnPool; +import org.apache.http.pool.ConnFactory; + +/** + * @since 4.2 + */ +class HttpConnPool extends AbstractConnPool { + + private static AtomicLong COUNTER = new AtomicLong(); + + private final Log log; + private final long timeToLive; + private final TimeUnit tunit; + + public HttpConnPool(final Log log, + final int defaultMaxPerRoute, final int maxTotal, + final long timeToLive, final TimeUnit tunit) { + super(new InternalConnFactory(), defaultMaxPerRoute, maxTotal); + this.log = log; + this.timeToLive = timeToLive; + this.tunit = tunit; + } + + @Override + protected HttpPoolEntry createEntry(final HttpRoute route, final OperatedClientConnection conn) { + String id = Long.toString(COUNTER.getAndIncrement()); + return new HttpPoolEntry(this.log, id, route, conn, this.timeToLive, this.tunit); + } + + static class InternalConnFactory implements ConnFactory { + + public OperatedClientConnection create(final HttpRoute route) throws IOException { + return new DefaultClientConnection(); + } + + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/HttpPoolEntry.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/HttpPoolEntry.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/HttpPoolEntry.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,95 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.logging.Log; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.routing.RouteTracker; +import org.apache.http.pool.PoolEntry; + +/** + * @since 4.2 + */ +class HttpPoolEntry extends PoolEntry { + + private final Log log; + private final RouteTracker tracker; + + public HttpPoolEntry( + final Log log, + final String id, + final HttpRoute route, + final OperatedClientConnection conn, + final long timeToLive, final TimeUnit tunit) { + super(id, route, conn, timeToLive, tunit); + this.log = log; + this.tracker = new RouteTracker(route); + } + + @Override + public boolean isExpired(long now) { + boolean expired = super.isExpired(now); + if (expired && this.log.isDebugEnabled()) { + this.log.debug("Connection " + this + " expired @ " + new Date(getExpiry())); + } + return expired; + } + + RouteTracker getTracker() { + return this.tracker; + } + + HttpRoute getPlannedRoute() { + return getRoute(); + } + + HttpRoute getEffectiveRoute() { + return this.tracker.toRoute(); + } + + @Override + public boolean isClosed() { + OperatedClientConnection conn = getConnection(); + return !conn.isOpen(); + } + + @Override + public void close() { + OperatedClientConnection conn = getConnection(); + try { + conn.close(); + } catch (IOException ex) { + this.log.debug("I/O error closing connection", ex); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/IdleConnectionHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/IdleConnectionHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/IdleConnectionHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,180 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.HttpConnection; + +// Currently only used by AbstractConnPool +/** + * A helper class for connection managers to track idle connections. + * + *

This class is not synchronized.

+ * + * @see org.apache.http.conn.ClientConnectionManager#closeIdleConnections + * + * @since 4.0 + * + * @deprecated (4.1) no longer used + */ +@Deprecated +public class IdleConnectionHandler { + + private final Log log = LogFactory.getLog(getClass()); + + /** Holds connections and the time they were added. */ + private final Map connectionToTimes; + + + public IdleConnectionHandler() { + super(); + connectionToTimes = new HashMap(); + } + + /** + * Registers the given connection with this handler. The connection will be held until + * {@link #remove} or {@link #closeIdleConnections} is called. + * + * @param connection the connection to add + * + * @see #remove + */ + public void add(HttpConnection connection, long validDuration, TimeUnit unit) { + + long timeAdded = System.currentTimeMillis(); + + if (log.isDebugEnabled()) { + log.debug("Adding connection at: " + timeAdded); + } + + connectionToTimes.put(connection, new TimeValues(timeAdded, validDuration, unit)); + } + + /** + * Removes the given connection from the list of connections to be closed when idle. + * This will return true if the connection is still valid, and false + * if the connection should be considered expired and not used. + * + * @param connection + * @return True if the connection is still valid. + */ + public boolean remove(HttpConnection connection) { + TimeValues times = connectionToTimes.remove(connection); + if(times == null) { + log.warn("Removing a connection that never existed!"); + return true; + } else { + return System.currentTimeMillis() <= times.timeExpires; + } + } + + /** + * Removes all connections referenced by this handler. + */ + public void removeAll() { + this.connectionToTimes.clear(); + } + + /** + * Closes connections that have been idle for at least the given amount of time. + * + * @param idleTime the minimum idle time, in milliseconds, for connections to be closed + */ + public void closeIdleConnections(long idleTime) { + + // the latest time for which connections will be closed + long idleTimeout = System.currentTimeMillis() - idleTime; + + if (log.isDebugEnabled()) { + log.debug("Checking for connections, idle timeout: " + idleTimeout); + } + + for (Entry entry : connectionToTimes.entrySet()) { + HttpConnection conn = entry.getKey(); + TimeValues times = entry.getValue(); + long connectionTime = times.timeAdded; + if (connectionTime <= idleTimeout) { + if (log.isDebugEnabled()) { + log.debug("Closing idle connection, connection time: " + connectionTime); + } + try { + conn.close(); + } catch (IOException ex) { + log.debug("I/O error closing connection", ex); + } + } + } + } + + + public void closeExpiredConnections() { + long now = System.currentTimeMillis(); + if (log.isDebugEnabled()) { + log.debug("Checking for expired connections, now: " + now); + } + + for (Entry entry : connectionToTimes.entrySet()) { + HttpConnection conn = entry.getKey(); + TimeValues times = entry.getValue(); + if(times.timeExpires <= now) { + if (log.isDebugEnabled()) { + log.debug("Closing connection, expired @: " + times.timeExpires); + } + try { + conn.close(); + } catch (IOException ex) { + log.debug("I/O error closing connection", ex); + } + } + } + } + + private static class TimeValues { + private final long timeAdded; + private final long timeExpires; + + /** + * @param now The current time in milliseconds + * @param validDuration The duration this connection is valid for + * @param validUnit The unit of time the duration is specified in. + */ + TimeValues(long now, long validDuration, TimeUnit validUnit) { + this.timeAdded = now; + if(validDuration > 0) { + this.timeExpires = now + validUnit.toMillis(validDuration); + } else { + this.timeExpires = Long.MAX_VALUE; + } + } + } +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/InMemoryDnsResolver.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/InMemoryDnsResolver.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/InMemoryDnsResolver.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,97 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.conn; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.conn.DnsResolver; + +/** + * In-memory DNS resolver implementation. + * + * @since 4.2 + */ +public class InMemoryDnsResolver implements DnsResolver { + + /** Logger associated to this class. */ + private final Log log = LogFactory.getLog(InMemoryDnsResolver.class); + + /** + * In-memory collection that will hold the associations between a host name + * and an array of InetAddress instances. + */ + private Map dnsMap; + + /** + * Builds a DNS resolver that will resolve the host names against a + * collection held in-memory. + */ + public InMemoryDnsResolver() { + dnsMap = new ConcurrentHashMap(); + } + + /** + * Associates the given array of IP addresses to the given host in this DNS overrider. + * The IP addresses are assumed to be already resolved. + * + * @param host + * The host name to be associated with the given IP. + * @param ips + * array of IP addresses to be resolved by this DNS overrider to the given + * host name. + */ + public void add(final String host, final InetAddress... ips) { + if (host == null) { + throw new IllegalArgumentException("Host name may not be null"); + } + if (ips == null) { + throw new IllegalArgumentException("Array of IP addresses may not be null"); + } + dnsMap.put(host, ips); + } + + /** + * {@inheritDoc} + */ + public InetAddress[] resolve(String host) throws UnknownHostException { + InetAddress[] resolvedAddresses = dnsMap.get(host); + if (log.isInfoEnabled()) { + log.info("Resolving " + host + " to " + Arrays.deepToString(resolvedAddresses)); + } + if(resolvedAddresses == null){ + throw new UnknownHostException(host + " cannot be resolved"); + } + return resolvedAddresses; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/LoggingSessionInputBuffer.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/LoggingSessionInputBuffer.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/LoggingSessionInputBuffer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,137 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; + +import org.apache.http.Consts; +import org.apache.http.annotation.Immutable; + +import org.apache.http.io.EofSensor; +import org.apache.http.io.HttpTransportMetrics; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.util.CharArrayBuffer; + +/** + * Logs all data read to the wire LOG. + * + * + * @since 4.0 + */ +@Immutable +public class LoggingSessionInputBuffer implements SessionInputBuffer, EofSensor { + + /** Original session input buffer. */ + private final SessionInputBuffer in; + + private final EofSensor eofSensor; + + /** The wire log to use for writing. */ + private final Wire wire; + + private final String charset; + + /** + * Create an instance that wraps the specified session input buffer. + * @param in The session input buffer. + * @param wire The wire log to use. + * @param charset protocol charset, ASCII if null + */ + public LoggingSessionInputBuffer( + final SessionInputBuffer in, final Wire wire, final String charset) { + super(); + this.in = in; + this.eofSensor = in instanceof EofSensor ? (EofSensor) in : null; + this.wire = wire; + this.charset = charset != null ? charset : Consts.ASCII.name(); + } + + public LoggingSessionInputBuffer(final SessionInputBuffer in, final Wire wire) { + this(in, wire, null); + } + + public boolean isDataAvailable(int timeout) throws IOException { + return this.in.isDataAvailable(timeout); + } + + public int read(byte[] b, int off, int len) throws IOException { + int l = this.in.read(b, off, len); + if (this.wire.enabled() && l > 0) { + this.wire.input(b, off, l); + } + return l; + } + + public int read() throws IOException { + int l = this.in.read(); + if (this.wire.enabled() && l != -1) { + this.wire.input(l); + } + return l; + } + + public int read(byte[] b) throws IOException { + int l = this.in.read(b); + if (this.wire.enabled() && l > 0) { + this.wire.input(b, 0, l); + } + return l; + } + + public String readLine() throws IOException { + String s = this.in.readLine(); + if (this.wire.enabled() && s != null) { + String tmp = s + "\r\n"; + this.wire.input(tmp.getBytes(this.charset)); + } + return s; + } + + public int readLine(final CharArrayBuffer buffer) throws IOException { + int l = this.in.readLine(buffer); + if (this.wire.enabled() && l >= 0) { + int pos = buffer.length() - l; + String s = new String(buffer.buffer(), pos, l); + String tmp = s + "\r\n"; + this.wire.input(tmp.getBytes(this.charset)); + } + return l; + } + + public HttpTransportMetrics getMetrics() { + return this.in.getMetrics(); + } + + public boolean isEof() { + if (this.eofSensor != null) { + return this.eofSensor.isEof(); + } else { + return false; + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/LoggingSessionOutputBuffer.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/LoggingSessionOutputBuffer.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/LoggingSessionOutputBuffer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,119 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; + +import org.apache.http.Consts; +import org.apache.http.annotation.Immutable; + +import org.apache.http.io.HttpTransportMetrics; +import org.apache.http.io.SessionOutputBuffer; +import org.apache.http.util.CharArrayBuffer; + +/** + * Logs all data written to the wire LOG. + * + * + * @since 4.0 + */ +@Immutable +public class LoggingSessionOutputBuffer implements SessionOutputBuffer { + + /** Original data transmitter. */ + private final SessionOutputBuffer out; + + /** The wire log to use. */ + private final Wire wire; + + private final String charset; + + /** + * Create an instance that wraps the specified session output buffer. + * @param out The session output buffer. + * @param wire The Wire log to use. + * @param charset protocol charset, ASCII if null + */ + public LoggingSessionOutputBuffer( + final SessionOutputBuffer out, final Wire wire, final String charset) { + super(); + this.out = out; + this.wire = wire; + this.charset = charset != null ? charset : Consts.ASCII.name(); + } + + public LoggingSessionOutputBuffer(final SessionOutputBuffer out, final Wire wire) { + this(out, wire, null); + } + + public void write(byte[] b, int off, int len) throws IOException { + this.out.write(b, off, len); + if (this.wire.enabled()) { + this.wire.output(b, off, len); + } + } + + public void write(int b) throws IOException { + this.out.write(b); + if (this.wire.enabled()) { + this.wire.output(b); + } + } + + public void write(byte[] b) throws IOException { + this.out.write(b); + if (this.wire.enabled()) { + this.wire.output(b); + } + } + + public void flush() throws IOException { + this.out.flush(); + } + + public void writeLine(final CharArrayBuffer buffer) throws IOException { + this.out.writeLine(buffer); + if (this.wire.enabled()) { + String s = new String(buffer.buffer(), 0, buffer.length()); + String tmp = s + "\r\n"; + this.wire.output(tmp.getBytes(this.charset)); + } + } + + public void writeLine(final String s) throws IOException { + this.out.writeLine(s); + if (this.wire.enabled()) { + String tmp = s + "\r\n"; + this.wire.output(tmp.getBytes(this.charset)); + } + } + + public HttpTransportMetrics getMetrics() { + return this.out.getMetrics(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/ManagedClientConnectionImpl.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/ManagedClientConnectionImpl.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/ManagedClientConnectionImpl.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,468 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.net.InetAddress; +import java.net.Socket; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; + +import org.apache.http.HttpConnectionMetrics; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionOperator; +import org.apache.http.conn.ManagedClientConnection; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.routing.RouteTracker; +import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; + +@NotThreadSafe +class ManagedClientConnectionImpl implements ManagedClientConnection { + + private final ClientConnectionManager manager; + private final ClientConnectionOperator operator; + private volatile HttpPoolEntry poolEntry; + private volatile boolean reusable; + private volatile long duration; + + ManagedClientConnectionImpl( + final ClientConnectionManager manager, + final ClientConnectionOperator operator, + final HttpPoolEntry entry) { + super(); + if (manager == null) { + throw new IllegalArgumentException("Connection manager may not be null"); + } + if (operator == null) { + throw new IllegalArgumentException("Connection operator may not be null"); + } + if (entry == null) { + throw new IllegalArgumentException("HTTP pool entry may not be null"); + } + this.manager = manager; + this.operator = operator; + this.poolEntry = entry; + this.reusable = false; + this.duration = Long.MAX_VALUE; + } + + HttpPoolEntry getPoolEntry() { + return this.poolEntry; + } + + HttpPoolEntry detach() { + HttpPoolEntry local = this.poolEntry; + this.poolEntry = null; + return local; + } + + public ClientConnectionManager getManager() { + return this.manager; + } + + private OperatedClientConnection getConnection() { + HttpPoolEntry local = this.poolEntry; + if (local == null) { + return null; + } + return local.getConnection(); + } + + private OperatedClientConnection ensureConnection() { + HttpPoolEntry local = this.poolEntry; + if (local == null) { + throw new ConnectionShutdownException(); + } + return local.getConnection(); + } + + private HttpPoolEntry ensurePoolEntry() { + HttpPoolEntry local = this.poolEntry; + if (local == null) { + throw new ConnectionShutdownException(); + } + return local; + } + + public void close() throws IOException { + HttpPoolEntry local = this.poolEntry; + if (local != null) { + OperatedClientConnection conn = local.getConnection(); + local.getTracker().reset(); + conn.close(); + } + } + + public void shutdown() throws IOException { + HttpPoolEntry local = this.poolEntry; + if (local != null) { + OperatedClientConnection conn = local.getConnection(); + local.getTracker().reset(); + conn.shutdown(); + } + } + + public boolean isOpen() { + OperatedClientConnection conn = getConnection(); + if (conn != null) { + return conn.isOpen(); + } else { + return false; + } + } + + public boolean isStale() { + OperatedClientConnection conn = getConnection(); + if (conn != null) { + return conn.isStale(); + } else { + return true; + } + } + + public void setSocketTimeout(int timeout) { + OperatedClientConnection conn = ensureConnection(); + conn.setSocketTimeout(timeout); + } + + public int getSocketTimeout() { + OperatedClientConnection conn = ensureConnection(); + return conn.getSocketTimeout(); + } + + public HttpConnectionMetrics getMetrics() { + OperatedClientConnection conn = ensureConnection(); + return conn.getMetrics(); + } + + public void flush() throws IOException { + OperatedClientConnection conn = ensureConnection(); + conn.flush(); + } + + public boolean isResponseAvailable(int timeout) throws IOException { + OperatedClientConnection conn = ensureConnection(); + return conn.isResponseAvailable(timeout); + } + + public void receiveResponseEntity( + final HttpResponse response) throws HttpException, IOException { + OperatedClientConnection conn = ensureConnection(); + conn.receiveResponseEntity(response); + } + + public HttpResponse receiveResponseHeader() throws HttpException, IOException { + OperatedClientConnection conn = ensureConnection(); + return conn.receiveResponseHeader(); + } + + public void sendRequestEntity( + final HttpEntityEnclosingRequest request) throws HttpException, IOException { + OperatedClientConnection conn = ensureConnection(); + conn.sendRequestEntity(request); + } + + public void sendRequestHeader( + final HttpRequest request) throws HttpException, IOException { + OperatedClientConnection conn = ensureConnection(); + conn.sendRequestHeader(request); + } + + public InetAddress getLocalAddress() { + OperatedClientConnection conn = ensureConnection(); + return conn.getLocalAddress(); + } + + public int getLocalPort() { + OperatedClientConnection conn = ensureConnection(); + return conn.getLocalPort(); + } + + public InetAddress getRemoteAddress() { + OperatedClientConnection conn = ensureConnection(); + return conn.getRemoteAddress(); + } + + public int getRemotePort() { + OperatedClientConnection conn = ensureConnection(); + return conn.getRemotePort(); + } + + public boolean isSecure() { + OperatedClientConnection conn = ensureConnection(); + return conn.isSecure(); + } + + public SSLSession getSSLSession() { + OperatedClientConnection conn = ensureConnection(); + SSLSession result = null; + Socket sock = conn.getSocket(); + if (sock instanceof SSLSocket) { + result = ((SSLSocket)sock).getSession(); + } + return result; + } + + public Object getAttribute(final String id) { + OperatedClientConnection conn = ensureConnection(); + if (conn instanceof HttpContext) { + return ((HttpContext) conn).getAttribute(id); + } else { + return null; + } + } + + public Object removeAttribute(final String id) { + OperatedClientConnection conn = ensureConnection(); + if (conn instanceof HttpContext) { + return ((HttpContext) conn).removeAttribute(id); + } else { + return null; + } + } + + public void setAttribute(final String id, final Object obj) { + OperatedClientConnection conn = ensureConnection(); + if (conn instanceof HttpContext) { + ((HttpContext) conn).setAttribute(id, obj); + } + } + + public HttpRoute getRoute() { + HttpPoolEntry local = ensurePoolEntry(); + return local.getEffectiveRoute(); + } + + public void open( + final HttpRoute route, + final HttpContext context, + final HttpParams params) throws IOException { + if (route == null) { + throw new IllegalArgumentException("Route may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + OperatedClientConnection conn; + synchronized (this) { + if (this.poolEntry == null) { + throw new ConnectionShutdownException(); + } + RouteTracker tracker = this.poolEntry.getTracker(); + if (tracker.isConnected()) { + throw new IllegalStateException("Connection already open"); + } + conn = this.poolEntry.getConnection(); + } + + HttpHost proxy = route.getProxyHost(); + this.operator.openConnection( + conn, + (proxy != null) ? proxy : route.getTargetHost(), + route.getLocalAddress(), + context, params); + + synchronized (this) { + if (this.poolEntry == null) { + throw new InterruptedIOException(); + } + RouteTracker tracker = this.poolEntry.getTracker(); + if (proxy == null) { + tracker.connectTarget(conn.isSecure()); + } else { + tracker.connectProxy(proxy, conn.isSecure()); + } + } + } + + public void tunnelTarget( + boolean secure, final HttpParams params) throws IOException { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + HttpHost target; + OperatedClientConnection conn; + synchronized (this) { + if (this.poolEntry == null) { + throw new ConnectionShutdownException(); + } + RouteTracker tracker = this.poolEntry.getTracker(); + if (!tracker.isConnected()) { + throw new IllegalStateException("Connection not open"); + } + if (tracker.isTunnelled()) { + throw new IllegalStateException("Connection is already tunnelled"); + } + target = tracker.getTargetHost(); + conn = this.poolEntry.getConnection(); + } + + conn.update(null, target, secure, params); + + synchronized (this) { + if (this.poolEntry == null) { + throw new InterruptedIOException(); + } + RouteTracker tracker = this.poolEntry.getTracker(); + tracker.tunnelTarget(secure); + } + } + + public void tunnelProxy( + final HttpHost next, boolean secure, final HttpParams params) throws IOException { + if (next == null) { + throw new IllegalArgumentException("Next proxy amy not be null"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + OperatedClientConnection conn; + synchronized (this) { + if (this.poolEntry == null) { + throw new ConnectionShutdownException(); + } + RouteTracker tracker = this.poolEntry.getTracker(); + if (!tracker.isConnected()) { + throw new IllegalStateException("Connection not open"); + } + conn = this.poolEntry.getConnection(); + } + + conn.update(null, next, secure, params); + + synchronized (this) { + if (this.poolEntry == null) { + throw new InterruptedIOException(); + } + RouteTracker tracker = this.poolEntry.getTracker(); + tracker.tunnelProxy(next, secure); + } + } + + public void layerProtocol( + final HttpContext context, final HttpParams params) throws IOException { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + HttpHost target; + OperatedClientConnection conn; + synchronized (this) { + if (this.poolEntry == null) { + throw new ConnectionShutdownException(); + } + RouteTracker tracker = this.poolEntry.getTracker(); + if (!tracker.isConnected()) { + throw new IllegalStateException("Connection not open"); + } + if (!tracker.isTunnelled()) { + throw new IllegalStateException("Protocol layering without a tunnel not supported"); + } + if (tracker.isLayered()) { + throw new IllegalStateException("Multiple protocol layering not supported"); + } + target = tracker.getTargetHost(); + conn = this.poolEntry.getConnection(); + } + this.operator.updateSecureConnection(conn, target, context, params); + + synchronized (this) { + if (this.poolEntry == null) { + throw new InterruptedIOException(); + } + RouteTracker tracker = this.poolEntry.getTracker(); + tracker.layerProtocol(conn.isSecure()); + } + } + + public Object getState() { + HttpPoolEntry local = ensurePoolEntry(); + return local.getState(); + } + + public void setState(final Object state) { + HttpPoolEntry local = ensurePoolEntry(); + local.setState(state); + } + + public void markReusable() { + this.reusable = true; + } + + public void unmarkReusable() { + this.reusable = false; + } + + public boolean isMarkedReusable() { + return this.reusable; + } + + public void setIdleDuration(long duration, TimeUnit unit) { + if(duration > 0) { + this.duration = unit.toMillis(duration); + } else { + this.duration = -1; + } + } + + public void releaseConnection() { + synchronized (this) { + if (this.poolEntry == null) { + return; + } + this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS); + this.poolEntry = null; + } + } + + public void abortConnection() { + synchronized (this) { + if (this.poolEntry == null) { + return; + } + this.reusable = false; + OperatedClientConnection conn = this.poolEntry.getConnection(); + try { + conn.shutdown(); + } catch (IOException ignore) { + } + this.manager.releaseConnection(this, this.duration, TimeUnit.MILLISECONDS); + this.poolEntry = null; + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/PoolingClientConnectionManager.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/PoolingClientConnectionManager.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/PoolingClientConnectionManager.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,338 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionOperator; +import org.apache.http.conn.ClientConnectionRequest; +import org.apache.http.conn.ConnectionPoolTimeoutException; +import org.apache.http.conn.ManagedClientConnection; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.pool.ConnPoolControl; +import org.apache.http.pool.PoolStats; +import org.apache.http.impl.conn.DefaultClientConnectionOperator; +import org.apache.http.impl.conn.SchemeRegistryFactory; +import org.apache.http.conn.DnsResolver; + +/** + * Manages a pool of {@link OperatedClientConnection client connections} and + * is able to service connection requests from multiple execution threads. + * Connections are pooled on a per route basis. A request for a route which + * already the manager has persistent connections for available in the pool + * will be services by leasing a connection from the pool rather than + * creating a brand new connection. + *

+ * PoolingConnectionManager maintains a maximum limit of connection on + * a per route basis and in total. Per default this implementation will + * create no more than than 2 concurrent connections per given route + * and no more 20 connections in total. For many real-world applications + * these limits may prove too constraining, especially if they use HTTP + * as a transport protocol for their services. Connection limits, however, + * can be adjusted using HTTP parameters. + * + * @since 4.2 + */ +@ThreadSafe +public class PoolingClientConnectionManager implements ClientConnectionManager, ConnPoolControl { + + private final Log log = LogFactory.getLog(getClass()); + + private final SchemeRegistry schemeRegistry; + + private final HttpConnPool pool; + + private final ClientConnectionOperator operator; + + /** the custom-configured DNS lookup mechanism. */ + private final DnsResolver dnsResolver; + + public PoolingClientConnectionManager(final SchemeRegistry schreg) { + this(schreg, -1, TimeUnit.MILLISECONDS); + } + + public PoolingClientConnectionManager(final SchemeRegistry schreg,final DnsResolver dnsResolver) { + this(schreg, -1, TimeUnit.MILLISECONDS,dnsResolver); + } + + public PoolingClientConnectionManager() { + this(SchemeRegistryFactory.createDefault()); + } + + public PoolingClientConnectionManager( + final SchemeRegistry schemeRegistry, + final long timeToLive, final TimeUnit tunit) { + this(schemeRegistry, timeToLive, tunit, new SystemDefaultDnsResolver()); + } + + public PoolingClientConnectionManager(final SchemeRegistry schemeRegistry, + final long timeToLive, final TimeUnit tunit, + final DnsResolver dnsResolver) { + super(); + if (schemeRegistry == null) { + throw new IllegalArgumentException("Scheme registry may not be null"); + } + if (dnsResolver == null) { + throw new IllegalArgumentException("DNS resolver may not be null"); + } + this.schemeRegistry = schemeRegistry; + this.dnsResolver = dnsResolver; + this.operator = createConnectionOperator(schemeRegistry); + this.pool = new HttpConnPool(this.log, 2, 20, timeToLive, tunit); + } + + @Override + protected void finalize() throws Throwable { + try { + shutdown(); + } finally { + super.finalize(); + } + } + + /** + * Hook for creating the connection operator. + * It is called by the constructor. + * Derived classes can override this method to change the + * instantiation of the operator. + * The default implementation here instantiates + * {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}. + * + * @param schreg the scheme registry. + * + * @return the connection operator to use + */ + protected ClientConnectionOperator createConnectionOperator(SchemeRegistry schreg) { + return new DefaultClientConnectionOperator(schreg, this.dnsResolver); + } + + public SchemeRegistry getSchemeRegistry() { + return this.schemeRegistry; + } + + private String format(final HttpRoute route, final Object state) { + StringBuilder buf = new StringBuilder(); + buf.append("[route: ").append(route).append("]"); + if (state != null) { + buf.append("[state: ").append(state).append("]"); + } + return buf.toString(); + } + + private String formatStats(final HttpRoute route) { + StringBuilder buf = new StringBuilder(); + PoolStats totals = this.pool.getTotalStats(); + PoolStats stats = this.pool.getStats(route); + buf.append("[total kept alive: ").append(totals.getAvailable()).append("; "); + buf.append("route allocated: ").append(stats.getLeased() + stats.getAvailable()); + buf.append(" of ").append(stats.getMax()).append("; "); + buf.append("total allocated: ").append(totals.getLeased() + totals.getAvailable()); + buf.append(" of ").append(totals.getMax()).append("]"); + return buf.toString(); + } + + private String format(final HttpPoolEntry entry) { + StringBuilder buf = new StringBuilder(); + buf.append("[id: ").append(entry.getId()).append("]"); + buf.append("[route: ").append(entry.getRoute()).append("]"); + Object state = entry.getState(); + if (state != null) { + buf.append("[state: ").append(state).append("]"); + } + return buf.toString(); + } + + public ClientConnectionRequest requestConnection( + final HttpRoute route, + final Object state) { + if (route == null) { + throw new IllegalArgumentException("HTTP route may not be null"); + } + if (this.log.isDebugEnabled()) { + this.log.debug("Connection request: " + format(route, state) + formatStats(route)); + } + final Future future = this.pool.lease(route, state); + + return new ClientConnectionRequest() { + + public void abortRequest() { + future.cancel(true); + } + + public ManagedClientConnection getConnection( + final long timeout, + final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException { + return leaseConnection(future, timeout, tunit); + } + + }; + + } + + ManagedClientConnection leaseConnection( + final Future future, + final long timeout, + final TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException { + HttpPoolEntry entry; + try { + entry = future.get(timeout, tunit); + if (entry == null || future.isCancelled()) { + throw new InterruptedException(); + } + if (entry.getConnection() == null) { + throw new IllegalStateException("Pool entry with no connection"); + } + if (this.log.isDebugEnabled()) { + this.log.debug("Connection leased: " + format(entry) + formatStats(entry.getRoute())); + } + return new ManagedClientConnectionImpl(this, this.operator, entry); + } catch (ExecutionException ex) { + Throwable cause = ex.getCause(); + if (cause == null) { + cause = ex; + } + this.log.error("Unexpected exception leasing connection from pool", cause); + // Should never happen + throw new InterruptedException(); + } catch (TimeoutException ex) { + throw new ConnectionPoolTimeoutException("Timeout waiting for connection"); + } + } + + public void releaseConnection( + final ManagedClientConnection conn, final long keepalive, final TimeUnit tunit) { + + if (!(conn instanceof ManagedClientConnectionImpl)) { + throw new IllegalArgumentException + ("Connection class mismatch, " + + "connection not obtained from this manager."); + } + ManagedClientConnectionImpl managedConn = (ManagedClientConnectionImpl) conn; + if (managedConn.getManager() != this) { + throw new IllegalStateException("Connection not obtained from this manager."); + } + + synchronized (managedConn) { + HttpPoolEntry entry = managedConn.detach(); + if (entry == null) { + return; + } + try { + if (managedConn.isOpen() && !managedConn.isMarkedReusable()) { + try { + managedConn.shutdown(); + } catch (IOException iox) { + if (this.log.isDebugEnabled()) { + this.log.debug("I/O exception shutting down released connection", iox); + } + } + } + entry.updateExpiry(keepalive, tunit != null ? tunit : TimeUnit.MILLISECONDS); + if (this.log.isDebugEnabled()) { + String s; + if (keepalive > 0) { + s = "for " + keepalive + " " + tunit; + } else { + s = "indefinitely"; + } + this.log.debug("Connection " + format(entry) + " can be kept alive " + s); + } + } finally { + this.pool.release(entry, managedConn.isMarkedReusable()); + } + if (this.log.isDebugEnabled()) { + this.log.debug("Connection released: " + format(entry) + formatStats(entry.getRoute())); + } + } + } + + public void shutdown() { + this.log.debug("Connection manager is shutting down"); + try { + this.pool.shutdown(); + } catch (IOException ex) { + this.log.debug("I/O exception shutting down connection manager", ex); + } + this.log.debug("Connection manager shut down"); + } + + public void closeIdleConnections(long idleTimeout, TimeUnit tunit) { + if (this.log.isDebugEnabled()) { + this.log.debug("Closing connections idle longer than " + idleTimeout + " " + tunit); + } + this.pool.closeIdle(idleTimeout, tunit); + } + + public void closeExpiredConnections() { + this.log.debug("Closing expired connections"); + this.pool.closeExpired(); + } + + public int getMaxTotal() { + return this.pool.getMaxTotal(); + } + + public void setMaxTotal(int max) { + this.pool.setMaxTotal(max); + } + + public int getDefaultMaxPerRoute() { + return this.pool.getDefaultMaxPerRoute(); + } + + public void setDefaultMaxPerRoute(int max) { + this.pool.setDefaultMaxPerRoute(max); + } + + public int getMaxPerRoute(final HttpRoute route) { + return this.pool.getMaxPerRoute(route); + } + + public void setMaxPerRoute(final HttpRoute route, int max) { + this.pool.setMaxPerRoute(route, max); + } + + public PoolStats getTotalStats() { + return this.pool.getTotalStats(); + } + + public PoolStats getStats(final HttpRoute route) { + return this.pool.getStats(route); + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/ProxySelectorRoutePlanner.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/ProxySelectorRoutePlanner.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/ProxySelectorRoutePlanner.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,287 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpRequest; +import org.apache.http.protocol.HttpContext; + +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.routing.HttpRoutePlanner; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; + +import org.apache.http.conn.params.ConnRouteParams; + + +/** + * Default implementation of an {@link HttpRoutePlanner}. + * This implementation is based on {@link java.net.ProxySelector}. + * By default, it will pick up the proxy settings of the JVM, either + * from system properties or from the browser running the application. + * Additionally, it interprets some + * {@link org.apache.http.conn.params.ConnRoutePNames parameters}, + * though not the {@link + * org.apache.http.conn.params.ConnRoutePNames#DEFAULT_PROXY DEFAULT_PROXY}. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#LOCAL_ADDRESS}
  • + *
  • {@link org.apache.http.conn.params.ConnRoutePNames#FORCED_ROUTE}
  • + *
+ * + * @since 4.0 + */ +@NotThreadSafe // e.g [gs]etProxySelector() +public class ProxySelectorRoutePlanner implements HttpRoutePlanner { + + /** The scheme registry. */ + protected final SchemeRegistry schemeRegistry; // @ThreadSafe + + /** The proxy selector to use, or null for system default. */ + protected ProxySelector proxySelector; + + /** + * Creates a new proxy selector route planner. + * + * @param schreg the scheme registry + * @param prosel the proxy selector, or + * null for the system default + */ + public ProxySelectorRoutePlanner(SchemeRegistry schreg, + ProxySelector prosel) { + + if (schreg == null) { + throw new IllegalArgumentException + ("SchemeRegistry must not be null."); + } + schemeRegistry = schreg; + proxySelector = prosel; + } + + /** + * Obtains the proxy selector to use. + * + * @return the proxy selector, or null for the system default + */ + public ProxySelector getProxySelector() { + return this.proxySelector; + } + + /** + * Sets the proxy selector to use. + * + * @param prosel the proxy selector, or + * null to use the system default + */ + public void setProxySelector(ProxySelector prosel) { + this.proxySelector = prosel; + } + + public HttpRoute determineRoute(HttpHost target, + HttpRequest request, + HttpContext context) + throws HttpException { + + if (request == null) { + throw new IllegalStateException + ("Request must not be null."); + } + + // If we have a forced route, we can do without a target. + HttpRoute route = + ConnRouteParams.getForcedRoute(request.getParams()); + if (route != null) + return route; + + // If we get here, there is no forced route. + // So we need a target to compute a route. + + if (target == null) { + throw new IllegalStateException + ("Target host must not be null."); + } + + final InetAddress local = + ConnRouteParams.getLocalAddress(request.getParams()); + final HttpHost proxy = determineProxy(target, request, context); + + final Scheme schm = + this.schemeRegistry.getScheme(target.getSchemeName()); + // as it is typically used for TLS/SSL, we assume that + // a layered scheme implies a secure connection + final boolean secure = schm.isLayered(); + + if (proxy == null) { + route = new HttpRoute(target, local, secure); + } else { + route = new HttpRoute(target, local, proxy, secure); + } + return route; + } + + /** + * Determines a proxy for the given target. + * + * @param target the planned target, never null + * @param request the request to be sent, never null + * @param context the context, or null + * + * @return the proxy to use, or null for a direct route + * + * @throws HttpException + * in case of system proxy settings that cannot be handled + */ + protected HttpHost determineProxy(HttpHost target, + HttpRequest request, + HttpContext context) + throws HttpException { + + // the proxy selector can be 'unset', so we better deal with null here + ProxySelector psel = this.proxySelector; + if (psel == null) + psel = ProxySelector.getDefault(); + if (psel == null) + return null; + + URI targetURI = null; + try { + targetURI = new URI(target.toURI()); + } catch (URISyntaxException usx) { + throw new HttpException + ("Cannot convert host to URI: " + target, usx); + } + List proxies = psel.select(targetURI); + + Proxy p = chooseProxy(proxies, target, request, context); + + HttpHost result = null; + if (p.type() == Proxy.Type.HTTP) { + // convert the socket address to an HttpHost + if (!(p.address() instanceof InetSocketAddress)) { + throw new HttpException + ("Unable to handle non-Inet proxy address: "+p.address()); + } + final InetSocketAddress isa = (InetSocketAddress) p.address(); + // assume default scheme (http) + result = new HttpHost(getHost(isa), isa.getPort()); + } + + return result; + } + + /** + * Obtains a host from an {@link InetSocketAddress}. + * + * @param isa the socket address + * + * @return a host string, either as a symbolic name or + * as a literal IP address string + *
+ * (TODO: determine format for IPv6 addresses, with or without [brackets]) + */ + protected String getHost(InetSocketAddress isa) { + + //@@@ Will this work with literal IPv6 addresses, or do we + //@@@ need to wrap these in [] for the string representation? + //@@@ Having it in this method at least allows for easy workarounds. + return isa.isUnresolved() ? + isa.getHostName() : isa.getAddress().getHostAddress(); + + } + + /** + * Chooses a proxy from a list of available proxies. + * The default implementation just picks the first non-SOCKS proxy + * from the list. If there are only SOCKS proxies, + * {@link Proxy#NO_PROXY Proxy.NO_PROXY} is returned. + * Derived classes may implement more advanced strategies, + * such as proxy rotation if there are multiple options. + * + * @param proxies the list of proxies to choose from, + * never null or empty + * @param target the planned target, never null + * @param request the request to be sent, never null + * @param context the context, or null + * + * @return a proxy type + */ + protected Proxy chooseProxy(List proxies, + HttpHost target, + HttpRequest request, + HttpContext context) { + + if ((proxies == null) || proxies.isEmpty()) { + throw new IllegalArgumentException + ("Proxy list must not be empty."); + } + + Proxy result = null; + + // check the list for one we can use + for (int i=0; (result == null) && (i < proxies.size()); i++) { + + Proxy p = proxies.get(i); + switch (p.type()) { + + case DIRECT: + case HTTP: + result = p; + break; + + case SOCKS: + // SOCKS hosts are not handled on the route level. + // The socket may make use of the SOCKS host though. + break; + } + } + + if (result == null) { + //@@@ log as warning or info that only a socks proxy is available? + // result can only be null if all proxies are socks proxies + // socks proxies are not handled on the route planning level + result = Proxy.NO_PROXY; + } + + return result; + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/SchemeRegistryFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/SchemeRegistryFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/SchemeRegistryFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,87 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.conn; + +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; + +/** + * @since 4.1 + */ +@ThreadSafe +public final class SchemeRegistryFactory { + + /** + * Initializes default scheme registry based on JSSE defaults. System properties will + * not be taken into consideration. + */ + public static SchemeRegistry createDefault() { + SchemeRegistry registry = new SchemeRegistry(); + registry.register( + new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); + registry.register( + new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); + return registry; + } + + /** + * Initializes default scheme registry using system properties as described in + * + * "JavaTM Secure Socket Extension (JSSE) Reference Guide for the JavaTM 2 Platform + * Standard Edition 5 + *

+ * The following system properties are taken into account by this method: + *

    + *
  • ssl.TrustManagerFactory.algorithm
  • + *
  • javax.net.ssl.trustStoreType
  • + *
  • javax.net.ssl.trustStore
  • + *
  • javax.net.ssl.trustStoreProvider
  • + *
  • javax.net.ssl.trustStorePassword
  • + *
  • java.home
  • + *
  • ssl.KeyManagerFactory.algorithm
  • + *
  • javax.net.ssl.keyStoreType
  • + *
  • javax.net.ssl.keyStore
  • + *
  • javax.net.ssl.keyStoreProvider
  • + *
  • javax.net.ssl.keyStorePassword
  • + *
+ *

+ * + * @since 4.2 + */ + public static SchemeRegistry createSystemDefault() { + SchemeRegistry registry = new SchemeRegistry(); + registry.register( + new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); + registry.register( + new Scheme("https", 443, SSLSocketFactory.getSystemSocketFactory())); + return registry; + } +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/SingleClientConnManager.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/SingleClientConnManager.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/SingleClientConnManager.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,431 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import org.apache.http.annotation.GuardedBy; +import org.apache.http.annotation.ThreadSafe; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionOperator; +import org.apache.http.conn.ClientConnectionRequest; +import org.apache.http.conn.ManagedClientConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.routing.RouteTracker; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.params.HttpParams; + +/** + * A connection manager for a single connection. This connection manager + * maintains only one active connection at a time. Even though this class + * is thread-safe it ought to be used by one execution thread only. + *

+ * SingleClientConnManager will make an effort to reuse the connection + * for subsequent requests with the same {@link HttpRoute route}. + * It will, however, close the existing connection and open it + * for the given route, if the route of the persistent connection does + * not match that of the connection request. If the connection has been + * already been allocated {@link IllegalStateException} is thrown. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link BasicClientConnectionManager} + */ +@ThreadSafe +@Deprecated +public class SingleClientConnManager implements ClientConnectionManager { + + private final Log log = LogFactory.getLog(getClass()); + + /** The message to be logged on multiple allocation. */ + public final static String MISUSE_MESSAGE = + "Invalid use of SingleClientConnManager: connection still allocated.\n" + + "Make sure to release the connection before allocating another one."; + + /** The schemes supported by this connection manager. */ + protected final SchemeRegistry schemeRegistry; + + /** The operator for opening and updating connections. */ + protected final ClientConnectionOperator connOperator; + + /** Whether the connection should be shut down on release. */ + protected final boolean alwaysShutDown; + + /** The one and only entry in this pool. */ + @GuardedBy("this") + protected volatile PoolEntry uniquePoolEntry; + + /** The currently issued managed connection, if any. */ + @GuardedBy("this") + protected volatile ConnAdapter managedConn; + + /** The time of the last connection release, or -1. */ + @GuardedBy("this") + protected volatile long lastReleaseTime; + + /** The time the last released connection expires and shouldn't be reused. */ + @GuardedBy("this") + protected volatile long connectionExpiresTime; + + /** Indicates whether this connection manager is shut down. */ + protected volatile boolean isShutDown; + + /** + * Creates a new simple connection manager. + * + * @param params the parameters for this manager + * @param schreg the scheme registry + * + * @deprecated (4.1) use {@link SingleClientConnManager#SingleClientConnManager(SchemeRegistry)} + */ + public SingleClientConnManager(HttpParams params, + SchemeRegistry schreg) { + this(schreg); + } + /** + * Creates a new simple connection manager. + * + * @param schreg the scheme registry + */ + public SingleClientConnManager(final SchemeRegistry schreg) { + if (schreg == null) { + throw new IllegalArgumentException + ("Scheme registry must not be null."); + } + this.schemeRegistry = schreg; + this.connOperator = createConnectionOperator(schreg); + this.uniquePoolEntry = new PoolEntry(); + this.managedConn = null; + this.lastReleaseTime = -1L; + this.alwaysShutDown = false; //@@@ from params? as argument? + this.isShutDown = false; + } + + /** + * @since 4.1 + */ + public SingleClientConnManager() { + this(SchemeRegistryFactory.createDefault()); + } + + @Override + protected void finalize() throws Throwable { + try { + shutdown(); + } finally { // Make sure we call overridden method even if shutdown barfs + super.finalize(); + } + } + + public SchemeRegistry getSchemeRegistry() { + return this.schemeRegistry; + } + + /** + * Hook for creating the connection operator. + * It is called by the constructor. + * Derived classes can override this method to change the + * instantiation of the operator. + * The default implementation here instantiates + * {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}. + * + * @param schreg the scheme registry to use, or null + * + * @return the connection operator to use + */ + protected ClientConnectionOperator + createConnectionOperator(SchemeRegistry schreg) { + return new DefaultClientConnectionOperator(schreg); + } + + /** + * Asserts that this manager is not shut down. + * + * @throws IllegalStateException if this manager is shut down + */ + protected final void assertStillUp() throws IllegalStateException { + if (this.isShutDown) + throw new IllegalStateException("Manager is shut down."); + } + + public final ClientConnectionRequest requestConnection( + final HttpRoute route, + final Object state) { + + return new ClientConnectionRequest() { + + public void abortRequest() { + // Nothing to abort, since requests are immediate. + } + + public ManagedClientConnection getConnection( + long timeout, TimeUnit tunit) { + return SingleClientConnManager.this.getConnection( + route, state); + } + + }; + } + + /** + * Obtains a connection. + * + * @param route where the connection should point to + * + * @return a connection that can be used to communicate + * along the given route + */ + public ManagedClientConnection getConnection(HttpRoute route, Object state) { + if (route == null) { + throw new IllegalArgumentException("Route may not be null."); + } + assertStillUp(); + + if (log.isDebugEnabled()) { + log.debug("Get connection for route " + route); + } + + synchronized (this) { + if (managedConn != null) + throw new IllegalStateException(MISUSE_MESSAGE); + + // check re-usability of the connection + boolean recreate = false; + boolean shutdown = false; + + // Kill the connection if it expired. + closeExpiredConnections(); + + if (uniquePoolEntry.connection.isOpen()) { + RouteTracker tracker = uniquePoolEntry.tracker; + shutdown = (tracker == null || // can happen if method is aborted + !tracker.toRoute().equals(route)); + } else { + // If the connection is not open, create a new PoolEntry, + // as the connection may have been marked not reusable, + // due to aborts -- and the PoolEntry should not be reused + // either. There's no harm in recreating an entry if + // the connection is closed. + recreate = true; + } + + if (shutdown) { + recreate = true; + try { + uniquePoolEntry.shutdown(); + } catch (IOException iox) { + log.debug("Problem shutting down connection.", iox); + } + } + + if (recreate) + uniquePoolEntry = new PoolEntry(); + + managedConn = new ConnAdapter(uniquePoolEntry, route); + + return managedConn; + } + } + + public void releaseConnection( + ManagedClientConnection conn, + long validDuration, TimeUnit timeUnit) { + assertStillUp(); + + if (!(conn instanceof ConnAdapter)) { + throw new IllegalArgumentException + ("Connection class mismatch, " + + "connection not obtained from this manager."); + } + + if (log.isDebugEnabled()) { + log.debug("Releasing connection " + conn); + } + + ConnAdapter sca = (ConnAdapter) conn; + synchronized (sca) { + if (sca.poolEntry == null) + return; // already released + ClientConnectionManager manager = sca.getManager(); + if (manager != null && manager != this) { + throw new IllegalArgumentException + ("Connection not obtained from this manager."); + } + try { + // make sure that the response has been read completely + if (sca.isOpen() && (this.alwaysShutDown || + !sca.isMarkedReusable()) + ) { + if (log.isDebugEnabled()) { + log.debug + ("Released connection open but not reusable."); + } + + // make sure this connection will not be re-used + // we might have gotten here because of a shutdown trigger + // shutdown of the adapter also clears the tracked route + sca.shutdown(); + } + } catch (IOException iox) { + if (log.isDebugEnabled()) + log.debug("Exception shutting down released connection.", + iox); + } finally { + sca.detach(); + synchronized (this) { + managedConn = null; + lastReleaseTime = System.currentTimeMillis(); + if(validDuration > 0) + connectionExpiresTime = timeUnit.toMillis(validDuration) + lastReleaseTime; + else + connectionExpiresTime = Long.MAX_VALUE; + } + } + } + } + + public void closeExpiredConnections() { + long time = connectionExpiresTime; + if (System.currentTimeMillis() >= time) { + closeIdleConnections(0, TimeUnit.MILLISECONDS); + } + } + + public void closeIdleConnections(long idletime, TimeUnit tunit) { + assertStillUp(); + + // idletime can be 0 or negative, no problem there + if (tunit == null) { + throw new IllegalArgumentException("Time unit must not be null."); + } + + synchronized (this) { + if ((managedConn == null) && uniquePoolEntry.connection.isOpen()) { + final long cutoff = + System.currentTimeMillis() - tunit.toMillis(idletime); + if (lastReleaseTime <= cutoff) { + try { + uniquePoolEntry.close(); + } catch (IOException iox) { + // ignore + log.debug("Problem closing idle connection.", iox); + } + } + } + } + } + + public void shutdown() { + this.isShutDown = true; + synchronized (this) { + try { + if (uniquePoolEntry != null) // and connection open? + uniquePoolEntry.shutdown(); + } catch (IOException iox) { + // ignore + log.debug("Problem while shutting down manager.", iox); + } finally { + uniquePoolEntry = null; + managedConn = null; + } + } + } + + protected void revokeConnection() { + ConnAdapter conn = managedConn; + if (conn == null) + return; + conn.detach(); + + synchronized (this) { + try { + uniquePoolEntry.shutdown(); + } catch (IOException iox) { + // ignore + log.debug("Problem while shutting down connection.", iox); + } + } + } + + /** + * The pool entry for this connection manager. + */ + protected class PoolEntry extends AbstractPoolEntry { + + /** + * Creates a new pool entry. + * + */ + protected PoolEntry() { + super(SingleClientConnManager.this.connOperator, null); + } + + /** + * Closes the connection in this pool entry. + */ + protected void close() throws IOException { + shutdownEntry(); + if (connection.isOpen()) + connection.close(); + } + + /** + * Shuts down the connection in this pool entry. + */ + protected void shutdown() throws IOException { + shutdownEntry(); + if (connection.isOpen()) + connection.shutdown(); + } + + } + + /** + * The connection adapter used by this manager. + */ + protected class ConnAdapter extends AbstractPooledConnAdapter { + + /** + * Creates a new connection adapter. + * + * @param entry the pool entry for the connection being wrapped + * @param route the planned route for this connection + */ + protected ConnAdapter(PoolEntry entry, HttpRoute route) { + super(SingleClientConnManager.this, entry); + markReusable(); + entry.route = route; + } + + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/SystemDefaultDnsResolver.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/SystemDefaultDnsResolver.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/SystemDefaultDnsResolver.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,48 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.conn; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import org.apache.http.conn.DnsResolver; + +/** + * DNS resolver that uses the default OS implementation for resolving host names. + * + * @since 4.2 + */ +public class SystemDefaultDnsResolver implements DnsResolver { + + /** + * {@inheritDoc} + */ + public InetAddress[] resolve(String host) throws UnknownHostException { + return InetAddress.getAllByName(host); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/Wire.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/Wire.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/Wire.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,167 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ByteArrayInputStream; + +import org.apache.http.annotation.Immutable; + +import org.apache.commons.logging.Log; + +/** + * Logs data to the wire LOG. + * + * + * @since 4.0 + */ +@Immutable +public class Wire { + + private final Log log; + + public Wire(Log log) { + this.log = log; + } + + private void wire(String header, InputStream instream) + throws IOException { + StringBuilder buffer = new StringBuilder(); + int ch; + while ((ch = instream.read()) != -1) { + if (ch == 13) { + buffer.append("[\\r]"); + } else if (ch == 10) { + buffer.append("[\\n]\""); + buffer.insert(0, "\""); + buffer.insert(0, header); + log.debug(buffer.toString()); + buffer.setLength(0); + } else if ((ch < 32) || (ch > 127)) { + buffer.append("[0x"); + buffer.append(Integer.toHexString(ch)); + buffer.append("]"); + } else { + buffer.append((char) ch); + } + } + if (buffer.length() > 0) { + buffer.append('\"'); + buffer.insert(0, '\"'); + buffer.insert(0, header); + log.debug(buffer.toString()); + } + } + + + public boolean enabled() { + return log.isDebugEnabled(); + } + + public void output(InputStream outstream) + throws IOException { + if (outstream == null) { + throw new IllegalArgumentException("Output may not be null"); + } + wire(">> ", outstream); + } + + public void input(InputStream instream) + throws IOException { + if (instream == null) { + throw new IllegalArgumentException("Input may not be null"); + } + wire("<< ", instream); + } + + public void output(byte[] b, int off, int len) + throws IOException { + if (b == null) { + throw new IllegalArgumentException("Output may not be null"); + } + wire(">> ", new ByteArrayInputStream(b, off, len)); + } + + public void input(byte[] b, int off, int len) + throws IOException { + if (b == null) { + throw new IllegalArgumentException("Input may not be null"); + } + wire("<< ", new ByteArrayInputStream(b, off, len)); + } + + public void output(byte[] b) + throws IOException { + if (b == null) { + throw new IllegalArgumentException("Output may not be null"); + } + wire(">> ", new ByteArrayInputStream(b)); + } + + public void input(byte[] b) + throws IOException { + if (b == null) { + throw new IllegalArgumentException("Input may not be null"); + } + wire("<< ", new ByteArrayInputStream(b)); + } + + public void output(int b) + throws IOException { + output(new byte[] {(byte) b}); + } + + public void input(int b) + throws IOException { + input(new byte[] {(byte) b}); + } + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + public void output(final String s) + throws IOException { + if (s == null) { + throw new IllegalArgumentException("Output may not be null"); + } + output(s.getBytes()); + } + + /** + * @deprecated (4.1) do not use + */ + @Deprecated + public void input(final String s) + throws IOException { + if (s == null) { + throw new IllegalArgumentException("Input may not be null"); + } + input(s.getBytes()); + } +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Default implementations for interfaces in +{@link org.apache.http.impl.conn org.apache.http.impl.conn} and related classes. + + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/AbstractConnPool.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/AbstractConnPool.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/AbstractConnPool.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,235 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn.tsccm; + +import java.io.IOException; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.util.Set; +import java.util.HashSet; +import java.util.Iterator; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.apache.http.annotation.GuardedBy; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.conn.ConnectionPoolTimeoutException; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.impl.conn.IdleConnectionHandler; + +/** + * An abstract connection pool. + * It is used by the {@link ThreadSafeClientConnManager}. + * The abstract pool includes a {@link #poolLock}, which is used to + * synchronize access to the internal pool datastructures. + * Don't use synchronized for that purpose! + * + * @since 4.0 + * + * @deprecated (4.2) use {@link org.apache.http.pool.AbstractConnPool} + */ +@Deprecated +public abstract class AbstractConnPool { + + private final Log log; + + /** + * The global lock for this pool. + */ + protected final Lock poolLock; + + /** References to issued connections */ + @GuardedBy("poolLock") + protected Set leasedConnections; + + /** The current total number of connections. */ + @GuardedBy("poolLock") + protected int numConnections; + + /** Indicates whether this pool is shut down. */ + protected volatile boolean isShutDown; + + protected Set issuedConnections; + + protected ReferenceQueue refQueue; + + protected IdleConnectionHandler idleConnHandler; + + /** + * Creates a new connection pool. + */ + protected AbstractConnPool() { + super(); + this.log = LogFactory.getLog(getClass()); + this.leasedConnections = new HashSet(); + this.idleConnHandler = new IdleConnectionHandler(); + this.poolLock = new ReentrantLock(); + } + + public void enableConnectionGC() + throws IllegalStateException { + } + + /** + * Obtains a pool entry with a connection within the given timeout. + * + * @param route the route for which to get the connection + * @param timeout the timeout, 0 or negative for no timeout + * @param tunit the unit for the timeout, + * may be null only if there is no timeout + * + * @return pool entry holding a connection for the route + * + * @throws ConnectionPoolTimeoutException + * if the timeout expired + * @throws InterruptedException + * if the calling thread was interrupted + */ + public final + BasicPoolEntry getEntry( + HttpRoute route, + Object state, + long timeout, + TimeUnit tunit) + throws ConnectionPoolTimeoutException, InterruptedException { + return requestPoolEntry(route, state).getPoolEntry(timeout, tunit); + } + + /** + * Returns a new {@link PoolEntryRequest}, from which a {@link BasicPoolEntry} + * can be obtained, or the request can be aborted. + */ + public abstract PoolEntryRequest requestPoolEntry(HttpRoute route, Object state); + + + /** + * Returns an entry into the pool. + * The connection of the entry is expected to be in a suitable state, + * either open and re-usable, or closed. The pool will not make any + * attempt to determine whether it can be re-used or not. + * + * @param entry the entry for the connection to release + * @param reusable true if the entry is deemed + * reusable, false otherwise. + * @param validDuration The duration that the entry should remain free and reusable. + * @param timeUnit The unit of time the duration is measured in. + */ + public abstract void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit) + ; + + public void handleReference(Reference ref) { + } + + protected abstract void handleLostEntry(HttpRoute route); + + /** + * Closes idle connections. + * + * @param idletime the time the connections should have been idle + * in order to be closed now + * @param tunit the unit for the idletime + */ + public void closeIdleConnections(long idletime, TimeUnit tunit) { + + // idletime can be 0 or negative, no problem there + if (tunit == null) { + throw new IllegalArgumentException("Time unit must not be null."); + } + + poolLock.lock(); + try { + idleConnHandler.closeIdleConnections(tunit.toMillis(idletime)); + } finally { + poolLock.unlock(); + } + } + + public void closeExpiredConnections() { + poolLock.lock(); + try { + idleConnHandler.closeExpiredConnections(); + } finally { + poolLock.unlock(); + } + } + + + /** + * Deletes all entries for closed connections. + */ + public abstract void deleteClosedConnections(); + + /** + * Shuts down this pool and all associated resources. + * Overriding methods MUST call the implementation here! + */ + public void shutdown() { + + poolLock.lock(); + try { + + if (isShutDown) + return; + + // close all connections that are issued to an application + Iterator iter = leasedConnections.iterator(); + while (iter.hasNext()) { + BasicPoolEntry entry = iter.next(); + iter.remove(); + closeConnection(entry.getConnection()); + } + idleConnHandler.removeAll(); + + isShutDown = true; + + } finally { + poolLock.unlock(); + } + } + + + /** + * Closes a connection from this pool. + * + * @param conn the connection to close, or null + */ + protected void closeConnection(final OperatedClientConnection conn) { + if (conn != null) { + try { + conn.close(); + } catch (IOException ex) { + log.debug("I/O error closing connection", ex); + } + } + } + +} // class AbstractConnPool + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/BasicPoolEntry.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/BasicPoolEntry.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/BasicPoolEntry.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,166 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn.tsccm; + +import java.lang.ref.ReferenceQueue; +import java.util.concurrent.TimeUnit; + +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.conn.ClientConnectionOperator; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.impl.conn.AbstractPoolEntry; + +/** + * Basic implementation of a connection pool entry. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link org.apache.http.pool.PoolEntry} + */ +@Deprecated +public class BasicPoolEntry extends AbstractPoolEntry { + + private final long created; + + private long updated; + private long validUntil; + private long expiry; + + public BasicPoolEntry(ClientConnectionOperator op, + HttpRoute route, + ReferenceQueue queue) { + super(op, route); + if (route == null) { + throw new IllegalArgumentException("HTTP route may not be null"); + } + this.created = System.currentTimeMillis(); + this.validUntil = Long.MAX_VALUE; + this.expiry = this.validUntil; + } + + /** + * Creates a new pool entry. + * + * @param op the connection operator + * @param route the planned route for the connection + */ + public BasicPoolEntry(ClientConnectionOperator op, + HttpRoute route) { + this(op, route, -1, TimeUnit.MILLISECONDS); + } + + /** + * Creates a new pool entry with a specified maximum lifetime. + * + * @param op the connection operator + * @param route the planned route for the connection + * @param connTTL maximum lifetime of this entry, <=0 implies "infinity" + * @param timeunit TimeUnit of connTTL + * + * @since 4.1 + */ + public BasicPoolEntry(ClientConnectionOperator op, + HttpRoute route, long connTTL, TimeUnit timeunit) { + super(op, route); + if (route == null) { + throw new IllegalArgumentException("HTTP route may not be null"); + } + this.created = System.currentTimeMillis(); + if (connTTL > 0) { + this.validUntil = this.created + timeunit.toMillis(connTTL); + } else { + this.validUntil = Long.MAX_VALUE; + } + this.expiry = this.validUntil; + } + + protected final OperatedClientConnection getConnection() { + return super.connection; + } + + protected final HttpRoute getPlannedRoute() { + return super.route; + } + + protected final BasicPoolEntryRef getWeakRef() { + return null; + } + + @Override + protected void shutdownEntry() { + super.shutdownEntry(); + } + + /** + * @since 4.1 + */ + public long getCreated() { + return this.created; + } + + /** + * @since 4.1 + */ + public long getUpdated() { + return this.updated; + } + + /** + * @since 4.1 + */ + public long getExpiry() { + return this.expiry; + } + + public long getValidUntil() { + return this.validUntil; + } + + /** + * @since 4.1 + */ + public void updateExpiry(long time, TimeUnit timeunit) { + this.updated = System.currentTimeMillis(); + long newExpiry; + if (time > 0) { + newExpiry = this.updated + timeunit.toMillis(time); + } else { + newExpiry = Long.MAX_VALUE; + } + this.expiry = Math.min(validUntil, newExpiry); + } + + /** + * @since 4.1 + */ + public boolean isExpired(long now) { + return now >= this.expiry; + } + +} + + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/BasicPoolEntryRef.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/BasicPoolEntryRef.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/BasicPoolEntryRef.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,78 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn.tsccm; + +import java.lang.ref.WeakReference; +import java.lang.ref.ReferenceQueue; + +import org.apache.http.conn.routing.HttpRoute; + +/** + * A weak reference to a {@link BasicPoolEntry BasicPoolEntry}. + * This reference explicitly keeps the planned route, so the connection + * can be reclaimed if it is lost to garbage collection. + * + * @since 4.0 + * + * @deprecated (4.2) do not use + */ +@Deprecated +public class BasicPoolEntryRef extends WeakReference { + + /** The planned route of the entry. */ + private final HttpRoute route; // HttpRoute is @Immutable + + + /** + * Creates a new reference to a pool entry. + * + * @param entry the pool entry, must not be null + * @param queue the reference queue, or null + */ + public BasicPoolEntryRef(BasicPoolEntry entry, + ReferenceQueue queue) { + super(entry, queue); + if (entry == null) { + throw new IllegalArgumentException + ("Pool entry must not be null."); + } + route = entry.getPlannedRoute(); + } + + + /** + * Obtain the planned route for the referenced entry. + * The planned route is still available, even if the entry is gone. + * + * @return the planned route + */ + public final HttpRoute getRoute() { + return this.route; + } + +} // class BasicPoolEntryRef + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/BasicPooledConnAdapter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,75 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn.tsccm; + +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.impl.conn.AbstractPoolEntry; +import org.apache.http.impl.conn.AbstractPooledConnAdapter; + +/** + * A connection wrapper and callback handler. + * All connections given out by the manager are wrappers which + * can be {@link #detach detach}ed to prevent further use on release. + * + * @since 4.0 + * + * @deprecated (4.2) do not use + */ +@Deprecated +public class BasicPooledConnAdapter extends AbstractPooledConnAdapter { + + /** + * Creates a new adapter. + * + * @param tsccm the connection manager + * @param entry the pool entry for the connection being wrapped + */ + protected BasicPooledConnAdapter(ThreadSafeClientConnManager tsccm, + AbstractPoolEntry entry) { + super(tsccm, entry); + markReusable(); + } + + @Override + protected ClientConnectionManager getManager() { + // override needed only to make method visible in this package + return super.getManager(); + } + + @Override + protected AbstractPoolEntry getPoolEntry() { + // override needed only to make method visible in this package + return super.getPoolEntry(); + } + + @Override + protected void detach() { + // override needed only to make method visible in this package + super.detach(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/ConnPoolByRoute.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,836 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn.tsccm; + +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Queue; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.ClientConnectionOperator; +import org.apache.http.conn.ConnectionPoolTimeoutException; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.conn.params.ConnPerRoute; +import org.apache.http.conn.params.ConnManagerParams; +import org.apache.http.params.HttpParams; + +/** + * A connection pool that maintains connections by route. + * This class is derived from MultiThreadedHttpConnectionManager + * in HttpClient 3.x, see there for original authors. It implements the same + * algorithm for connection re-use and connection-per-host enforcement: + *
    + *
  • connections are re-used only for the exact same route
  • + *
  • connection limits are enforced per route rather than per host
  • + *
+ * Note that access to the pool data structures is synchronized via the + * {@link AbstractConnPool#poolLock poolLock} in the base class, + * not via synchronized methods. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link org.apache.http.pool.AbstractConnPool} + */ +@Deprecated +public class ConnPoolByRoute extends AbstractConnPool { + + private final Log log = LogFactory.getLog(getClass()); + + private final Lock poolLock; + + /** Connection operator for this pool */ + protected final ClientConnectionOperator operator; + + /** Connections per route lookup */ + protected final ConnPerRoute connPerRoute; + + /** References to issued connections */ + protected final Set leasedConnections; + + /** The list of free connections */ + protected final Queue freeConnections; + + /** The list of WaitingThreads waiting for a connection */ + protected final Queue waitingThreads; + + /** Map of route-specific pools */ + protected final Map routeToPool; + + private final long connTTL; + + private final TimeUnit connTTLTimeUnit; + + protected volatile boolean shutdown; + + protected volatile int maxTotalConnections; + + protected volatile int numConnections; + + /** + * Creates a new connection pool, managed by route. + * + * @since 4.1 + */ + public ConnPoolByRoute( + final ClientConnectionOperator operator, + final ConnPerRoute connPerRoute, + int maxTotalConnections) { + this(operator, connPerRoute, maxTotalConnections, -1, TimeUnit.MILLISECONDS); + } + + /** + * @since 4.1 + */ + public ConnPoolByRoute( + final ClientConnectionOperator operator, + final ConnPerRoute connPerRoute, + int maxTotalConnections, + long connTTL, + final TimeUnit connTTLTimeUnit) { + super(); + if (operator == null) { + throw new IllegalArgumentException("Connection operator may not be null"); + } + if (connPerRoute == null) { + throw new IllegalArgumentException("Connections per route may not be null"); + } + this.poolLock = super.poolLock; + this.leasedConnections = super.leasedConnections; + this.operator = operator; + this.connPerRoute = connPerRoute; + this.maxTotalConnections = maxTotalConnections; + this.freeConnections = createFreeConnQueue(); + this.waitingThreads = createWaitingThreadQueue(); + this.routeToPool = createRouteToPoolMap(); + this.connTTL = connTTL; + this.connTTLTimeUnit = connTTLTimeUnit; + } + + protected Lock getLock() { + return this.poolLock; + } + + /** + * Creates a new connection pool, managed by route. + * + * @deprecated (4.1) use {@link ConnPoolByRoute#ConnPoolByRoute(ClientConnectionOperator, ConnPerRoute, int)} + */ + public ConnPoolByRoute(final ClientConnectionOperator operator, final HttpParams params) { + this(operator, + ConnManagerParams.getMaxConnectionsPerRoute(params), + ConnManagerParams.getMaxTotalConnections(params)); + } + + /** + * Creates the queue for {@link #freeConnections}. + * Called once by the constructor. + * + * @return a queue + */ + protected Queue createFreeConnQueue() { + return new LinkedList(); + } + + /** + * Creates the queue for {@link #waitingThreads}. + * Called once by the constructor. + * + * @return a queue + */ + protected Queue createWaitingThreadQueue() { + return new LinkedList(); + } + + /** + * Creates the map for {@link #routeToPool}. + * Called once by the constructor. + * + * @return a map + */ + protected Map createRouteToPoolMap() { + return new HashMap(); + } + + + /** + * Creates a new route-specific pool. + * Called by {@link #getRoutePool} when necessary. + * + * @param route the route + * + * @return the new pool + */ + protected RouteSpecificPool newRouteSpecificPool(HttpRoute route) { + return new RouteSpecificPool(route, this.connPerRoute); + } + + + /** + * Creates a new waiting thread. + * Called by {@link #getRoutePool} when necessary. + * + * @param cond the condition to wait for + * @param rospl the route specific pool, or null + * + * @return a waiting thread representation + */ + protected WaitingThread newWaitingThread(Condition cond, + RouteSpecificPool rospl) { + return new WaitingThread(cond, rospl); + } + + private void closeConnection(final BasicPoolEntry entry) { + OperatedClientConnection conn = entry.getConnection(); + if (conn != null) { + try { + conn.close(); + } catch (IOException ex) { + log.debug("I/O error closing connection", ex); + } + } + } + + /** + * Get a route-specific pool of available connections. + * + * @param route the route + * @param create whether to create the pool if it doesn't exist + * + * @return the pool for the argument route, + * never null if create is true + */ + protected RouteSpecificPool getRoutePool(HttpRoute route, + boolean create) { + RouteSpecificPool rospl = null; + poolLock.lock(); + try { + + rospl = routeToPool.get(route); + if ((rospl == null) && create) { + // no pool for this route yet (or anymore) + rospl = newRouteSpecificPool(route); + routeToPool.put(route, rospl); + } + + } finally { + poolLock.unlock(); + } + + return rospl; + } + + public int getConnectionsInPool(HttpRoute route) { + poolLock.lock(); + try { + // don't allow a pool to be created here! + RouteSpecificPool rospl = getRoutePool(route, false); + return (rospl != null) ? rospl.getEntryCount() : 0; + + } finally { + poolLock.unlock(); + } + } + + public int getConnectionsInPool() { + poolLock.lock(); + try { + return numConnections; + } finally { + poolLock.unlock(); + } + } + + @Override + public PoolEntryRequest requestPoolEntry( + final HttpRoute route, + final Object state) { + + final WaitingThreadAborter aborter = new WaitingThreadAborter(); + + return new PoolEntryRequest() { + + public void abortRequest() { + poolLock.lock(); + try { + aborter.abort(); + } finally { + poolLock.unlock(); + } + } + + public BasicPoolEntry getPoolEntry( + long timeout, + TimeUnit tunit) + throws InterruptedException, ConnectionPoolTimeoutException { + return getEntryBlocking(route, state, timeout, tunit, aborter); + } + + }; + } + + /** + * Obtains a pool entry with a connection within the given timeout. + * If a {@link WaitingThread} is used to block, {@link WaitingThreadAborter#setWaitingThread(WaitingThread)} + * must be called before blocking, to allow the thread to be interrupted. + * + * @param route the route for which to get the connection + * @param timeout the timeout, 0 or negative for no timeout + * @param tunit the unit for the timeout, + * may be null only if there is no timeout + * @param aborter an object which can abort a {@link WaitingThread}. + * + * @return pool entry holding a connection for the route + * + * @throws ConnectionPoolTimeoutException + * if the timeout expired + * @throws InterruptedException + * if the calling thread was interrupted + */ + protected BasicPoolEntry getEntryBlocking( + HttpRoute route, Object state, + long timeout, TimeUnit tunit, + WaitingThreadAborter aborter) + throws ConnectionPoolTimeoutException, InterruptedException { + + Date deadline = null; + if (timeout > 0) { + deadline = new Date + (System.currentTimeMillis() + tunit.toMillis(timeout)); + } + + BasicPoolEntry entry = null; + poolLock.lock(); + try { + + RouteSpecificPool rospl = getRoutePool(route, true); + WaitingThread waitingThread = null; + + while (entry == null) { + + if (shutdown) { + throw new IllegalStateException("Connection pool shut down"); + } + + if (log.isDebugEnabled()) { + log.debug("[" + route + "] total kept alive: " + freeConnections.size() + + ", total issued: " + leasedConnections.size() + + ", total allocated: " + numConnections + " out of " + maxTotalConnections); + } + + // the cases to check for: + // - have a free connection for that route + // - allowed to create a free connection for that route + // - can delete and replace a free connection for another route + // - need to wait for one of the things above to come true + + entry = getFreeEntry(rospl, state); + if (entry != null) { + break; + } + + boolean hasCapacity = rospl.getCapacity() > 0; + + if (log.isDebugEnabled()) { + log.debug("Available capacity: " + rospl.getCapacity() + + " out of " + rospl.getMaxEntries() + + " [" + route + "][" + state + "]"); + } + + if (hasCapacity && numConnections < maxTotalConnections) { + + entry = createEntry(rospl, operator); + + } else if (hasCapacity && !freeConnections.isEmpty()) { + + deleteLeastUsedEntry(); + // if least used entry's route was the same as rospl, + // rospl is now out of date : we preemptively refresh + rospl = getRoutePool(route, true); + entry = createEntry(rospl, operator); + + } else { + + if (log.isDebugEnabled()) { + log.debug("Need to wait for connection" + + " [" + route + "][" + state + "]"); + } + + if (waitingThread == null) { + waitingThread = + newWaitingThread(poolLock.newCondition(), rospl); + aborter.setWaitingThread(waitingThread); + } + + boolean success = false; + try { + rospl.queueThread(waitingThread); + waitingThreads.add(waitingThread); + success = waitingThread.await(deadline); + + } finally { + // In case of 'success', we were woken up by the + // connection pool and should now have a connection + // waiting for us, or else we're shutting down. + // Just continue in the loop, both cases are checked. + rospl.removeThread(waitingThread); + waitingThreads.remove(waitingThread); + } + + // check for spurious wakeup vs. timeout + if (!success && (deadline != null) && + (deadline.getTime() <= System.currentTimeMillis())) { + throw new ConnectionPoolTimeoutException + ("Timeout waiting for connection"); + } + } + } // while no entry + + } finally { + poolLock.unlock(); + } + return entry; + } + + @Override + public void freeEntry(BasicPoolEntry entry, boolean reusable, long validDuration, TimeUnit timeUnit) { + + HttpRoute route = entry.getPlannedRoute(); + if (log.isDebugEnabled()) { + log.debug("Releasing connection" + + " [" + route + "][" + entry.getState() + "]"); + } + + poolLock.lock(); + try { + if (shutdown) { + // the pool is shut down, release the + // connection's resources and get out of here + closeConnection(entry); + return; + } + + // no longer issued, we keep a hard reference now + leasedConnections.remove(entry); + + RouteSpecificPool rospl = getRoutePool(route, true); + + if (reusable && rospl.getCapacity() >= 0) { + if (log.isDebugEnabled()) { + String s; + if (validDuration > 0) { + s = "for " + validDuration + " " + timeUnit; + } else { + s = "indefinitely"; + } + log.debug("Pooling connection" + + " [" + route + "][" + entry.getState() + "]; keep alive " + s); + } + rospl.freeEntry(entry); + entry.updateExpiry(validDuration, timeUnit); + freeConnections.add(entry); + } else { + closeConnection(entry); + rospl.dropEntry(); + numConnections--; + } + + notifyWaitingThread(rospl); + + } finally { + poolLock.unlock(); + } + } + + /** + * If available, get a free pool entry for a route. + * + * @param rospl the route-specific pool from which to get an entry + * + * @return an available pool entry for the given route, or + * null if none is available + */ + protected BasicPoolEntry getFreeEntry(RouteSpecificPool rospl, Object state) { + + BasicPoolEntry entry = null; + poolLock.lock(); + try { + boolean done = false; + while(!done) { + + entry = rospl.allocEntry(state); + + if (entry != null) { + if (log.isDebugEnabled()) { + log.debug("Getting free connection" + + " [" + rospl.getRoute() + "][" + state + "]"); + + } + freeConnections.remove(entry); + if (entry.isExpired(System.currentTimeMillis())) { + // If the free entry isn't valid anymore, get rid of it + // and loop to find another one that might be valid. + if (log.isDebugEnabled()) + log.debug("Closing expired free connection" + + " [" + rospl.getRoute() + "][" + state + "]"); + closeConnection(entry); + // We use dropEntry instead of deleteEntry because the entry + // is no longer "free" (we just allocated it), and deleteEntry + // can only be used to delete free entries. + rospl.dropEntry(); + numConnections--; + } else { + leasedConnections.add(entry); + done = true; + } + + } else { + done = true; + if (log.isDebugEnabled()) { + log.debug("No free connections" + + " [" + rospl.getRoute() + "][" + state + "]"); + } + } + } + } finally { + poolLock.unlock(); + } + return entry; + } + + + /** + * Creates a new pool entry. + * This method assumes that the new connection will be handed + * out immediately. + * + * @param rospl the route-specific pool for which to create the entry + * @param op the operator for creating a connection + * + * @return the new pool entry for a new connection + */ + protected BasicPoolEntry createEntry(RouteSpecificPool rospl, + ClientConnectionOperator op) { + + if (log.isDebugEnabled()) { + log.debug("Creating new connection [" + rospl.getRoute() + "]"); + } + + // the entry will create the connection when needed + BasicPoolEntry entry = new BasicPoolEntry(op, rospl.getRoute(), connTTL, connTTLTimeUnit); + + poolLock.lock(); + try { + rospl.createdEntry(entry); + numConnections++; + leasedConnections.add(entry); + } finally { + poolLock.unlock(); + } + + return entry; + } + + + /** + * Deletes a given pool entry. + * This closes the pooled connection and removes all references, + * so that it can be GCed. + * + *

Note: Does not remove the entry from the freeConnections list. + * It is assumed that the caller has already handled this step.

+ * + * + * @param entry the pool entry for the connection to delete + */ + protected void deleteEntry(BasicPoolEntry entry) { + + HttpRoute route = entry.getPlannedRoute(); + + if (log.isDebugEnabled()) { + log.debug("Deleting connection" + + " [" + route + "][" + entry.getState() + "]"); + } + + poolLock.lock(); + try { + + closeConnection(entry); + + RouteSpecificPool rospl = getRoutePool(route, true); + rospl.deleteEntry(entry); + numConnections--; + if (rospl.isUnused()) { + routeToPool.remove(route); + } + + } finally { + poolLock.unlock(); + } + } + + + /** + * Delete an old, free pool entry to make room for a new one. + * Used to replace pool entries with ones for a different route. + */ + protected void deleteLeastUsedEntry() { + poolLock.lock(); + try { + + BasicPoolEntry entry = freeConnections.remove(); + + if (entry != null) { + deleteEntry(entry); + } else if (log.isDebugEnabled()) { + log.debug("No free connection to delete"); + } + + } finally { + poolLock.unlock(); + } + } + + @Override + protected void handleLostEntry(HttpRoute route) { + + poolLock.lock(); + try { + + RouteSpecificPool rospl = getRoutePool(route, true); + rospl.dropEntry(); + if (rospl.isUnused()) { + routeToPool.remove(route); + } + + numConnections--; + notifyWaitingThread(rospl); + + } finally { + poolLock.unlock(); + } + } + + /** + * Notifies a waiting thread that a connection is available. + * This will wake a thread waiting in the specific route pool, + * if there is one. + * Otherwise, a thread in the connection pool will be notified. + * + * @param rospl the pool in which to notify, or null + */ + protected void notifyWaitingThread(RouteSpecificPool rospl) { + + //@@@ while this strategy provides for best connection re-use, + //@@@ is it fair? only do this if the connection is open? + // Find the thread we are going to notify. We want to ensure that + // each waiting thread is only interrupted once, so we will remove + // it from all wait queues before interrupting. + WaitingThread waitingThread = null; + + poolLock.lock(); + try { + + if ((rospl != null) && rospl.hasThread()) { + if (log.isDebugEnabled()) { + log.debug("Notifying thread waiting on pool" + + " [" + rospl.getRoute() + "]"); + } + waitingThread = rospl.nextThread(); + } else if (!waitingThreads.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("Notifying thread waiting on any pool"); + } + waitingThread = waitingThreads.remove(); + } else if (log.isDebugEnabled()) { + log.debug("Notifying no-one, there are no waiting threads"); + } + + if (waitingThread != null) { + waitingThread.wakeup(); + } + + } finally { + poolLock.unlock(); + } + } + + + @Override + public void deleteClosedConnections() { + poolLock.lock(); + try { + Iterator iter = freeConnections.iterator(); + while (iter.hasNext()) { + BasicPoolEntry entry = iter.next(); + if (!entry.getConnection().isOpen()) { + iter.remove(); + deleteEntry(entry); + } + } + } finally { + poolLock.unlock(); + } + } + + /** + * Closes idle connections. + * + * @param idletime the time the connections should have been idle + * in order to be closed now + * @param tunit the unit for the idletime + */ + @Override + public void closeIdleConnections(long idletime, TimeUnit tunit) { + if (tunit == null) { + throw new IllegalArgumentException("Time unit must not be null."); + } + if (idletime < 0) { + idletime = 0; + } + if (log.isDebugEnabled()) { + log.debug("Closing connections idle longer than " + idletime + " " + tunit); + } + // the latest time for which connections will be closed + long deadline = System.currentTimeMillis() - tunit.toMillis(idletime); + poolLock.lock(); + try { + Iterator iter = freeConnections.iterator(); + while (iter.hasNext()) { + BasicPoolEntry entry = iter.next(); + if (entry.getUpdated() <= deadline) { + if (log.isDebugEnabled()) { + log.debug("Closing connection last used @ " + new Date(entry.getUpdated())); + } + iter.remove(); + deleteEntry(entry); + } + } + } finally { + poolLock.unlock(); + } + } + + @Override + public void closeExpiredConnections() { + log.debug("Closing expired connections"); + long now = System.currentTimeMillis(); + + poolLock.lock(); + try { + Iterator iter = freeConnections.iterator(); + while (iter.hasNext()) { + BasicPoolEntry entry = iter.next(); + if (entry.isExpired(now)) { + if (log.isDebugEnabled()) { + log.debug("Closing connection expired @ " + new Date(entry.getExpiry())); + } + iter.remove(); + deleteEntry(entry); + } + } + } finally { + poolLock.unlock(); + } + } + + @Override + public void shutdown() { + poolLock.lock(); + try { + if (shutdown) { + return; + } + shutdown = true; + + // close all connections that are issued to an application + Iterator iter1 = leasedConnections.iterator(); + while (iter1.hasNext()) { + BasicPoolEntry entry = iter1.next(); + iter1.remove(); + closeConnection(entry); + } + + // close all free connections + Iterator iter2 = freeConnections.iterator(); + while (iter2.hasNext()) { + BasicPoolEntry entry = iter2.next(); + iter2.remove(); + + if (log.isDebugEnabled()) { + log.debug("Closing connection" + + " [" + entry.getPlannedRoute() + "][" + entry.getState() + "]"); + } + closeConnection(entry); + } + + // wake up all waiting threads + Iterator iwth = waitingThreads.iterator(); + while (iwth.hasNext()) { + WaitingThread waiter = iwth.next(); + iwth.remove(); + waiter.wakeup(); + } + + routeToPool.clear(); + + } finally { + poolLock.unlock(); + } + } + + /** + * since 4.1 + */ + public void setMaxTotalConnections(int max) { + poolLock.lock(); + try { + maxTotalConnections = max; + } finally { + poolLock.unlock(); + } + } + + + /** + * since 4.1 + */ + public int getMaxTotalConnections() { + return maxTotalConnections; + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/PoolEntryRequest.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/PoolEntryRequest.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/PoolEntryRequest.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,70 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn.tsccm; + +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.apache.http.conn.ConnectionPoolTimeoutException; + +/** + * Encapsulates a request for a {@link BasicPoolEntry}. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link Future} + */ +@Deprecated +public interface PoolEntryRequest { + + /** + * Obtains a pool entry with a connection within the given timeout. + * If {@link #abortRequest()} is called before this completes + * an {@link InterruptedException} is thrown. + * + * @param timeout the timeout, 0 or negative for no timeout + * @param tunit the unit for the timeout, + * may be null only if there is no timeout + * + * @return pool entry holding a connection for the route + * + * @throws ConnectionPoolTimeoutException + * if the timeout expired + * @throws InterruptedException + * if the calling thread was interrupted or the request was aborted + */ + BasicPoolEntry getPoolEntry( + long timeout, + TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException; + + /** + * Aborts the active or next call to + * {@link #getPoolEntry(long, TimeUnit)}. + */ + void abortRequest(); + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/RouteSpecificPool.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/RouteSpecificPool.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/RouteSpecificPool.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,322 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn.tsccm; + +import java.io.IOException; +import java.util.ListIterator; +import java.util.Queue; +import java.util.LinkedList; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.conn.params.ConnPerRoute; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.util.LangUtils; + + +/** + * A connection sub-pool for a specific route, used by {@link ConnPoolByRoute}. + * The methods in this class are unsynchronized. It is expected that the + * containing pool takes care of synchronization. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link org.apache.http.pool.AbstractConnPool} + */ +@Deprecated +public class RouteSpecificPool { + + private final Log log = LogFactory.getLog(getClass()); + + /** The route this pool is for. */ + protected final HttpRoute route; //Immutable + + protected final int maxEntries; + + /** Connections per route */ + protected final ConnPerRoute connPerRoute; + + /** + * The list of free entries. + * This list is managed LIFO, to increase idle times and + * allow for closing connections that are not really needed. + */ + protected final LinkedList freeEntries; + + /** The list of threads waiting for this pool. */ + protected final Queue waitingThreads; + + /** The number of created entries. */ + protected int numEntries; + + /** + * @deprecated (4.1) use {@link RouteSpecificPool#RouteSpecificPool(HttpRoute, ConnPerRoute)} + */ + public RouteSpecificPool(HttpRoute route, int maxEntries) { + this.route = route; + this.maxEntries = maxEntries; + this.connPerRoute = new ConnPerRoute() { + public int getMaxForRoute(HttpRoute route) { + return RouteSpecificPool.this.maxEntries; + } + }; + this.freeEntries = new LinkedList(); + this.waitingThreads = new LinkedList(); + this.numEntries = 0; + } + + + /** + * Creates a new route-specific pool. + * + * @param route the route for which to pool + * @param connPerRoute the connections per route configuration + */ + public RouteSpecificPool(HttpRoute route, ConnPerRoute connPerRoute) { + this.route = route; + this.connPerRoute = connPerRoute; + this.maxEntries = connPerRoute.getMaxForRoute(route); + this.freeEntries = new LinkedList(); + this.waitingThreads = new LinkedList(); + this.numEntries = 0; + } + + + /** + * Obtains the route for which this pool is specific. + * + * @return the route + */ + public final HttpRoute getRoute() { + return route; + } + + + /** + * Obtains the maximum number of entries allowed for this pool. + * + * @return the max entry number + */ + public final int getMaxEntries() { + return maxEntries; + } + + + /** + * Indicates whether this pool is unused. + * A pool is unused if there is neither an entry nor a waiting thread. + * All entries count, not only the free but also the allocated ones. + * + * @return true if this pool is unused, + * false otherwise + */ + public boolean isUnused() { + return (numEntries < 1) && waitingThreads.isEmpty(); + } + + + /** + * Return remaining capacity of this pool + * + * @return capacity + */ + public int getCapacity() { + return connPerRoute.getMaxForRoute(route) - numEntries; + } + + + /** + * Obtains the number of entries. + * This includes not only the free entries, but also those that + * have been created and are currently issued to an application. + * + * @return the number of entries for the route of this pool + */ + public final int getEntryCount() { + return numEntries; + } + + + /** + * Obtains a free entry from this pool, if one is available. + * + * @return an available pool entry, or null if there is none + */ + public BasicPoolEntry allocEntry(final Object state) { + if (!freeEntries.isEmpty()) { + ListIterator it = freeEntries.listIterator(freeEntries.size()); + while (it.hasPrevious()) { + BasicPoolEntry entry = it.previous(); + if (entry.getState() == null || LangUtils.equals(state, entry.getState())) { + it.remove(); + return entry; + } + } + } + if (getCapacity() == 0 && !freeEntries.isEmpty()) { + BasicPoolEntry entry = freeEntries.remove(); + entry.shutdownEntry(); + OperatedClientConnection conn = entry.getConnection(); + try { + conn.close(); + } catch (IOException ex) { + log.debug("I/O error closing connection", ex); + } + return entry; + } + return null; + } + + + /** + * Returns an allocated entry to this pool. + * + * @param entry the entry obtained from {@link #allocEntry allocEntry} + * or presented to {@link #createdEntry createdEntry} + */ + public void freeEntry(BasicPoolEntry entry) { + + if (numEntries < 1) { + throw new IllegalStateException + ("No entry created for this pool. " + route); + } + if (numEntries <= freeEntries.size()) { + throw new IllegalStateException + ("No entry allocated from this pool. " + route); + } + freeEntries.add(entry); + } + + + /** + * Indicates creation of an entry for this pool. + * The entry will not be added to the list of free entries, + * it is only recognized as belonging to this pool now. It can then + * be passed to {@link #freeEntry freeEntry}. + * + * @param entry the entry that was created for this pool + */ + public void createdEntry(BasicPoolEntry entry) { + + if (!route.equals(entry.getPlannedRoute())) { + throw new IllegalArgumentException + ("Entry not planned for this pool." + + "\npool: " + route + + "\nplan: " + entry.getPlannedRoute()); + } + + numEntries++; + } + + + /** + * Deletes an entry from this pool. + * Only entries that are currently free in this pool can be deleted. + * Allocated entries can not be deleted. + * + * @param entry the entry to delete from this pool + * + * @return true if the entry was found and deleted, or + * false if the entry was not found + */ + public boolean deleteEntry(BasicPoolEntry entry) { + + final boolean found = freeEntries.remove(entry); + if (found) + numEntries--; + return found; + } + + + /** + * Forgets about an entry from this pool. + * This method is used to indicate that an entry + * {@link #allocEntry allocated} + * from this pool has been lost and will not be returned. + */ + public void dropEntry() { + if (numEntries < 1) { + throw new IllegalStateException + ("There is no entry that could be dropped."); + } + numEntries--; + } + + + /** + * Adds a waiting thread. + * This pool makes no attempt to match waiting threads with pool entries. + * It is the caller's responsibility to check that there is no entry + * before adding a waiting thread. + * + * @param wt the waiting thread + */ + public void queueThread(WaitingThread wt) { + if (wt == null) { + throw new IllegalArgumentException + ("Waiting thread must not be null."); + } + this.waitingThreads.add(wt); + } + + + /** + * Checks whether there is a waiting thread in this pool. + * + * @return true if there is a waiting thread, + * false otherwise + */ + public boolean hasThread() { + return !this.waitingThreads.isEmpty(); + } + + + /** + * Returns the next thread in the queue. + * + * @return a waiting thread, or null if there is none + */ + public WaitingThread nextThread() { + return this.waitingThreads.peek(); + } + + + /** + * Removes a waiting thread, if it is queued. + * + * @param wt the waiting thread + */ + public void removeThread(WaitingThread wt) { + if (wt == null) + return; + + this.waitingThreads.remove(wt); + } + + +} // class RouteSpecificPool Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,385 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn.tsccm; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.conn.params.ConnPerRouteBean; +import org.apache.http.conn.routing.HttpRoute; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.ClientConnectionOperator; +import org.apache.http.conn.ClientConnectionRequest; +import org.apache.http.conn.ConnectionPoolTimeoutException; +import org.apache.http.conn.ManagedClientConnection; +import org.apache.http.conn.OperatedClientConnection; +import org.apache.http.params.HttpParams; +import org.apache.http.impl.conn.DefaultClientConnectionOperator; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.impl.conn.SchemeRegistryFactory; + +/** + * Manages a pool of {@link OperatedClientConnection client connections} and + * is able to service connection requests from multiple execution threads. + * Connections are pooled on a per route basis. A request for a route which + * already the manager has persistent connections for available in the pool + * will be services by leasing a connection from the pool rather than + * creating a brand new connection. + *

+ * ThreadSafeClientConnManager maintains a maximum limit of connection on + * a per route basis and in total. Per default this implementation will + * create no more than than 2 concurrent connections per given route + * and no more 20 connections in total. For many real-world applications + * these limits may prove too constraining, especially if they use HTTP + * as a transport protocol for their services. Connection limits, however, + * can be adjusted using HTTP parameters. + * + * @since 4.0 + * + * @deprecated (4.2) use {@link PoolingClientConnectionManager} + */ +@ThreadSafe +@Deprecated +public class ThreadSafeClientConnManager implements ClientConnectionManager { + + private final Log log; + + /** The schemes supported by this connection manager. */ + protected final SchemeRegistry schemeRegistry; // @ThreadSafe + + protected final AbstractConnPool connectionPool; + + /** The pool of connections being managed. */ + protected final ConnPoolByRoute pool; + + /** The operator for opening and updating connections. */ + protected final ClientConnectionOperator connOperator; // DefaultClientConnectionOperator is @ThreadSafe + + protected final ConnPerRouteBean connPerRoute; + + /** + * Creates a new thread safe connection manager. + * + * @param schreg the scheme registry. + */ + public ThreadSafeClientConnManager(final SchemeRegistry schreg) { + this(schreg, -1, TimeUnit.MILLISECONDS); + } + + /** + * @since 4.1 + */ + public ThreadSafeClientConnManager() { + this(SchemeRegistryFactory.createDefault()); + } + + /** + * Creates a new thread safe connection manager. + * + * @param schreg the scheme registry. + * @param connTTL max connection lifetime, <=0 implies "infinity" + * @param connTTLTimeUnit TimeUnit of connTTL + * + * @since 4.1 + */ + public ThreadSafeClientConnManager(final SchemeRegistry schreg, + long connTTL, TimeUnit connTTLTimeUnit) { + this(schreg, connTTL, connTTLTimeUnit, new ConnPerRouteBean()); + } + + /** + * Creates a new thread safe connection manager. + * + * @param schreg the scheme registry. + * @param connTTL max connection lifetime, <=0 implies "infinity" + * @param connTTLTimeUnit TimeUnit of connTTL + * @param connPerRoute mapping of maximum connections per route, + * provided as a dependency so it can be managed externally, e.g. + * for dynamic connection pool size management. + * + * @since 4.2 + */ + public ThreadSafeClientConnManager(final SchemeRegistry schreg, + long connTTL, TimeUnit connTTLTimeUnit, ConnPerRouteBean connPerRoute) { + super(); + if (schreg == null) { + throw new IllegalArgumentException("Scheme registry may not be null"); + } + this.log = LogFactory.getLog(getClass()); + this.schemeRegistry = schreg; + this.connPerRoute = connPerRoute; + this.connOperator = createConnectionOperator(schreg); + this.pool = createConnectionPool(connTTL, connTTLTimeUnit) ; + this.connectionPool = this.pool; + } + + /** + * Creates a new thread safe connection manager. + * + * @param params the parameters for this manager. + * @param schreg the scheme registry. + * + * @deprecated (4.1) use {@link ThreadSafeClientConnManager#ThreadSafeClientConnManager(SchemeRegistry)} + */ + public ThreadSafeClientConnManager(HttpParams params, + SchemeRegistry schreg) { + if (schreg == null) { + throw new IllegalArgumentException("Scheme registry may not be null"); + } + this.log = LogFactory.getLog(getClass()); + this.schemeRegistry = schreg; + this.connPerRoute = new ConnPerRouteBean(); + this.connOperator = createConnectionOperator(schreg); + this.pool = (ConnPoolByRoute) createConnectionPool(params) ; + this.connectionPool = this.pool; + } + + @Override + protected void finalize() throws Throwable { + try { + shutdown(); + } finally { + super.finalize(); + } + } + + /** + * Hook for creating the connection pool. + * + * @return the connection pool to use + * + * @deprecated (4.1) use #createConnectionPool(long, TimeUnit)) + */ + protected AbstractConnPool createConnectionPool(final HttpParams params) { + return new ConnPoolByRoute(connOperator, params); + } + + /** + * Hook for creating the connection pool. + * + * @return the connection pool to use + * + * @since 4.1 + */ + protected ConnPoolByRoute createConnectionPool(long connTTL, TimeUnit connTTLTimeUnit) { + return new ConnPoolByRoute(connOperator, connPerRoute, 20, connTTL, connTTLTimeUnit); + } + + /** + * Hook for creating the connection operator. + * It is called by the constructor. + * Derived classes can override this method to change the + * instantiation of the operator. + * The default implementation here instantiates + * {@link DefaultClientConnectionOperator DefaultClientConnectionOperator}. + * + * @param schreg the scheme registry. + * + * @return the connection operator to use + */ + protected ClientConnectionOperator + createConnectionOperator(SchemeRegistry schreg) { + + return new DefaultClientConnectionOperator(schreg);// @ThreadSafe + } + + public SchemeRegistry getSchemeRegistry() { + return this.schemeRegistry; + } + + public ClientConnectionRequest requestConnection( + final HttpRoute route, + final Object state) { + + final PoolEntryRequest poolRequest = pool.requestPoolEntry( + route, state); + + return new ClientConnectionRequest() { + + public void abortRequest() { + poolRequest.abortRequest(); + } + + public ManagedClientConnection getConnection( + long timeout, TimeUnit tunit) throws InterruptedException, + ConnectionPoolTimeoutException { + if (route == null) { + throw new IllegalArgumentException("Route may not be null."); + } + + if (log.isDebugEnabled()) { + log.debug("Get connection: " + route + ", timeout = " + timeout); + } + + BasicPoolEntry entry = poolRequest.getPoolEntry(timeout, tunit); + return new BasicPooledConnAdapter(ThreadSafeClientConnManager.this, entry); + } + + }; + + } + + public void releaseConnection(ManagedClientConnection conn, long validDuration, TimeUnit timeUnit) { + + if (!(conn instanceof BasicPooledConnAdapter)) { + throw new IllegalArgumentException + ("Connection class mismatch, " + + "connection not obtained from this manager."); + } + BasicPooledConnAdapter hca = (BasicPooledConnAdapter) conn; + if ((hca.getPoolEntry() != null) && (hca.getManager() != this)) { + throw new IllegalArgumentException + ("Connection not obtained from this manager."); + } + synchronized (hca) { + BasicPoolEntry entry = (BasicPoolEntry) hca.getPoolEntry(); + if (entry == null) { + return; + } + try { + // make sure that the response has been read completely + if (hca.isOpen() && !hca.isMarkedReusable()) { + // In MTHCM, there would be a call to + // SimpleHttpConnectionManager.finishLastResponse(conn); + // Consuming the response is handled outside in 4.0. + + // make sure this connection will not be re-used + // Shut down rather than close, we might have gotten here + // because of a shutdown trigger. + // Shutdown of the adapter also clears the tracked route. + hca.shutdown(); + } + } catch (IOException iox) { + if (log.isDebugEnabled()) + log.debug("Exception shutting down released connection.", + iox); + } finally { + boolean reusable = hca.isMarkedReusable(); + if (log.isDebugEnabled()) { + if (reusable) { + log.debug("Released connection is reusable."); + } else { + log.debug("Released connection is not reusable."); + } + } + hca.detach(); + pool.freeEntry(entry, reusable, validDuration, timeUnit); + } + } + } + + public void shutdown() { + log.debug("Shutting down"); + pool.shutdown(); + } + + /** + * Gets the total number of pooled connections for the given route. + * This is the total number of connections that have been created and + * are still in use by this connection manager for the route. + * This value will not exceed the maximum number of connections per host. + * + * @param route the route in question + * + * @return the total number of pooled connections for that route + */ + public int getConnectionsInPool(final HttpRoute route) { + return pool.getConnectionsInPool(route); + } + + /** + * Gets the total number of pooled connections. This is the total number of + * connections that have been created and are still in use by this connection + * manager. This value will not exceed the maximum number of connections + * in total. + * + * @return the total number of pooled connections + */ + public int getConnectionsInPool() { + return pool.getConnectionsInPool(); + } + + public void closeIdleConnections(long idleTimeout, TimeUnit tunit) { + if (log.isDebugEnabled()) { + log.debug("Closing connections idle longer than " + idleTimeout + " " + tunit); + } + pool.closeIdleConnections(idleTimeout, tunit); + } + + public void closeExpiredConnections() { + log.debug("Closing expired connections"); + pool.closeExpiredConnections(); + } + + /** + * since 4.1 + */ + public int getMaxTotal() { + return pool.getMaxTotalConnections(); + } + + /** + * since 4.1 + */ + public void setMaxTotal(int max) { + pool.setMaxTotalConnections(max); + } + + /** + * @since 4.1 + */ + public int getDefaultMaxPerRoute() { + return connPerRoute.getDefaultMaxPerRoute(); + } + + /** + * @since 4.1 + */ + public void setDefaultMaxPerRoute(int max) { + connPerRoute.setDefaultMaxPerRoute(max); + } + + /** + * @since 4.1 + */ + public int getMaxForRoute(final HttpRoute route) { + return connPerRoute.getMaxForRoute(route); + } + + /** + * @since 4.1 + */ + public void setMaxForRoute(final HttpRoute route, int max) { + connPerRoute.setMaxForRoute(route, max); + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/WaitingThread.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/WaitingThread.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/WaitingThread.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,196 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn.tsccm; + + +import java.util.Date; +import java.util.concurrent.locks.Condition; + +/** + * Represents a thread waiting for a connection. + * This class implements throwaway objects. It is instantiated whenever + * a thread needs to wait. Instances are not re-used, except if the + * waiting thread experiences a spurious wakeup and continues to wait. + *
+ * All methods assume external synchronization on the condition + * passed to the constructor. + * Instances of this class do not synchronize access! + * + * + * @since 4.0 + * + * @deprecated (4.2) do not use + */ +@Deprecated +public class WaitingThread { + + /** The condition on which the thread is waiting. */ + private final Condition cond; + + /** The route specific pool on which the thread is waiting. */ + //@@@ replace with generic pool interface + private final RouteSpecificPool pool; + + /** The thread that is waiting for an entry. */ + private Thread waiter; + + /** True if this was interrupted. */ + private boolean aborted; + + + /** + * Creates a new entry for a waiting thread. + * + * @param cond the condition for which to wait + * @param pool the pool on which the thread will be waiting, + * or null + */ + public WaitingThread(Condition cond, RouteSpecificPool pool) { + + if (cond == null) { + throw new IllegalArgumentException("Condition must not be null."); + } + + this.cond = cond; + this.pool = pool; + } + + + /** + * Obtains the condition. + * + * @return the condition on which to wait, never null + */ + public final Condition getCondition() { + // not synchronized + return this.cond; + } + + + /** + * Obtains the pool, if there is one. + * + * @return the pool on which a thread is or was waiting, + * or null + */ + public final RouteSpecificPool getPool() { + // not synchronized + return this.pool; + } + + + /** + * Obtains the thread, if there is one. + * + * @return the thread which is waiting, or null + */ + public final Thread getThread() { + // not synchronized + return this.waiter; + } + + + /** + * Blocks the calling thread. + * This method returns when the thread is notified or interrupted, + * if a timeout occurrs, or if there is a spurious wakeup. + *
+ * This method assumes external synchronization. + * + * @param deadline when to time out, or null for no timeout + * + * @return true if the condition was satisfied, + * false in case of a timeout. + * Typically, a call to {@link #wakeup} is used to indicate + * that the condition was satisfied. Since the condition is + * accessible outside, this cannot be guaranteed though. + * + * @throws InterruptedException if the waiting thread was interrupted + * + * @see #wakeup + */ + public boolean await(Date deadline) + throws InterruptedException { + + // This is only a sanity check. We cannot synchronize here, + // the lock would not be released on calling cond.await() below. + if (this.waiter != null) { + throw new IllegalStateException + ("A thread is already waiting on this object." + + "\ncaller: " + Thread.currentThread() + + "\nwaiter: " + this.waiter); + } + + if (aborted) + throw new InterruptedException("Operation interrupted"); + + this.waiter = Thread.currentThread(); + + boolean success = false; + try { + if (deadline != null) { + success = this.cond.awaitUntil(deadline); + } else { + this.cond.await(); + success = true; + } + if (aborted) + throw new InterruptedException("Operation interrupted"); + } finally { + this.waiter = null; + } + return success; + + } // await + + + /** + * Wakes up the waiting thread. + *
+ * This method assumes external synchronization. + */ + public void wakeup() { + + // If external synchronization and pooling works properly, + // this cannot happen. Just a sanity check. + if (this.waiter == null) { + throw new IllegalStateException + ("Nobody waiting on this object."); + } + + // One condition might be shared by several WaitingThread instances. + // It probably isn't, but just in case: wake all, not just one. + this.cond.signalAll(); + } + + public void interrupt() { + aborted = true; + this.cond.signalAll(); + } + + +} // class WaitingThread Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/WaitingThreadAborter.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/WaitingThreadAborter.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/WaitingThreadAborter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.conn.tsccm; + +/** + * A simple class that can interrupt a {@link WaitingThread}. + * + * Must be called with the pool lock held. + * + * @since 4.0 + * + * @deprecated (4.2) do not use + */ +@Deprecated +public class WaitingThreadAborter { + + private WaitingThread waitingThread; + private boolean aborted; + + /** + * If a waiting thread has been set, interrupts it. + */ + public void abort() { + aborted = true; + + if (waitingThread != null) + waitingThread.interrupt(); + + } + + /** + * Sets the waiting thread. If this has already been aborted, + * the waiting thread is immediately interrupted. + * + * @param waitingThread The thread to interrupt when aborting. + */ + public void setWaitingThread(WaitingThread waitingThread) { + this.waitingThread = waitingThread; + if (aborted) + waitingThread.interrupt(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/doc-files/tsccm-structure.png =================================================================== diff -u Binary files differ Index: 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/conn/tsccm/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,200 @@ + + + + + +The implementation of a thread-safe client connection manager. + +

+Relation Diagram +
+ +

+The implementation is structured into three areas, as illustrated +by the diagram above. +Facing the application is the Manager (green), which internally +maintains a Pool (yellow) of connections and waiting threads. +Both Manager and Pool rely on Operations (cyan) to provide the +actual connections. +

+

+In order to allow connection garbage collection, it is +imperative that hard object references between the areas are +restricted to the relations indicated by arrows in the diagram: +

+
    +
  • Applications reference only the Manager objects.
  • +
  • Manager objects reference Pool objects, but not vice versa.
  • +
  • Operations objects do not reference either Manager or Pool objects.
  • +
+ +

+The following table shows a selection of classes and interfaces, +and their assignment to the three areas. +

+
+ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+{@link org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager} + +{@link org.apache.http.impl.conn.tsccm.AbstractConnPool} +
+{@link org.apache.http.impl.conn.tsccm.BasicPooledConnAdapter} + +{@link org.apache.http.impl.conn.tsccm.ConnPoolByRoute} +
+{@link org.apache.http.impl.conn.tsccm.BasicPoolEntry} + +{@link org.apache.http.impl.conn.tsccm.BasicPoolEntry} +
+{@link org.apache.http.conn.ClientConnectionOperator} +
+{@link org.apache.http.conn.OperatedClientConnection} +
+
+ +

+The Manager area has implementations for the connection management +interfaces {@link org.apache.http.conn.ClientConnectionManager} +and {@link org.apache.http.conn.ManagedClientConnection}. +The latter is an adapter from managed to operated connections, based on a +{@link org.apache.http.impl.conn.tsccm.BasicPoolEntry}. +
+The Pool area shows an abstract pool class +{@link org.apache.http.impl.conn.tsccm.AbstractConnPool} +and a concrete implementation +{@link org.apache.http.impl.conn.tsccm.ConnPoolByRoute} +which uses the same basic algorithm as the +MultiThreadedHttpConnectionManager +in HttpClient 3.x. +A pool contains instances of +{@link org.apache.http.impl.conn.tsccm.BasicPoolEntry}. +Most other classes in this package also belong to the Pool area. +
+In the Operations area, you will find only the interfaces for +operated connections as defined in the org.apache.http.conn package. +The connection manager will work with all correct implementations +of these interfaces. This package therefore does not define anything +specific to the Operations area. +

+ +

+As you have surely noticed, the +{@link org.apache.http.impl.conn.tsccm.BasicPoolEntry} +appears in both the Manager and Pool areas. +This is where things get tricky for connection garbage collection. +
+A connection pool may start a background thread to implement cleanup. +In that case, the connection pool will not be garbage collected until +it is shut down, since the background thread keeps a hard reference +to the pool. The pool itself keeps hard references to the pooled entries, +which in turn reference idle connections. Neither of these is subject +to garbage collection. +Only the shutdown of the pool will stop the background thread, +thereby enabling garbage collection of the pool objects. +
+A pool entry that is passed to an application by means of a connection +adapter will move from the Pool area to the Manager area. When the +connection is released by the application, the manager returns the +entry back to the pool. With that step, the pool entry moves from +the Manager area back to the Pool area. +While the entry is in the Manager area, the pool MUST NOT keep a +hard reference to it. +

+ +

+The purpose of connection garbage collection is to detect when an +application fails to return a connection. In order to achieve this, +the only hard reference to the pool entry in the Manager area is +in the connection wrapper. The manager will not keep a hard reference +to the connection wrapper either, since that wrapper is effectively +moving to the Application area. +If the application drops it's reference to the connection wrapper, +that wrapper will be garbage collected, and with it the pool entry. +
+In order to detect garbage collection of pool entries handed out +to the application, the pool keeps a weak reference to the +entry. Instances of +{@link org.apache.http.impl.conn.tsccm.BasicPoolEntryRef} +combine the weak reference with information about the route for +which the pool entry was allocated. If one of these entry references +becomes stale, the pool can accommodate for the lost connection. +This is triggered either by a background thread waiting for the +references to be queued by the garbage collector, or by the +application calling a {@link + org.apache.http.conn.ClientConnectionManager#closeIdleConnections cleanup} +method of the connection manager. +
+Basically the same trick is used for detecting garbage collection +of the connection manager itself. The pool keeps a weak reference +to the connection manager that created it. However, this will work +only if there is a background thread to detect when that reference +is queued by the garbage collector. Otherwise, a finalizer of the +connection manager will shut down the pool and release it's resources. +

+ + + + Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/AbstractCookieAttributeHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/AbstractCookieAttributeHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/AbstractCookieAttributeHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,53 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.MalformedCookieException; + +/** + * + * @since 4.0 + */ +@Immutable +public abstract class AbstractCookieAttributeHandler implements CookieAttributeHandler { + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + // Do nothing + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + // Always match + return true; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/AbstractCookieSpec.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/AbstractCookieSpec.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/AbstractCookieSpec.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,108 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieSpec; + +/** + * Abstract cookie specification which can delegate the job of parsing, + * validation or matching cookie attributes to a number of arbitrary + * {@link CookieAttributeHandler}s. + * + * + * @since 4.0 + */ +@NotThreadSafe // HashMap is not thread-safe +public abstract class AbstractCookieSpec implements CookieSpec { + + /** + * Stores attribute name -> attribute handler mappings + */ + private final Map attribHandlerMap; + + /** + * Default constructor + * */ + public AbstractCookieSpec() { + super(); + this.attribHandlerMap = new HashMap(10); + } + + public void registerAttribHandler( + final String name, final CookieAttributeHandler handler) { + if (name == null) { + throw new IllegalArgumentException("Attribute name may not be null"); + } + if (handler == null) { + throw new IllegalArgumentException("Attribute handler may not be null"); + } + this.attribHandlerMap.put(name, handler); + } + + /** + * Finds an attribute handler {@link CookieAttributeHandler} for the + * given attribute. Returns null if no attribute handler is + * found for the specified attribute. + * + * @param name attribute name. e.g. Domain, Path, etc. + * @return an attribute handler or null + */ + protected CookieAttributeHandler findAttribHandler(final String name) { + return this.attribHandlerMap.get(name); + } + + /** + * Gets attribute handler {@link CookieAttributeHandler} for the + * given attribute. + * + * @param name attribute name. e.g. Domain, Path, etc. + * @throws IllegalStateException if handler not found for the + * specified attribute. + */ + protected CookieAttributeHandler getAttribHandler(final String name) { + CookieAttributeHandler handler = findAttribHandler(name); + if (handler == null) { + throw new IllegalStateException("Handler not registered for " + + name + " attribute."); + } else { + return handler; + } + } + + protected Collection getAttribHandlers() { + return this.attribHandlerMap.values(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicClientCookie.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicClientCookie.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicClientCookie.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,365 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.SetCookie; + +/** + * Default implementation of {@link SetCookie}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicClientCookie implements SetCookie, ClientCookie, Cloneable, Serializable { + + private static final long serialVersionUID = -3869795591041535538L; + + /** + * Default Constructor taking a name and a value. The value may be null. + * + * @param name The name. + * @param value The value. + */ + public BasicClientCookie(final String name, final String value) { + super(); + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + this.name = name; + this.attribs = new HashMap(); + this.value = value; + } + + /** + * Returns the name. + * + * @return String name The name + */ + public String getName() { + return this.name; + } + + /** + * Returns the value. + * + * @return String value The current value. + */ + public String getValue() { + return this.value; + } + + /** + * Sets the value + * + * @param value + */ + public void setValue(final String value) { + this.value = value; + } + + /** + * Returns the comment describing the purpose of this cookie, or + * null if no such comment has been defined. + * + * @return comment + * + * @see #setComment(String) + */ + public String getComment() { + return cookieComment; + } + + /** + * If a user agent (web browser) presents this cookie to a user, the + * cookie's purpose will be described using this comment. + * + * @param comment + * + * @see #getComment() + */ + public void setComment(String comment) { + cookieComment = comment; + } + + + /** + * Returns null. Cookies prior to RFC2965 do not set this attribute + */ + public String getCommentURL() { + return null; + } + + + /** + * Returns the expiration {@link Date} of the cookie, or null + * if none exists. + *

Note: the object returned by this method is + * considered immutable. Changing it (e.g. using setTime()) could result + * in undefined behaviour. Do so at your peril.

+ * @return Expiration {@link Date}, or null. + * + * @see #setExpiryDate(java.util.Date) + * + */ + public Date getExpiryDate() { + return cookieExpiryDate; + } + + /** + * Sets expiration date. + *

Note: the object returned by this method is considered + * immutable. Changing it (e.g. using setTime()) could result in undefined + * behaviour. Do so at your peril.

+ * + * @param expiryDate the {@link Date} after which this cookie is no longer valid. + * + * @see #getExpiryDate + * + */ + public void setExpiryDate (Date expiryDate) { + cookieExpiryDate = expiryDate; + } + + + /** + * Returns false if the cookie should be discarded at the end + * of the "session"; true otherwise. + * + * @return false if the cookie should be discarded at the end + * of the "session"; true otherwise + */ + public boolean isPersistent() { + return (null != cookieExpiryDate); + } + + + /** + * Returns domain attribute of the cookie. + * + * @return the value of the domain attribute + * + * @see #setDomain(java.lang.String) + */ + public String getDomain() { + return cookieDomain; + } + + /** + * Sets the domain attribute. + * + * @param domain The value of the domain attribute + * + * @see #getDomain + */ + public void setDomain(String domain) { + if (domain != null) { + cookieDomain = domain.toLowerCase(Locale.ENGLISH); + } else { + cookieDomain = null; + } + } + + + /** + * Returns the path attribute of the cookie + * + * @return The value of the path attribute. + * + * @see #setPath(java.lang.String) + */ + public String getPath() { + return cookiePath; + } + + /** + * Sets the path attribute. + * + * @param path The value of the path attribute + * + * @see #getPath + * + */ + public void setPath(String path) { + cookiePath = path; + } + + /** + * @return true if this cookie should only be sent over secure connections. + * @see #setSecure(boolean) + */ + public boolean isSecure() { + return isSecure; + } + + /** + * Sets the secure attribute of the cookie. + *

+ * When true the cookie should only be sent + * using a secure protocol (https). This should only be set when + * the cookie's originating server used a secure protocol to set the + * cookie's value. + * + * @param secure The value of the secure attribute + * + * @see #isSecure() + */ + public void setSecure (boolean secure) { + isSecure = secure; + } + + + /** + * Returns null. Cookies prior to RFC2965 do not set this attribute + */ + public int[] getPorts() { + return null; + } + + + /** + * Returns the version of the cookie specification to which this + * cookie conforms. + * + * @return the version of the cookie. + * + * @see #setVersion(int) + * + */ + public int getVersion() { + return cookieVersion; + } + + /** + * Sets the version of the cookie specification to which this + * cookie conforms. + * + * @param version the version of the cookie. + * + * @see #getVersion + */ + public void setVersion(int version) { + cookieVersion = version; + } + + /** + * Returns true if this cookie has expired. + * @param date Current time + * + * @return true if the cookie has expired. + */ + public boolean isExpired(final Date date) { + if (date == null) { + throw new IllegalArgumentException("Date may not be null"); + } + return (cookieExpiryDate != null + && cookieExpiryDate.getTime() <= date.getTime()); + } + + public void setAttribute(final String name, final String value) { + this.attribs.put(name, value); + } + + public String getAttribute(final String name) { + return this.attribs.get(name); + } + + public boolean containsAttribute(final String name) { + return this.attribs.get(name) != null; + } + + @Override + public Object clone() throws CloneNotSupportedException { + BasicClientCookie clone = (BasicClientCookie) super.clone(); + clone.attribs = new HashMap(this.attribs); + return clone; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("[version: "); + buffer.append(Integer.toString(this.cookieVersion)); + buffer.append("]"); + buffer.append("[name: "); + buffer.append(this.name); + buffer.append("]"); + buffer.append("[value: "); + buffer.append(this.value); + buffer.append("]"); + buffer.append("[domain: "); + buffer.append(this.cookieDomain); + buffer.append("]"); + buffer.append("[path: "); + buffer.append(this.cookiePath); + buffer.append("]"); + buffer.append("[expiry: "); + buffer.append(this.cookieExpiryDate); + buffer.append("]"); + return buffer.toString(); + } + + // ----------------------------------------------------- Instance Variables + + /** Cookie name */ + private final String name; + + /** Cookie attributes as specified by the origin server */ + private Map attribs; + + /** Cookie value */ + private String value; + + /** Comment attribute. */ + private String cookieComment; + + /** Domain attribute. */ + private String cookieDomain; + + /** Expiration {@link Date}. */ + private Date cookieExpiryDate; + + /** Path attribute. */ + private String cookiePath; + + /** My secure flag. */ + private boolean isSecure; + + /** The version of the cookie specification I was created from. */ + private int cookieVersion; + +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicClientCookie2.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicClientCookie2.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicClientCookie2.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,103 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.io.Serializable; +import java.util.Date; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.cookie.SetCookie2; + +/** + * Default implementation of {@link SetCookie2}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicClientCookie2 extends BasicClientCookie implements SetCookie2, Serializable { + + private static final long serialVersionUID = -7744598295706617057L; + + private String commentURL; + private int[] ports; + private boolean discard; + + /** + * Default Constructor taking a name and a value. The value may be null. + * + * @param name The name. + * @param value The value. + */ + public BasicClientCookie2(final String name, final String value) { + super(name, value); + } + + @Override + public int[] getPorts() { + return this.ports; + } + + public void setPorts(final int[] ports) { + this.ports = ports; + } + + @Override + public String getCommentURL() { + return this.commentURL; + } + + public void setCommentURL(final String commentURL) { + this.commentURL = commentURL; + } + + public void setDiscard(boolean discard) { + this.discard = discard; + } + + @Override + public boolean isPersistent() { + return !this.discard && super.isPersistent(); + } + + @Override + public boolean isExpired(final Date date) { + return this.discard || super.isExpired(date); + } + + @Override + public Object clone() throws CloneNotSupportedException { + BasicClientCookie2 clone = (BasicClientCookie2) super.clone(); + if (this.ports != null) { + clone.ports = this.ports.clone(); + } + return clone; + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicCommentHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicCommentHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicCommentHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,53 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicCommentHandler extends AbstractCookieAttributeHandler { + + public BasicCommentHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + cookie.setComment(value); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicDomainHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicDomainHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicDomainHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,126 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieRestrictionViolationException; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicDomainHandler implements CookieAttributeHandler { + + public BasicDomainHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (value == null) { + throw new MalformedCookieException("Missing value for domain attribute"); + } + if (value.trim().length() == 0) { + throw new MalformedCookieException("Blank value for domain attribute"); + } + cookie.setDomain(value); + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + // Validate the cookies domain attribute. NOTE: Domains without + // any dots are allowed to support hosts on private LANs that don't + // have DNS names. Since they have no dots, to domain-match the + // request-host and domain must be identical for the cookie to sent + // back to the origin-server. + String host = origin.getHost(); + String domain = cookie.getDomain(); + if (domain == null) { + throw new CookieRestrictionViolationException("Cookie domain may not be null"); + } + if (host.contains(".")) { + // Not required to have at least two dots. RFC 2965. + // A Set-Cookie2 with Domain=ajax.com will be accepted. + + // domain must match host + if (!host.endsWith(domain)) { + if (domain.startsWith(".")) { + domain = domain.substring(1, domain.length()); + } + if (!host.equals(domain)) { + throw new CookieRestrictionViolationException( + "Illegal domain attribute \"" + domain + + "\". Domain of origin: \"" + host + "\""); + } + } + } else { + if (!host.equals(domain)) { + throw new CookieRestrictionViolationException( + "Illegal domain attribute \"" + domain + + "\". Domain of origin: \"" + host + "\""); + } + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + String host = origin.getHost(); + String domain = cookie.getDomain(); + if (domain == null) { + return false; + } + if (host.equals(domain)) { + return true; + } + if (!domain.startsWith(".")) { + domain = '.' + domain; + } + return host.endsWith(domain) || host.equals(domain.substring(1)); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicExpiresHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicExpiresHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicExpiresHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,68 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; + + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicExpiresHandler extends AbstractCookieAttributeHandler { + + /** Valid date patterns */ + private final String[] datepatterns; + + public BasicExpiresHandler(final String[] datepatterns) { + if (datepatterns == null) { + throw new IllegalArgumentException("Array of date patterns may not be null"); + } + this.datepatterns = datepatterns; + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (value == null) { + throw new MalformedCookieException("Missing value for expires attribute"); + } + try { + cookie.setExpiryDate(DateUtils.parseDate(value, this.datepatterns)); + } catch (DateParseException dpe) { + throw new MalformedCookieException("Unable to parse expires attribute: " + + value); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicMaxAgeHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicMaxAgeHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicMaxAgeHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,69 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.cookie; + +import java.util.Date; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicMaxAgeHandler extends AbstractCookieAttributeHandler { + + public BasicMaxAgeHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (value == null) { + throw new MalformedCookieException("Missing value for max-age attribute"); + } + int age; + try { + age = Integer.parseInt(value); + } catch (NumberFormatException e) { + throw new MalformedCookieException ("Invalid max-age attribute: " + + value); + } + if (age < 0) { + throw new MalformedCookieException ("Negative max-age attribute: " + + value); + } + cookie.setExpiryDate(new Date(System.currentTimeMillis() + age * 1000L)); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicPathHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicPathHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicPathHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,95 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieRestrictionViolationException; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicPathHandler implements CookieAttributeHandler { + + public BasicPathHandler() { + super(); + } + + public void parse(final SetCookie cookie, String value) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (value == null || value.trim().length() == 0) { + value = "/"; + } + cookie.setPath(value); + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + if (!match(cookie, origin)) { + throw new CookieRestrictionViolationException( + "Illegal path attribute \"" + cookie.getPath() + + "\". Path of origin: \"" + origin.getPath() + "\""); + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + String targetpath = origin.getPath(); + String topmostPath = cookie.getPath(); + if (topmostPath == null) { + topmostPath = "/"; + } + if (topmostPath.length() > 1 && topmostPath.endsWith("/")) { + topmostPath = topmostPath.substring(0, topmostPath.length() - 1); + } + boolean match = targetpath.startsWith (topmostPath); + // if there is a match and these values are not exactly the same we have + // to make sure we're not matcing "/foobar" and "/foo" + if (match && targetpath.length() != topmostPath.length()) { + if (!topmostPath.endsWith("/")) { + match = (targetpath.charAt(topmostPath.length()) == '/'); + } + } + return match; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicSecureHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicSecureHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BasicSecureHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,66 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; + +/** + * + * @since 4.0 + */ +@Immutable +public class BasicSecureHandler extends AbstractCookieAttributeHandler { + + public BasicSecureHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + cookie.setSecure(true); + } + + @Override + public boolean match(final Cookie cookie, final CookieOrigin origin) { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + return !cookie.isSecure() || origin.isSecure(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BestMatchSpec.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BestMatchSpec.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BestMatchSpec.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,221 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.List; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.FormattedHeader; +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SM; +import org.apache.http.cookie.SetCookie2; +import org.apache.http.message.ParserCursor; +import org.apache.http.util.CharArrayBuffer; + +/** + * 'Meta' cookie specification that picks up a cookie policy based on + * the format of cookies sent with the HTTP response. + * + * @since 4.0 + */ +@NotThreadSafe // CookieSpec fields are @NotThreadSafe +public class BestMatchSpec implements CookieSpec { + + private final String[] datepatterns; + private final boolean oneHeader; + + // Cached values of CookieSpec instances + private RFC2965Spec strict; // @NotThreadSafe + private RFC2109Spec obsoleteStrict; // @NotThreadSafe + private BrowserCompatSpec compat; // @NotThreadSafe + + public BestMatchSpec(final String[] datepatterns, boolean oneHeader) { + super(); + this.datepatterns = datepatterns == null ? null : datepatterns.clone(); + this.oneHeader = oneHeader; + } + + public BestMatchSpec() { + this(null, false); + } + + private RFC2965Spec getStrict() { + if (this.strict == null) { + this.strict = new RFC2965Spec(this.datepatterns, this.oneHeader); + } + return strict; + } + + private RFC2109Spec getObsoleteStrict() { + if (this.obsoleteStrict == null) { + this.obsoleteStrict = new RFC2109Spec(this.datepatterns, this.oneHeader); + } + return obsoleteStrict; + } + + private BrowserCompatSpec getCompat() { + if (this.compat == null) { + this.compat = new BrowserCompatSpec(this.datepatterns); + } + return compat; + } + + public List parse( + final Header header, + final CookieOrigin origin) throws MalformedCookieException { + if (header == null) { + throw new IllegalArgumentException("Header may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + HeaderElement[] helems = header.getElements(); + boolean versioned = false; + boolean netscape = false; + for (HeaderElement helem: helems) { + if (helem.getParameterByName("version") != null) { + versioned = true; + } + if (helem.getParameterByName("expires") != null) { + netscape = true; + } + } + if (netscape || !versioned) { + // Need to parse the header again, because Netscape style cookies do not correctly + // support multiple header elements (comma cannot be treated as an element separator) + NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; + CharArrayBuffer buffer; + ParserCursor cursor; + if (header instanceof FormattedHeader) { + buffer = ((FormattedHeader) header).getBuffer(); + cursor = new ParserCursor( + ((FormattedHeader) header).getValuePos(), + buffer.length()); + } else { + String s = header.getValue(); + if (s == null) { + throw new MalformedCookieException("Header value is null"); + } + buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + cursor = new ParserCursor(0, buffer.length()); + } + helems = new HeaderElement[] { parser.parseHeader(buffer, cursor) }; + return getCompat().parse(helems, origin); + } else { + if (SM.SET_COOKIE2.equals(header.getName())) { + return getStrict().parse(helems, origin); + } else { + return getObsoleteStrict().parse(helems, origin); + } + } + } + + public void validate( + final Cookie cookie, + final CookieOrigin origin) throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + if (cookie.getVersion() > 0) { + if (cookie instanceof SetCookie2) { + getStrict().validate(cookie, origin); + } else { + getObsoleteStrict().validate(cookie, origin); + } + } else { + getCompat().validate(cookie, origin); + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + if (cookie.getVersion() > 0) { + if (cookie instanceof SetCookie2) { + return getStrict().match(cookie, origin); + } else { + return getObsoleteStrict().match(cookie, origin); + } + } else { + return getCompat().match(cookie, origin); + } + } + + public List

formatCookies(final List cookies) { + if (cookies == null) { + throw new IllegalArgumentException("List of cookies may not be null"); + } + int version = Integer.MAX_VALUE; + boolean isSetCookie2 = true; + for (Cookie cookie: cookies) { + if (!(cookie instanceof SetCookie2)) { + isSetCookie2 = false; + } + if (cookie.getVersion() < version) { + version = cookie.getVersion(); + } + } + if (version > 0) { + if (isSetCookie2) { + return getStrict().formatCookies(cookies); + } else { + return getObsoleteStrict().formatCookies(cookies); + } + } else { + return getCompat().formatCookies(cookies); + } + } + + public int getVersion() { + return getStrict().getVersion(); + } + + public Header getVersionHeader() { + return getStrict().getVersionHeader(); + } + + @Override + public String toString() { + return "best-match"; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BestMatchSpecFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BestMatchSpecFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BestMatchSpecFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.Collection; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.CookieSpecFactory; +import org.apache.http.cookie.params.CookieSpecPNames; +import org.apache.http.params.HttpParams; + +/** + * {@link CookieSpecFactory} implementation that creates and initializes + * {@link BestMatchSpec} instances. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}
  • + *
+ * + * @since 4.0 + */ +@Immutable +public class BestMatchSpecFactory implements CookieSpecFactory { + + public CookieSpec newInstance(final HttpParams params) { + if (params != null) { + + String[] patterns = null; + Collection param = (Collection) params.getParameter( + CookieSpecPNames.DATE_PATTERNS); + if (param != null) { + patterns = new String[param.size()]; + patterns = param.toArray(patterns); + } + boolean singleHeader = params.getBooleanParameter( + CookieSpecPNames.SINGLE_COOKIE_HEADER, false); + + return new BestMatchSpec(patterns, singleHeader); + } else { + return new BestMatchSpec(); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BrowserCompatSpec.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BrowserCompatSpec.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BrowserCompatSpec.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,188 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.FormattedHeader; +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SM; +import org.apache.http.message.BufferedHeader; +import org.apache.http.message.ParserCursor; +import org.apache.http.util.CharArrayBuffer; + +/** + * Cookie specification that strives to closely mimic (mis)behavior of + * common web browser applications such as Microsoft Internet Explorer + * and Mozilla FireFox. + * + * + * @since 4.0 + */ +@NotThreadSafe // superclass is @NotThreadSafe +public class BrowserCompatSpec extends CookieSpecBase { + + private static final String[] DEFAULT_DATE_PATTERNS = new String[] { + DateUtils.PATTERN_RFC1123, + DateUtils.PATTERN_RFC1036, + DateUtils.PATTERN_ASCTIME, + "EEE, dd-MMM-yyyy HH:mm:ss z", + "EEE, dd-MMM-yyyy HH-mm-ss z", + "EEE, dd MMM yy HH:mm:ss z", + "EEE dd-MMM-yyyy HH:mm:ss z", + "EEE dd MMM yyyy HH:mm:ss z", + "EEE dd-MMM-yyyy HH-mm-ss z", + "EEE dd-MMM-yy HH:mm:ss z", + "EEE dd MMM yy HH:mm:ss z", + "EEE,dd-MMM-yy HH:mm:ss z", + "EEE,dd-MMM-yyyy HH:mm:ss z", + "EEE, dd-MM-yyyy HH:mm:ss z", + }; + + private final String[] datepatterns; + + /** Default constructor */ + public BrowserCompatSpec(final String[] datepatterns) { + super(); + if (datepatterns != null) { + this.datepatterns = datepatterns.clone(); + } else { + this.datepatterns = DEFAULT_DATE_PATTERNS; + } + registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); + registerAttribHandler(ClientCookie.DOMAIN_ATTR, new BasicDomainHandler()); + registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); + registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); + registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); + registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( + this.datepatterns)); + } + + /** Default constructor */ + public BrowserCompatSpec() { + this(null); + } + + public List parse(final Header header, final CookieOrigin origin) + throws MalformedCookieException { + if (header == null) { + throw new IllegalArgumentException("Header may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + String headername = header.getName(); + if (!headername.equalsIgnoreCase(SM.SET_COOKIE)) { + throw new MalformedCookieException("Unrecognized cookie header '" + + header.toString() + "'"); + } + HeaderElement[] helems = header.getElements(); + boolean versioned = false; + boolean netscape = false; + for (HeaderElement helem: helems) { + if (helem.getParameterByName("version") != null) { + versioned = true; + } + if (helem.getParameterByName("expires") != null) { + netscape = true; + } + } + if (netscape || !versioned) { + // Need to parse the header again, because Netscape style cookies do not correctly + // support multiple header elements (comma cannot be treated as an element separator) + NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; + CharArrayBuffer buffer; + ParserCursor cursor; + if (header instanceof FormattedHeader) { + buffer = ((FormattedHeader) header).getBuffer(); + cursor = new ParserCursor( + ((FormattedHeader) header).getValuePos(), + buffer.length()); + } else { + String s = header.getValue(); + if (s == null) { + throw new MalformedCookieException("Header value is null"); + } + buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + cursor = new ParserCursor(0, buffer.length()); + } + helems = new HeaderElement[] { parser.parseHeader(buffer, cursor) }; + } + return parse(helems, origin); + } + + public List
formatCookies(final List cookies) { + if (cookies == null) { + throw new IllegalArgumentException("List of cookies may not be null"); + } + if (cookies.isEmpty()) { + throw new IllegalArgumentException("List of cookies may not be empty"); + } + CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size()); + buffer.append(SM.COOKIE); + buffer.append(": "); + for (int i = 0; i < cookies.size(); i++) { + Cookie cookie = cookies.get(i); + if (i > 0) { + buffer.append("; "); + } + buffer.append(cookie.getName()); + buffer.append("="); + String s = cookie.getValue(); + if (s != null) { + buffer.append(s); + } + } + List
headers = new ArrayList
(1); + headers.add(new BufferedHeader(buffer)); + return headers; + } + + public int getVersion() { + return 0; + } + + public Header getVersionHeader() { + return null; + } + + @Override + public String toString() { + return "compatibility"; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BrowserCompatSpecFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BrowserCompatSpecFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/BrowserCompatSpecFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,70 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.Collection; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.CookieSpecFactory; +import org.apache.http.cookie.params.CookieSpecPNames; +import org.apache.http.params.HttpParams; + +/** + * {@link CookieSpecFactory} implementation that creates and initializes + * {@link BrowserCompatSpec} instances. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • + *
+ * + * @since 4.0 + */ +@Immutable +public class BrowserCompatSpecFactory implements CookieSpecFactory { + + public CookieSpec newInstance(final HttpParams params) { + if (params != null) { + + String[] patterns = null; + Collection param = (Collection) params.getParameter( + CookieSpecPNames.DATE_PATTERNS); + if (param != null) { + patterns = new String[param.size()]; + patterns = param.toArray(patterns); + } + return new BrowserCompatSpec(patterns); + } else { + return new BrowserCompatSpec(); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/CookieSpecBase.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/CookieSpecBase.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/CookieSpecBase.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,129 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.HeaderElement; +import org.apache.http.NameValuePair; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.MalformedCookieException; + +/** + * Cookie management functions shared by all specification. + * + * + * @since 4.0 + */ +@NotThreadSafe // AbstractCookieSpec is not thread-safe +public abstract class CookieSpecBase extends AbstractCookieSpec { + + protected static String getDefaultPath(final CookieOrigin origin) { + String defaultPath = origin.getPath(); + int lastSlashIndex = defaultPath.lastIndexOf('/'); + if (lastSlashIndex >= 0) { + if (lastSlashIndex == 0) { + //Do not remove the very first slash + lastSlashIndex = 1; + } + defaultPath = defaultPath.substring(0, lastSlashIndex); + } + return defaultPath; + } + + protected static String getDefaultDomain(final CookieOrigin origin) { + return origin.getHost(); + } + + protected List parse(final HeaderElement[] elems, final CookieOrigin origin) + throws MalformedCookieException { + List cookies = new ArrayList(elems.length); + for (HeaderElement headerelement : elems) { + String name = headerelement.getName(); + String value = headerelement.getValue(); + if (name == null || name.length() == 0) { + throw new MalformedCookieException("Cookie name may not be empty"); + } + + BasicClientCookie cookie = new BasicClientCookie(name, value); + cookie.setPath(getDefaultPath(origin)); + cookie.setDomain(getDefaultDomain(origin)); + + // cycle through the parameters + NameValuePair[] attribs = headerelement.getParameters(); + for (int j = attribs.length - 1; j >= 0; j--) { + NameValuePair attrib = attribs[j]; + String s = attrib.getName().toLowerCase(Locale.ENGLISH); + + cookie.setAttribute(s, attrib.getValue()); + + CookieAttributeHandler handler = findAttribHandler(s); + if (handler != null) { + handler.parse(cookie, attrib.getValue()); + } + } + cookies.add(cookie); + } + return cookies; + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + for (CookieAttributeHandler handler: getAttribHandlers()) { + handler.validate(cookie, origin); + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + for (CookieAttributeHandler handler: getAttribHandlers()) { + if (!handler.match(cookie, origin)) { + return false; + } + } + return true; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/DateParseException.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/DateParseException.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/DateParseException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,59 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +/** + * An exception to indicate an error parsing a date string. + * + * @see DateUtils + * + * + * @since 4.0 + */ +@Immutable +public class DateParseException extends Exception { + + private static final long serialVersionUID = 4417696455000643370L; + + /** + * + */ + public DateParseException() { + super(); + } + + /** + * @param message the exception message + */ + public DateParseException(String message) { + super(message); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/DateUtils.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/DateUtils.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/DateUtils.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,259 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.lang.ref.SoftReference; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.TimeZone; + +import org.apache.http.annotation.Immutable; + +/** + * A utility class for parsing and formatting HTTP dates as used in cookies and + * other headers. This class handles dates as defined by RFC 2616 section + * 3.3.1 as well as some other common non-standard formats. + * + * + * @since 4.0 + */ +@Immutable +public final class DateUtils { + + /** + * Date format pattern used to parse HTTP date headers in RFC 1123 format. + */ + public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; + + /** + * Date format pattern used to parse HTTP date headers in RFC 1036 format. + */ + public static final String PATTERN_RFC1036 = "EEEE, dd-MMM-yy HH:mm:ss zzz"; + + /** + * Date format pattern used to parse HTTP date headers in ANSI C + * asctime() format. + */ + public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy"; + + private static final String[] DEFAULT_PATTERNS = new String[] { + PATTERN_RFC1036, + PATTERN_RFC1123, + PATTERN_ASCTIME + }; + + private static final Date DEFAULT_TWO_DIGIT_YEAR_START; + + public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + + static { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeZone(GMT); + calendar.set(2000, Calendar.JANUARY, 1, 0, 0, 0); + calendar.set(Calendar.MILLISECOND, 0); + DEFAULT_TWO_DIGIT_YEAR_START = calendar.getTime(); + } + + /** + * Parses a date value. The formats used for parsing the date value are retrieved from + * the default http params. + * + * @param dateValue the date value to parse + * + * @return the parsed date + * + * @throws DateParseException if the value could not be parsed using any of the + * supported date formats + */ + public static Date parseDate(String dateValue) throws DateParseException { + return parseDate(dateValue, null, null); + } + + /** + * Parses the date value using the given date formats. + * + * @param dateValue the date value to parse + * @param dateFormats the date formats to use + * + * @return the parsed date + * + * @throws DateParseException if none of the dataFormats could parse the dateValue + */ + public static Date parseDate(final String dateValue, String[] dateFormats) + throws DateParseException { + return parseDate(dateValue, dateFormats, null); + } + + /** + * Parses the date value using the given date formats. + * + * @param dateValue the date value to parse + * @param dateFormats the date formats to use + * @param startDate During parsing, two digit years will be placed in the range + * startDate to startDate + 100 years. This value may + * be null. When null is given as a parameter, year + * 2000 will be used. + * + * @return the parsed date + * + * @throws DateParseException if none of the dataFormats could parse the dateValue + */ + public static Date parseDate( + String dateValue, + String[] dateFormats, + Date startDate + ) throws DateParseException { + + if (dateValue == null) { + throw new IllegalArgumentException("dateValue is null"); + } + if (dateFormats == null) { + dateFormats = DEFAULT_PATTERNS; + } + if (startDate == null) { + startDate = DEFAULT_TWO_DIGIT_YEAR_START; + } + // trim single quotes around date if present + // see issue #5279 + if (dateValue.length() > 1 + && dateValue.startsWith("'") + && dateValue.endsWith("'") + ) { + dateValue = dateValue.substring (1, dateValue.length() - 1); + } + + for (String dateFormat : dateFormats) { + SimpleDateFormat dateParser = DateFormatHolder.formatFor(dateFormat); + dateParser.set2DigitYearStart(startDate); + + try { + return dateParser.parse(dateValue); + } catch (ParseException pe) { + // ignore this exception, we will try the next format + } + } + + // we were unable to parse the date + throw new DateParseException("Unable to parse the date " + dateValue); + } + + /** + * Formats the given date according to the RFC 1123 pattern. + * + * @param date The date to format. + * @return An RFC 1123 formatted date string. + * + * @see #PATTERN_RFC1123 + */ + public static String formatDate(Date date) { + return formatDate(date, PATTERN_RFC1123); + } + + /** + * Formats the given date according to the specified pattern. The pattern + * must conform to that used by the {@link SimpleDateFormat simple date + * format} class. + * + * @param date The date to format. + * @param pattern The pattern to use for formatting the date. + * @return A formatted date string. + * + * @throws IllegalArgumentException If the given date pattern is invalid. + * + * @see SimpleDateFormat + */ + public static String formatDate(Date date, String pattern) { + if (date == null) throw new IllegalArgumentException("date is null"); + if (pattern == null) throw new IllegalArgumentException("pattern is null"); + + SimpleDateFormat formatter = DateFormatHolder.formatFor(pattern); + return formatter.format(date); + } + + /** This class should not be instantiated. */ + private DateUtils() { + } + + /** + * A factory for {@link SimpleDateFormat}s. The instances are stored in a + * threadlocal way because SimpleDateFormat is not threadsafe as noted in + * {@link SimpleDateFormat its javadoc}. + * + */ + final static class DateFormatHolder { + + private static final ThreadLocal>> + THREADLOCAL_FORMATS = new ThreadLocal>>() { + + @Override + protected SoftReference> initialValue() { + return new SoftReference>( + new HashMap()); + } + + }; + + /** + * creates a {@link SimpleDateFormat} for the requested format string. + * + * @param pattern + * a non-null format String according to + * {@link SimpleDateFormat}. The format is not checked against + * null since all paths go through + * {@link DateUtils}. + * @return the requested format. This simple dateformat should not be used + * to {@link SimpleDateFormat#applyPattern(String) apply} to a + * different pattern. + */ + public static SimpleDateFormat formatFor(String pattern) { + SoftReference> ref = THREADLOCAL_FORMATS.get(); + Map formats = ref.get(); + if (formats == null) { + formats = new HashMap(); + THREADLOCAL_FORMATS.set( + new SoftReference>(formats)); + } + + SimpleDateFormat format = formats.get(pattern); + if (format == null) { + format = new SimpleDateFormat(pattern, Locale.US); + format.setTimeZone(TimeZone.getTimeZone("GMT")); + formats.put(pattern, format); + } + + return format; + } + + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/IgnoreSpec.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/IgnoreSpec.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/IgnoreSpec.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,63 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.Collections; +import java.util.List; + +import org.apache.http.Header; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.MalformedCookieException; + +/** + * CookieSpec that ignores all cookies + * + * @since 4.1 + */ +@NotThreadSafe // superclass is @NotThreadSafe +public class IgnoreSpec extends CookieSpecBase { + + public int getVersion() { + return 0; + } + + public List parse(Header header, CookieOrigin origin) + throws MalformedCookieException { + return Collections.emptyList(); + } + + public List
formatCookies(List cookies) { + return Collections.emptyList(); + } + + public Header getVersionHeader() { + return null; + } +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/IgnoreSpecFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/IgnoreSpecFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/IgnoreSpecFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,47 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.CookieSpecFactory; +import org.apache.http.params.HttpParams; + +/** + * {@link CookieSpecFactory} implementation that ignores all cookies. + * + * @since 4.1 + */ +@Immutable +public class IgnoreSpecFactory implements CookieSpecFactory { + + public CookieSpec newInstance(final HttpParams params) { + return new IgnoreSpec(); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDomainHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDomainHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDomainHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,110 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.cookie; + +import java.util.Locale; +import java.util.StringTokenizer; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieRestrictionViolationException; +import org.apache.http.cookie.MalformedCookieException; + +/** + * + * @since 4.0 + */ +@Immutable +public class NetscapeDomainHandler extends BasicDomainHandler { + + public NetscapeDomainHandler() { + super(); + } + + @Override + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + super.validate(cookie, origin); + // Perform Netscape Cookie draft specific validation + String host = origin.getHost(); + String domain = cookie.getDomain(); + if (host.contains(".")) { + int domainParts = new StringTokenizer(domain, ".").countTokens(); + + if (isSpecialDomain(domain)) { + if (domainParts < 2) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" violates the Netscape cookie specification for " + + "special domains"); + } + } else { + if (domainParts < 3) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" violates the Netscape cookie specification"); + } + } + } + } + + /** + * Checks if the given domain is in one of the seven special + * top level domains defined by the Netscape cookie specification. + * @param domain The domain. + * @return True if the specified domain is "special" + */ + private static boolean isSpecialDomain(final String domain) { + final String ucDomain = domain.toUpperCase(Locale.ENGLISH); + return ucDomain.endsWith(".COM") + || ucDomain.endsWith(".EDU") + || ucDomain.endsWith(".NET") + || ucDomain.endsWith(".GOV") + || ucDomain.endsWith(".MIL") + || ucDomain.endsWith(".ORG") + || ucDomain.endsWith(".INT"); + } + + @Override + public boolean match(Cookie cookie, CookieOrigin origin) { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + String host = origin.getHost(); + String domain = cookie.getDomain(); + if (domain == null) { + return false; + } + return host.endsWith(domain); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDraftHeaderParser.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDraftHeaderParser.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDraftHeaderParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,142 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.HeaderElement; +import org.apache.http.NameValuePair; +import org.apache.http.ParseException; +import org.apache.http.message.BasicHeaderElement; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.message.ParserCursor; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.CharArrayBuffer; + +/** + * + * @since 4.0 + */ +@Immutable +public class NetscapeDraftHeaderParser { + + public final static NetscapeDraftHeaderParser DEFAULT = new NetscapeDraftHeaderParser(); + + public NetscapeDraftHeaderParser() { + super(); + } + + public HeaderElement parseHeader( + final CharArrayBuffer buffer, + final ParserCursor cursor) throws ParseException { + if (buffer == null) { + throw new IllegalArgumentException("Char array buffer may not be null"); + } + if (cursor == null) { + throw new IllegalArgumentException("Parser cursor may not be null"); + } + NameValuePair nvp = parseNameValuePair(buffer, cursor); + List params = new ArrayList(); + while (!cursor.atEnd()) { + NameValuePair param = parseNameValuePair(buffer, cursor); + params.add(param); + } + return new BasicHeaderElement( + nvp.getName(), + nvp.getValue(), params.toArray(new NameValuePair[params.size()])); + } + + private NameValuePair parseNameValuePair( + final CharArrayBuffer buffer, final ParserCursor cursor) { + boolean terminated = false; + + int pos = cursor.getPos(); + int indexFrom = cursor.getPos(); + int indexTo = cursor.getUpperBound(); + + // Find name + String name = null; + while (pos < indexTo) { + char ch = buffer.charAt(pos); + if (ch == '=') { + break; + } + if (ch == ';') { + terminated = true; + break; + } + pos++; + } + + if (pos == indexTo) { + terminated = true; + name = buffer.substringTrimmed(indexFrom, indexTo); + } else { + name = buffer.substringTrimmed(indexFrom, pos); + pos++; + } + + if (terminated) { + cursor.updatePos(pos); + return new BasicNameValuePair(name, null); + } + + // Find value + String value = null; + int i1 = pos; + + while (pos < indexTo) { + char ch = buffer.charAt(pos); + if (ch == ';') { + terminated = true; + break; + } + pos++; + } + + int i2 = pos; + // Trim leading white spaces + while (i1 < i2 && (HTTP.isWhitespace(buffer.charAt(i1)))) { + i1++; + } + // Trim trailing white spaces + while ((i2 > i1) && (HTTP.isWhitespace(buffer.charAt(i2 - 1)))) { + i2--; + } + value = buffer.substring(i1, i2); + if (terminated) { + pos++; + } + cursor.updatePos(pos); + return new BasicNameValuePair(name, value); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDraftSpec.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDraftSpec.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDraftSpec.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,180 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.FormattedHeader; +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SM; +import org.apache.http.message.BufferedHeader; +import org.apache.http.message.ParserCursor; +import org.apache.http.util.CharArrayBuffer; + +/** + * This {@link CookieSpec} implementation conforms to the original draft + * specification published by Netscape Communications. It should be avoided + * unless absolutely necessary for compatibility with legacy code. + * + * @since 4.0 + */ +@NotThreadSafe // superclass is @NotThreadSafe +public class NetscapeDraftSpec extends CookieSpecBase { + + protected static final String EXPIRES_PATTERN = "EEE, dd-MMM-yy HH:mm:ss z"; + + private final String[] datepatterns; + + /** Default constructor */ + public NetscapeDraftSpec(final String[] datepatterns) { + super(); + if (datepatterns != null) { + this.datepatterns = datepatterns.clone(); + } else { + this.datepatterns = new String[] { EXPIRES_PATTERN }; + } + registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); + registerAttribHandler(ClientCookie.DOMAIN_ATTR, new NetscapeDomainHandler()); + registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); + registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); + registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); + registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( + this.datepatterns)); + } + + /** Default constructor */ + public NetscapeDraftSpec() { + this(null); + } + + /** + * Parses the Set-Cookie value into an array of Cookies. + * + *

Syntax of the Set-Cookie HTTP Response Header:

+ * + *

This is the format a CGI script would use to add to + * the HTTP headers a new piece of data which is to be stored by + * the client for later retrieval.

+ * + *
+      *  Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
+      * 
+ * + *

Please note that the Netscape draft specification does not fully conform to the HTTP + * header format. Comma character if present in Set-Cookie will not be treated + * as a header element separator

+ * + * @see + * The Cookie Spec. + * + * @param header the Set-Cookie received from the server + * @return an array of Cookies parsed from the Set-Cookie value + * @throws MalformedCookieException if an exception occurs during parsing + */ + public List parse(final Header header, final CookieOrigin origin) + throws MalformedCookieException { + if (header == null) { + throw new IllegalArgumentException("Header may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) { + throw new MalformedCookieException("Unrecognized cookie header '" + + header.toString() + "'"); + } + NetscapeDraftHeaderParser parser = NetscapeDraftHeaderParser.DEFAULT; + CharArrayBuffer buffer; + ParserCursor cursor; + if (header instanceof FormattedHeader) { + buffer = ((FormattedHeader) header).getBuffer(); + cursor = new ParserCursor( + ((FormattedHeader) header).getValuePos(), + buffer.length()); + } else { + String s = header.getValue(); + if (s == null) { + throw new MalformedCookieException("Header value is null"); + } + buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + cursor = new ParserCursor(0, buffer.length()); + } + return parse(new HeaderElement[] { parser.parseHeader(buffer, cursor) }, origin); + } + + public List
formatCookies(final List cookies) { + if (cookies == null) { + throw new IllegalArgumentException("List of cookies may not be null"); + } + if (cookies.isEmpty()) { + throw new IllegalArgumentException("List of cookies may not be empty"); + } + CharArrayBuffer buffer = new CharArrayBuffer(20 * cookies.size()); + buffer.append(SM.COOKIE); + buffer.append(": "); + for (int i = 0; i < cookies.size(); i++) { + Cookie cookie = cookies.get(i); + if (i > 0) { + buffer.append("; "); + } + buffer.append(cookie.getName()); + String s = cookie.getValue(); + if (s != null) { + buffer.append("="); + buffer.append(s); + } + } + List
headers = new ArrayList
(1); + headers.add(new BufferedHeader(buffer)); + return headers; + } + + public int getVersion() { + return 0; + } + + public Header getVersionHeader() { + return null; + } + + @Override + public String toString() { + return "netscape"; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDraftSpecFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDraftSpecFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/NetscapeDraftSpecFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,70 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.Collection; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.CookieSpecFactory; +import org.apache.http.cookie.params.CookieSpecPNames; +import org.apache.http.params.HttpParams; + +/** + * {@link CookieSpecFactory} implementation that creates and initializes + * {@link NetscapeDraftSpec} instances. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • + *
+ * + * @since 4.0 + */ +@Immutable +public class NetscapeDraftSpecFactory implements CookieSpecFactory { + + public CookieSpec newInstance(final HttpParams params) { + if (params != null) { + + String[] patterns = null; + Collection param = (Collection) params.getParameter( + CookieSpecPNames.DATE_PATTERNS); + if (param != null) { + patterns = new String[param.size()]; + patterns = param.toArray(patterns); + } + return new NetscapeDraftSpec(patterns); + } else { + return new NetscapeDraftSpec(); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/PublicSuffixFilter.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/PublicSuffixFilter.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/PublicSuffixFilter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,123 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.apache.http.client.utils.Punycode; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; + +/** + * Wraps a CookieAttributeHandler and leverages its match method + * to never match a suffix from a black list. May be used to provide + * additional security for cross-site attack types by preventing + * cookies from apparent domains that are not publicly available. + * An uptodate list of suffixes can be obtained from + * publicsuffix.org + * + * @since 4.0 + */ +public class PublicSuffixFilter implements CookieAttributeHandler { + private final CookieAttributeHandler wrapped; + private Set exceptions; + private Set suffixes; + + public PublicSuffixFilter(CookieAttributeHandler wrapped) { + this.wrapped = wrapped; + } + + /** + * Sets the suffix blacklist patterns. + * A pattern can be "com", "*.jp" + * TODO add support for patterns like "lib.*.us" + * @param suffixes + */ + public void setPublicSuffixes(Collection suffixes) { + this.suffixes = new HashSet(suffixes); + } + + /** + * Sets the exceptions from the blacklist. Exceptions can not be patterns. + * TODO add support for patterns + * @param exceptions + */ + public void setExceptions(Collection exceptions) { + this.exceptions = new HashSet(exceptions); + } + + /** + * Never matches if the cookie's domain is from the blacklist. + */ + public boolean match(Cookie cookie, CookieOrigin origin) { + if (isForPublicSuffix(cookie)) return false; + return wrapped.match(cookie, origin); + } + + public void parse(SetCookie cookie, String value) throws MalformedCookieException { + wrapped.parse(cookie, value); + } + + public void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException { + wrapped.validate(cookie, origin); + } + + private boolean isForPublicSuffix(Cookie cookie) { + String domain = cookie.getDomain(); + if (domain.startsWith(".")) domain = domain.substring(1); + domain = Punycode.toUnicode(domain); + + // An exception rule takes priority over any other matching rule. + if (this.exceptions != null) { + if (this.exceptions.contains(domain)) return false; + } + + + if (this.suffixes == null) return false; + + do { + if (this.suffixes.contains(domain)) return true; + // patterns + if (domain.startsWith("*.")) domain = domain.substring(2); + int nextdot = domain.indexOf('.'); + if (nextdot == -1) break; + domain = "*" + domain.substring(nextdot); + } while (domain.length() > 0); + + return false; + } +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/PublicSuffixListParser.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/PublicSuffixListParser.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/PublicSuffixListParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,113 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.http.annotation.Immutable; + +/** + * Parses the list from publicsuffix.org + * and configures a PublicSuffixFilter. + * + * @since 4.0 + */ +@Immutable +public class PublicSuffixListParser { + private static final int MAX_LINE_LEN = 256; + private final PublicSuffixFilter filter; + + PublicSuffixListParser(PublicSuffixFilter filter) { + this.filter = filter; + } + + /** + * Parses the public suffix list format. + * When creating the reader from the file, make sure to + * use the correct encoding (the original list is in UTF-8). + * + * @param list the suffix list. The caller is responsible for closing the reader. + * @throws IOException on error while reading from list + */ + public void parse(Reader list) throws IOException { + Collection rules = new ArrayList(); + Collection exceptions = new ArrayList(); + BufferedReader r = new BufferedReader(list); + StringBuilder sb = new StringBuilder(256); + boolean more = true; + while (more) { + more = readLine(r, sb); + String line = sb.toString(); + if (line.length() == 0) continue; + if (line.startsWith("//")) continue; //entire lines can also be commented using // + if (line.startsWith(".")) line = line.substring(1); // A leading dot is optional + // An exclamation mark (!) at the start of a rule marks an exception to a previous wildcard rule + boolean isException = line.startsWith("!"); + if (isException) line = line.substring(1); + + if (isException) { + exceptions.add(line); + } else { + rules.add(line); + } + } + + filter.setPublicSuffixes(rules); + filter.setExceptions(exceptions); + } + + /** + * + * @param r + * @param sb + * @return false when the end of the stream is reached + * @throws IOException + */ + private boolean readLine(Reader r, StringBuilder sb) throws IOException { + sb.setLength(0); + int b; + boolean hitWhitespace = false; + while ((b = r.read()) != -1) { + char c = (char) b; + if (c == '\n') break; + // Each line is only read up to the first whitespace + if (Character.isWhitespace(c)) hitWhitespace = true; + if (!hitWhitespace) sb.append(c); + if (sb.length() > MAX_LINE_LEN) throw new IOException("Line too long"); // prevent excess memory usage + } + return (b != -1); + } +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109DomainHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109DomainHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109DomainHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,130 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.cookie; + +import java.util.Locale; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieRestrictionViolationException; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; + +/** + * + * @since 4.0 + */ +@Immutable +public class RFC2109DomainHandler implements CookieAttributeHandler { + + public RFC2109DomainHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (value == null) { + throw new MalformedCookieException("Missing value for domain attribute"); + } + if (value.trim().length() == 0) { + throw new MalformedCookieException("Blank value for domain attribute"); + } + cookie.setDomain(value); + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + String host = origin.getHost(); + String domain = cookie.getDomain(); + if (domain == null) { + throw new CookieRestrictionViolationException("Cookie domain may not be null"); + } + if (!domain.equals(host)) { + int dotIndex = domain.indexOf('.'); + if (dotIndex == -1) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" does not match the host \"" + + host + "\""); + } + // domain must start with dot + if (!domain.startsWith(".")) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" violates RFC 2109: domain must start with a dot"); + } + // domain must have at least one embedded dot + dotIndex = domain.indexOf('.', 1); + if (dotIndex < 0 || dotIndex == domain.length() - 1) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" violates RFC 2109: domain must contain an embedded dot"); + } + host = host.toLowerCase(Locale.ENGLISH); + if (!host.endsWith(domain)) { + throw new CookieRestrictionViolationException( + "Illegal domain attribute \"" + domain + + "\". Domain of origin: \"" + host + "\""); + } + // host minus domain may not contain any dots + String hostWithoutDomain = host.substring(0, host.length() - domain.length()); + if (hostWithoutDomain.indexOf('.') != -1) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + domain + + "\" violates RFC 2109: host minus domain may not contain any dots"); + } + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + String host = origin.getHost(); + String domain = cookie.getDomain(); + if (domain == null) { + return false; + } + return host.equals(domain) || (domain.startsWith(".") && host.endsWith(domain)); + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109Spec.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109Spec.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109Spec.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,248 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookiePathComparator; +import org.apache.http.cookie.CookieRestrictionViolationException; +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SM; +import org.apache.http.message.BufferedHeader; +import org.apache.http.util.CharArrayBuffer; + +/** + * RFC 2109 compliant {@link CookieSpec} implementation. This is an older + * version of the official HTTP state management specification superseded + * by RFC 2965. + * + * @see RFC2965Spec + * + * @since 4.0 + */ +@NotThreadSafe // superclass is @NotThreadSafe +public class RFC2109Spec extends CookieSpecBase { + + private final static CookiePathComparator PATH_COMPARATOR = new CookiePathComparator(); + + private final static String[] DATE_PATTERNS = { + DateUtils.PATTERN_RFC1123, + DateUtils.PATTERN_RFC1036, + DateUtils.PATTERN_ASCTIME + }; + + private final String[] datepatterns; + private final boolean oneHeader; + + /** Default constructor */ + public RFC2109Spec(final String[] datepatterns, boolean oneHeader) { + super(); + if (datepatterns != null) { + this.datepatterns = datepatterns.clone(); + } else { + this.datepatterns = DATE_PATTERNS; + } + this.oneHeader = oneHeader; + registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2109VersionHandler()); + registerAttribHandler(ClientCookie.PATH_ATTR, new BasicPathHandler()); + registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2109DomainHandler()); + registerAttribHandler(ClientCookie.MAX_AGE_ATTR, new BasicMaxAgeHandler()); + registerAttribHandler(ClientCookie.SECURE_ATTR, new BasicSecureHandler()); + registerAttribHandler(ClientCookie.COMMENT_ATTR, new BasicCommentHandler()); + registerAttribHandler(ClientCookie.EXPIRES_ATTR, new BasicExpiresHandler( + this.datepatterns)); + } + + /** Default constructor */ + public RFC2109Spec() { + this(null, false); + } + + public List parse(final Header header, final CookieOrigin origin) + throws MalformedCookieException { + if (header == null) { + throw new IllegalArgumentException("Header may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE)) { + throw new MalformedCookieException("Unrecognized cookie header '" + + header.toString() + "'"); + } + HeaderElement[] elems = header.getElements(); + return parse(elems, origin); + } + + @Override + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + String name = cookie.getName(); + if (name.indexOf(' ') != -1) { + throw new CookieRestrictionViolationException("Cookie name may not contain blanks"); + } + if (name.startsWith("$")) { + throw new CookieRestrictionViolationException("Cookie name may not start with $"); + } + super.validate(cookie, origin); + } + + public List
formatCookies(List cookies) { + if (cookies == null) { + throw new IllegalArgumentException("List of cookies may not be null"); + } + if (cookies.isEmpty()) { + throw new IllegalArgumentException("List of cookies may not be empty"); + } + if (cookies.size() > 1) { + // Create a mutable copy and sort the copy. + cookies = new ArrayList(cookies); + Collections.sort(cookies, PATH_COMPARATOR); + } + if (this.oneHeader) { + return doFormatOneHeader(cookies); + } else { + return doFormatManyHeaders(cookies); + } + } + + private List
doFormatOneHeader(final List cookies) { + int version = Integer.MAX_VALUE; + // Pick the lowest common denominator + for (Cookie cookie : cookies) { + if (cookie.getVersion() < version) { + version = cookie.getVersion(); + } + } + CharArrayBuffer buffer = new CharArrayBuffer(40 * cookies.size()); + buffer.append(SM.COOKIE); + buffer.append(": "); + buffer.append("$Version="); + buffer.append(Integer.toString(version)); + for (Cookie cooky : cookies) { + buffer.append("; "); + Cookie cookie = cooky; + formatCookieAsVer(buffer, cookie, version); + } + List
headers = new ArrayList
(1); + headers.add(new BufferedHeader(buffer)); + return headers; + } + + private List
doFormatManyHeaders(final List cookies) { + List
headers = new ArrayList
(cookies.size()); + for (Cookie cookie : cookies) { + int version = cookie.getVersion(); + CharArrayBuffer buffer = new CharArrayBuffer(40); + buffer.append("Cookie: "); + buffer.append("$Version="); + buffer.append(Integer.toString(version)); + buffer.append("; "); + formatCookieAsVer(buffer, cookie, version); + headers.add(new BufferedHeader(buffer)); + } + return headers; + } + + /** + * Return a name/value string suitable for sending in a "Cookie" + * header as defined in RFC 2109 for backward compatibility with cookie + * version 0 + * @param buffer The char array buffer to use for output + * @param name The cookie name + * @param value The cookie value + * @param version The cookie version + */ + protected void formatParamAsVer(final CharArrayBuffer buffer, + final String name, final String value, int version) { + buffer.append(name); + buffer.append("="); + if (value != null) { + if (version > 0) { + buffer.append('\"'); + buffer.append(value); + buffer.append('\"'); + } else { + buffer.append(value); + } + } + } + + /** + * Return a string suitable for sending in a "Cookie" header + * as defined in RFC 2109 for backward compatibility with cookie version 0 + * @param buffer The char array buffer to use for output + * @param cookie The {@link Cookie} to be formatted as string + * @param version The version to use. + */ + protected void formatCookieAsVer(final CharArrayBuffer buffer, + final Cookie cookie, int version) { + formatParamAsVer(buffer, cookie.getName(), cookie.getValue(), version); + if (cookie.getPath() != null) { + if (cookie instanceof ClientCookie + && ((ClientCookie) cookie).containsAttribute(ClientCookie.PATH_ATTR)) { + buffer.append("; "); + formatParamAsVer(buffer, "$Path", cookie.getPath(), version); + } + } + if (cookie.getDomain() != null) { + if (cookie instanceof ClientCookie + && ((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) { + buffer.append("; "); + formatParamAsVer(buffer, "$Domain", cookie.getDomain(), version); + } + } + } + + public int getVersion() { + return 1; + } + + public Header getVersionHeader() { + return null; + } + + @Override + public String toString() { + return "rfc2109"; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109SpecFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109SpecFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109SpecFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.Collection; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.CookieSpecFactory; +import org.apache.http.cookie.params.CookieSpecPNames; +import org.apache.http.params.HttpParams; + +/** + * {@link CookieSpecFactory} implementation that creates and initializes + * {@link RFC2109Spec} instances. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}
  • + *
+ * + * @since 4.0 + */ +@Immutable +public class RFC2109SpecFactory implements CookieSpecFactory { + + public CookieSpec newInstance(final HttpParams params) { + if (params != null) { + + String[] patterns = null; + Collection param = (Collection) params.getParameter( + CookieSpecPNames.DATE_PATTERNS); + if (param != null) { + patterns = new String[param.size()]; + patterns = param.toArray(patterns); + } + boolean singleHeader = params.getBooleanParameter( + CookieSpecPNames.SINGLE_COOKIE_HEADER, false); + + return new RFC2109Spec(patterns, singleHeader); + } else { + return new RFC2109Spec(); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109VersionHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109VersionHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2109VersionHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,78 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieRestrictionViolationException; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; + +/** + * + * @since 4.0 + */ +@Immutable +public class RFC2109VersionHandler extends AbstractCookieAttributeHandler { + + public RFC2109VersionHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (value == null) { + throw new MalformedCookieException("Missing value for version attribute"); + } + if (value.trim().length() == 0) { + throw new MalformedCookieException("Blank value for version attribute"); + } + try { + cookie.setVersion(Integer.parseInt(value)); + } catch (NumberFormatException e) { + throw new MalformedCookieException("Invalid version: " + + e.getMessage()); + } + } + + @Override + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (cookie.getVersion() < 0) { + throw new CookieRestrictionViolationException("Cookie version may not be negative"); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965CommentUrlAttributeHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965CommentUrlAttributeHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965CommentUrlAttributeHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; +import org.apache.http.cookie.SetCookie2; + +/** + * "CommentURL" cookie attribute handler for RFC 2965 cookie spec. + * + * @since 4.0 + */ +@Immutable +public class RFC2965CommentUrlAttributeHandler implements CookieAttributeHandler { + + public RFC2965CommentUrlAttributeHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String commenturl) + throws MalformedCookieException { + if (cookie instanceof SetCookie2) { + SetCookie2 cookie2 = (SetCookie2) cookie; + cookie2.setCommentURL(commenturl); + } + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + return true; + } + + } Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965DiscardAttributeHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965DiscardAttributeHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965DiscardAttributeHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; +import org.apache.http.cookie.SetCookie2; + +/** + * "Discard" cookie attribute handler for RFC 2965 cookie spec. + * + * @since 4.0 + */ +@Immutable +public class RFC2965DiscardAttributeHandler implements CookieAttributeHandler { + + public RFC2965DiscardAttributeHandler() { + super(); + } + + public void parse(final SetCookie cookie, final String commenturl) + throws MalformedCookieException { + if (cookie instanceof SetCookie2) { + SetCookie2 cookie2 = (SetCookie2) cookie; + cookie2.setDiscard(true); + } + } + + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + return true; + } + + } Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965DomainAttributeHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965DomainAttributeHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965DomainAttributeHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,194 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.Locale; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieRestrictionViolationException; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; + +/** + * "Domain" cookie attribute handler for RFC 2965 cookie spec. + * + * + * @since 3.1 + */ +@Immutable +public class RFC2965DomainAttributeHandler implements CookieAttributeHandler { + + public RFC2965DomainAttributeHandler() { + super(); + } + + /** + * Parse cookie domain attribute. + */ + public void parse(final SetCookie cookie, String domain) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (domain == null) { + throw new MalformedCookieException( + "Missing value for domain attribute"); + } + if (domain.trim().length() == 0) { + throw new MalformedCookieException( + "Blank value for domain attribute"); + } + domain = domain.toLowerCase(Locale.ENGLISH); + if (!domain.startsWith(".")) { + // Per RFC 2965 section 3.2.2 + // "... If an explicitly specified value does not start with + // a dot, the user agent supplies a leading dot ..." + // That effectively implies that the domain attribute + // MAY NOT be an IP address of a host name + domain = '.' + domain; + } + cookie.setDomain(domain); + } + + /** + * Performs domain-match as defined by the RFC2965. + *

+ * Host A's name domain-matches host B's if + *

    + *
      their host name strings string-compare equal; or
    + *
      A is a HDN string and has the form NB, where N is a non-empty + * name string, B has the form .B', and B' is a HDN string. (So, + * x.y.com domain-matches .Y.com but not Y.com.)
    + *
+ * + * @param host host name where cookie is received from or being sent to. + * @param domain The cookie domain attribute. + * @return true if the specified host matches the given domain. + */ + public boolean domainMatch(String host, String domain) { + boolean match = host.equals(domain) + || (domain.startsWith(".") && host.endsWith(domain)); + + return match; + } + + /** + * Validate cookie domain attribute. + */ + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + String host = origin.getHost().toLowerCase(Locale.ENGLISH); + if (cookie.getDomain() == null) { + throw new CookieRestrictionViolationException("Invalid cookie state: " + + "domain not specified"); + } + String cookieDomain = cookie.getDomain().toLowerCase(Locale.ENGLISH); + + if (cookie instanceof ClientCookie + && ((ClientCookie) cookie).containsAttribute(ClientCookie.DOMAIN_ATTR)) { + // Domain attribute must start with a dot + if (!cookieDomain.startsWith(".")) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + cookie.getDomain() + "\" violates RFC 2109: domain must start with a dot"); + } + + // Domain attribute must contain at least one embedded dot, + // or the value must be equal to .local. + int dotIndex = cookieDomain.indexOf('.', 1); + if (((dotIndex < 0) || (dotIndex == cookieDomain.length() - 1)) + && (!cookieDomain.equals(".local"))) { + throw new CookieRestrictionViolationException( + "Domain attribute \"" + cookie.getDomain() + + "\" violates RFC 2965: the value contains no embedded dots " + + "and the value is not .local"); + } + + // The effective host name must domain-match domain attribute. + if (!domainMatch(host, cookieDomain)) { + throw new CookieRestrictionViolationException( + "Domain attribute \"" + cookie.getDomain() + + "\" violates RFC 2965: effective host name does not " + + "domain-match domain attribute."); + } + + // effective host name minus domain must not contain any dots + String effectiveHostWithoutDomain = host.substring( + 0, host.length() - cookieDomain.length()); + if (effectiveHostWithoutDomain.indexOf('.') != -1) { + throw new CookieRestrictionViolationException("Domain attribute \"" + + cookie.getDomain() + "\" violates RFC 2965: " + + "effective host minus domain may not contain any dots"); + } + } else { + // Domain was not specified in header. In this case, domain must + // string match request host (case-insensitive). + if (!cookie.getDomain().equals(host)) { + throw new CookieRestrictionViolationException("Illegal domain attribute: \"" + + cookie.getDomain() + "\"." + + "Domain of origin: \"" + + host + "\""); + } + } + } + + /** + * Match cookie domain attribute. + */ + public boolean match(final Cookie cookie, final CookieOrigin origin) { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + String host = origin.getHost().toLowerCase(Locale.ENGLISH); + String cookieDomain = cookie.getDomain(); + + // The effective host name MUST domain-match the Domain + // attribute of the cookie. + if (!domainMatch(host, cookieDomain)) { + return false; + } + // effective host name minus domain must not contain any dots + String effectiveHostWithoutDomain = host.substring( + 0, host.length() - cookieDomain.length()); + return effectiveHostWithoutDomain.indexOf('.') == -1; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965PortAttributeHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,170 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.StringTokenizer; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieRestrictionViolationException; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; +import org.apache.http.cookie.SetCookie2; + +/** + * "Port" cookie attribute handler for RFC 2965 cookie spec. + * + * @since 4.0 + */ +@Immutable +public class RFC2965PortAttributeHandler implements CookieAttributeHandler { + + public RFC2965PortAttributeHandler() { + super(); + } + + /** + * Parses the given Port attribute value (e.g. "8000,8001,8002") + * into an array of ports. + * + * @param portValue port attribute value + * @return parsed array of ports + * @throws MalformedCookieException if there is a problem in + * parsing due to invalid portValue. + */ + private static int[] parsePortAttribute(final String portValue) + throws MalformedCookieException { + StringTokenizer st = new StringTokenizer(portValue, ","); + int[] ports = new int[st.countTokens()]; + try { + int i = 0; + while(st.hasMoreTokens()) { + ports[i] = Integer.parseInt(st.nextToken().trim()); + if (ports[i] < 0) { + throw new MalformedCookieException ("Invalid Port attribute."); + } + ++i; + } + } catch (NumberFormatException e) { + throw new MalformedCookieException ("Invalid Port " + + "attribute: " + e.getMessage()); + } + return ports; + } + + /** + * Returns true if the given port exists in the given + * ports list. + * + * @param port port of host where cookie was received from or being sent to. + * @param ports port list + * @return true returns true if the given port exists in + * the given ports list; false otherwise. + */ + private static boolean portMatch(int port, int[] ports) { + boolean portInList = false; + for (int i = 0, len = ports.length; i < len; i++) { + if (port == ports[i]) { + portInList = true; + break; + } + } + return portInList; + } + + /** + * Parse cookie port attribute. + */ + public void parse(final SetCookie cookie, final String portValue) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (cookie instanceof SetCookie2) { + SetCookie2 cookie2 = (SetCookie2) cookie; + if (portValue != null && portValue.trim().length() > 0) { + int[] ports = parsePortAttribute(portValue); + cookie2.setPorts(ports); + } + } + } + + /** + * Validate cookie port attribute. If the Port attribute was specified + * in header, the request port must be in cookie's port list. + */ + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + int port = origin.getPort(); + if (cookie instanceof ClientCookie + && ((ClientCookie) cookie).containsAttribute(ClientCookie.PORT_ATTR)) { + if (!portMatch(port, cookie.getPorts())) { + throw new CookieRestrictionViolationException( + "Port attribute violates RFC 2965: " + + "Request port not found in cookie's port list."); + } + } + } + + /** + * Match cookie port attribute. If the Port attribute is not specified + * in header, the cookie can be sent to any port. Otherwise, the request port + * must be in the cookie's port list. + */ + public boolean match(final Cookie cookie, final CookieOrigin origin) { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + int port = origin.getPort(); + if (cookie instanceof ClientCookie + && ((ClientCookie) cookie).containsAttribute(ClientCookie.PORT_ATTR)) { + if (cookie.getPorts() == null) { + // Invalid cookie state: port not specified + return false; + } + if (!portMatch(port, cookie.getPorts())) { + return false; + } + } + return true; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965Spec.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965Spec.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965Spec.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,256 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.apache.http.annotation.NotThreadSafe; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.NameValuePair; +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SM; +import org.apache.http.message.BufferedHeader; +import org.apache.http.util.CharArrayBuffer; + +/** + * RFC 2965 compliant {@link CookieSpec} implementation. + * + * @since 4.0 + */ +@NotThreadSafe // superclass is @NotThreadSafe +public class RFC2965Spec extends RFC2109Spec { + + /** + * Default constructor + * + */ + public RFC2965Spec() { + this(null, false); + } + + public RFC2965Spec(final String[] datepatterns, boolean oneHeader) { + super(datepatterns, oneHeader); + registerAttribHandler(ClientCookie.DOMAIN_ATTR, new RFC2965DomainAttributeHandler()); + registerAttribHandler(ClientCookie.PORT_ATTR, new RFC2965PortAttributeHandler()); + registerAttribHandler(ClientCookie.COMMENTURL_ATTR, new RFC2965CommentUrlAttributeHandler()); + registerAttribHandler(ClientCookie.DISCARD_ATTR, new RFC2965DiscardAttributeHandler()); + registerAttribHandler(ClientCookie.VERSION_ATTR, new RFC2965VersionAttributeHandler()); + } + + @Override + public List parse( + final Header header, + CookieOrigin origin) throws MalformedCookieException { + if (header == null) { + throw new IllegalArgumentException("Header may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + if (!header.getName().equalsIgnoreCase(SM.SET_COOKIE2)) { + throw new MalformedCookieException("Unrecognized cookie header '" + + header.toString() + "'"); + } + origin = adjustEffectiveHost(origin); + HeaderElement[] elems = header.getElements(); + return createCookies(elems, origin); + } + + @Override + protected List parse( + final HeaderElement[] elems, + CookieOrigin origin) throws MalformedCookieException { + origin = adjustEffectiveHost(origin); + return createCookies(elems, origin); + } + + private List createCookies( + final HeaderElement[] elems, + final CookieOrigin origin) throws MalformedCookieException { + List cookies = new ArrayList(elems.length); + for (HeaderElement headerelement : elems) { + String name = headerelement.getName(); + String value = headerelement.getValue(); + if (name == null || name.length() == 0) { + throw new MalformedCookieException("Cookie name may not be empty"); + } + + BasicClientCookie2 cookie = new BasicClientCookie2(name, value); + cookie.setPath(getDefaultPath(origin)); + cookie.setDomain(getDefaultDomain(origin)); + cookie.setPorts(new int [] { origin.getPort() }); + // cycle through the parameters + NameValuePair[] attribs = headerelement.getParameters(); + + // Eliminate duplicate attributes. The first occurrence takes precedence + // See RFC2965: 3.2 Origin Server Role + Map attribmap = + new HashMap(attribs.length); + for (int j = attribs.length - 1; j >= 0; j--) { + NameValuePair param = attribs[j]; + attribmap.put(param.getName().toLowerCase(Locale.ENGLISH), param); + } + for (Map.Entry entry : attribmap.entrySet()) { + NameValuePair attrib = entry.getValue(); + String s = attrib.getName().toLowerCase(Locale.ENGLISH); + + cookie.setAttribute(s, attrib.getValue()); + + CookieAttributeHandler handler = findAttribHandler(s); + if (handler != null) { + handler.parse(cookie, attrib.getValue()); + } + } + cookies.add(cookie); + } + return cookies; + } + + @Override + public void validate(final Cookie cookie, CookieOrigin origin) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + origin = adjustEffectiveHost(origin); + super.validate(cookie, origin); + } + + @Override + public boolean match(final Cookie cookie, CookieOrigin origin) { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (origin == null) { + throw new IllegalArgumentException("Cookie origin may not be null"); + } + origin = adjustEffectiveHost(origin); + return super.match(cookie, origin); + } + + /** + * Adds valid Port attribute value, e.g. "8000,8001,8002" + */ + @Override + protected void formatCookieAsVer(final CharArrayBuffer buffer, + final Cookie cookie, int version) { + super.formatCookieAsVer(buffer, cookie, version); + // format port attribute + if (cookie instanceof ClientCookie) { + // Test if the port attribute as set by the origin server is not blank + String s = ((ClientCookie) cookie).getAttribute(ClientCookie.PORT_ATTR); + if (s != null) { + buffer.append("; $Port"); + buffer.append("=\""); + if (s.trim().length() > 0) { + int[] ports = cookie.getPorts(); + if (ports != null) { + for (int i = 0, len = ports.length; i < len; i++) { + if (i > 0) { + buffer.append(","); + } + buffer.append(Integer.toString(ports[i])); + } + } + } + buffer.append("\""); + } + } + } + + /** + * Set 'effective host name' as defined in RFC 2965. + *

+ * If a host name contains no dots, the effective host name is + * that name with the string .local appended to it. Otherwise + * the effective host name is the same as the host name. Note + * that all effective host names contain at least one dot. + * + * @param origin origin where cookie is received from or being sent to. + * @return + */ + private static CookieOrigin adjustEffectiveHost(final CookieOrigin origin) { + String host = origin.getHost(); + + // Test if the host name appears to be a fully qualified DNS name, + // IPv4 address or IPv6 address + boolean isLocalHost = true; + for (int i = 0; i < host.length(); i++) { + char ch = host.charAt(i); + if (ch == '.' || ch == ':') { + isLocalHost = false; + break; + } + } + if (isLocalHost) { + host += ".local"; + return new CookieOrigin( + host, + origin.getPort(), + origin.getPath(), + origin.isSecure()); + } else { + return origin; + } + } + + @Override + public int getVersion() { + return 1; + } + + @Override + public Header getVersionHeader() { + CharArrayBuffer buffer = new CharArrayBuffer(40); + buffer.append(SM.COOKIE2); + buffer.append(": "); + buffer.append("$Version="); + buffer.append(Integer.toString(getVersion())); + return new BufferedHeader(buffer); + } + + @Override + public String toString() { + return "rfc2965"; + } + +} + Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965SpecFactory.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965SpecFactory.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965SpecFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import java.util.Collection; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.CookieSpec; +import org.apache.http.cookie.CookieSpecFactory; +import org.apache.http.cookie.params.CookieSpecPNames; +import org.apache.http.params.HttpParams; + +/** + * {@link CookieSpecFactory} implementation that creates and initializes + * {@link RFC2965Spec} instances. + *

+ * The following parameters can be used to customize the behavior of this + * class: + *

    + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#DATE_PATTERNS}
  • + *
  • {@link org.apache.http.cookie.params.CookieSpecPNames#SINGLE_COOKIE_HEADER}
  • + *
+ * + * @since 4.0 + */ +@Immutable +public class RFC2965SpecFactory implements CookieSpecFactory { + + public CookieSpec newInstance(final HttpParams params) { + if (params != null) { + + String[] patterns = null; + Collection param = (Collection) params.getParameter( + CookieSpecPNames.DATE_PATTERNS); + if (param != null) { + patterns = new String[param.size()]; + patterns = param.toArray(patterns); + } + boolean singleHeader = params.getBooleanParameter( + CookieSpecPNames.SINGLE_COOKIE_HEADER, false); + + return new RFC2965Spec(patterns, singleHeader); + } else { + return new RFC2965Spec(); + } + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/RFC2965VersionAttributeHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,98 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.cookie; + +import org.apache.http.annotation.Immutable; + +import org.apache.http.cookie.ClientCookie; +import org.apache.http.cookie.Cookie; +import org.apache.http.cookie.CookieAttributeHandler; +import org.apache.http.cookie.CookieOrigin; +import org.apache.http.cookie.CookieRestrictionViolationException; +import org.apache.http.cookie.MalformedCookieException; +import org.apache.http.cookie.SetCookie; +import org.apache.http.cookie.SetCookie2; + +/** + * "Version" cookie attribute handler for RFC 2965 cookie spec. + * + * @since 4.0 + */ +@Immutable +public class RFC2965VersionAttributeHandler implements CookieAttributeHandler { + + public RFC2965VersionAttributeHandler() { + super(); + } + + /** + * Parse cookie version attribute. + */ + public void parse(final SetCookie cookie, final String value) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (value == null) { + throw new MalformedCookieException( + "Missing value for version attribute"); + } + int version = -1; + try { + version = Integer.parseInt(value); + } catch (NumberFormatException e) { + version = -1; + } + if (version < 0) { + throw new MalformedCookieException("Invalid cookie version."); + } + cookie.setVersion(version); + } + + /** + * validate cookie version attribute. Version attribute is REQUIRED. + */ + public void validate(final Cookie cookie, final CookieOrigin origin) + throws MalformedCookieException { + if (cookie == null) { + throw new IllegalArgumentException("Cookie may not be null"); + } + if (cookie instanceof SetCookie2) { + if (cookie instanceof ClientCookie + && !((ClientCookie) cookie).containsAttribute(ClientCookie.VERSION_ATTR)) { + throw new CookieRestrictionViolationException( + "Violates RFC 2965. Version attribute is required."); + } + } + } + + public boolean match(final Cookie cookie, final CookieOrigin origin) { + return true; + } + +} Index: 3rdParty_sources/httpclient/org/apache/http/impl/cookie/package.html =================================================================== diff -u --- 3rdParty_sources/httpclient/org/apache/http/impl/cookie/package.html (revision 0) +++ 3rdParty_sources/httpclient/org/apache/http/impl/cookie/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Default implementations for interfaces in +{@link org.apache.http.cookie org.apache.http.cookie}. + + Index: 3rdParty_sources/httpcore/org/apache/http/ConnectionClosedException.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/ConnectionClosedException.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/ConnectionClosedException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,50 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.IOException; + +/** + * Signals that the connection has been closed unexpectedly. + * + * @since 4.0 + */ +public class ConnectionClosedException extends IOException { + + private static final long serialVersionUID = 617550366255636674L; + + /** + * Creates a new ConnectionClosedException with the specified detail message. + * + * @param message The exception detail message + */ + public ConnectionClosedException(final String message) { + super(message); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/ConnectionReuseStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/ConnectionReuseStrategy.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/ConnectionReuseStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,70 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import org.apache.http.protocol.HttpContext; + +/** + * Interface for deciding whether a connection can be re-used for + * subsequent requests and should be kept alive. + *

+ * Implementations of this interface must be thread-safe. Access to shared + * data must be synchronized as methods of this interface may be executed + * from multiple threads. + * + * @since 4.0 + */ +public interface ConnectionReuseStrategy { + + /** + * Decides whether a connection can be kept open after a request. + * If this method returns false, the caller MUST + * close the connection to correctly comply with the HTTP protocol. + * If it returns true, the caller SHOULD attempt to + * keep the connection open for reuse with another request. + *
+ * One can use the HTTP context to retrieve additional objects that + * may be relevant for the keep-alive strategy: the actual HTTP + * connection, the original HTTP request, target host if known, + * number of times the connection has been reused already and so on. + *
+ * If the connection is already closed, false is returned. + * The stale connection check MUST NOT be triggered by a + * connection reuse strategy. + * + * @param response + * The last response received over that connection. + * @param context the context in which the connection is being + * used. + * + * @return true if the connection is allowed to be reused, or + * false if it MUST NOT be reused + */ + boolean keepAlive(HttpResponse response, HttpContext context); + +} Index: 3rdParty_sources/httpcore/org/apache/http/Consts.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/Consts.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/Consts.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,51 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.nio.charset.Charset; + +/** + * Commons constants. + * + * @since 4.2 + */ +public final class Consts { + + public static final int CR = 13; // + public static final int LF = 10; // + public static final int SP = 32; // + public static final int HT = 9; // + + public static final Charset UTF_8 = Charset.forName("UTF-8"); + public static final Charset ASCII = Charset.forName("US-ASCII"); + public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); + + private Consts() { + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/ContentTooLongException.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/ContentTooLongException.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/ContentTooLongException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,50 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.IOException; + +/** + * Signals that HTTP entity content is too long. + * + * @since 4.2 + */ +public class ContentTooLongException extends IOException { + + private static final long serialVersionUID = -924287689552495383L; + + /** + * Creates a new ContentTooLongException with the specified detail message. + * + * @param message exception message + */ + public ContentTooLongException(String message) { + super(message); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/FormattedHeader.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/FormattedHeader.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/FormattedHeader.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,60 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import org.apache.http.util.CharArrayBuffer; + +/** + * An HTTP header which is already formatted. + * For example when headers are received, the original formatting + * can be preserved. This allows for the header to be sent without + * another formatting step. + * + * @since 4.0 + */ +public interface FormattedHeader extends Header { + + /** + * Obtains the buffer with the formatted header. + * The returned buffer MUST NOT be modified. + * + * @return the formatted header, in a buffer that must not be modified + */ + CharArrayBuffer getBuffer(); + + /** + * Obtains the start of the header value in the {@link #getBuffer buffer}. + * By accessing the value in the buffer, creation of a temporary string + * can be avoided. + * + * @return index of the first character of the header value + * in the buffer returned by {@link #getBuffer getBuffer}. + */ + int getValuePos(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/Header.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/Header.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/Header.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * Represents an HTTP header field. + * + *

The HTTP header fields follow the same generic format as + * that given in Section 3.1 of RFC 822. Each header field consists + * of a name followed by a colon (":") and the field value. Field names + * are case-insensitive. The field value MAY be preceded by any amount + * of LWS, though a single SP is preferred. + * + *

+ *     message-header = field-name ":" [ field-value ]
+ *     field-name     = token
+ *     field-value    = *( field-content | LWS )
+ *     field-content  = <the OCTETs making up the field-value
+ *                      and consisting of either *TEXT or combinations
+ *                      of token, separators, and quoted-string>
+ *
+ * + * @since 4.0 + */ +public interface Header { + + /** + * Get the name of the Header. + * + * @return the name of the Header, never {@code null} + */ + String getName(); + + /** + * Get the value of the Header. + * + * @return the value of the Header, may be {@code null} + */ + String getValue(); + + /** + * Parses the value. + * + * @return an array of {@link HeaderElement} entries, may be empty, but is never {@code null} + * @throws ParseException + */ + HeaderElement[] getElements() throws ParseException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/HeaderElement.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HeaderElement.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HeaderElement.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,108 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * One element of an HTTP {@link Header header} value consisting of + * a name / value pair and a number of optional name / value parameters. + *

+ * Some HTTP headers (such as the set-cookie header) have values that + * can be decomposed into multiple elements. Such headers must be in the + * following form: + *

+ *
+ * header  = [ element ] *( "," [ element ] )
+ * element = name [ "=" [ value ] ] *( ";" [ param ] )
+ * param   = name [ "=" [ value ] ]
+ *
+ * name    = token
+ * value   = ( token | quoted-string )
+ *
+ * token         = 1*<any char except "=", ",", ";", <"> and
+ *                       white space>
+ * quoted-string = <"> *( text | quoted-char ) <">
+ * text          = any char except <">
+ * quoted-char   = "\" char
+ * 
+ *

+ * Any amount of white space is allowed between any part of the + * header, element or param and is ignored. A missing value in any + * element or param will be stored as the empty {@link String}; + * if the "=" is also missing null will be stored instead. + * + * @since 4.0 + */ +public interface HeaderElement { + + /** + * Returns header element name. + * + * @return header element name + */ + String getName(); + + /** + * Returns header element value. + * + * @return header element value + */ + String getValue(); + + /** + * Returns an array of name / value pairs. + * + * @return array of name / value pairs + */ + NameValuePair[] getParameters(); + + /** + * Returns the first parameter with the given name. + * + * @param name parameter name + * + * @return name / value pair + */ + NameValuePair getParameterByName(String name); + + /** + * Returns the total count of parameters. + * + * @return parameter count + */ + int getParameterCount(); + + /** + * Returns parameter with the given index. + * + * @param index + * @return name / value pair + */ + NameValuePair getParameter(int index); + +} + Index: 3rdParty_sources/httpcore/org/apache/http/HeaderElementIterator.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HeaderElementIterator.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HeaderElementIterator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,57 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.util.Iterator; + +/** + * A type-safe iterator for {@link HeaderElement} objects. + * + * @since 4.0 + */ +public interface HeaderElementIterator extends Iterator { + + /** + * Indicates whether there is another header element in this + * iteration. + * + * @return true if there is another header element, + * false otherwise + */ + boolean hasNext(); + + /** + * Obtains the next header element from this iteration. + * This method should only be called while {@link #hasNext hasNext} + * is true. + * + * @return the next header element in this iteration + */ + HeaderElement nextElement(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/HeaderIterator.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HeaderIterator.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HeaderIterator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,56 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.util.Iterator; + +/** + * A type-safe iterator for {@link Header} objects. + * + * @since 4.0 + */ +public interface HeaderIterator extends Iterator { + + /** + * Indicates whether there is another header in this iteration. + * + * @return true if there is another header, + * false otherwise + */ + boolean hasNext(); + + /** + * Obtains the next header from this iteration. + * This method should only be called while {@link #hasNext hasNext} + * is true. + * + * @return the next header in this iteration + */ + Header nextHeader(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpClientConnection.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpClientConnection.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpClientConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,102 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.IOException; + +/** + * A client-side HTTP connection, which can be used for sending + * requests and receiving responses. + * + * @since 4.0 + */ +public interface HttpClientConnection extends HttpConnection { + + /** + * Checks if response data is available from the connection. May wait for + * the specified time until some data becomes available. Note that some + * implementations may completely ignore the timeout parameter. + * + * @param timeout the maximum time in milliseconds to wait for data + * @return true if data is available; false if there was no data available + * even after waiting for timeout milliseconds. + * @throws IOException if an error happens on the connection + */ + boolean isResponseAvailable(int timeout) + throws IOException; + + /** + * Sends the request line and all headers over the connection. + * @param request the request whose headers to send. + * @throws HttpException in case of HTTP protocol violation + * @throws IOException in case of an I/O error + */ + void sendRequestHeader(HttpRequest request) + throws HttpException, IOException; + + /** + * Sends the request entity over the connection. + * @param request the request whose entity to send. + * @throws HttpException in case of HTTP protocol violation + * @throws IOException in case of an I/O error + */ + void sendRequestEntity(HttpEntityEnclosingRequest request) + throws HttpException, IOException; + + /** + * Receives the request line and headers of the next response available from + * this connection. The caller should examine the HttpResponse object to + * find out if it should try to receive a response entity as well. + * + * @return a new HttpResponse object with status line and headers + * initialized. + * @throws HttpException in case of HTTP protocol violation + * @throws IOException in case of an I/O error + */ + HttpResponse receiveResponseHeader() + throws HttpException, IOException; + + /** + * Receives the next response entity available from this connection and + * attaches it to an existing HttpResponse object. + * + * @param response the response to attach the entity to + * @throws HttpException in case of HTTP protocol violation + * @throws IOException in case of an I/O error + */ + void receiveResponseEntity(HttpResponse response) + throws HttpException, IOException; + + /** + * Writes out all pending buffered data over the open connection. + * + * @throws IOException in case of an I/O error + */ + void flush() throws IOException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpConnection.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpConnection.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,104 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.Closeable; +import java.io.IOException; + +/** + * A generic HTTP connection, useful on client and server side. + * + * @since 4.0 + */ +public interface HttpConnection extends Closeable { + + /** + * Closes this connection gracefully. + * This method will attempt to flush the internal output + * buffer prior to closing the underlying socket. + * This method MUST NOT be called from a different thread to force + * shutdown of the connection. Use {@link #shutdown shutdown} instead. + */ + void close() throws IOException; + + /** + * Checks if this connection is open. + * @return true if it is open, false if it is closed. + */ + boolean isOpen(); + + /** + * Checks whether this connection has gone down. + * Network connections may get closed during some time of inactivity + * for several reasons. The next time a read is attempted on such a + * connection it will throw an IOException. + * This method tries to alleviate this inconvenience by trying to + * find out if a connection is still usable. Implementations may do + * that by attempting a read with a very small timeout. Thus this + * method may block for a small amount of time before returning a result. + * It is therefore an expensive operation. + * + * @return true if attempts to use this connection are + * likely to succeed, or false if they are likely + * to fail and this connection should be closed + */ + boolean isStale(); + + /** + * Sets the socket timeout value. + * + * @param timeout timeout value in milliseconds + */ + void setSocketTimeout(int timeout); + + /** + * Returns the socket timeout value. + * + * @return positive value in milliseconds if a timeout is set, + * 0 if timeout is disabled or -1 if + * timeout is undefined. + */ + int getSocketTimeout(); + + /** + * Force-closes this connection. + * This is the only method of a connection which may be called + * from a different thread to terminate the connection. + * This method will not attempt to flush the transmitter's + * internal buffer prior to closing the underlying socket. + */ + void shutdown() throws IOException; + + /** + * Returns a collection of connection metrics. + * + * @return HttpConnectionMetrics + */ + HttpConnectionMetrics getMetrics(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpConnectionMetrics.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpConnectionMetrics.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpConnectionMetrics.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,77 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * The point of access to the statistics of an {@link HttpConnection}. + * + * @since 4.0 + */ +public interface HttpConnectionMetrics { + + /** + * Returns the number of requests transferred over the connection, + * 0 if not available. + */ + long getRequestCount(); + + /** + * Returns the number of responses transferred over the connection, + * 0 if not available. + */ + long getResponseCount(); + + /** + * Returns the number of bytes transferred over the connection, + * 0 if not available. + */ + long getSentBytesCount(); + + /** + * Returns the number of bytes transferred over the connection, + * 0 if not available. + */ + long getReceivedBytesCount(); + + /** + * Return the value for the specified metric. + * + *@param metricName the name of the metric to query. + * + *@return the object representing the metric requested, + * null if the metric cannot not found. + */ + Object getMetric(String metricName); + + /** + * Resets the counts + * + */ + void reset(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpEntity.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpEntity.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,199 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * An entity that can be sent or received with an HTTP message. + * Entities can be found in some + * {@link HttpEntityEnclosingRequest requests} and in + * {@link HttpResponse responses}, where they are optional. + *

+ * There are three distinct types of entities in HttpCore, + * depending on where their {@link #getContent content} originates: + *

    + *
  • streamed: The content is received from a stream, or + * generated on the fly. In particular, this category includes + * entities being received from a {@link HttpConnection connection}. + * {@link #isStreaming Streamed} entities are generally not + * {@link #isRepeatable repeatable}. + *
  • + *
  • self-contained: The content is in memory or obtained by + * means that are independent from a connection or other entity. + * Self-contained entities are generally {@link #isRepeatable repeatable}. + *
  • + *
  • wrapping: The content is obtained from another entity. + *
  • + *
+ * This distinction is important for connection management with incoming + * entities. For entities that are created by an application and only sent + * using the HTTP components framework, the difference between streamed + * and self-contained is of little importance. In that case, it is suggested + * to consider non-repeatable entities as streamed, and those that are + * repeatable (without a huge effort) as self-contained. + * + * @since 4.0 + */ +public interface HttpEntity { + + /** + * Tells if the entity is capable of producing its data more than once. + * A repeatable entity's getContent() and writeTo(OutputStream) methods + * can be called more than once whereas a non-repeatable entity's can not. + * @return true if the entity is repeatable, false otherwise. + */ + boolean isRepeatable(); + + /** + * Tells about chunked encoding for this entity. + * The primary purpose of this method is to indicate whether + * chunked encoding should be used when the entity is sent. + * For entities that are received, it can also indicate whether + * the entity was received with chunked encoding. + *
+ * The behavior of wrapping entities is implementation dependent, + * but should respect the primary purpose. + * + * @return true if chunked encoding is preferred for this + * entity, or false if it is not + */ + boolean isChunked(); + + /** + * Tells the length of the content, if known. + * + * @return the number of bytes of the content, or + * a negative number if unknown. If the content length is known + * but exceeds {@link java.lang.Long#MAX_VALUE Long.MAX_VALUE}, + * a negative number is returned. + */ + long getContentLength(); + + /** + * Obtains the Content-Type header, if known. + * This is the header that should be used when sending the entity, + * or the one that was received with the entity. It can include a + * charset attribute. + * + * @return the Content-Type header for this entity, or + * null if the content type is unknown + */ + Header getContentType(); + + /** + * Obtains the Content-Encoding header, if known. + * This is the header that should be used when sending the entity, + * or the one that was received with the entity. + * Wrapping entities that modify the content encoding should + * adjust this header accordingly. + * + * @return the Content-Encoding header for this entity, or + * null if the content encoding is unknown + */ + Header getContentEncoding(); + + /** + * Returns a content stream of the entity. + * {@link #isRepeatable Repeatable} entities are expected + * to create a new instance of {@link InputStream} for each invocation + * of this method and therefore can be consumed multiple times. + * Entities that are not {@link #isRepeatable repeatable} are expected + * to return the same {@link InputStream} instance and therefore + * may not be consumed more than once. + *

+ * IMPORTANT: Please note all entity implementations must ensure that + * all allocated resources are properly deallocated after + * the {@link InputStream#close()} method is invoked. + * + * @return content stream of the entity. + * + * @throws IOException if the stream could not be created + * @throws IllegalStateException + * if content stream cannot be created. + * + * @see #isRepeatable() + */ + InputStream getContent() throws IOException, IllegalStateException; + + /** + * Writes the entity content out to the output stream. + *

+ *

+ * IMPORTANT: Please note all entity implementations must ensure that + * all allocated resources are properly deallocated when this method + * returns. + * + * @param outstream the output stream to write entity content to + * + * @throws IOException if an I/O error occurs + */ + void writeTo(OutputStream outstream) throws IOException; + + /** + * Tells whether this entity depends on an underlying stream. + * Streamed entities that read data directly from the socket should + * return true. Self-contained entities should return + * false. Wrapping entities should delegate this call + * to the wrapped entity. + * + * @return true if the entity content is streamed, + * false otherwise + */ + boolean isStreaming(); // don't expect an exception here + + /** + * This method is deprecated since version 4.1. Please use standard + * java convention to ensure resource deallocation by calling + * {@link InputStream#close()} on the input stream returned by + * {@link #getContent()} + *

+ * This method is called to indicate that the content of this entity + * is no longer required. All entity implementations are expected to + * release all allocated resources as a result of this method + * invocation. Content streaming entities are also expected to + * dispose of the remaining content, if any. Wrapping entities should + * delegate this call to the wrapped entity. + *

+ * This method is of particular importance for entities being + * received from a {@link HttpConnection connection}. The entity + * needs to be consumed completely in order to re-use the connection + * with keep-alive. + * + * @throws IOException if an I/O error occurs. + * + * @deprecated (4.1) Use {@link org.apache.http.util.EntityUtils#consume(HttpEntity)} + * + * @see #getContent() and #writeTo(OutputStream) + */ + @Deprecated + void consumeContent() throws IOException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpEntityEnclosingRequest.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpEntityEnclosingRequest.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpEntityEnclosingRequest.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,62 @@ +/* + * $Header$ + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * A request with an entity. + * + * @since 4.0 + */ +public interface HttpEntityEnclosingRequest extends HttpRequest { + + /** + * Tells if this request should use the expect-continue handshake. + * The expect continue handshake gives the server a chance to decide + * whether to accept the entity enclosing request before the possibly + * lengthy entity is sent across the wire. + * @return true if the expect continue handshake should be used, false if + * not. + */ + boolean expectContinue(); + + /** + * Associates the entity with this request. + * + * @param entity the entity to send. + */ + void setEntity(HttpEntity entity); + + /** + * Returns the entity associated with this request. + * + * @return entity + */ + HttpEntity getEntity(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpException.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpException.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * Signals that an HTTP exception has occurred. + * + * @since 4.0 + */ +public class HttpException extends Exception { + + private static final long serialVersionUID = -5437299376222011036L; + + /** + * Creates a new HttpException with a null detail message. + */ + public HttpException() { + super(); + } + + /** + * Creates a new HttpException with the specified detail message. + * + * @param message the exception detail message + */ + public HttpException(final String message) { + super(message); + } + + /** + * Creates a new HttpException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public HttpException(final String message, final Throwable cause) { + super(message); + initCause(cause); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpHeaders.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpHeaders.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpHeaders.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,206 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * Constants enumerating the HTTP headers. All headers defined in RFC1945 (HTTP/1.0), RFC2616 (HTTP/1.1), and RFC2518 + * (WebDAV) are listed. + * + * @since 4.1 + */ +public final class HttpHeaders { + + private HttpHeaders() { + } + + /** RFC 2616 (HTTP/1.1) Section 14.1 */ + public static final String ACCEPT = "Accept"; + + /** RFC 2616 (HTTP/1.1) Section 14.2 */ + public static final String ACCEPT_CHARSET = "Accept-Charset"; + + /** RFC 2616 (HTTP/1.1) Section 14.3 */ + public static final String ACCEPT_ENCODING = "Accept-Encoding"; + + /** RFC 2616 (HTTP/1.1) Section 14.4 */ + public static final String ACCEPT_LANGUAGE = "Accept-Language"; + + /** RFC 2616 (HTTP/1.1) Section 14.5 */ + public static final String ACCEPT_RANGES = "Accept-Ranges"; + + /** RFC 2616 (HTTP/1.1) Section 14.6 */ + public static final String AGE = "Age"; + + /** RFC 1945 (HTTP/1.0) Section 10.1, RFC 2616 (HTTP/1.1) Section 14.7 */ + public static final String ALLOW = "Allow"; + + /** RFC 1945 (HTTP/1.0) Section 10.2, RFC 2616 (HTTP/1.1) Section 14.8 */ + public static final String AUTHORIZATION = "Authorization"; + + /** RFC 2616 (HTTP/1.1) Section 14.9 */ + public static final String CACHE_CONTROL = "Cache-Control"; + + /** RFC 2616 (HTTP/1.1) Section 14.10 */ + public static final String CONNECTION = "Connection"; + + /** RFC 1945 (HTTP/1.0) Section 10.3, RFC 2616 (HTTP/1.1) Section 14.11 */ + public static final String CONTENT_ENCODING = "Content-Encoding"; + + /** RFC 2616 (HTTP/1.1) Section 14.12 */ + public static final String CONTENT_LANGUAGE = "Content-Language"; + + /** RFC 1945 (HTTP/1.0) Section 10.4, RFC 2616 (HTTP/1.1) Section 14.13 */ + public static final String CONTENT_LENGTH = "Content-Length"; + + /** RFC 2616 (HTTP/1.1) Section 14.14 */ + public static final String CONTENT_LOCATION = "Content-Location"; + + /** RFC 2616 (HTTP/1.1) Section 14.15 */ + public static final String CONTENT_MD5 = "Content-MD5"; + + /** RFC 2616 (HTTP/1.1) Section 14.16 */ + public static final String CONTENT_RANGE = "Content-Range"; + + /** RFC 1945 (HTTP/1.0) Section 10.5, RFC 2616 (HTTP/1.1) Section 14.17 */ + public static final String CONTENT_TYPE = "Content-Type"; + + /** RFC 1945 (HTTP/1.0) Section 10.6, RFC 2616 (HTTP/1.1) Section 14.18 */ + public static final String DATE = "Date"; + + /** RFC 2518 (WevDAV) Section 9.1 */ + public static final String DAV = "Dav"; + + /** RFC 2518 (WevDAV) Section 9.2 */ + public static final String DEPTH = "Depth"; + + /** RFC 2518 (WevDAV) Section 9.3 */ + public static final String DESTINATION = "Destination"; + + /** RFC 2616 (HTTP/1.1) Section 14.19 */ + public static final String ETAG = "ETag"; + + /** RFC 2616 (HTTP/1.1) Section 14.20 */ + public static final String EXPECT = "Expect"; + + /** RFC 1945 (HTTP/1.0) Section 10.7, RFC 2616 (HTTP/1.1) Section 14.21 */ + public static final String EXPIRES = "Expires"; + + /** RFC 1945 (HTTP/1.0) Section 10.8, RFC 2616 (HTTP/1.1) Section 14.22 */ + public static final String FROM = "From"; + + /** RFC 2616 (HTTP/1.1) Section 14.23 */ + public static final String HOST = "Host"; + + /** RFC 2518 (WevDAV) Section 9.4 */ + public static final String IF = "If"; + + /** RFC 2616 (HTTP/1.1) Section 14.24 */ + public static final String IF_MATCH = "If-Match"; + + /** RFC 1945 (HTTP/1.0) Section 10.9, RFC 2616 (HTTP/1.1) Section 14.25 */ + public static final String IF_MODIFIED_SINCE = "If-Modified-Since"; + + /** RFC 2616 (HTTP/1.1) Section 14.26 */ + public static final String IF_NONE_MATCH = "If-None-Match"; + + /** RFC 2616 (HTTP/1.1) Section 14.27 */ + public static final String IF_RANGE = "If-Range"; + + /** RFC 2616 (HTTP/1.1) Section 14.28 */ + public static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since"; + + /** RFC 1945 (HTTP/1.0) Section 10.10, RFC 2616 (HTTP/1.1) Section 14.29 */ + public static final String LAST_MODIFIED = "Last-Modified"; + + /** RFC 1945 (HTTP/1.0) Section 10.11, RFC 2616 (HTTP/1.1) Section 14.30 */ + public static final String LOCATION = "Location"; + + /** RFC 2518 (WevDAV) Section 9.5 */ + public static final String LOCK_TOKEN = "Lock-Token"; + + /** RFC 2616 (HTTP/1.1) Section 14.31 */ + public static final String MAX_FORWARDS = "Max-Forwards"; + + /** RFC 2518 (WevDAV) Section 9.6 */ + public static final String OVERWRITE = "Overwrite"; + + /** RFC 1945 (HTTP/1.0) Section 10.12, RFC 2616 (HTTP/1.1) Section 14.32 */ + public static final String PRAGMA = "Pragma"; + + /** RFC 2616 (HTTP/1.1) Section 14.33 */ + public static final String PROXY_AUTHENTICATE = "Proxy-Authenticate"; + + /** RFC 2616 (HTTP/1.1) Section 14.34 */ + public static final String PROXY_AUTHORIZATION = "Proxy-Authorization"; + + /** RFC 2616 (HTTP/1.1) Section 14.35 */ + public static final String RANGE = "Range"; + + /** RFC 1945 (HTTP/1.0) Section 10.13, RFC 2616 (HTTP/1.1) Section 14.36 */ + public static final String REFERER = "Referer"; + + /** RFC 2616 (HTTP/1.1) Section 14.37 */ + public static final String RETRY_AFTER = "Retry-After"; + + /** RFC 1945 (HTTP/1.0) Section 10.14, RFC 2616 (HTTP/1.1) Section 14.38 */ + public static final String SERVER = "Server"; + + /** RFC 2518 (WevDAV) Section 9.7 */ + public static final String STATUS_URI = "Status-URI"; + + /** RFC 2616 (HTTP/1.1) Section 14.39 */ + public static final String TE = "TE"; + + /** RFC 2518 (WevDAV) Section 9.8 */ + public static final String TIMEOUT = "Timeout"; + + /** RFC 2616 (HTTP/1.1) Section 14.40 */ + public static final String TRAILER = "Trailer"; + + /** RFC 2616 (HTTP/1.1) Section 14.41 */ + public static final String TRANSFER_ENCODING = "Transfer-Encoding"; + + /** RFC 2616 (HTTP/1.1) Section 14.42 */ + public static final String UPGRADE = "Upgrade"; + + /** RFC 1945 (HTTP/1.0) Section 10.15, RFC 2616 (HTTP/1.1) Section 14.43 */ + public static final String USER_AGENT = "User-Agent"; + + /** RFC 2616 (HTTP/1.1) Section 14.44 */ + public static final String VARY = "Vary"; + + /** RFC 2616 (HTTP/1.1) Section 14.45 */ + public static final String VIA = "Via"; + + /** RFC 2616 (HTTP/1.1) Section 14.46 */ + public static final String WARNING = "Warning"; + + /** RFC 1945 (HTTP/1.0) Section 10.16, RFC 2616 (HTTP/1.1) Section 14.47 */ + public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpHost.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpHost.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpHost.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,220 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.Serializable; +import java.util.Locale; + +import org.apache.http.annotation.Immutable; +import org.apache.http.util.LangUtils; + +/** + * Holds all of the variables needed to describe an HTTP connection to a host. + * This includes remote host name, port and scheme. + * + * + * @since 4.0 + */ +@Immutable +public final class HttpHost implements Cloneable, Serializable { + + private static final long serialVersionUID = -7529410654042457626L; + + /** The default scheme is "http". */ + public static final String DEFAULT_SCHEME_NAME = "http"; + + /** The host to use. */ + protected final String hostname; + + /** The lowercase host, for {@link #equals} and {@link #hashCode}. */ + protected final String lcHostname; + + + /** The port to use, defaults to -1 if not set. */ + protected final int port; + + /** The scheme (lowercased) */ + protected final String schemeName; + + + /** + * Creates a new {@link HttpHost HttpHost}, specifying all values. + * Constructor for HttpHost. + * + * @param hostname the hostname (IP or DNS name) + * @param port the port number. + * -1 indicates the scheme default port. + * @param scheme the name of the scheme. + * null indicates the + * {@link #DEFAULT_SCHEME_NAME default scheme} + */ + public HttpHost(final String hostname, int port, final String scheme) { + super(); + if (hostname == null) { + throw new IllegalArgumentException("Host name may not be null"); + } + this.hostname = hostname; + this.lcHostname = hostname.toLowerCase(Locale.ENGLISH); + if (scheme != null) { + this.schemeName = scheme.toLowerCase(Locale.ENGLISH); + } else { + this.schemeName = DEFAULT_SCHEME_NAME; + } + this.port = port; + } + + /** + * Creates a new {@link HttpHost HttpHost}, with default scheme. + * + * @param hostname the hostname (IP or DNS name) + * @param port the port number. + * -1 indicates the scheme default port. + */ + public HttpHost(final String hostname, int port) { + this(hostname, port, null); + } + + /** + * Creates a new {@link HttpHost HttpHost}, with default scheme and port. + * + * @param hostname the hostname (IP or DNS name) + */ + public HttpHost(final String hostname) { + this(hostname, -1, null); + } + + /** + * Copy constructor for {@link HttpHost HttpHost}. + * + * @param httphost the HTTP host to copy details from + */ + public HttpHost (final HttpHost httphost) { + this(httphost.hostname, httphost.port, httphost.schemeName); + } + + /** + * Returns the host name. + * + * @return the host name (IP or DNS name) + */ + public String getHostName() { + return this.hostname; + } + + /** + * Returns the port. + * + * @return the host port, or -1 if not set + */ + public int getPort() { + return this.port; + } + + /** + * Returns the scheme name. + * + * @return the scheme name + */ + public String getSchemeName() { + return this.schemeName; + } + + /** + * Return the host URI, as a string. + * + * @return the host URI + */ + public String toURI() { + StringBuilder buffer = new StringBuilder(); + buffer.append(this.schemeName); + buffer.append("://"); + buffer.append(this.hostname); + if (this.port != -1) { + buffer.append(':'); + buffer.append(Integer.toString(this.port)); + } + return buffer.toString(); + } + + + /** + * Obtains the host string, without scheme prefix. + * + * @return the host string, for example localhost:8080 + */ + public String toHostString() { + if (this.port != -1) { + //the highest port number is 65535, which is length 6 with the addition of the colon + StringBuilder buffer = new StringBuilder(this.hostname.length() + 6); + buffer.append(this.hostname); + buffer.append(":"); + buffer.append(Integer.toString(this.port)); + return buffer.toString(); + } else { + return this.hostname; + } + } + + + @Override + public String toString() { + return toURI(); + } + + + @Override + public boolean equals(final Object obj) { + if (this == obj) return true; + if (obj instanceof HttpHost) { + HttpHost that = (HttpHost) obj; + return this.lcHostname.equals(that.lcHostname) + && this.port == that.port + && this.schemeName.equals(that.schemeName); + } else { + return false; + } + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.lcHostname); + hash = LangUtils.hashCode(hash, this.port); + hash = LangUtils.hashCode(hash, this.schemeName); + return hash; + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpInetConnection.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpInetConnection.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpInetConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,47 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.net.InetAddress; + +/** + * An HTTP connection over the Internet Protocol (IP). + * + * @since 4.0 + */ +public interface HttpInetConnection extends HttpConnection { + + InetAddress getLocalAddress(); + + int getLocalPort(); + + InetAddress getRemoteAddress(); + + int getRemotePort(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpMessage.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpMessage.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpMessage.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,201 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import org.apache.http.params.HttpParams; + +/** + * HTTP messages consist of requests from client to server and responses + * from server to client. + *

+ *     HTTP-message   = Request | Response     ; HTTP/1.1 messages
+ * 
+ *

+ * HTTP messages use the generic message format of RFC 822 for + * transferring entities (the payload of the message). Both types + * of message consist of a start-line, zero or more header fields + * (also known as "headers"), an empty line (i.e., a line with nothing + * preceding the CRLF) indicating the end of the header fields, + * and possibly a message-body. + *

+ *
+ *      generic-message = start-line
+ *                        *(message-header CRLF)
+ *                        CRLF
+ *                        [ message-body ]
+ *      start-line      = Request-Line | Status-Line
+ * 
+ * + * @since 4.0 + */ +public interface HttpMessage { + + /** + * Returns the protocol version this message is compatible with. + */ + ProtocolVersion getProtocolVersion(); + + /** + * Checks if a certain header is present in this message. Header values are + * ignored. + * + * @param name the header name to check for. + * @return true if at least one header with this name is present. + */ + boolean containsHeader(String name); + + /** + * Returns all the headers with a specified name of this message. Header values + * are ignored. Headers are orderd in the sequence they will be sent over a + * connection. + * + * @param name the name of the headers to return. + * @return the headers whose name property equals name. + */ + Header[] getHeaders(String name); + + /** + * Returns the first header with a specified name of this message. Header + * values are ignored. If there is more than one matching header in the + * message the first element of {@link #getHeaders(String)} is returned. + * If there is no matching header in the message null is + * returned. + * + * @param name the name of the header to return. + * @return the first header whose name property equals name + * or null if no such header could be found. + */ + Header getFirstHeader(String name); + + /** + * Returns the last header with a specified name of this message. Header values + * are ignored. If there is more than one matching header in the message the + * last element of {@link #getHeaders(String)} is returned. If there is no + * matching header in the message null is returned. + * + * @param name the name of the header to return. + * @return the last header whose name property equals name. + * or null if no such header could be found. + */ + Header getLastHeader(String name); + + /** + * Returns all the headers of this message. Headers are orderd in the sequence + * they will be sent over a connection. + * + * @return all the headers of this message + */ + Header[] getAllHeaders(); + + /** + * Adds a header to this message. The header will be appended to the end of + * the list. + * + * @param header the header to append. + */ + void addHeader(Header header); + + /** + * Adds a header to this message. The header will be appended to the end of + * the list. + * + * @param name the name of the header. + * @param value the value of the header. + */ + void addHeader(String name, String value); + + /** + * Overwrites the first header with the same name. The new header will be appended to + * the end of the list, if no header with the given name can be found. + * + * @param header the header to set. + */ + void setHeader(Header header); + + /** + * Overwrites the first header with the same name. The new header will be appended to + * the end of the list, if no header with the given name can be found. + * + * @param name the name of the header. + * @param value the value of the header. + */ + void setHeader(String name, String value); + + /** + * Overwrites all the headers in the message. + * + * @param headers the array of headers to set. + */ + void setHeaders(Header[] headers); + + /** + * Removes a header from this message. + * + * @param header the header to remove. + */ + void removeHeader(Header header); + + /** + * Removes all headers with a certain name from this message. + * + * @param name The name of the headers to remove. + */ + void removeHeaders(String name); + + /** + * Returns an iterator of all the headers. + * + * @return Iterator that returns Header objects in the sequence they are + * sent over a connection. + */ + HeaderIterator headerIterator(); + + /** + * Returns an iterator of the headers with a given name. + * + * @param name the name of the headers over which to iterate, or + * null for all headers + * + * @return Iterator that returns Header objects with the argument name + * in the sequence they are sent over a connection. + */ + HeaderIterator headerIterator(String name); + + /** + * Returns the parameters effective for this message as set by + * {@link #setParams(HttpParams)}. + */ + HttpParams getParams(); + + /** + * Provides parameters to be used for the processing of this message. + * @param params the parameters + */ + void setParams(HttpParams params); + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpRequest.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpRequest.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpRequest.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,53 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * A request message from a client to a server includes, within the + * first line of that message, the method to be applied to the resource, + * the identifier of the resource, and the protocol version in use. + *
+ *      Request       = Request-Line
+ *                      *(( general-header
+ *                       | request-header
+ *                       | entity-header ) CRLF)
+ *                      CRLF
+ *                      [ message-body ]
+ * 
+ * + * @since 4.0 + */ +public interface HttpRequest extends HttpMessage { + + /** + * Returns the request line of this request. + * @return the request line. + */ + RequestLine getRequestLine(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpRequestFactory.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpRequestFactory.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpRequestFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,43 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * A factory for {@link HttpRequest HttpRequest} objects. + * + * @since 4.0 + */ +public interface HttpRequestFactory { + + HttpRequest newHttpRequest(RequestLine requestline) + throws MethodNotSupportedException; + + HttpRequest newHttpRequest(String method, String uri) + throws MethodNotSupportedException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpRequestInterceptor.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpRequestInterceptor.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpRequestInterceptor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,68 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.IOException; + +import org.apache.http.protocol.HttpContext; + +/** + * HTTP protocol interceptor is a routine that implements a specific aspect of + * the HTTP protocol. Usually protocol interceptors are expected to act upon + * one specific header or a group of related headers of the incoming message + * or populate the outgoing message with one specific header or a group of + * related headers. + *

+ * Protocol Interceptors can also manipulate content entities enclosed with messages. + * Usually this is accomplished by using the 'Decorator' pattern where a wrapper + * entity class is used to decorate the original entity. + *

+ * Protocol interceptors must be implemented as thread-safe. Similarly to + * servlets, protocol interceptors should not use instance variables unless + * access to those variables is synchronized. + * + * @since 4.0 + */ +public interface HttpRequestInterceptor { + + /** + * Processes a request. + * On the client side, this step is performed before the request is + * sent to the server. On the server side, this step is performed + * on incoming messages before the message body is evaluated. + * + * @param request the request to preprocess + * @param context the context for the request + * + * @throws HttpException in case of an HTTP protocol violation + * @throws IOException in case of an I/O error + */ + void process(HttpRequest request, HttpContext context) + throws HttpException, IOException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpResponse.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpResponse.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpResponse.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,160 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.util.Locale; + +/** + * After receiving and interpreting a request message, a server responds + * with an HTTP response message. + *

+ *     Response      = Status-Line
+ *                     *(( general-header
+ *                      | response-header
+ *                      | entity-header ) CRLF)
+ *                     CRLF
+ *                     [ message-body ]
+ * 
+ * + * @since 4.0 + */ +public interface HttpResponse extends HttpMessage { + + /** + * Obtains the status line of this response. + * The status line can be set using one of the + * {@link #setStatusLine setStatusLine} methods, + * or it can be initialized in a constructor. + * + * @return the status line, or null if not yet set + */ + StatusLine getStatusLine(); + + /** + * Sets the status line of this response. + * + * @param statusline the status line of this response + */ + void setStatusLine(StatusLine statusline); + + /** + * Sets the status line of this response. + * The reason phrase will be determined based on the current + * {@link #getLocale locale}. + * + * @param ver the HTTP version + * @param code the status code + */ + void setStatusLine(ProtocolVersion ver, int code); + + /** + * Sets the status line of this response with a reason phrase. + * + * @param ver the HTTP version + * @param code the status code + * @param reason the reason phrase, or null to omit + */ + void setStatusLine(ProtocolVersion ver, int code, String reason); + + /** + * Updates the status line of this response with a new status code. + * The status line can only be updated if it is available. It must + * have been set either explicitly or in a constructor. + *
+ * The reason phrase will be updated according to the new status code, + * based on the current {@link #getLocale locale}. It can be set + * explicitly using {@link #setReasonPhrase setReasonPhrase}. + * + * @param code the HTTP status code. + * + * @throws IllegalStateException + * if the status line has not be set + * + * @see HttpStatus + * @see #setStatusLine(StatusLine) + * @see #setStatusLine(ProtocolVersion,int) + */ + void setStatusCode(int code) + throws IllegalStateException; + + /** + * Updates the status line of this response with a new reason phrase. + * The status line can only be updated if it is available. It must + * have been set either explicitly or in a constructor. + * + * @param reason the new reason phrase as a single-line string, or + * null to unset the reason phrase + * + * @throws IllegalStateException + * if the status line has not be set + * + * @see #setStatusLine(StatusLine) + * @see #setStatusLine(ProtocolVersion,int) + */ + void setReasonPhrase(String reason) + throws IllegalStateException; + + /** + * Obtains the message entity of this response, if any. + * The entity is provided by calling {@link #setEntity setEntity}. + * + * @return the response entity, or + * null if there is none + */ + HttpEntity getEntity(); + + /** + * Associates a response entity with this response. + * + * @param entity the entity to associate with this response, or + * null to unset + */ + void setEntity(HttpEntity entity); + + /** + * Obtains the locale of this response. + * The locale is used to determine the reason phrase + * for the {@link #setStatusCode status code}. + * It can be changed using {@link #setLocale setLocale}. + * + * @return the locale of this response, never null + */ + Locale getLocale(); + + /** + * Changes the locale of this response. + * If there is a status line, it's reason phrase will be updated + * according to the status code and new locale. + * + * @param loc the new locale + * + * @see #getLocale getLocale + * @see #setStatusCode setStatusCode + */ + void setLocale(Locale loc); +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpResponseFactory.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpResponseFactory.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpResponseFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import org.apache.http.protocol.HttpContext; + +/** + * A factory for {@link HttpResponse HttpResponse} objects. + * + * @since 4.0 + */ +public interface HttpResponseFactory { + + /** + * Creates a new response from status line elements. + * + * @param ver the protocol version + * @param status the status code + * @param context the context from which to determine the locale + * for looking up a reason phrase to the status code, or + * null to use the default locale + * + * @return the new response with an initialized status line + */ + HttpResponse newHttpResponse(ProtocolVersion ver, int status, + HttpContext context); + + /** + * Creates a new response from a status line. + * + * @param statusline the status line + * @param context the context from which to determine the locale + * for looking up a reason phrase if the status code + * is updated, or + * null to use the default locale + * + * @return the new response with the argument status line + */ + HttpResponse newHttpResponse(StatusLine statusline, + HttpContext context); + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpResponseInterceptor.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpResponseInterceptor.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpResponseInterceptor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,68 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.IOException; + +import org.apache.http.protocol.HttpContext; + +/** + * HTTP protocol interceptor is a routine that implements a specific aspect of + * the HTTP protocol. Usually protocol interceptors are expected to act upon + * one specific header or a group of related headers of the incoming message + * or populate the outgoing message with one specific header or a group of + * related headers. Protocol + *

+ * Interceptors can also manipulate content entities enclosed with messages. + * Usually this is accomplished by using the 'Decorator' pattern where a wrapper + * entity class is used to decorate the original entity. + *

+ * Protocol interceptors must be implemented as thread-safe. Similarly to + * servlets, protocol interceptors should not use instance variables unless + * access to those variables is synchronized. + * + * @since 4.0 + */ +public interface HttpResponseInterceptor { + + /** + * Processes a response. + * On the server side, this step is performed before the response is + * sent to the client. On the client side, this step is performed + * on incoming messages before the message body is evaluated. + * + * @param response the response to postprocess + * @param context the context for the request + * + * @throws HttpException in case of an HTTP protocol violation + * @throws IOException in case of an I/O error + */ + void process(HttpResponse response, HttpContext context) + throws HttpException, IOException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpServerConnection.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpServerConnection.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpServerConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,88 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.IOException; + +/** + * A server-side HTTP connection, which can be used for receiving + * requests and sending responses. + * + * @since 4.0 + */ +public interface HttpServerConnection extends HttpConnection { + + /** + * Receives the request line and all headers available from this connection. + * The caller should examine the returned request and decide if to receive a + * request entity as well. + * + * @return a new HttpRequest object whose request line and headers are + * initialized. + * @throws HttpException in case of HTTP protocol violation + * @throws IOException in case of an I/O error + */ + HttpRequest receiveRequestHeader() + throws HttpException, IOException; + + /** + * Receives the next request entity available from this connection and attaches it to + * an existing request. + * @param request the request to attach the entity to. + * @throws HttpException in case of HTTP protocol violation + * @throws IOException in case of an I/O error + */ + void receiveRequestEntity(HttpEntityEnclosingRequest request) + throws HttpException, IOException; + + /** + * Sends the response line and headers of a response over this connection. + * @param response the response whose headers to send. + * @throws HttpException in case of HTTP protocol violation + * @throws IOException in case of an I/O error + */ + void sendResponseHeader(HttpResponse response) + throws HttpException, IOException; + + /** + * Sends the response entity of a response over this connection. + * @param response the response whose entity to send. + * @throws HttpException in case of HTTP protocol violation + * @throws IOException in case of an I/O error + */ + void sendResponseEntity(HttpResponse response) + throws HttpException, IOException; + + /** + * Sends all pending buffered data over this connection. + * @throws IOException in case of an I/O error + */ + void flush() + throws IOException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpStatus.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpStatus.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpStatus.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,175 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * Constants enumerating the HTTP status codes. + * All status codes defined in RFC1945 (HTTP/1.0), RFC2616 (HTTP/1.1), and + * RFC2518 (WebDAV) are listed. + * + * @see StatusLine + * + * @since 4.0 + */ +public interface HttpStatus { + + // --- 1xx Informational --- + + /** 100 Continue (HTTP/1.1 - RFC 2616) */ + public static final int SC_CONTINUE = 100; + /** 101 Switching Protocols (HTTP/1.1 - RFC 2616)*/ + public static final int SC_SWITCHING_PROTOCOLS = 101; + /** 102 Processing (WebDAV - RFC 2518) */ + public static final int SC_PROCESSING = 102; + + // --- 2xx Success --- + + /** 200 OK (HTTP/1.0 - RFC 1945) */ + public static final int SC_OK = 200; + /** 201 Created (HTTP/1.0 - RFC 1945) */ + public static final int SC_CREATED = 201; + /** 202 Accepted (HTTP/1.0 - RFC 1945) */ + public static final int SC_ACCEPTED = 202; + /** 203 Non Authoritative Information (HTTP/1.1 - RFC 2616) */ + public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203; + /** 204 No Content (HTTP/1.0 - RFC 1945) */ + public static final int SC_NO_CONTENT = 204; + /** 205 Reset Content (HTTP/1.1 - RFC 2616) */ + public static final int SC_RESET_CONTENT = 205; + /** 206 Partial Content (HTTP/1.1 - RFC 2616) */ + public static final int SC_PARTIAL_CONTENT = 206; + /** + * 207 Multi-Status (WebDAV - RFC 2518) or 207 Partial Update + * OK (HTTP/1.1 - draft-ietf-http-v11-spec-rev-01?) + */ + public static final int SC_MULTI_STATUS = 207; + + // --- 3xx Redirection --- + + /** 300 Mutliple Choices (HTTP/1.1 - RFC 2616) */ + public static final int SC_MULTIPLE_CHOICES = 300; + /** 301 Moved Permanently (HTTP/1.0 - RFC 1945) */ + public static final int SC_MOVED_PERMANENTLY = 301; + /** 302 Moved Temporarily (Sometimes Found) (HTTP/1.0 - RFC 1945) */ + public static final int SC_MOVED_TEMPORARILY = 302; + /** 303 See Other (HTTP/1.1 - RFC 2616) */ + public static final int SC_SEE_OTHER = 303; + /** 304 Not Modified (HTTP/1.0 - RFC 1945) */ + public static final int SC_NOT_MODIFIED = 304; + /** 305 Use Proxy (HTTP/1.1 - RFC 2616) */ + public static final int SC_USE_PROXY = 305; + /** 307 Temporary Redirect (HTTP/1.1 - RFC 2616) */ + public static final int SC_TEMPORARY_REDIRECT = 307; + + // --- 4xx Client Error --- + + /** 400 Bad Request (HTTP/1.1 - RFC 2616) */ + public static final int SC_BAD_REQUEST = 400; + /** 401 Unauthorized (HTTP/1.0 - RFC 1945) */ + public static final int SC_UNAUTHORIZED = 401; + /** 402 Payment Required (HTTP/1.1 - RFC 2616) */ + public static final int SC_PAYMENT_REQUIRED = 402; + /** 403 Forbidden (HTTP/1.0 - RFC 1945) */ + public static final int SC_FORBIDDEN = 403; + /** 404 Not Found (HTTP/1.0 - RFC 1945) */ + public static final int SC_NOT_FOUND = 404; + /** 405 Method Not Allowed (HTTP/1.1 - RFC 2616) */ + public static final int SC_METHOD_NOT_ALLOWED = 405; + /** 406 Not Acceptable (HTTP/1.1 - RFC 2616) */ + public static final int SC_NOT_ACCEPTABLE = 406; + /** 407 Proxy Authentication Required (HTTP/1.1 - RFC 2616)*/ + public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407; + /** 408 Request Timeout (HTTP/1.1 - RFC 2616) */ + public static final int SC_REQUEST_TIMEOUT = 408; + /** 409 Conflict (HTTP/1.1 - RFC 2616) */ + public static final int SC_CONFLICT = 409; + /** 410 Gone (HTTP/1.1 - RFC 2616) */ + public static final int SC_GONE = 410; + /** 411 Length Required (HTTP/1.1 - RFC 2616) */ + public static final int SC_LENGTH_REQUIRED = 411; + /** 412 Precondition Failed (HTTP/1.1 - RFC 2616) */ + public static final int SC_PRECONDITION_FAILED = 412; + /** 413 Request Entity Too Large (HTTP/1.1 - RFC 2616) */ + public static final int SC_REQUEST_TOO_LONG = 413; + /** 414 Request-URI Too Long (HTTP/1.1 - RFC 2616) */ + public static final int SC_REQUEST_URI_TOO_LONG = 414; + /** 415 Unsupported Media Type (HTTP/1.1 - RFC 2616) */ + public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415; + /** 416 Requested Range Not Satisfiable (HTTP/1.1 - RFC 2616) */ + public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416; + /** 417 Expectation Failed (HTTP/1.1 - RFC 2616) */ + public static final int SC_EXPECTATION_FAILED = 417; + + /** + * Static constant for a 418 error. + * 418 Unprocessable Entity (WebDAV drafts?) + * or 418 Reauthentication Required (HTTP/1.1 drafts?) + */ + // not used + // public static final int SC_UNPROCESSABLE_ENTITY = 418; + + /** + * Static constant for a 419 error. + * 419 Insufficient Space on Resource + * (WebDAV - draft-ietf-webdav-protocol-05?) + * or 419 Proxy Reauthentication Required + * (HTTP/1.1 drafts?) + */ + public static final int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 419; + /** + * Static constant for a 420 error. + * 420 Method Failure + * (WebDAV - draft-ietf-webdav-protocol-05?) + */ + public static final int SC_METHOD_FAILURE = 420; + /** 422 Unprocessable Entity (WebDAV - RFC 2518) */ + public static final int SC_UNPROCESSABLE_ENTITY = 422; + /** 423 Locked (WebDAV - RFC 2518) */ + public static final int SC_LOCKED = 423; + /** 424 Failed Dependency (WebDAV - RFC 2518) */ + public static final int SC_FAILED_DEPENDENCY = 424; + + // --- 5xx Server Error --- + + /** 500 Server Error (HTTP/1.0 - RFC 1945) */ + public static final int SC_INTERNAL_SERVER_ERROR = 500; + /** 501 Not Implemented (HTTP/1.0 - RFC 1945) */ + public static final int SC_NOT_IMPLEMENTED = 501; + /** 502 Bad Gateway (HTTP/1.0 - RFC 1945) */ + public static final int SC_BAD_GATEWAY = 502; + /** 503 Service Unavailable (HTTP/1.0 - RFC 1945) */ + public static final int SC_SERVICE_UNAVAILABLE = 503; + /** 504 Gateway Timeout (HTTP/1.1 - RFC 2616) */ + public static final int SC_GATEWAY_TIMEOUT = 504; + /** 505 HTTP Version Not Supported (HTTP/1.1 - RFC 2616) */ + public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505; + + /** 507 Insufficient Storage (WebDAV - RFC 2518) */ + public static final int SC_INSUFFICIENT_STORAGE = 507; + +} Index: 3rdParty_sources/httpcore/org/apache/http/HttpVersion.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/HttpVersion.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/HttpVersion.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,110 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.Serializable; + +import org.apache.http.annotation.Immutable; + +/** + * Represents an HTTP version. HTTP uses a "major.minor" numbering + * scheme to indicate versions of the protocol. + *

+ * The version of an HTTP message is indicated by an HTTP-Version field + * in the first line of the message. + *

+ *
+ *     HTTP-Version   = "HTTP" "/" 1*DIGIT "." 1*DIGIT
+ * 
+ * + * @since 4.0 + */ +@Immutable +public final class HttpVersion extends ProtocolVersion + implements Serializable { + + private static final long serialVersionUID = -5856653513894415344L; + + /** The protocol name. */ + public static final String HTTP = "HTTP"; + + /** HTTP protocol version 0.9 */ + public static final HttpVersion HTTP_0_9 = new HttpVersion(0, 9); + + /** HTTP protocol version 1.0 */ + public static final HttpVersion HTTP_1_0 = new HttpVersion(1, 0); + + /** HTTP protocol version 1.1 */ + public static final HttpVersion HTTP_1_1 = new HttpVersion(1, 1); + + + /** + * Create an HTTP protocol version designator. + * + * @param major the major version number of the HTTP protocol + * @param minor the minor version number of the HTTP protocol + * + * @throws IllegalArgumentException if either major or minor version number is negative + */ + public HttpVersion(int major, int minor) { + super(HTTP, major, minor); + } + + + /** + * Obtains a specific HTTP version. + * + * @param major the major version + * @param minor the minor version + * + * @return an instance of {@link HttpVersion} with the argument version + */ + @Override + public ProtocolVersion forVersion(int major, int minor) { + + if ((major == this.major) && (minor == this.minor)) { + return this; + } + + if (major == 1) { + if (minor == 0) { + return HTTP_1_0; + } + if (minor == 1) { + return HTTP_1_1; + } + } + if ((major == 0) && (minor == 9)) { + return HTTP_0_9; + } + + // argument checking is done in the constructor + return new HttpVersion(major, minor); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/MalformedChunkCodingException.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/MalformedChunkCodingException.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/MalformedChunkCodingException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,57 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.IOException; + +/** + * Signals a malformed chunked stream. + * + * @since 4.0 + */ +public class MalformedChunkCodingException extends IOException { + + private static final long serialVersionUID = 2158560246948994524L; + + /** + * Creates a MalformedChunkCodingException without a detail message. + */ + public MalformedChunkCodingException() { + super(); + } + + /** + * Creates a MalformedChunkCodingException with the specified detail message. + * + * @param message The exception detail message + */ + public MalformedChunkCodingException(final String message) { + super(message); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/MethodNotSupportedException.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/MethodNotSupportedException.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/MethodNotSupportedException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,59 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + + +/** + * Signals that an HTTP method is not supported. + * + * @since 4.0 + */ +public class MethodNotSupportedException extends HttpException { + + private static final long serialVersionUID = 3365359036840171201L; + + /** + * Creates a new MethodNotSupportedException with the specified detail message. + * + * @param message The exception detail message + */ + public MethodNotSupportedException(final String message) { + super(message); + } + + /** + * Creates a new MethodNotSupportedException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public MethodNotSupportedException(final String message, final Throwable cause) { + super(message, cause); + } +} Index: 3rdParty_sources/httpcore/org/apache/http/NameValuePair.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/NameValuePair.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/NameValuePair.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,47 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * A name / value pair parameter used as an element of HTTP messages. + *
+ * parameter               = attribute "=" value
+ * attribute               = token
+ * value                   = token | quoted-string
+ * 
+ * + * + * @since 4.0 + */ +public interface NameValuePair { + + String getName(); + + String getValue(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/NoHttpResponseException.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/NoHttpResponseException.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/NoHttpResponseException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,50 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.IOException; + +/** + * Signals that the target server failed to respond with a valid HTTP response. + * + * @since 4.0 + */ +public class NoHttpResponseException extends IOException { + + private static final long serialVersionUID = -7658940387386078766L; + + /** + * Creates a new NoHttpResponseException with the specified detail message. + * + * @param message exception message + */ + public NoHttpResponseException(String message) { + super(message); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/ParseException.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/ParseException.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/ParseException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,61 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * Signals a parse error. + * Parse errors when receiving a message will typically trigger + * {@link ProtocolException}. Parse errors that do not occur during + * protocol execution may be handled differently. + * This is an unchecked exception, since there are cases where + * the data to be parsed has been generated and is therefore + * known to be parseable. + * + * @since 4.0 + */ +public class ParseException extends RuntimeException { + + private static final long serialVersionUID = -7288819855864183578L; + + /** + * Creates a {@link ParseException} without details. + */ + public ParseException() { + super(); + } + + /** + * Creates a {@link ParseException} with a detail message. + * + * @param message the exception detail message, or null + */ + public ParseException(String message) { + super(message); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/ProtocolException.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/ProtocolException.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/ProtocolException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * Signals that an HTTP protocol violation has occurred. + * For example a malformed status line or headers, a missing message body, etc. + * + * + * @since 4.0 + */ +public class ProtocolException extends HttpException { + + private static final long serialVersionUID = -2143571074341228994L; + + /** + * Creates a new ProtocolException with a null detail message. + */ + public ProtocolException() { + super(); + } + + /** + * Creates a new ProtocolException with the specified detail message. + * + * @param message The exception detail message + */ + public ProtocolException(String message) { + super(message); + } + + /** + * Creates a new ProtocolException with the specified detail message and cause. + * + * @param message the exception detail message + * @param cause the Throwable that caused this exception, or null + * if the cause is unavailable, unknown, or not a Throwable + */ + public ProtocolException(String message, Throwable cause) { + super(message, cause); + } +} Index: 3rdParty_sources/httpcore/org/apache/http/ProtocolVersion.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/ProtocolVersion.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/ProtocolVersion.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,282 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.io.Serializable; + +import org.apache.http.annotation.Immutable; + +/** + * Represents a protocol version. The "major.minor" numbering + * scheme is used to indicate versions of the protocol. + *

+ * This class defines a protocol version as a combination of + * protocol name, major version number, and minor version number. + * Note that {@link #equals} and {@link #hashCode} are defined as + * final here, they cannot be overridden in derived classes. + *

+ * + * @since 4.0 + */ +@Immutable +public class ProtocolVersion implements Serializable, Cloneable { + + private static final long serialVersionUID = 8950662842175091068L; + + + /** Name of the protocol. */ + protected final String protocol; + + /** Major version number of the protocol */ + protected final int major; + + /** Minor version number of the protocol */ + protected final int minor; + + + /** + * Create a protocol version designator. + * + * @param protocol the name of the protocol, for example "HTTP" + * @param major the major version number of the protocol + * @param minor the minor version number of the protocol + */ + public ProtocolVersion(String protocol, int major, int minor) { + if (protocol == null) { + throw new IllegalArgumentException + ("Protocol name must not be null."); + } + if (major < 0) { + throw new IllegalArgumentException + ("Protocol major version number must not be negative."); + } + if (minor < 0) { + throw new IllegalArgumentException + ("Protocol minor version number may not be negative"); + } + this.protocol = protocol; + this.major = major; + this.minor = minor; + } + + /** + * Returns the name of the protocol. + * + * @return the protocol name + */ + public final String getProtocol() { + return protocol; + } + + /** + * Returns the major version number of the protocol. + * + * @return the major version number. + */ + public final int getMajor() { + return major; + } + + /** + * Returns the minor version number of the HTTP protocol. + * + * @return the minor version number. + */ + public final int getMinor() { + return minor; + } + + + /** + * Obtains a specific version of this protocol. + * This can be used by derived classes to instantiate themselves instead + * of the base class, and to define constants for commonly used versions. + *
+ * The default implementation in this class returns this + * if the version matches, and creates a new {@link ProtocolVersion} + * otherwise. + * + * @param major the major version + * @param minor the minor version + * + * @return a protocol version with the same protocol name + * and the argument version + */ + public ProtocolVersion forVersion(int major, int minor) { + + if ((major == this.major) && (minor == this.minor)) { + return this; + } + + // argument checking is done in the constructor + return new ProtocolVersion(this.protocol, major, minor); + } + + + /** + * Obtains a hash code consistent with {@link #equals}. + * + * @return the hashcode of this protocol version + */ + @Override + public final int hashCode() { + return this.protocol.hashCode() ^ (this.major * 100000) ^ this.minor; + } + + + /** + * Checks equality of this protocol version with an object. + * The object is equal if it is a protocl version with the same + * protocol name, major version number, and minor version number. + * The specific class of the object is not relevant, + * instances of derived classes with identical attributes are + * equal to instances of the base class and vice versa. + * + * @param obj the object to compare with + * + * @return true if the argument is the same protocol version, + * false otherwise + */ + @Override + public final boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ProtocolVersion)) { + return false; + } + ProtocolVersion that = (ProtocolVersion) obj; + + return ((this.protocol.equals(that.protocol)) && + (this.major == that.major) && + (this.minor == that.minor)); + } + + + /** + * Checks whether this protocol can be compared to another one. + * Only protocol versions with the same protocol name can be + * {@link #compareToVersion compared}. + * + * @param that the protocol version to consider + * + * @return true if {@link #compareToVersion compareToVersion} + * can be called with the argument, false otherwise + */ + public boolean isComparable(ProtocolVersion that) { + return (that != null) && this.protocol.equals(that.protocol); + } + + + /** + * Compares this protocol version with another one. + * Only protocol versions with the same protocol name can be compared. + * This method does not define a total ordering, as it would be + * required for {@link java.lang.Comparable}. + * + * @param that the protocl version to compare with + * + * @return a negative integer, zero, or a positive integer + * as this version is less than, equal to, or greater than + * the argument version. + * + * @throws IllegalArgumentException + * if the argument has a different protocol name than this object, + * or if the argument is null + */ + public int compareToVersion(ProtocolVersion that) { + if (that == null) { + throw new IllegalArgumentException + ("Protocol version must not be null."); + } + if (!this.protocol.equals(that.protocol)) { + throw new IllegalArgumentException + ("Versions for different protocols cannot be compared. " + + this + " " + that); + } + + int delta = getMajor() - that.getMajor(); + if (delta == 0) { + delta = getMinor() - that.getMinor(); + } + return delta; + } + + + /** + * Tests if this protocol version is greater or equal to the given one. + * + * @param version the version against which to check this version + * + * @return true if this protocol version is + * {@link #isComparable comparable} to the argument + * and {@link #compareToVersion compares} as greater or equal, + * false otherwise + */ + public final boolean greaterEquals(ProtocolVersion version) { + return isComparable(version) && (compareToVersion(version) >= 0); + } + + + /** + * Tests if this protocol version is less or equal to the given one. + * + * @param version the version against which to check this version + * + * @return true if this protocol version is + * {@link #isComparable comparable} to the argument + * and {@link #compareToVersion compares} as less or equal, + * false otherwise + */ + public final boolean lessEquals(ProtocolVersion version) { + return isComparable(version) && (compareToVersion(version) <= 0); + } + + + /** + * Converts this protocol version to a string. + * + * @return a protocol version string, like "HTTP/1.1" + */ + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append(this.protocol); + buffer.append('/'); + buffer.append(Integer.toString(this.major)); + buffer.append('.'); + buffer.append(Integer.toString(this.minor)); + return buffer.toString(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/ReasonPhraseCatalog.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/ReasonPhraseCatalog.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/ReasonPhraseCatalog.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,51 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.util.Locale; + +/** + * Interface for obtaining reason phrases for HTTP status codes. + * + * @since 4.0 + */ +public interface ReasonPhraseCatalog { + + /** + * Obtains the reason phrase for a status code. + * The optional context allows for catalogs that detect + * the language for the reason phrase. + * + * @param status the status code, in the range 100-599 + * @param loc the preferred locale for the reason phrase + * + * @return the reason phrase, or null if unknown + */ + public String getReason(int status, Locale loc); + +} Index: 3rdParty_sources/httpcore/org/apache/http/RequestLine.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/RequestLine.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/RequestLine.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,49 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * The Request-Line begins with a method token, followed by the + * Request-URI and the protocol version, and ending with CRLF. The + * elements are separated by SP characters. No CR or LF is allowed + * except in the final CRLF sequence. + *
+ *      Request-Line   = Method SP Request-URI SP HTTP-Version CRLF
+ * 
+ * + * @since 4.0 + */ +public interface RequestLine { + + String getMethod(); + + ProtocolVersion getProtocolVersion(); + + String getUri(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/StatusLine.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/StatusLine.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/StatusLine.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,52 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * The first line of a Response message is the Status-Line, consisting + * of the protocol version followed by a numeric status code and its + * associated textual phrase, with each element separated by SP + * characters. No CR or LF is allowed except in the final CRLF sequence. + *
+ *     Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
+ * 
+ * + * @see HttpStatus + * @version $Id$ + * + * @since 4.0 + */ +public interface StatusLine { + + ProtocolVersion getProtocolVersion(); + + int getStatusCode(); + + String getReasonPhrase(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/TokenIterator.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/TokenIterator.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/TokenIterator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,59 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import java.util.Iterator; + +/** + * An iterator for {@link String} tokens. + * This interface is designed as a complement to + * {@link HeaderElementIterator}, in cases where the items + * are plain strings rather than full header elements. + * + * @since 4.0 + */ +public interface TokenIterator extends Iterator { + + /** + * Indicates whether there is another token in this iteration. + * + * @return true if there is another token, + * false otherwise + */ + boolean hasNext(); + + /** + * Obtains the next token from this iteration. + * This method should only be called while {@link #hasNext hasNext} + * is true. + * + * @return the next token in this iteration + */ + String nextToken(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/TruncatedChunkException.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/TruncatedChunkException.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/TruncatedChunkException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,48 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +/** + * Signals a truncated chunk in a chunked stream. + * + * @since 4.1 + */ +public class TruncatedChunkException extends MalformedChunkCodingException { + + private static final long serialVersionUID = -23506263930279460L; + + /** + * Creates a TruncatedChunkException with the specified detail message. + * + * @param message The exception detail message + */ + public TruncatedChunkException(final String message) { + super(message); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/UnsupportedHttpVersionException.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/UnsupportedHttpVersionException.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/UnsupportedHttpVersionException.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,58 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http; + +import org.apache.http.ProtocolException; + +/** + * Signals an unsupported version of the HTTP protocol. + * + * @since 4.0 + */ +public class UnsupportedHttpVersionException extends ProtocolException { + + private static final long serialVersionUID = -1348448090193107031L; + + + /** + * Creates an exception without a detail message. + */ + public UnsupportedHttpVersionException() { + super(); + } + + /** + * Creates an exception with the specified detail message. + * + * @param message The exception detail message + */ + public UnsupportedHttpVersionException(final String message) { + super(message); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/annotation/GuardedBy.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/annotation/GuardedBy.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/annotation/GuardedBy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,75 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The field or method to which this annotation is applied can only be accessed + * when holding a particular lock, which may be a built-in (synchronization) lock, + * or may be an explicit java.util.concurrent.Lock. + * + * The argument determines which lock guards the annotated field or method: + *
    + *
  • + * this : The intrinsic lock of the object in whose class the field is defined. + *
  • + *
  • + * class-name.this : For inner classes, it may be necessary to disambiguate 'this'; + * the class-name.this designation allows you to specify which 'this' reference is intended + *
  • + *
  • + * itself : For reference fields only; the object to which the field refers. + *
  • + *
  • + * field-name : The lock object is referenced by the (instance or static) field + * specified by field-name. + *
  • + *
  • + * class-name.field-name : The lock object is reference by the static field specified + * by class-name.field-name. + *
  • + *
  • + * method-name() : The lock object is returned by calling the named nil-ary method. + *
  • + *
  • + * class-name.class : The Class object for the specified class should be used as the lock object. + *
  • + *

    + * Based on code developed by Brian Goetz and Tim Peierls and concepts + * published in 'Java Concurrency in Practice' by Brian Goetz, Tim Peierls, + * Joshua Bloch, Joseph Bowbeer, David Holmes and Doug Lea. + */ +@Documented +@Target({ElementType.FIELD, ElementType.METHOD}) +@Retention(RetentionPolicy.CLASS) // The original version used RUNTIME +public @interface GuardedBy { + String value(); +} Index: 3rdParty_sources/httpcore/org/apache/http/annotation/Immutable.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/annotation/Immutable.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/annotation/Immutable.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,58 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The class to which this annotation is applied is immutable. This means that + * its state cannot be seen to change by callers, which implies that + *

      + *
    • all public fields are final,
    • + *
    • all public final reference fields refer to other immutable objects, and
    • + *
    • constructors and methods do not publish references to any internal state + * which is potentially mutable by the implementation.
    • + *
    + * Immutable objects may still have internal mutable state for purposes of performance + * optimization; some state variables may be lazily computed, so long as they are computed + * from immutable state and that callers cannot tell the difference. + *

    + * Immutable objects are inherently thread-safe; they may be passed between threads or + * published without synchronization. + *

    + * Based on code developed by Brian Goetz and Tim Peierls and concepts + * published in 'Java Concurrency in Practice' by Brian Goetz, Tim Peierls, + * Joshua Bloch, Joseph Bowbeer, David Holmes and Doug Lea. + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.CLASS) // The original version used RUNTIME +public @interface Immutable { +} Index: 3rdParty_sources/httpcore/org/apache/http/annotation/NotThreadSafe.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/annotation/NotThreadSafe.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/annotation/NotThreadSafe.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,49 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The class to which this annotation is applied is not thread-safe. + * This annotation primarily exists for clarifying the non-thread-safety of a class + * that might otherwise be assumed to be thread-safe, despite the fact that it is a bad + * idea to assume a class is thread-safe without good reason. + * @see ThreadSafe + *

    + * Based on code developed by Brian Goetz and Tim Peierls and concepts + * published in 'Java Concurrency in Practice' by Brian Goetz, Tim Peierls, + * Joshua Bloch, Joseph Bowbeer, David Holmes and Doug Lea. + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.CLASS) // The original version used RUNTIME +public @interface NotThreadSafe { +} Index: 3rdParty_sources/httpcore/org/apache/http/annotation/ThreadSafe.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/annotation/ThreadSafe.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/annotation/ThreadSafe.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,50 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The class to which this annotation is applied is thread-safe. This means that + * no sequences of accesses (reads and writes to public fields, calls to public methods) + * may put the object into an invalid state, regardless of the interleaving of those actions + * by the runtime, and without requiring any additional synchronization or coordination on the + * part of the caller. + * @see NotThreadSafe + *

    + * Based on code developed by Brian Goetz and Tim Peierls and concepts + * published in 'Java Concurrency in Practice' by Brian Goetz, Tim Peierls, + * Joshua Bloch, Joseph Bowbeer, David Holmes and Doug Lea. + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.CLASS) // The original version used RUNTIME +public @interface ThreadSafe { +} Index: 3rdParty_sources/httpcore/org/apache/http/annotation/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/annotation/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/annotation/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,37 @@ + + + + + +Thread-safety annotations based on JCIP-ANNOTATIONS +
    +Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net + + Index: 3rdParty_sources/httpcore/org/apache/http/concurrent/BasicFuture.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/concurrent/BasicFuture.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/concurrent/BasicFuture.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,145 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.concurrent; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Basic implementation of the {@link Future} interface. BasicFuture + * can be put into a completed state by invoking any of the following methods: + * {@link #cancel()}, {@link #failed(Exception)}, or {@link #completed(Object)}. + * + * @param the future result type of an asynchronous operation. + * @since 4.2 + */ +public class BasicFuture implements Future, Cancellable { + + private final FutureCallback callback; + + private volatile boolean completed; + private volatile boolean cancelled; + private volatile T result; + private volatile Exception ex; + + public BasicFuture(final FutureCallback callback) { + super(); + this.callback = callback; + } + + public boolean isCancelled() { + return this.cancelled; + } + + public boolean isDone() { + return this.completed; + } + + private T getResult() throws ExecutionException { + if (this.ex != null) { + throw new ExecutionException(this.ex); + } + return this.result; + } + + public synchronized T get() throws InterruptedException, ExecutionException { + while (!this.completed) { + wait(); + } + return getResult(); + } + + public synchronized T get(long timeout, final TimeUnit unit) + throws InterruptedException, ExecutionException, TimeoutException { + long msecs = unit.toMillis(timeout); + long startTime = (msecs <= 0) ? 0 : System.currentTimeMillis(); + long waitTime = msecs; + if (this.completed) { + return getResult(); + } else if (waitTime <= 0) { + throw new TimeoutException(); + } else { + for (;;) { + wait(waitTime); + if (this.completed) { + return getResult(); + } else { + waitTime = msecs - (System.currentTimeMillis() - startTime); + if (waitTime <= 0) { + throw new TimeoutException(); + } + } + } + } + } + + public synchronized boolean completed(final T result) { + if (this.completed) { + return false; + } + this.completed = true; + this.result = result; + if (this.callback != null) { + this.callback.completed(result); + } + notifyAll(); + return true; + } + + public synchronized boolean failed(final Exception exception) { + if (this.completed) { + return false; + } + this.completed = true; + this.ex = exception; + if (this.callback != null) { + this.callback.failed(exception); + } + notifyAll(); + return true; + } + + public synchronized boolean cancel(boolean mayInterruptIfRunning) { + if (this.completed) { + return false; + } + this.completed = true; + this.cancelled = true; + if (this.callback != null) { + this.callback.cancelled(); + } + notifyAll(); + return true; + } + + public boolean cancel() { + return cancel(true); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/concurrent/Cancellable.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/concurrent/Cancellable.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/concurrent/Cancellable.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,39 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.concurrent; + +/** + * A Cancellable represents a process or an operation that can be + * canceled. + * + * @since 4.2 + */ +public interface Cancellable { + + boolean cancel(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/concurrent/FutureCallback.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/concurrent/FutureCallback.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/concurrent/FutureCallback.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,45 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.concurrent; + +import java.util.concurrent.Future; + +/** + * A callback interface that gets invoked upon completion of a {@link Future}. + * + * @param the future result type returned by this callback. + * @since 4.2 + */ +public interface FutureCallback { + + void completed(T result); + + void failed(Exception ex); + + void cancelled(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/concurrent/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/concurrent/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/concurrent/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,35 @@ + + + + + +Common concurrency components. + + Index: 3rdParty_sources/httpcore/org/apache/http/entity/AbstractHttpEntity.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/AbstractHttpEntity.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/AbstractHttpEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,185 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; + +/** + * Abstract base class for entities. + * Provides the commonly used attributes for streamed and self-contained + * implementations of {@link HttpEntity HttpEntity}. + * + * @since 4.0 + */ +@NotThreadSafe +public abstract class AbstractHttpEntity implements HttpEntity { + + protected Header contentType; + protected Header contentEncoding; + protected boolean chunked; + + /** + * Protected default constructor. + * The contentType, contentEncoding and chunked attributes of the created object are set to + * null, null and false, respectively. + */ + protected AbstractHttpEntity() { + super(); + } + + + /** + * Obtains the Content-Type header. + * The default implementation returns the value of the + * {@link #contentType contentType} attribute. + * + * @return the Content-Type header, or null + */ + public Header getContentType() { + return this.contentType; + } + + + /** + * Obtains the Content-Encoding header. + * The default implementation returns the value of the + * {@link #contentEncoding contentEncoding} attribute. + * + * @return the Content-Encoding header, or null + */ + public Header getContentEncoding() { + return this.contentEncoding; + } + + /** + * Obtains the 'chunked' flag. + * The default implementation returns the value of the + * {@link #chunked chunked} attribute. + * + * @return the 'chunked' flag + */ + public boolean isChunked() { + return this.chunked; + } + + + /** + * Specifies the Content-Type header. + * The default implementation sets the value of the + * {@link #contentType contentType} attribute. + * + * @param contentType the new Content-Encoding header, or + * null to unset + */ + public void setContentType(final Header contentType) { + this.contentType = contentType; + } + + /** + * Specifies the Content-Type header, as a string. + * The default implementation calls + * {@link #setContentType(Header) setContentType(Header)}. + * + * @param ctString the new Content-Type header, or + * null to unset + */ + public void setContentType(final String ctString) { + Header h = null; + if (ctString != null) { + h = new BasicHeader(HTTP.CONTENT_TYPE, ctString); + } + setContentType(h); + } + + + /** + * Specifies the Content-Encoding header. + * The default implementation sets the value of the + * {@link #contentEncoding contentEncoding} attribute. + * + * @param contentEncoding the new Content-Encoding header, or + * null to unset + */ + public void setContentEncoding(final Header contentEncoding) { + this.contentEncoding = contentEncoding; + } + + /** + * Specifies the Content-Encoding header, as a string. + * The default implementation calls + * {@link #setContentEncoding(Header) setContentEncoding(Header)}. + * + * @param ceString the new Content-Encoding header, or + * null to unset + */ + public void setContentEncoding(final String ceString) { + Header h = null; + if (ceString != null) { + h = new BasicHeader(HTTP.CONTENT_ENCODING, ceString); + } + setContentEncoding(h); + } + + + /** + * Specifies the 'chunked' flag. + *

    + * Note that the chunked setting is a hint only. + * If using HTTP/1.0, chunking is never performed. + * Otherwise, even if chunked is false, HttpClient must + * use chunk coding if the entity content length is + * unknown (-1). + *

    + * The default implementation sets the value of the + * {@link #chunked chunked} attribute. + * + * @param b the new 'chunked' flag + */ + public void setChunked(boolean b) { + this.chunked = b; + } + + + /** + * The default implementation does not consume anything. + * + * @deprecated (4.1) Either use {@link #getContent()} and call {@link java.io.InputStream#close()} on that; + * otherwise call {@link #writeTo(OutputStream)} which is required to free the resources. + */ + @Deprecated + public void consumeContent() throws IOException { + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/entity/BasicHttpEntity.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/BasicHttpEntity.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/BasicHttpEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,142 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * A generic streamed, non-repeatable entity that obtains its content + * from an {@link InputStream}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicHttpEntity extends AbstractHttpEntity { + + private InputStream content; + private long length; + + /** + * Creates a new basic entity. + * The content is initially missing, the content length + * is set to a negative number. + */ + public BasicHttpEntity() { + super(); + this.length = -1; + } + + public long getContentLength() { + return this.length; + } + + /** + * Obtains the content, once only. + * + * @return the content, if this is the first call to this method + * since {@link #setContent setContent} has been called + * + * @throws IllegalStateException + * if the content has not been provided + */ + public InputStream getContent() throws IllegalStateException { + if (this.content == null) { + throw new IllegalStateException("Content has not been provided"); + } + return this.content; + + } + + /** + * Tells that this entity is not repeatable. + * + * @return false + */ + public boolean isRepeatable() { + return false; + } + + /** + * Specifies the length of the content. + * + * @param len the number of bytes in the content, or + * a negative number to indicate an unknown length + */ + public void setContentLength(long len) { + this.length = len; + } + + /** + * Specifies the content. + * + * @param instream the stream to return with the next call to + * {@link #getContent getContent} + */ + public void setContent(final InputStream instream) { + this.content = instream; + } + + public void writeTo(final OutputStream outstream) throws IOException { + if (outstream == null) { + throw new IllegalArgumentException("Output stream may not be null"); + } + InputStream instream = getContent(); + try { + int l; + byte[] tmp = new byte[2048]; + while ((l = instream.read(tmp)) != -1) { + outstream.write(tmp, 0, l); + } + } finally { + instream.close(); + } + } + + public boolean isStreaming() { + return this.content != null; + } + + /** + * Closes the content InputStream. + * + * @deprecated (4.1) Either use {@link #getContent()} and call {@link java.io.InputStream#close()} on that; + * otherwise call {@link #writeTo(OutputStream)} which is required to free the resources. + */ + @Deprecated + @Override + public void consumeContent() throws IOException { + if (content != null) { + content.close(); // reads to the end of the entity + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/entity/BufferedHttpEntity.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/BufferedHttpEntity.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/BufferedHttpEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,126 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.http.HttpEntity; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.util.EntityUtils; + +/** + * A wrapping entity that buffers it content if necessary. + * The buffered entity is always repeatable. + * If the wrapped entity is repeatable itself, calls are passed through. + * If the wrapped entity is not repeatable, the content is read into a + * buffer once and provided from there as often as required. + * + * @since 4.0 + */ +@NotThreadSafe +public class BufferedHttpEntity extends HttpEntityWrapper { + + private final byte[] buffer; + + /** + * Creates a new buffered entity wrapper. + * + * @param entity the entity to wrap, not null + * @throws IllegalArgumentException if wrapped is null + */ + public BufferedHttpEntity(final HttpEntity entity) throws IOException { + super(entity); + if (!entity.isRepeatable() || entity.getContentLength() < 0) { + this.buffer = EntityUtils.toByteArray(entity); + } else { + this.buffer = null; + } + } + + @Override + public long getContentLength() { + if (this.buffer != null) { + return this.buffer.length; + } else { + return wrappedEntity.getContentLength(); + } + } + + @Override + public InputStream getContent() throws IOException { + if (this.buffer != null) { + return new ByteArrayInputStream(this.buffer); + } else { + return wrappedEntity.getContent(); + } + } + + /** + * Tells that this entity does not have to be chunked. + * + * @return false + */ + @Override + public boolean isChunked() { + return (buffer == null) && wrappedEntity.isChunked(); + } + + /** + * Tells that this entity is repeatable. + * + * @return true + */ + @Override + public boolean isRepeatable() { + return true; + } + + + @Override + public void writeTo(final OutputStream outstream) throws IOException { + if (outstream == null) { + throw new IllegalArgumentException("Output stream may not be null"); + } + if (this.buffer != null) { + outstream.write(this.buffer); + } else { + wrappedEntity.writeTo(outstream); + } + } + + + // non-javadoc, see interface HttpEntity + @Override + public boolean isStreaming() { + return (buffer == null) && wrappedEntity.isStreaming(); + } + +} // class BufferedHttpEntity Index: 3rdParty_sources/httpcore/org/apache/http/entity/ByteArrayEntity.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/ByteArrayEntity.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/ByteArrayEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,134 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * A self contained, repeatable entity that obtains its content from a byte array. + * + * @since 4.0 + */ +@NotThreadSafe +public class ByteArrayEntity extends AbstractHttpEntity implements Cloneable { + + /** + * @deprecated (4.2) + */ + @Deprecated + protected final byte[] content; + private final byte[] b; + private final int off, len; + + /** + * @since 4.2 + */ + public ByteArrayEntity(final byte[] b, final ContentType contentType) { + super(); + if (b == null) { + throw new IllegalArgumentException("Source byte array may not be null"); + } + this.content = b; + this.b = b; + this.off = 0; + this.len = this.b.length; + if (contentType != null) { + setContentType(contentType.toString()); + } + } + + /** + * @since 4.2 + */ + public ByteArrayEntity(final byte[] b, int off, int len, final ContentType contentType) { + super(); + if (b == null) { + throw new IllegalArgumentException("Source byte array may not be null"); + } + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) < 0) || ((off + len) > b.length)) { + throw new IndexOutOfBoundsException("off: " + off + " len: " + len + " b.length: " + b.length); + } + this.content = b; + this.b = b; + this.off = off; + this.len = len; + if (contentType != null) { + setContentType(contentType.toString()); + } + } + + public ByteArrayEntity(final byte[] b) { + this(b, null); + } + + public ByteArrayEntity(final byte[] b, int off, int len) { + this(b, off, len, null); + } + + public boolean isRepeatable() { + return true; + } + + public long getContentLength() { + return this.len; + } + + public InputStream getContent() { + return new ByteArrayInputStream(this.b, this.off, this.len); + } + + public void writeTo(final OutputStream outstream) throws IOException { + if (outstream == null) { + throw new IllegalArgumentException("Output stream may not be null"); + } + outstream.write(this.b, this.off, this.len); + outstream.flush(); + } + + + /** + * Tells that this entity is not streaming. + * + * @return false + */ + public boolean isStreaming() { + return false; + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} // class ByteArrayEntity Index: 3rdParty_sources/httpcore/org/apache/http/entity/ContentLengthStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/ContentLengthStrategy.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/ContentLengthStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,57 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; + +/** + * Represents a strategy to determine length of the enclosed content entity + * based on properties of the HTTP message. + * + * @since 4.0 + */ +public interface ContentLengthStrategy { + + public static final int IDENTITY = -1; + public static final int CHUNKED = -2; + + /** + * Returns length of the given message in bytes. The returned value + * must be a non-negative number, {@link #IDENTITY} if the end of the + * message will be delimited by the end of connection, or {@link #CHUNKED} + * if the message is chunk coded + * + * @param message + * @return content length, {@link #IDENTITY}, or {@link #CHUNKED} + * + * @throws HttpException in case of HTTP protocol violation + */ + long determineLength(HttpMessage message) throws HttpException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/entity/ContentProducer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/ContentProducer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/ContentProducer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,44 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * An abstract entity content producer. + *

    Content producers are expected to be able to produce their + * content multiple times

    + * + * @since 4.0 + */ +public interface ContentProducer { + + void writeTo(OutputStream outstream) throws IOException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/entity/ContentType.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/ContentType.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/ContentType.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,250 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; +import java.util.Locale; + +import org.apache.http.Consts; +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.ParseException; +import org.apache.http.annotation.Immutable; +import org.apache.http.message.BasicHeaderValueParser; + +/** + * Content type information consisting of a MIME type and an optional charset. + *

    + * This class makes no attempts to verify validity of the MIME type. + * The input parameters of the {@link #create(String, String)} method, however, may not + * contain characters <">, <;>, <,> reserved by the HTTP specification. + * + * @since 4.2 + */ +@Immutable +public final class ContentType { + + // constants + public static final ContentType APPLICATION_ATOM_XML = create( + "application/atom+xml", Consts.ISO_8859_1); + public static final ContentType APPLICATION_FORM_URLENCODED = create( + "application/x-www-form-urlencoded", Consts.ISO_8859_1); + public static final ContentType APPLICATION_JSON = create( + "application/json", Consts.UTF_8); + public static final ContentType APPLICATION_OCTET_STREAM = create( + "application/octet-stream", (Charset) null); + public static final ContentType APPLICATION_SVG_XML = create( + "application/svg+xml", Consts.ISO_8859_1); + public static final ContentType APPLICATION_XHTML_XML = create( + "application/xhtml+xml", Consts.ISO_8859_1); + public static final ContentType APPLICATION_XML = create( + "application/xml", Consts.ISO_8859_1); + public static final ContentType MULTIPART_FORM_DATA = create( + "multipart/form-data", Consts.ISO_8859_1); + public static final ContentType TEXT_HTML = create( + "text/html", Consts.ISO_8859_1); + public static final ContentType TEXT_PLAIN = create( + "text/plain", Consts.ISO_8859_1); + public static final ContentType TEXT_XML = create( + "text/xml", Consts.ISO_8859_1); + public static final ContentType WILDCARD = create( + "*/*", (Charset) null); + + // defaults + public static final ContentType DEFAULT_TEXT = TEXT_PLAIN; + public static final ContentType DEFAULT_BINARY = APPLICATION_OCTET_STREAM; + + private final String mimeType; + private final Charset charset; + + /** + * Given a MIME type and a character set, constructs a ContentType. + * @param mimeType The MIME type to use for the ContentType header. + * @param charset The optional character set to use with the ContentType header. + * @throws UnsupportedCharsetException + * If no support for the named charset is available in this Java virtual machine + */ + ContentType(final String mimeType, final Charset charset) { + this.mimeType = mimeType; + this.charset = charset; + } + + public String getMimeType() { + return this.mimeType; + } + + public Charset getCharset() { + return this.charset; + } + + /** + * Converts a ContentType to a string which can be used as a ContentType header. + * If a charset is provided by the ContentType, it will be included in the string. + */ + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append(this.mimeType); + if (this.charset != null) { + buf.append("; charset="); + buf.append(this.charset.name()); + } + return buf.toString(); + } + + private static boolean valid(final String s) { + for (int i = 0; i < s.length(); i++) { + char ch = s.charAt(i); + if (ch == '"' || ch == ',' || ch == ';') { + return false; + } + } + return true; + } + + /** + * Creates a new instance of {@link ContentType}. + * + * @param mimeType MIME type. It may not be null or empty. It may not contain + * characters <">, <;>, <,> reserved by the HTTP specification. + * @param charset charset. + * @return content type + */ + public static ContentType create(final String mimeType, final Charset charset) { + if (mimeType == null) { + throw new IllegalArgumentException("MIME type may not be null"); + } + String type = mimeType.trim().toLowerCase(Locale.US); + if (type.length() == 0) { + throw new IllegalArgumentException("MIME type may not be empty"); + } + if (!valid(type)) { + throw new IllegalArgumentException("MIME type may not contain reserved characters"); + } + return new ContentType(type, charset); + } + + /** + * Creates a new instance of {@link ContentType} without a charset. + * + * @param mimeType MIME type. It may not be null or empty. It may not contain + * characters <">, <;>, <,> reserved by the HTTP specification. + * @return content type + */ + public static ContentType create(final String mimeType) { + return new ContentType(mimeType, (Charset) null); + } + + /** + * Creates a new instance of {@link ContentType}. + * + * @param mimeType MIME type. It may not be null or empty. It may not contain + * characters <">, <;>, <,> reserved by the HTTP specification. + * @param charset charset. It may not contain characters <">, <;>, <,> reserved by the HTTP + * specification. This parameter is optional. + * @return content type + */ + public static ContentType create( + final String mimeType, final String charset) throws UnsupportedCharsetException { + return create(mimeType, charset != null ? Charset.forName(charset) : null); + } + + private static ContentType create(final HeaderElement helem) { + String mimeType = helem.getName(); + String charset = null; + NameValuePair param = helem.getParameterByName("charset"); + if (param != null) { + charset = param.getValue(); + } + return create(mimeType, charset); + } + + /** + * Parses textual representation of Content-Type value. + * + * @param s text + * @return content type + * @throws ParseException if the given text does not represent a valid + * Content-Type value. + */ + public static ContentType parse( + final String s) throws ParseException, UnsupportedCharsetException { + if (s == null) { + throw new IllegalArgumentException("Content type may not be null"); + } + HeaderElement[] elements = BasicHeaderValueParser.parseElements(s, null); + if (elements.length > 0) { + return create(elements[0]); + } else { + throw new ParseException("Invalid content type: " + s); + } + } + + /** + * Extracts Content-Type value from {@link HttpEntity} exactly as + * specified by the Content-Type header of the entity. Returns null + * if not specified. + * + * @param entity HTTP entity + * @return content type + * @throws ParseException if the given text does not represent a valid + * Content-Type value. + */ + public static ContentType get( + final HttpEntity entity) throws ParseException, UnsupportedCharsetException { + if (entity == null) { + return null; + } + Header header = entity.getContentType(); + if (header != null) { + HeaderElement[] elements = header.getElements(); + if (elements.length > 0) { + return create(elements[0]); + } + } + return null; + } + + /** + * Extracts Content-Type value from {@link HttpEntity} or returns default value + * if not explicitly specified. + * + * @param entity HTTP entity + * @return content type + * @throws ParseException if the given text does not represent a valid + * Content-Type value. + */ + public static ContentType getOrDefault(final HttpEntity entity) throws ParseException { + ContentType contentType = get(entity); + return contentType != null ? contentType : DEFAULT_TEXT; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/entity/EntityTemplate.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/EntityTemplate.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/EntityTemplate.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,79 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Entity that delegates the process of content generation + * to a {@link ContentProducer}. + * + * @since 4.0 + */ +public class EntityTemplate extends AbstractHttpEntity { + + private final ContentProducer contentproducer; + + public EntityTemplate(final ContentProducer contentproducer) { + super(); + if (contentproducer == null) { + throw new IllegalArgumentException("Content producer may not be null"); + } + this.contentproducer = contentproducer; + } + + public long getContentLength() { + return -1; + } + + public InputStream getContent() throws IOException { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + writeTo(buf); + return new ByteArrayInputStream(buf.toByteArray()); + } + + public boolean isRepeatable() { + return true; + } + + public void writeTo(final OutputStream outstream) throws IOException { + if (outstream == null) { + throw new IllegalArgumentException("Output stream may not be null"); + } + this.contentproducer.writeTo(outstream); + } + + public boolean isStreaming() { + return false; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/entity/FileEntity.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/FileEntity.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/FileEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,131 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * A self contained, repeatable entity that obtains its content from a file. + * + * @since 4.0 + */ +@NotThreadSafe +public class FileEntity extends AbstractHttpEntity implements Cloneable { + + protected final File file; + + /** + * @deprecated (4.1.3) {@link #FileEntity(File, ContentType)} + */ + @Deprecated + public FileEntity(final File file, final String contentType) { + super(); + if (file == null) { + throw new IllegalArgumentException("File may not be null"); + } + this.file = file; + setContentType(contentType); + } + + /** + * @since 4.2 + */ + public FileEntity(final File file, final ContentType contentType) { + super(); + if (file == null) { + throw new IllegalArgumentException("File may not be null"); + } + this.file = file; + if (contentType != null) { + setContentType(contentType.toString()); + } + } + + /** + * @since 4.2 + */ + public FileEntity(final File file) { + super(); + if (file == null) { + throw new IllegalArgumentException("File may not be null"); + } + this.file = file; + } + + public boolean isRepeatable() { + return true; + } + + public long getContentLength() { + return this.file.length(); + } + + public InputStream getContent() throws IOException { + return new FileInputStream(this.file); + } + + public void writeTo(final OutputStream outstream) throws IOException { + if (outstream == null) { + throw new IllegalArgumentException("Output stream may not be null"); + } + InputStream instream = new FileInputStream(this.file); + try { + byte[] tmp = new byte[4096]; + int l; + while ((l = instream.read(tmp)) != -1) { + outstream.write(tmp, 0, l); + } + outstream.flush(); + } finally { + instream.close(); + } + } + + /** + * Tells that this entity is not streaming. + * + * @return false + */ + public boolean isStreaming() { + return false; + } + + @Override + public Object clone() throws CloneNotSupportedException { + // File instance is considered immutable + // No need to make a copy of it + return super.clone(); + } + +} // class FileEntity Index: 3rdParty_sources/httpcore/org/apache/http/entity/HttpEntityWrapper.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/HttpEntityWrapper.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/HttpEntityWrapper.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,114 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.annotation.NotThreadSafe; + +/** + * Base class for wrapping entities. + * Keeps a {@link #wrappedEntity wrappedEntity} and delegates all + * calls to it. Implementations of wrapping entities can derive + * from this class and need to override only those methods that + * should not be delegated to the wrapped entity. + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpEntityWrapper implements HttpEntity { + + /** The wrapped entity. */ + protected HttpEntity wrappedEntity; + + /** + * Creates a new entity wrapper. + * + * @param wrapped the entity to wrap, not null + * @throws IllegalArgumentException if wrapped is null + */ + public HttpEntityWrapper(HttpEntity wrapped) { + super(); + + if (wrapped == null) { + throw new IllegalArgumentException + ("wrapped entity must not be null"); + } + wrappedEntity = wrapped; + + } // constructor + + + public boolean isRepeatable() { + return wrappedEntity.isRepeatable(); + } + + public boolean isChunked() { + return wrappedEntity.isChunked(); + } + + public long getContentLength() { + return wrappedEntity.getContentLength(); + } + + public Header getContentType() { + return wrappedEntity.getContentType(); + } + + public Header getContentEncoding() { + return wrappedEntity.getContentEncoding(); + } + + public InputStream getContent() + throws IOException { + return wrappedEntity.getContent(); + } + + public void writeTo(OutputStream outstream) + throws IOException { + wrappedEntity.writeTo(outstream); + } + + public boolean isStreaming() { + return wrappedEntity.isStreaming(); + } + + /** + * @deprecated (4.1) Either use {@link #getContent()} and call {@link java.io.InputStream#close()} on that; + * otherwise call {@link #writeTo(OutputStream)} which is required to free the resources. + */ + @Deprecated + public void consumeContent() throws IOException { + wrappedEntity.consumeContent(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/entity/InputStreamEntity.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/InputStreamEntity.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/InputStreamEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,127 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * A streamed, non-repeatable entity that obtains its content from + * an {@link InputStream}. + * + * @since 4.0 + */ +@NotThreadSafe +public class InputStreamEntity extends AbstractHttpEntity { + + private final static int BUFFER_SIZE = 2048; + + private final InputStream content; + private final long length; + + public InputStreamEntity(final InputStream instream, long length) { + this(instream, length, null); + } + + /** + * @since 4.2 + */ + public InputStreamEntity(final InputStream instream, long length, final ContentType contentType) { + super(); + if (instream == null) { + throw new IllegalArgumentException("Source input stream may not be null"); + } + this.content = instream; + this.length = length; + if (contentType != null) { + setContentType(contentType.toString()); + } + } + + public boolean isRepeatable() { + return false; + } + + public long getContentLength() { + return this.length; + } + + public InputStream getContent() throws IOException { + return this.content; + } + + public void writeTo(final OutputStream outstream) throws IOException { + if (outstream == null) { + throw new IllegalArgumentException("Output stream may not be null"); + } + InputStream instream = this.content; + try { + byte[] buffer = new byte[BUFFER_SIZE]; + int l; + if (this.length < 0) { + // consume until EOF + while ((l = instream.read(buffer)) != -1) { + outstream.write(buffer, 0, l); + } + } else { + // consume no more than length + long remaining = this.length; + while (remaining > 0) { + l = instream.read(buffer, 0, (int)Math.min(BUFFER_SIZE, remaining)); + if (l == -1) { + break; + } + outstream.write(buffer, 0, l); + remaining -= l; + } + } + } finally { + instream.close(); + } + } + + public boolean isStreaming() { + return true; + } + + /** + * @deprecated (4.1) Either use {@link #getContent()} and call {@link java.io.InputStream#close()} on that; + * otherwise call {@link #writeTo(OutputStream)} which is required to free the resources. + */ + @Deprecated + @Override + public void consumeContent() throws IOException { + // If the input stream is from a connection, closing it will read to + // the end of the content. Otherwise, we don't care what it does. + this.content.close(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/entity/SerializableEntity.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/SerializableEntity.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/SerializableEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,122 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Serializable; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * A streamed entity that obtains its content from a {@link Serializable}. + * The content obtained from the {@link Serializable} instance can + * optionally be buffered in a byte array in order to make the + * entity self-contained and repeatable. + * + * @since 4.0 + */ +@NotThreadSafe +public class SerializableEntity extends AbstractHttpEntity { + + private byte[] objSer; + + private Serializable objRef; + + /** + * Creates new instance of this class. + * + * @param ser input + * @param bufferize tells whether the content should be + * stored in an internal buffer + * @throws IOException in case of an I/O error + */ + public SerializableEntity(Serializable ser, boolean bufferize) throws IOException { + super(); + if (ser == null) { + throw new IllegalArgumentException("Source object may not be null"); + } + + if (bufferize) { + createBytes(ser); + } else { + this.objRef = ser; + } + } + + private void createBytes(Serializable ser) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(baos); + out.writeObject(ser); + out.flush(); + this.objSer = baos.toByteArray(); + } + + public InputStream getContent() throws IOException, IllegalStateException { + if (this.objSer == null) { + createBytes(this.objRef); + } + return new ByteArrayInputStream(this.objSer); + } + + public long getContentLength() { + if (this.objSer == null) { + return -1; + } else { + return this.objSer.length; + } + } + + public boolean isRepeatable() { + return true; + } + + public boolean isStreaming() { + return this.objSer == null; + } + + public void writeTo(OutputStream outstream) throws IOException { + if (outstream == null) { + throw new IllegalArgumentException("Output stream may not be null"); + } + + if (this.objSer == null) { + ObjectOutputStream out = new ObjectOutputStream(outstream); + out.writeObject(this.objRef); + out.flush(); + } else { + outstream.write(this.objSer); + outstream.flush(); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/entity/StringEntity.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/StringEntity.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/StringEntity.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,194 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.protocol.HTTP; + +/** + * A self contained, repeatable entity that obtains its content from + * a {@link String}. + * + * @since 4.0 + */ +@NotThreadSafe +public class StringEntity extends AbstractHttpEntity implements Cloneable { + + protected final byte[] content; + + /** + * Creates a StringEntity with the specified content and content type. + * + * @param string content to be used. Not {@code null}. + * @param contentType content type to be used. May be {@code null}, in which case the default + * MIME type {@link ContentType#TEXT_PLAIN} is assumed. + * + * @throws IllegalArgumentException if the string parameter is null + * + * @since 4.2 + */ + public StringEntity(final String string, final ContentType contentType) { + super(); + if (string == null) { + throw new IllegalArgumentException("Source string may not be null"); + } + Charset charset = contentType != null ? contentType.getCharset() : null; + if (charset == null) { + charset = HTTP.DEF_CONTENT_CHARSET; + } + try { + this.content = string.getBytes(charset.name()); + } catch (UnsupportedEncodingException ex) { + // should never happen + throw new UnsupportedCharsetException(charset.name()); + } + if (contentType != null) { + setContentType(contentType.toString()); + } + } + + /** + * Creates a StringEntity with the specified content, MIME type and charset + * + * @param string content to be used. Not {@code null}. + * @param mimeType MIME type to be used. May be {@code null}, in which case the default + * is {@link HTTP#PLAIN_TEXT_TYPE} i.e. "text/plain" + * @param charset character set to be used. May be {@code null}, in which case the default + * is {@link HTTP#DEF_CONTENT_CHARSET} i.e. "ISO-8859-1" + * + * @since 4.1 + * @throws IllegalArgumentException if the string parameter is null + * + * @deprecated (4.1.3) use {@link #StringEntity(String, ContentType)} + */ + @Deprecated + public StringEntity(final String string, String mimeType, String charset) + throws UnsupportedEncodingException { + super(); + if (string == null) { + throw new IllegalArgumentException("Source string may not be null"); + } + if (mimeType == null) { + mimeType = HTTP.PLAIN_TEXT_TYPE; + } + if (charset == null) { + charset = HTTP.DEFAULT_CONTENT_CHARSET; + } + this.content = string.getBytes(charset); + setContentType(mimeType + HTTP.CHARSET_PARAM + charset); + } + + /** + * Creates a StringEntity with the specified content and charset. The MIME type defaults + * to "text/plain". + * + * @param string content to be used. Not {@code null}. + * @param charset character set to be used. May be {@code null}, in which case the default + * is {@link HTTP#DEF_CONTENT_CHARSET} is assumed + * + * @throws IllegalArgumentException if the string parameter is null + * @throws UnsupportedEncodingException if the charset is not supported. + */ + public StringEntity(final String string, final String charset) + throws UnsupportedEncodingException { + this(string, ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset)); + } + + /** + * Creates a StringEntity with the specified content and charset. The MIME type defaults + * to "text/plain". + * + * @param string content to be used. Not {@code null}. + * @param charset character set to be used. May be {@code null}, in which case the default + * is {@link HTTP#DEF_CONTENT_CHARSET} is assumed + * + * @throws IllegalArgumentException if the string parameter is null + * + * @since 4.2 + */ + public StringEntity(final String string, final Charset charset) { + this(string, ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset)); + } + + /** + * Creates a StringEntity with the specified content. The content type defaults to + * {@link ContentType#TEXT_PLAIN}. + * + * @param string content to be used. Not {@code null}. + * + * @throws IllegalArgumentException if the string parameter is null + * @throws UnsupportedEncodingException if the default HTTP charset is not supported. + */ + public StringEntity(final String string) + throws UnsupportedEncodingException { + this(string, ContentType.DEFAULT_TEXT); + } + + public boolean isRepeatable() { + return true; + } + + public long getContentLength() { + return this.content.length; + } + + public InputStream getContent() throws IOException { + return new ByteArrayInputStream(this.content); + } + + public void writeTo(final OutputStream outstream) throws IOException { + if (outstream == null) { + throw new IllegalArgumentException("Output stream may not be null"); + } + outstream.write(this.content); + outstream.flush(); + } + + /** + * Tells that this entity is not streaming. + * + * @return false + */ + public boolean isStreaming() { + return false; + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} // class StringEntity Index: 3rdParty_sources/httpcore/org/apache/http/entity/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/entity/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/entity/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,55 @@ + + + + + +Common HTTP entity implementations. + +An {@link org.apache.http.HttpEntity entity} is the optional content of a +{@link org.apache.http.HttpMessage message}. +This package provides a basic selection of entity implementations +that can obtain content from +{@link org.apache.http.entity.ByteArrayEntity byte array}, +{@link org.apache.http.entity.StringEntity string}, +{@link org.apache.http.entity.FileEntity file}, or through an arbitrary +{@link org.apache.http.entity.InputStreamEntity input stream}. +If a message is received from an open connection, usually it is +represented by +{@link org.apache.http.entity.BasicHttpEntity streamed} entity. +Entity implementations can be +{@link org.apache.http.entity.HttpEntityWrapper wrapped}, +for example to +{@link org.apache.http.entity.BufferedHttpEntity buffer} +the content in memory. + + + + + Index: 3rdParty_sources/httpcore/org/apache/http/impl/AbstractHttpClientConnection.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/AbstractHttpClientConnection.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/AbstractHttpClientConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,331 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import java.io.IOException; +import java.net.SocketTimeoutException; + +import org.apache.http.HttpClientConnection; +import org.apache.http.HttpConnectionMetrics; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseFactory; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.entity.ContentLengthStrategy; +import org.apache.http.impl.entity.EntityDeserializer; +import org.apache.http.impl.entity.EntitySerializer; +import org.apache.http.impl.entity.LaxContentLengthStrategy; +import org.apache.http.impl.entity.StrictContentLengthStrategy; +import org.apache.http.impl.io.DefaultHttpResponseParser; +import org.apache.http.impl.io.HttpRequestWriter; +import org.apache.http.io.EofSensor; +import org.apache.http.io.HttpMessageParser; +import org.apache.http.io.HttpMessageWriter; +import org.apache.http.io.HttpTransportMetrics; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.io.SessionOutputBuffer; +import org.apache.http.message.LineFormatter; +import org.apache.http.message.LineParser; +import org.apache.http.params.HttpParams; + +/** + * Abstract client-side HTTP connection capable of transmitting and receiving + * data using arbitrary {@link SessionInputBuffer} and + * {@link SessionOutputBuffer} implementations. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public abstract class AbstractHttpClientConnection implements HttpClientConnection { + + private final EntitySerializer entityserializer; + private final EntityDeserializer entitydeserializer; + + private SessionInputBuffer inbuffer = null; + private SessionOutputBuffer outbuffer = null; + private EofSensor eofSensor = null; + private HttpMessageParser responseParser = null; + private HttpMessageWriter requestWriter = null; + private HttpConnectionMetricsImpl metrics = null; + + /** + * Creates an instance of this class. + *

    + * This constructor will invoke {@link #createEntityDeserializer()} + * and {@link #createEntitySerializer()} methods in order to initialize + * HTTP entity serializer and deserializer implementations for this + * connection. + */ + public AbstractHttpClientConnection() { + super(); + this.entityserializer = createEntitySerializer(); + this.entitydeserializer = createEntityDeserializer(); + } + + /** + * Asserts if the connection is open. + * + * @throws IllegalStateException if the connection is not open. + */ + protected abstract void assertOpen() throws IllegalStateException; + + /** + * Creates an instance of {@link EntityDeserializer} with the + * {@link LaxContentLengthStrategy} implementation to be used for + * de-serializing entities received over this connection. + *

    + * This method can be overridden in a super class in order to create + * instances of {@link EntityDeserializer} using a custom + * {@link ContentLengthStrategy}. + * + * @return HTTP entity deserializer + */ + protected EntityDeserializer createEntityDeserializer() { + return new EntityDeserializer(new LaxContentLengthStrategy()); + } + + /** + * Creates an instance of {@link EntitySerializer} with the + * {@link StrictContentLengthStrategy} implementation to be used for + * serializing HTTP entities sent over this connection. + *

    + * This method can be overridden in a super class in order to create + * instances of {@link EntitySerializer} using a custom + * {@link ContentLengthStrategy}. + * + * @return HTTP entity serialzier. + */ + protected EntitySerializer createEntitySerializer() { + return new EntitySerializer(new StrictContentLengthStrategy()); + } + + /** + * Creates an instance of {@link DefaultHttpResponseFactory} to be used + * for creating {@link HttpResponse} objects received by over this + * connection. + *

    + * This method can be overridden in a super class in order to provide + * a different implementation of the {@link HttpResponseFactory} interface. + * + * @return HTTP response factory. + */ + protected HttpResponseFactory createHttpResponseFactory() { + return new DefaultHttpResponseFactory(); + } + + /** + * Creates an instance of {@link HttpMessageParser} to be used for parsing + * HTTP responses received over this connection. + *

    + * This method can be overridden in a super class in order to provide + * a different implementation of the {@link HttpMessageParser} interface or + * to pass a different implementation of the {@link LineParser} to the + * the {@link DefaultHttpResponseParser} constructor. + * + * @param buffer the session input buffer. + * @param responseFactory the HTTP response factory. + * @param params HTTP parameters. + * @return HTTP message parser. + */ + protected HttpMessageParser createResponseParser( + final SessionInputBuffer buffer, + final HttpResponseFactory responseFactory, + final HttpParams params) { + return new DefaultHttpResponseParser(buffer, null, responseFactory, params); + } + + /** + * Creates an instance of {@link HttpMessageWriter} to be used for + * writing out HTTP requests sent over this connection. + *

    + * This method can be overridden in a super class in order to provide + * a different implementation of the {@link HttpMessageWriter} interface or + * to pass a different implementation of {@link LineFormatter} to the + * the default implementation {@link HttpRequestWriter}. + * + * @param buffer the session output buffer + * @param params HTTP parameters + * @return HTTP message writer + */ + protected HttpMessageWriter createRequestWriter( + final SessionOutputBuffer buffer, + final HttpParams params) { + return new HttpRequestWriter(buffer, null, params); + } + + /** + * @since 4.1 + */ + protected HttpConnectionMetricsImpl createConnectionMetrics( + final HttpTransportMetrics inTransportMetric, + final HttpTransportMetrics outTransportMetric) { + return new HttpConnectionMetricsImpl(inTransportMetric, outTransportMetric); + } + + /** + * Initializes this connection object with {@link SessionInputBuffer} and + * {@link SessionOutputBuffer} instances to be used for sending and + * receiving data. These session buffers can be bound to any arbitrary + * physical output medium. + *

    + * This method will invoke {@link #createHttpResponseFactory()}, + * {@link #createRequestWriter(SessionOutputBuffer, HttpParams)} + * and {@link #createResponseParser(SessionInputBuffer, HttpResponseFactory, HttpParams)} + * methods to initialize HTTP request writer and response parser for this + * connection. + * + * @param inbuffer the session input buffer. + * @param outbuffer the session output buffer. + * @param params HTTP parameters. + */ + protected void init( + final SessionInputBuffer inbuffer, + final SessionOutputBuffer outbuffer, + final HttpParams params) { + if (inbuffer == null) { + throw new IllegalArgumentException("Input session buffer may not be null"); + } + if (outbuffer == null) { + throw new IllegalArgumentException("Output session buffer may not be null"); + } + this.inbuffer = inbuffer; + this.outbuffer = outbuffer; + if (inbuffer instanceof EofSensor) { + this.eofSensor = (EofSensor) inbuffer; + } + this.responseParser = createResponseParser( + inbuffer, + createHttpResponseFactory(), + params); + this.requestWriter = createRequestWriter( + outbuffer, params); + this.metrics = createConnectionMetrics( + inbuffer.getMetrics(), + outbuffer.getMetrics()); + } + + public boolean isResponseAvailable(int timeout) throws IOException { + assertOpen(); + try { + return this.inbuffer.isDataAvailable(timeout); + } catch (SocketTimeoutException ex) { + return false; + } + } + + public void sendRequestHeader(final HttpRequest request) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + assertOpen(); + this.requestWriter.write(request); + this.metrics.incrementRequestCount(); + } + + public void sendRequestEntity(final HttpEntityEnclosingRequest request) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + assertOpen(); + if (request.getEntity() == null) { + return; + } + this.entityserializer.serialize( + this.outbuffer, + request, + request.getEntity()); + } + + protected void doFlush() throws IOException { + this.outbuffer.flush(); + } + + public void flush() throws IOException { + assertOpen(); + doFlush(); + } + + public HttpResponse receiveResponseHeader() + throws HttpException, IOException { + assertOpen(); + HttpResponse response = this.responseParser.parse(); + if (response.getStatusLine().getStatusCode() >= 200) { + this.metrics.incrementResponseCount(); + } + return response; + } + + public void receiveResponseEntity(final HttpResponse response) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + assertOpen(); + HttpEntity entity = this.entitydeserializer.deserialize(this.inbuffer, response); + response.setEntity(entity); + } + + protected boolean isEof() { + return this.eofSensor != null && this.eofSensor.isEof(); + } + + public boolean isStale() { + if (!isOpen()) { + return true; + } + if (isEof()) { + return true; + } + try { + this.inbuffer.isDataAvailable(1); + return isEof(); + } catch (SocketTimeoutException ex) { + return false; + } catch (IOException ex) { + return true; + } + } + + public HttpConnectionMetrics getMetrics() { + return this.metrics; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/AbstractHttpServerConnection.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/AbstractHttpServerConnection.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/AbstractHttpServerConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,317 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import java.io.IOException; + +import org.apache.http.HttpConnectionMetrics; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestFactory; +import org.apache.http.HttpResponse; +import org.apache.http.HttpServerConnection; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.entity.ContentLengthStrategy; +import org.apache.http.impl.entity.DisallowIdentityContentLengthStrategy; +import org.apache.http.impl.entity.EntityDeserializer; +import org.apache.http.impl.entity.EntitySerializer; +import org.apache.http.impl.entity.LaxContentLengthStrategy; +import org.apache.http.impl.entity.StrictContentLengthStrategy; +import org.apache.http.impl.io.DefaultHttpRequestParser; +import org.apache.http.impl.io.HttpResponseWriter; +import org.apache.http.io.EofSensor; +import org.apache.http.io.HttpMessageParser; +import org.apache.http.io.HttpMessageWriter; +import org.apache.http.io.HttpTransportMetrics; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.io.SessionOutputBuffer; +import org.apache.http.message.LineFormatter; +import org.apache.http.message.LineParser; +import org.apache.http.params.HttpParams; + +/** + * Abstract server-side HTTP connection capable of transmitting and receiving + * data using arbitrary {@link SessionInputBuffer} and + * {@link SessionOutputBuffer} implementations. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public abstract class AbstractHttpServerConnection implements HttpServerConnection { + + private final EntitySerializer entityserializer; + private final EntityDeserializer entitydeserializer; + + private SessionInputBuffer inbuffer = null; + private SessionOutputBuffer outbuffer = null; + private EofSensor eofSensor = null; + private HttpMessageParser requestParser = null; + private HttpMessageWriter responseWriter = null; + private HttpConnectionMetricsImpl metrics = null; + + /** + * Creates an instance of this class. + *

    + * This constructor will invoke {@link #createEntityDeserializer()} + * and {@link #createEntitySerializer()} methods in order to initialize + * HTTP entity serializer and deserializer implementations for this + * connection. + */ + public AbstractHttpServerConnection() { + super(); + this.entityserializer = createEntitySerializer(); + this.entitydeserializer = createEntityDeserializer(); + } + + /** + * Asserts if the connection is open. + * + * @throws IllegalStateException if the connection is not open. + */ + protected abstract void assertOpen() throws IllegalStateException; + + /** + * Creates an instance of {@link EntityDeserializer} with the + * {@link LaxContentLengthStrategy} implementation to be used for + * de-serializing entities received over this connection. + *

    + * This method can be overridden in a super class in order to create + * instances of {@link EntityDeserializer} using a custom + * {@link ContentLengthStrategy}. + * + * @return HTTP entity deserializer + */ + protected EntityDeserializer createEntityDeserializer() { + return new EntityDeserializer(new DisallowIdentityContentLengthStrategy( + new LaxContentLengthStrategy(0))); + } + + /** + * Creates an instance of {@link EntitySerializer} with the + * {@link StrictContentLengthStrategy} implementation to be used for + * serializing HTTP entities sent over this connection. + *

    + * This method can be overridden in a super class in order to create + * instances of {@link EntitySerializer} using a custom + * {@link ContentLengthStrategy}. + * + * @return HTTP entity serialzier. + */ + protected EntitySerializer createEntitySerializer() { + return new EntitySerializer(new StrictContentLengthStrategy()); + } + + /** + * Creates an instance of {@link DefaultHttpRequestFactory} to be used + * for creating {@link HttpRequest} objects received by over this + * connection. + *

    + * This method can be overridden in a super class in order to provide + * a different implementation of the {@link HttpRequestFactory} interface. + * + * @return HTTP request factory. + */ + protected HttpRequestFactory createHttpRequestFactory() { + return new DefaultHttpRequestFactory(); + } + + /** + * Creates an instance of {@link HttpMessageParser} to be used for parsing + * HTTP requests received over this connection. + *

    + * This method can be overridden in a super class in order to provide + * a different implementation of the {@link HttpMessageParser} interface or + * to pass a different implementation of the {@link LineParser} to the + * the {@link DefaultHttpRequestParser} constructor. + * + * @param buffer the session input buffer. + * @param requestFactory the HTTP request factory. + * @param params HTTP parameters. + * @return HTTP message parser. + */ + protected HttpMessageParser createRequestParser( + final SessionInputBuffer buffer, + final HttpRequestFactory requestFactory, + final HttpParams params) { + return new DefaultHttpRequestParser(buffer, null, requestFactory, params); + } + + /** + * Creates an instance of {@link HttpMessageWriter} to be used for + * writing out HTTP responses sent over this connection. + *

    + * This method can be overridden in a super class in order to provide + * a different implementation of the {@link HttpMessageWriter} interface or + * to pass a different implementation of {@link LineFormatter} to the + * the default implementation {@link HttpResponseWriter}. + * + * @param buffer the session output buffer + * @param params HTTP parameters + * @return HTTP message writer + */ + protected HttpMessageWriter createResponseWriter( + final SessionOutputBuffer buffer, + final HttpParams params) { + return new HttpResponseWriter(buffer, null, params); + } + + /** + * @since 4.1 + */ + protected HttpConnectionMetricsImpl createConnectionMetrics( + final HttpTransportMetrics inTransportMetric, + final HttpTransportMetrics outTransportMetric) { + return new HttpConnectionMetricsImpl(inTransportMetric, outTransportMetric); + } + + /** + * Initializes this connection object with {@link SessionInputBuffer} and + * {@link SessionOutputBuffer} instances to be used for sending and + * receiving data. These session buffers can be bound to any arbitrary + * physical output medium. + *

    + * This method will invoke {@link #createHttpRequestFactory}, + * {@link #createRequestParser(SessionInputBuffer, HttpRequestFactory, HttpParams)} + * and {@link #createResponseWriter(SessionOutputBuffer, HttpParams)} + * methods to initialize HTTP request parser and response writer for this + * connection. + * + * @param inbuffer the session input buffer. + * @param outbuffer the session output buffer. + * @param params HTTP parameters. + */ + protected void init( + final SessionInputBuffer inbuffer, + final SessionOutputBuffer outbuffer, + final HttpParams params) { + if (inbuffer == null) { + throw new IllegalArgumentException("Input session buffer may not be null"); + } + if (outbuffer == null) { + throw new IllegalArgumentException("Output session buffer may not be null"); + } + this.inbuffer = inbuffer; + this.outbuffer = outbuffer; + if (inbuffer instanceof EofSensor) { + this.eofSensor = (EofSensor) inbuffer; + } + this.requestParser = createRequestParser( + inbuffer, + createHttpRequestFactory(), + params); + this.responseWriter = createResponseWriter( + outbuffer, params); + this.metrics = createConnectionMetrics( + inbuffer.getMetrics(), + outbuffer.getMetrics()); + } + + public HttpRequest receiveRequestHeader() + throws HttpException, IOException { + assertOpen(); + HttpRequest request = this.requestParser.parse(); + this.metrics.incrementRequestCount(); + return request; + } + + public void receiveRequestEntity(final HttpEntityEnclosingRequest request) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + assertOpen(); + HttpEntity entity = this.entitydeserializer.deserialize(this.inbuffer, request); + request.setEntity(entity); + } + + protected void doFlush() throws IOException { + this.outbuffer.flush(); + } + + public void flush() throws IOException { + assertOpen(); + doFlush(); + } + + public void sendResponseHeader(final HttpResponse response) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + assertOpen(); + this.responseWriter.write(response); + if (response.getStatusLine().getStatusCode() >= 200) { + this.metrics.incrementResponseCount(); + } + } + + public void sendResponseEntity(final HttpResponse response) + throws HttpException, IOException { + if (response.getEntity() == null) { + return; + } + this.entityserializer.serialize( + this.outbuffer, + response, + response.getEntity()); + } + + protected boolean isEof() { + return this.eofSensor != null && this.eofSensor.isEof(); + } + + public boolean isStale() { + if (!isOpen()) { + return true; + } + if (isEof()) { + return true; + } + try { + this.inbuffer.isDataAvailable(1); + return isEof(); + } catch (IOException ex) { + return true; + } + } + + public HttpConnectionMetrics getMetrics() { + return this.metrics; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/DefaultConnectionReuseStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/DefaultConnectionReuseStrategy.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/DefaultConnectionReuseStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,176 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.Header; +import org.apache.http.HeaderIterator; +import org.apache.http.HttpResponse; +import org.apache.http.HttpVersion; +import org.apache.http.ParseException; +import org.apache.http.ProtocolVersion; +import org.apache.http.protocol.HTTP; +import org.apache.http.protocol.HttpContext; +import org.apache.http.TokenIterator; +import org.apache.http.annotation.Immutable; +import org.apache.http.message.BasicTokenIterator; + +/** + * Default implementation of a strategy deciding about connection re-use. + * The default implementation first checks some basics, for example + * whether the connection is still open or whether the end of the + * request entity can be determined without closing the connection. + * If these checks pass, the tokens in the Connection header will + * be examined. In the absence of a Connection header, the + * non-standard but commonly used Proxy-Connection header takes + * it's role. A token close indicates that the connection cannot + * be reused. If there is no such token, a token keep-alive + * indicates that the connection should be re-used. If neither token is found, + * or if there are no Connection headers, the default policy for + * the HTTP version is applied. Since HTTP/1.1, connections are + * re-used by default. Up until HTTP/1.0, connections are not + * re-used by default. + * + * @since 4.0 + */ +@Immutable +public class DefaultConnectionReuseStrategy implements ConnectionReuseStrategy { + + public DefaultConnectionReuseStrategy() { + super(); + } + + // see interface ConnectionReuseStrategy + public boolean keepAlive(final HttpResponse response, + final HttpContext context) { + if (response == null) { + throw new IllegalArgumentException + ("HTTP response may not be null."); + } + if (context == null) { + throw new IllegalArgumentException + ("HTTP context may not be null."); + } + + // Check for a self-terminating entity. If the end of the entity will + // be indicated by closing the connection, there is no keep-alive. + ProtocolVersion ver = response.getStatusLine().getProtocolVersion(); + Header teh = response.getFirstHeader(HTTP.TRANSFER_ENCODING); + if (teh != null) { + if (!HTTP.CHUNK_CODING.equalsIgnoreCase(teh.getValue())) { + return false; + } + } else { + Header[] clhs = response.getHeaders(HTTP.CONTENT_LEN); + // Do not reuse if not properly content-length delimited + if (clhs == null || clhs.length != 1) { + return false; + } + Header clh = clhs[0]; + try { + int contentLen = Integer.parseInt(clh.getValue()); + if (contentLen < 0) { + return false; + } + } catch (NumberFormatException ex) { + return false; + } + } + + // Check for the "Connection" header. If that is absent, check for + // the "Proxy-Connection" header. The latter is an unspecified and + // broken but unfortunately common extension of HTTP. + HeaderIterator hit = response.headerIterator(HTTP.CONN_DIRECTIVE); + if (!hit.hasNext()) + hit = response.headerIterator("Proxy-Connection"); + + // Experimental usage of the "Connection" header in HTTP/1.0 is + // documented in RFC 2068, section 19.7.1. A token "keep-alive" is + // used to indicate that the connection should be persistent. + // Note that the final specification of HTTP/1.1 in RFC 2616 does not + // include this information. Neither is the "Connection" header + // mentioned in RFC 1945, which informally describes HTTP/1.0. + // + // RFC 2616 specifies "close" as the only connection token with a + // specific meaning: it disables persistent connections. + // + // The "Proxy-Connection" header is not formally specified anywhere, + // but is commonly used to carry one token, "close" or "keep-alive". + // The "Connection" header, on the other hand, is defined as a + // sequence of tokens, where each token is a header name, and the + // token "close" has the above-mentioned additional meaning. + // + // To get through this mess, we treat the "Proxy-Connection" header + // in exactly the same way as the "Connection" header, but only if + // the latter is missing. We scan the sequence of tokens for both + // "close" and "keep-alive". As "close" is specified by RFC 2068, + // it takes precedence and indicates a non-persistent connection. + // If there is no "close" but a "keep-alive", we take the hint. + + if (hit.hasNext()) { + try { + TokenIterator ti = createTokenIterator(hit); + boolean keepalive = false; + while (ti.hasNext()) { + final String token = ti.nextToken(); + if (HTTP.CONN_CLOSE.equalsIgnoreCase(token)) { + return false; + } else if (HTTP.CONN_KEEP_ALIVE.equalsIgnoreCase(token)) { + // continue the loop, there may be a "close" afterwards + keepalive = true; + } + } + if (keepalive) + return true; + // neither "close" nor "keep-alive", use default policy + + } catch (ParseException px) { + // invalid connection header means no persistent connection + // we don't have logging in HttpCore, so the exception is lost + return false; + } + } + + // default since HTTP/1.1 is persistent, before it was non-persistent + return !ver.lessEquals(HttpVersion.HTTP_1_0); + } + + + /** + * Creates a token iterator from a header iterator. + * This method can be overridden to replace the implementation of + * the token iterator. + * + * @param hit the header iterator + * + * @return the token iterator + */ + protected TokenIterator createTokenIterator(HeaderIterator hit) { + return new BasicTokenIterator(hit); + } +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpClientConnection.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpClientConnection.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpClientConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,85 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import java.io.IOException; +import java.net.Socket; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +/** + * Default implementation of a client-side HTTP connection. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SO_KEEPALIVE}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public class DefaultHttpClientConnection extends SocketHttpClientConnection { + + public DefaultHttpClientConnection() { + super(); + } + + @Override + public void bind( + final Socket socket, + final HttpParams params) throws IOException { + if (socket == null) { + throw new IllegalArgumentException("Socket may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + assertNotOpen(); + socket.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params)); + socket.setSoTimeout(HttpConnectionParams.getSoTimeout(params)); + socket.setKeepAlive(HttpConnectionParams.getSoKeepalive(params)); + + int linger = HttpConnectionParams.getLinger(params); + if (linger >= 0) { + socket.setSoLinger(linger > 0, linger); + } + super.bind(socket, params); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpRequestFactory.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpRequestFactory.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpRequestFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,108 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestFactory; +import org.apache.http.MethodNotSupportedException; +import org.apache.http.RequestLine; +import org.apache.http.annotation.Immutable; +import org.apache.http.message.BasicHttpEntityEnclosingRequest; +import org.apache.http.message.BasicHttpRequest; + +/** + * Default factory for creating {@link HttpRequest} objects. + * + * @since 4.0 + */ +@Immutable +public class DefaultHttpRequestFactory implements HttpRequestFactory { + + private static final String[] RFC2616_COMMON_METHODS = { + "GET" + }; + + private static final String[] RFC2616_ENTITY_ENC_METHODS = { + "POST", + "PUT" + }; + + private static final String[] RFC2616_SPECIAL_METHODS = { + "HEAD", + "OPTIONS", + "DELETE", + "TRACE", + "CONNECT" + }; + + + public DefaultHttpRequestFactory() { + super(); + } + + private static boolean isOneOf(final String[] methods, final String method) { + for (int i = 0; i < methods.length; i++) { + if (methods[i].equalsIgnoreCase(method)) { + return true; + } + } + return false; + } + + public HttpRequest newHttpRequest(final RequestLine requestline) + throws MethodNotSupportedException { + if (requestline == null) { + throw new IllegalArgumentException("Request line may not be null"); + } + String method = requestline.getMethod(); + if (isOneOf(RFC2616_COMMON_METHODS, method)) { + return new BasicHttpRequest(requestline); + } else if (isOneOf(RFC2616_ENTITY_ENC_METHODS, method)) { + return new BasicHttpEntityEnclosingRequest(requestline); + } else if (isOneOf(RFC2616_SPECIAL_METHODS, method)) { + return new BasicHttpRequest(requestline); + } else { + throw new MethodNotSupportedException(method + " method not supported"); + } + } + + public HttpRequest newHttpRequest(final String method, final String uri) + throws MethodNotSupportedException { + if (isOneOf(RFC2616_COMMON_METHODS, method)) { + return new BasicHttpRequest(method, uri); + } else if (isOneOf(RFC2616_ENTITY_ENC_METHODS, method)) { + return new BasicHttpEntityEnclosingRequest(method, uri); + } else if (isOneOf(RFC2616_SPECIAL_METHODS, method)) { + return new BasicHttpRequest(method, uri); + } else { + throw new MethodNotSupportedException(method + + " method not supported"); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpResponseFactory.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpResponseFactory.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpResponseFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,114 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import java.util.Locale; + +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseFactory; +import org.apache.http.ProtocolVersion; +import org.apache.http.StatusLine; +import org.apache.http.message.BasicHttpResponse; +import org.apache.http.message.BasicStatusLine; +import org.apache.http.protocol.HttpContext; +import org.apache.http.ReasonPhraseCatalog; +import org.apache.http.annotation.Immutable; +import org.apache.http.impl.EnglishReasonPhraseCatalog; + +/** + * Default factory for creating {@link HttpResponse} objects. + * + * @since 4.0 + */ +@Immutable +public class DefaultHttpResponseFactory implements HttpResponseFactory { + + /** The catalog for looking up reason phrases. */ + protected final ReasonPhraseCatalog reasonCatalog; + + + /** + * Creates a new response factory with the given catalog. + * + * @param catalog the catalog of reason phrases + */ + public DefaultHttpResponseFactory(ReasonPhraseCatalog catalog) { + if (catalog == null) { + throw new IllegalArgumentException + ("Reason phrase catalog must not be null."); + } + this.reasonCatalog = catalog; + } + + /** + * Creates a new response factory with the default catalog. + * The default catalog is {@link EnglishReasonPhraseCatalog}. + */ + public DefaultHttpResponseFactory() { + this(EnglishReasonPhraseCatalog.INSTANCE); + } + + + // non-javadoc, see interface HttpResponseFactory + public HttpResponse newHttpResponse(final ProtocolVersion ver, + final int status, + HttpContext context) { + if (ver == null) { + throw new IllegalArgumentException("HTTP version may not be null"); + } + final Locale loc = determineLocale(context); + final String reason = reasonCatalog.getReason(status, loc); + StatusLine statusline = new BasicStatusLine(ver, status, reason); + return new BasicHttpResponse(statusline, reasonCatalog, loc); + } + + + // non-javadoc, see interface HttpResponseFactory + public HttpResponse newHttpResponse(final StatusLine statusline, + HttpContext context) { + if (statusline == null) { + throw new IllegalArgumentException("Status line may not be null"); + } + final Locale loc = determineLocale(context); + return new BasicHttpResponse(statusline, reasonCatalog, loc); + } + + + /** + * Determines the locale of the response. + * The implementation in this class always returns the default locale. + * + * @param context the context from which to determine the locale, or + * null to use the default locale + * + * @return the locale for the response, never null + */ + protected Locale determineLocale(HttpContext context) { + return Locale.getDefault(); + } +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpServerConnection.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpServerConnection.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/DefaultHttpServerConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,83 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import java.io.IOException; +import java.net.Socket; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +/** + * Default implementation of a server-side HTTP connection. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SO_KEEPALIVE}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public class DefaultHttpServerConnection extends SocketHttpServerConnection { + + public DefaultHttpServerConnection() { + super(); + } + + @Override + public void bind(final Socket socket, final HttpParams params) throws IOException { + if (socket == null) { + throw new IllegalArgumentException("Socket may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + assertNotOpen(); + socket.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params)); + socket.setSoTimeout(HttpConnectionParams.getSoTimeout(params)); + socket.setKeepAlive(HttpConnectionParams.getSoKeepalive(params)); + + int linger = HttpConnectionParams.getLinger(params); + if (linger >= 0) { + socket.setSoLinger(linger > 0, linger); + } + super.bind(socket, params); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/EnglishReasonPhraseCatalog.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/EnglishReasonPhraseCatalog.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/EnglishReasonPhraseCatalog.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,226 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import java.util.Locale; + +import org.apache.http.HttpStatus; +import org.apache.http.ReasonPhraseCatalog; +import org.apache.http.annotation.Immutable; + +/** + * English reason phrases for HTTP status codes. + * All status codes defined in RFC1945 (HTTP/1.0), RFC2616 (HTTP/1.1), and + * RFC2518 (WebDAV) are supported. + * + * @since 4.0 + */ +@Immutable +public class EnglishReasonPhraseCatalog implements ReasonPhraseCatalog { + + // static array with english reason phrases defined below + + /** + * The default instance of this catalog. + * This catalog is thread safe, so there typically + * is no need to create other instances. + */ + public final static EnglishReasonPhraseCatalog INSTANCE = + new EnglishReasonPhraseCatalog(); + + + /** + * Restricted default constructor, for derived classes. + * If you need an instance of this class, use {@link #INSTANCE INSTANCE}. + */ + protected EnglishReasonPhraseCatalog() { + // no body + } + + + /** + * Obtains the reason phrase for a status code. + * + * @param status the status code, in the range 100-599 + * @param loc ignored + * + * @return the reason phrase, or null + */ + public String getReason(int status, Locale loc) { + if ((status < 100) || (status >= 600)) { + throw new IllegalArgumentException + ("Unknown category for status code " + status + "."); + } + + final int category = status / 100; + final int subcode = status - 100*category; + + String reason = null; + if (REASON_PHRASES[category].length > subcode) + reason = REASON_PHRASES[category][subcode]; + + return reason; + } + + + /** Reason phrases lookup table. */ + private static final String[][] REASON_PHRASES = new String[][]{ + null, + new String[3], // 1xx + new String[8], // 2xx + new String[8], // 3xx + new String[25], // 4xx + new String[8] // 5xx + }; + + + + /** + * Stores the given reason phrase, by status code. + * Helper method to initialize the static lookup table. + * + * @param status the status code for which to define the phrase + * @param reason the reason phrase for this status code + */ + private static void setReason(int status, String reason) { + final int category = status / 100; + final int subcode = status - 100*category; + REASON_PHRASES[category][subcode] = reason; + } + + + // ----------------------------------------------------- Static Initializer + + /** Set up status code to "reason phrase" map. */ + static { + // HTTP 1.0 Server status codes -- see RFC 1945 + setReason(HttpStatus.SC_OK, + "OK"); + setReason(HttpStatus.SC_CREATED, + "Created"); + setReason(HttpStatus.SC_ACCEPTED, + "Accepted"); + setReason(HttpStatus.SC_NO_CONTENT, + "No Content"); + setReason(HttpStatus.SC_MOVED_PERMANENTLY, + "Moved Permanently"); + setReason(HttpStatus.SC_MOVED_TEMPORARILY, + "Moved Temporarily"); + setReason(HttpStatus.SC_NOT_MODIFIED, + "Not Modified"); + setReason(HttpStatus.SC_BAD_REQUEST, + "Bad Request"); + setReason(HttpStatus.SC_UNAUTHORIZED, + "Unauthorized"); + setReason(HttpStatus.SC_FORBIDDEN, + "Forbidden"); + setReason(HttpStatus.SC_NOT_FOUND, + "Not Found"); + setReason(HttpStatus.SC_INTERNAL_SERVER_ERROR, + "Internal Server Error"); + setReason(HttpStatus.SC_NOT_IMPLEMENTED, + "Not Implemented"); + setReason(HttpStatus.SC_BAD_GATEWAY, + "Bad Gateway"); + setReason(HttpStatus.SC_SERVICE_UNAVAILABLE, + "Service Unavailable"); + + // HTTP 1.1 Server status codes -- see RFC 2048 + setReason(HttpStatus.SC_CONTINUE, + "Continue"); + setReason(HttpStatus.SC_TEMPORARY_REDIRECT, + "Temporary Redirect"); + setReason(HttpStatus.SC_METHOD_NOT_ALLOWED, + "Method Not Allowed"); + setReason(HttpStatus.SC_CONFLICT, + "Conflict"); + setReason(HttpStatus.SC_PRECONDITION_FAILED, + "Precondition Failed"); + setReason(HttpStatus.SC_REQUEST_TOO_LONG, + "Request Too Long"); + setReason(HttpStatus.SC_REQUEST_URI_TOO_LONG, + "Request-URI Too Long"); + setReason(HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE, + "Unsupported Media Type"); + setReason(HttpStatus.SC_MULTIPLE_CHOICES, + "Multiple Choices"); + setReason(HttpStatus.SC_SEE_OTHER, + "See Other"); + setReason(HttpStatus.SC_USE_PROXY, + "Use Proxy"); + setReason(HttpStatus.SC_PAYMENT_REQUIRED, + "Payment Required"); + setReason(HttpStatus.SC_NOT_ACCEPTABLE, + "Not Acceptable"); + setReason(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, + "Proxy Authentication Required"); + setReason(HttpStatus.SC_REQUEST_TIMEOUT, + "Request Timeout"); + + setReason(HttpStatus.SC_SWITCHING_PROTOCOLS, + "Switching Protocols"); + setReason(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION, + "Non Authoritative Information"); + setReason(HttpStatus.SC_RESET_CONTENT, + "Reset Content"); + setReason(HttpStatus.SC_PARTIAL_CONTENT, + "Partial Content"); + setReason(HttpStatus.SC_GATEWAY_TIMEOUT, + "Gateway Timeout"); + setReason(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED, + "Http Version Not Supported"); + setReason(HttpStatus.SC_GONE, + "Gone"); + setReason(HttpStatus.SC_LENGTH_REQUIRED, + "Length Required"); + setReason(HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE, + "Requested Range Not Satisfiable"); + setReason(HttpStatus.SC_EXPECTATION_FAILED, + "Expectation Failed"); + + // WebDAV Server-specific status codes + setReason(HttpStatus.SC_PROCESSING, + "Processing"); + setReason(HttpStatus.SC_MULTI_STATUS, + "Multi-Status"); + setReason(HttpStatus.SC_UNPROCESSABLE_ENTITY, + "Unprocessable Entity"); + setReason(HttpStatus.SC_INSUFFICIENT_SPACE_ON_RESOURCE, + "Insufficient Space On Resource"); + setReason(HttpStatus.SC_METHOD_FAILURE, + "Method Failure"); + setReason(HttpStatus.SC_LOCKED, + "Locked"); + setReason(HttpStatus.SC_INSUFFICIENT_STORAGE, + "Insufficient Storage"); + setReason(HttpStatus.SC_FAILED_DEPENDENCY, + "Failed Dependency"); + } + + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/HttpConnectionMetricsImpl.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/HttpConnectionMetricsImpl.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/HttpConnectionMetricsImpl.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,148 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.http.HttpConnectionMetrics; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.HttpTransportMetrics; + +/** + * Default implementation of the {@link HttpConnectionMetrics} interface. + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpConnectionMetricsImpl implements HttpConnectionMetrics { + + public static final String REQUEST_COUNT = "http.request-count"; + public static final String RESPONSE_COUNT = "http.response-count"; + public static final String SENT_BYTES_COUNT = "http.sent-bytes-count"; + public static final String RECEIVED_BYTES_COUNT = "http.received-bytes-count"; + + private final HttpTransportMetrics inTransportMetric; + private final HttpTransportMetrics outTransportMetric; + private long requestCount = 0; + private long responseCount = 0; + + /** + * The cache map for all metrics values. + */ + private Map metricsCache; + + public HttpConnectionMetricsImpl( + final HttpTransportMetrics inTransportMetric, + final HttpTransportMetrics outTransportMetric) { + super(); + this.inTransportMetric = inTransportMetric; + this.outTransportMetric = outTransportMetric; + } + + /* ------------------ Public interface method -------------------------- */ + + public long getReceivedBytesCount() { + if (this.inTransportMetric != null) { + return this.inTransportMetric.getBytesTransferred(); + } else { + return -1; + } + } + + public long getSentBytesCount() { + if (this.outTransportMetric != null) { + return this.outTransportMetric.getBytesTransferred(); + } else { + return -1; + } + } + + public long getRequestCount() { + return this.requestCount; + } + + public void incrementRequestCount() { + this.requestCount++; + } + + public long getResponseCount() { + return this.responseCount; + } + + public void incrementResponseCount() { + this.responseCount++; + } + + public Object getMetric(final String metricName) { + Object value = null; + if (this.metricsCache != null) { + value = this.metricsCache.get(metricName); + } + if (value == null) { + if (REQUEST_COUNT.equals(metricName)) { + value = new Long(requestCount); + } else if (RESPONSE_COUNT.equals(metricName)) { + value = new Long(responseCount); + } else if (RECEIVED_BYTES_COUNT.equals(metricName)) { + if (this.inTransportMetric != null) { + return new Long(this.inTransportMetric.getBytesTransferred()); + } else { + return null; + } + } else if (SENT_BYTES_COUNT.equals(metricName)) { + if (this.outTransportMetric != null) { + return new Long(this.outTransportMetric.getBytesTransferred()); + } else { + return null; + } + } + } + return value; + } + + public void setMetric(final String metricName, Object obj) { + if (this.metricsCache == null) { + this.metricsCache = new HashMap(); + } + this.metricsCache.put(metricName, obj); + } + + public void reset() { + if (this.outTransportMetric != null) { + this.outTransportMetric.reset(); + } + if (this.inTransportMetric != null) { + this.inTransportMetric.reset(); + } + this.requestCount = 0; + this.responseCount = 0; + this.metricsCache = null; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/NoConnectionReuseStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/NoConnectionReuseStrategy.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/NoConnectionReuseStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,58 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.HttpResponse; +import org.apache.http.annotation.Immutable; +import org.apache.http.protocol.HttpContext; + +/** + * A strategy that never re-uses a connection. + * + * @since 4.0 + */ +@Immutable +public class NoConnectionReuseStrategy implements ConnectionReuseStrategy { + + // default constructor + + + // non-JavaDoc, see interface ConnectionReuseStrategy + public boolean keepAlive(final HttpResponse response, final HttpContext context) { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + return false; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/SocketHttpClientConnection.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/SocketHttpClientConnection.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/SocketHttpClientConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,298 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; + +import org.apache.http.HttpInetConnection; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.impl.io.SocketInputBuffer; +import org.apache.http.impl.io.SocketOutputBuffer; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.io.SessionOutputBuffer; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +/** + * Implementation of a client-side HTTP connection that can be bound to an + * arbitrary {@link Socket} for receiving data from and transmitting data to + * a remote server. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
    • + *
    • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public class SocketHttpClientConnection + extends AbstractHttpClientConnection implements HttpInetConnection { + + private volatile boolean open; + private volatile Socket socket = null; + + public SocketHttpClientConnection() { + super(); + } + + protected void assertNotOpen() { + if (this.open) { + throw new IllegalStateException("Connection is already open"); + } + } + + @Override + protected void assertOpen() { + if (!this.open) { + throw new IllegalStateException("Connection is not open"); + } + } + + /** + * Creates an instance of {@link SocketInputBuffer} to be used for + * receiving data from the given {@link Socket}. + *

    + * This method can be overridden in a super class in order to provide + * a custom implementation of {@link SessionInputBuffer} interface. + * + * @see SocketInputBuffer#SocketInputBuffer(Socket, int, HttpParams) + * + * @param socket the socket. + * @param buffersize the buffer size. + * @param params HTTP parameters. + * @return session input buffer. + * @throws IOException in case of an I/O error. + */ + protected SessionInputBuffer createSessionInputBuffer( + final Socket socket, + int buffersize, + final HttpParams params) throws IOException { + return new SocketInputBuffer(socket, buffersize, params); + } + + /** + * Creates an instance of {@link SessionOutputBuffer} to be used for + * sending data to the given {@link Socket}. + *

    + * This method can be overridden in a super class in order to provide + * a custom implementation of {@link SocketOutputBuffer} interface. + * + * @see SocketOutputBuffer#SocketOutputBuffer(Socket, int, HttpParams) + * + * @param socket the socket. + * @param buffersize the buffer size. + * @param params HTTP parameters. + * @return session output buffer. + * @throws IOException in case of an I/O error. + */ + protected SessionOutputBuffer createSessionOutputBuffer( + final Socket socket, + int buffersize, + final HttpParams params) throws IOException { + return new SocketOutputBuffer(socket, buffersize, params); + } + + /** + * Binds this connection to the given {@link Socket}. This socket will be + * used by the connection to send and receive data. + *

    + * This method will invoke {@link #createSessionInputBuffer(Socket, int, HttpParams)} + * and {@link #createSessionOutputBuffer(Socket, int, HttpParams)} methods + * to create session input / output buffers bound to this socket and then + * will invoke {@link #init(SessionInputBuffer, SessionOutputBuffer, HttpParams)} + * method to pass references to those buffers to the underlying HTTP message + * parser and formatter. + *

    + * After this method's execution the connection status will be reported + * as open and the {@link #isOpen()} will return true. + * + * @param socket the socket. + * @param params HTTP parameters. + * @throws IOException in case of an I/O error. + */ + protected void bind( + final Socket socket, + final HttpParams params) throws IOException { + if (socket == null) { + throw new IllegalArgumentException("Socket may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + this.socket = socket; + + int buffersize = HttpConnectionParams.getSocketBufferSize(params); + + init( + createSessionInputBuffer(socket, buffersize, params), + createSessionOutputBuffer(socket, buffersize, params), + params); + + this.open = true; + } + + public boolean isOpen() { + return this.open; + } + + protected Socket getSocket() { + return this.socket; + } + + public InetAddress getLocalAddress() { + if (this.socket != null) { + return this.socket.getLocalAddress(); + } else { + return null; + } + } + + public int getLocalPort() { + if (this.socket != null) { + return this.socket.getLocalPort(); + } else { + return -1; + } + } + + public InetAddress getRemoteAddress() { + if (this.socket != null) { + return this.socket.getInetAddress(); + } else { + return null; + } + } + + public int getRemotePort() { + if (this.socket != null) { + return this.socket.getPort(); + } else { + return -1; + } + } + + public void setSocketTimeout(int timeout) { + assertOpen(); + if (this.socket != null) { + try { + this.socket.setSoTimeout(timeout); + } catch (SocketException ignore) { + // It is not quite clear from the Sun's documentation if there are any + // other legitimate cases for a socket exception to be thrown when setting + // SO_TIMEOUT besides the socket being already closed + } + } + } + + public int getSocketTimeout() { + if (this.socket != null) { + try { + return this.socket.getSoTimeout(); + } catch (SocketException ignore) { + return -1; + } + } else { + return -1; + } + } + + public void shutdown() throws IOException { + this.open = false; + Socket tmpsocket = this.socket; + if (tmpsocket != null) { + tmpsocket.close(); + } + } + + public void close() throws IOException { + if (!this.open) { + return; + } + this.open = false; + Socket sock = this.socket; + try { + doFlush(); + try { + try { + sock.shutdownOutput(); + } catch (IOException ignore) { + } + try { + sock.shutdownInput(); + } catch (IOException ignore) { + } + } catch (UnsupportedOperationException ignore) { + // if one isn't supported, the other one isn't either + } + } finally { + sock.close(); + } + } + + private static void formatAddress(final StringBuilder buffer, final SocketAddress socketAddress) { + if (socketAddress instanceof InetSocketAddress) { + InetSocketAddress addr = ((InetSocketAddress) socketAddress); + buffer.append(addr.getAddress() != null ? addr.getAddress().getHostAddress() : + addr.getAddress()) + .append(':') + .append(addr.getPort()); + } else { + buffer.append(socketAddress); + } + } + + @Override + public String toString() { + if (this.socket != null) { + StringBuilder buffer = new StringBuilder(); + SocketAddress remoteAddress = this.socket.getRemoteSocketAddress(); + SocketAddress localAddress = this.socket.getLocalSocketAddress(); + if (remoteAddress != null && localAddress != null) { + formatAddress(buffer, localAddress); + buffer.append("<->"); + formatAddress(buffer, remoteAddress); + } + return buffer.toString(); + } else { + return super.toString(); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/SocketHttpServerConnection.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/SocketHttpServerConnection.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/SocketHttpServerConnection.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,296 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; + +import org.apache.http.HttpInetConnection; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.impl.io.SocketInputBuffer; +import org.apache.http.impl.io.SocketOutputBuffer; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.io.SessionOutputBuffer; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; + +/** + * Implementation of a server-side HTTP connection that can be bound to a + * network Socket in order to receive and transmit data. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
    • + *
    • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public class SocketHttpServerConnection extends + AbstractHttpServerConnection implements HttpInetConnection { + + private volatile boolean open; + private volatile Socket socket = null; + + public SocketHttpServerConnection() { + super(); + } + + protected void assertNotOpen() { + if (this.open) { + throw new IllegalStateException("Connection is already open"); + } + } + + @Override + protected void assertOpen() { + if (!this.open) { + throw new IllegalStateException("Connection is not open"); + } + } + + /** + * Creates an instance of {@link SocketInputBuffer} to be used for + * receiving data from the given {@link Socket}. + *

    + * This method can be overridden in a super class in order to provide + * a custom implementation of {@link SessionInputBuffer} interface. + * + * @see SocketInputBuffer#SocketInputBuffer(Socket, int, HttpParams) + * + * @param socket the socket. + * @param buffersize the buffer size. + * @param params HTTP parameters. + * @return session input buffer. + * @throws IOException in case of an I/O error. + */ + protected SessionInputBuffer createSessionInputBuffer( + final Socket socket, + int buffersize, + final HttpParams params) throws IOException { + return new SocketInputBuffer(socket, buffersize, params); + } + + /** + * Creates an instance of {@link SessionOutputBuffer} to be used for + * sending data to the given {@link Socket}. + *

    + * This method can be overridden in a super class in order to provide + * a custom implementation of {@link SocketOutputBuffer} interface. + * + * @see SocketOutputBuffer#SocketOutputBuffer(Socket, int, HttpParams) + * + * @param socket the socket. + * @param buffersize the buffer size. + * @param params HTTP parameters. + * @return session output buffer. + * @throws IOException in case of an I/O error. + */ + protected SessionOutputBuffer createSessionOutputBuffer( + final Socket socket, + int buffersize, + final HttpParams params) throws IOException { + return new SocketOutputBuffer(socket, buffersize, params); + } + + /** + * Binds this connection to the given {@link Socket}. This socket will be + * used by the connection to send and receive data. + *

    + * This method will invoke {@link #createSessionInputBuffer(Socket, int, HttpParams)} + * and {@link #createSessionOutputBuffer(Socket, int, HttpParams)} methods + * to create session input / output buffers bound to this socket and then + * will invoke {@link #init(SessionInputBuffer, SessionOutputBuffer, HttpParams)} + * method to pass references to those buffers to the underlying HTTP message + * parser and formatter. + *

    + * After this method's execution the connection status will be reported + * as open and the {@link #isOpen()} will return true. + * + * @param socket the socket. + * @param params HTTP parameters. + * @throws IOException in case of an I/O error. + */ + protected void bind(final Socket socket, final HttpParams params) throws IOException { + if (socket == null) { + throw new IllegalArgumentException("Socket may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + this.socket = socket; + + int buffersize = HttpConnectionParams.getSocketBufferSize(params); + + init( + createSessionInputBuffer(socket, buffersize, params), + createSessionOutputBuffer(socket, buffersize, params), + params); + + this.open = true; + } + + protected Socket getSocket() { + return this.socket; + } + + public boolean isOpen() { + return this.open; + } + + public InetAddress getLocalAddress() { + if (this.socket != null) { + return this.socket.getLocalAddress(); + } else { + return null; + } + } + + public int getLocalPort() { + if (this.socket != null) { + return this.socket.getLocalPort(); + } else { + return -1; + } + } + + public InetAddress getRemoteAddress() { + if (this.socket != null) { + return this.socket.getInetAddress(); + } else { + return null; + } + } + + public int getRemotePort() { + if (this.socket != null) { + return this.socket.getPort(); + } else { + return -1; + } + } + + public void setSocketTimeout(int timeout) { + assertOpen(); + if (this.socket != null) { + try { + this.socket.setSoTimeout(timeout); + } catch (SocketException ignore) { + // It is not quite clear from the Sun's documentation if there are any + // other legitimate cases for a socket exception to be thrown when setting + // SO_TIMEOUT besides the socket being already closed + } + } + } + + public int getSocketTimeout() { + if (this.socket != null) { + try { + return this.socket.getSoTimeout(); + } catch (SocketException ignore) { + return -1; + } + } else { + return -1; + } + } + + public void shutdown() throws IOException { + this.open = false; + Socket tmpsocket = this.socket; + if (tmpsocket != null) { + tmpsocket.close(); + } + } + + public void close() throws IOException { + if (!this.open) { + return; + } + this.open = false; + this.open = false; + Socket sock = this.socket; + try { + doFlush(); + try { + try { + sock.shutdownOutput(); + } catch (IOException ignore) { + } + try { + sock.shutdownInput(); + } catch (IOException ignore) { + } + } catch (UnsupportedOperationException ignore) { + // if one isn't supported, the other one isn't either + } + } finally { + sock.close(); + } + } + + private static void formatAddress(final StringBuilder buffer, final SocketAddress socketAddress) { + if (socketAddress instanceof InetSocketAddress) { + InetSocketAddress addr = ((InetSocketAddress) socketAddress); + buffer.append(addr.getAddress() != null ? addr.getAddress().getHostAddress() : + addr.getAddress()) + .append(':') + .append(addr.getPort()); + } else { + buffer.append(socketAddress); + } + } + + @Override + public String toString() { + if (this.socket != null) { + StringBuilder buffer = new StringBuilder(); + SocketAddress remoteAddress = this.socket.getRemoteSocketAddress(); + SocketAddress localAddress = this.socket.getLocalSocketAddress(); + if (remoteAddress != null && localAddress != null) { + formatAddress(buffer, localAddress); + buffer.append("<->"); + formatAddress(buffer, remoteAddress); + } + return buffer.toString(); + } else { + return super.toString(); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/entity/DisallowIdentityContentLengthStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,60 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.entity; + +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.ProtocolException; +import org.apache.http.annotation.Immutable; +import org.apache.http.entity.ContentLengthStrategy; + +/** + * Decorator for {@link ContentLengthStrategy} implementations that disallows the use of + * identity transfer encoding. + * + * @since 4.2 + */ +@Immutable +public class DisallowIdentityContentLengthStrategy implements ContentLengthStrategy { + + private final ContentLengthStrategy contentLengthStrategy; + + public DisallowIdentityContentLengthStrategy(final ContentLengthStrategy contentLengthStrategy) { + super(); + this.contentLengthStrategy = contentLengthStrategy; + } + + public long determineLength(final HttpMessage message) throws HttpException { + long result = this.contentLengthStrategy.determineLength(message); + if (result == ContentLengthStrategy.IDENTITY) { + throw new ProtocolException("Identity transfer encoding cannot be used"); + } + return result; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/entity/EntityDeserializer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/entity/EntityDeserializer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/entity/EntityDeserializer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,146 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.entity; + +import java.io.IOException; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.annotation.Immutable; +import org.apache.http.entity.BasicHttpEntity; +import org.apache.http.entity.ContentLengthStrategy; +import org.apache.http.impl.io.ChunkedInputStream; +import org.apache.http.impl.io.ContentLengthInputStream; +import org.apache.http.impl.io.IdentityInputStream; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.protocol.HTTP; + +/** + * HTTP entity deserializer. + *

    + * This entity deserializer supports "chunked" and "identitiy" transfer-coding + * and content length delimited content. + *

    + * This class relies on a specific implementation of + * {@link ContentLengthStrategy} to determine the content length or transfer + * encoding of the entity. + *

    + * This class generates an instance of {@link HttpEntity} based on + * properties of the message. The content of the entity will be decoded + * transparently for the consumer. + * + * @since 4.0 + */ +@Immutable // assuming injected dependencies are immutable +public class EntityDeserializer { + + private final ContentLengthStrategy lenStrategy; + + public EntityDeserializer(final ContentLengthStrategy lenStrategy) { + super(); + if (lenStrategy == null) { + throw new IllegalArgumentException("Content length strategy may not be null"); + } + this.lenStrategy = lenStrategy; + } + + /** + * Creates a {@link BasicHttpEntity} based on properties of the given + * message. The content of the entity is created by wrapping + * {@link SessionInputBuffer} with a content decoder depending on the + * transfer mechanism used by the message. + *

    + * This method is called by the public + * {@link #deserialize(SessionInputBuffer, HttpMessage)}. + * + * @param inbuffer the session input buffer. + * @param message the message. + * @return HTTP entity. + * @throws HttpException in case of HTTP protocol violation. + * @throws IOException in case of an I/O error. + */ + protected BasicHttpEntity doDeserialize( + final SessionInputBuffer inbuffer, + final HttpMessage message) throws HttpException, IOException { + BasicHttpEntity entity = new BasicHttpEntity(); + + long len = this.lenStrategy.determineLength(message); + if (len == ContentLengthStrategy.CHUNKED) { + entity.setChunked(true); + entity.setContentLength(-1); + entity.setContent(new ChunkedInputStream(inbuffer)); + } else if (len == ContentLengthStrategy.IDENTITY) { + entity.setChunked(false); + entity.setContentLength(-1); + entity.setContent(new IdentityInputStream(inbuffer)); + } else { + entity.setChunked(false); + entity.setContentLength(len); + entity.setContent(new ContentLengthInputStream(inbuffer, len)); + } + + Header contentTypeHeader = message.getFirstHeader(HTTP.CONTENT_TYPE); + if (contentTypeHeader != null) { + entity.setContentType(contentTypeHeader); + } + Header contentEncodingHeader = message.getFirstHeader(HTTP.CONTENT_ENCODING); + if (contentEncodingHeader != null) { + entity.setContentEncoding(contentEncodingHeader); + } + return entity; + } + + /** + * Creates an {@link HttpEntity} based on properties of the given message. + * The content of the entity is created by wrapping + * {@link SessionInputBuffer} with a content decoder depending on the + * transfer mechanism used by the message. + *

    + * The content of the entity is NOT retrieved by this method. + * + * @param inbuffer the session input buffer. + * @param message the message. + * @return HTTP entity. + * @throws HttpException in case of HTTP protocol violation. + * @throws IOException in case of an I/O error. + */ + public HttpEntity deserialize( + final SessionInputBuffer inbuffer, + final HttpMessage message) throws HttpException, IOException { + if (inbuffer == null) { + throw new IllegalArgumentException("Session input buffer may not be null"); + } + if (message == null) { + throw new IllegalArgumentException("HTTP message may not be null"); + } + return doDeserialize(inbuffer, message); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/entity/EntitySerializer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/entity/EntitySerializer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/entity/EntitySerializer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,126 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.entity; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.annotation.Immutable; +import org.apache.http.entity.ContentLengthStrategy; +import org.apache.http.impl.io.ChunkedOutputStream; +import org.apache.http.impl.io.ContentLengthOutputStream; +import org.apache.http.impl.io.IdentityOutputStream; +import org.apache.http.io.SessionOutputBuffer; + +/** + * HTTP entity serializer. + *

    + * This entity serializer currently supports "chunked" and "identitiy" + * transfer-coding and content length delimited content. + *

    + * This class relies on a specific implementation of + * {@link ContentLengthStrategy} to determine the content length or transfer + * encoding of the entity. + *

    + * This class writes out the content of {@link HttpEntity} to the data stream + * using a transfer coding based on properties on the HTTP message. + * + * @since 4.0 + */ +@Immutable // assuming injected dependencies are immutable +public class EntitySerializer { + + private final ContentLengthStrategy lenStrategy; + + public EntitySerializer(final ContentLengthStrategy lenStrategy) { + super(); + if (lenStrategy == null) { + throw new IllegalArgumentException("Content length strategy may not be null"); + } + this.lenStrategy = lenStrategy; + } + + /** + * Creates a transfer codec based on properties of the given HTTP message + * and returns {@link OutputStream} instance that transparently encodes + * output data as it is being written out to the output stream. + *

    + * This method is called by the public + * {@link #serialize(SessionOutputBuffer, HttpMessage, HttpEntity)}. + * + * @param outbuffer the session output buffer. + * @param message the HTTP message. + * @return output stream. + * @throws HttpException in case of HTTP protocol violation. + * @throws IOException in case of an I/O error. + */ + protected OutputStream doSerialize( + final SessionOutputBuffer outbuffer, + final HttpMessage message) throws HttpException, IOException { + long len = this.lenStrategy.determineLength(message); + if (len == ContentLengthStrategy.CHUNKED) { + return new ChunkedOutputStream(outbuffer); + } else if (len == ContentLengthStrategy.IDENTITY) { + return new IdentityOutputStream(outbuffer); + } else { + return new ContentLengthOutputStream(outbuffer, len); + } + } + + /** + * Writes out the content of the given HTTP entity to the session output + * buffer based on properties of the given HTTP message. + * + * @param outbuffer the output session buffer. + * @param message the HTTP message. + * @param entity the HTTP entity to be written out. + * @throws HttpException in case of HTTP protocol violation. + * @throws IOException in case of an I/O error. + */ + public void serialize( + final SessionOutputBuffer outbuffer, + final HttpMessage message, + final HttpEntity entity) throws HttpException, IOException { + if (outbuffer == null) { + throw new IllegalArgumentException("Session output buffer may not be null"); + } + if (message == null) { + throw new IllegalArgumentException("HTTP message may not be null"); + } + if (entity == null) { + throw new IllegalArgumentException("HTTP entity may not be null"); + } + OutputStream outstream = doSerialize(outbuffer, message); + entity.writeTo(outstream); + outstream.close(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/entity/LaxContentLengthStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/entity/LaxContentLengthStrategy.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/entity/LaxContentLengthStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,156 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.entity; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.ParseException; +import org.apache.http.ProtocolException; +import org.apache.http.annotation.Immutable; +import org.apache.http.entity.ContentLengthStrategy; +import org.apache.http.params.HttpParams; +import org.apache.http.params.CoreProtocolPNames; +import org.apache.http.protocol.HTTP; + +/** + * The lax implementation of the content length strategy. This class will ignore + * unrecognized transfer encodings and malformed Content-Length + * header values if the {@link CoreProtocolPNames#STRICT_TRANSFER_ENCODING} + * parameter of the given message is not set or set to false. + *

    + * This class recognizes "chunked" and "identitiy" transfer-coding only. + *

    + * The following parameters can be used to customize the behavior of this class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#STRICT_TRANSFER_ENCODING}
    • + *
    + * + * @since 4.0 + */ +@Immutable +public class LaxContentLengthStrategy implements ContentLengthStrategy { + + private final int implicitLen; + + /** + * Creates LaxContentLengthStrategy instance with the given length used per default + * when content length is not explicitly specified in the message. + * + * @param implicitLen implicit content length. + * + * @since 4.2 + */ + public LaxContentLengthStrategy(int implicitLen) { + super(); + this.implicitLen = implicitLen; + } + + /** + * Creates LaxContentLengthStrategy instance. {@link ContentLengthStrategy#IDENTITY} + * is used per default when content length is not explicitly specified in the message. + */ + public LaxContentLengthStrategy() { + this(IDENTITY); + } + + public long determineLength(final HttpMessage message) throws HttpException { + if (message == null) { + throw new IllegalArgumentException("HTTP message may not be null"); + } + + HttpParams params = message.getParams(); + boolean strict = params.isParameterTrue(CoreProtocolPNames.STRICT_TRANSFER_ENCODING); + + Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING); + // We use Transfer-Encoding if present and ignore Content-Length. + // RFC2616, 4.4 item number 3 + if (transferEncodingHeader != null) { + HeaderElement[] encodings = null; + try { + encodings = transferEncodingHeader.getElements(); + } catch (ParseException px) { + throw new ProtocolException + ("Invalid Transfer-Encoding header value: " + + transferEncodingHeader, px); + } + if (strict) { + // Currently only chunk and identity are supported + for (int i = 0; i < encodings.length; i++) { + String encoding = encodings[i].getName(); + if (encoding != null && encoding.length() > 0 + && !encoding.equalsIgnoreCase(HTTP.CHUNK_CODING) + && !encoding.equalsIgnoreCase(HTTP.IDENTITY_CODING)) { + throw new ProtocolException("Unsupported transfer encoding: " + encoding); + } + } + } + // The chunked encoding must be the last one applied RFC2616, 14.41 + int len = encodings.length; + if (HTTP.IDENTITY_CODING.equalsIgnoreCase(transferEncodingHeader.getValue())) { + return IDENTITY; + } else if ((len > 0) && (HTTP.CHUNK_CODING.equalsIgnoreCase( + encodings[len - 1].getName()))) { + return CHUNKED; + } else { + if (strict) { + throw new ProtocolException("Chunk-encoding must be the last one applied"); + } + return IDENTITY; + } + } + Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN); + if (contentLengthHeader != null) { + long contentlen = -1; + Header[] headers = message.getHeaders(HTTP.CONTENT_LEN); + if (strict && headers.length > 1) { + throw new ProtocolException("Multiple content length headers"); + } + for (int i = headers.length - 1; i >= 0; i--) { + Header header = headers[i]; + try { + contentlen = Long.parseLong(header.getValue()); + break; + } catch (NumberFormatException e) { + if (strict) { + throw new ProtocolException("Invalid content length: " + header.getValue()); + } + } + // See if we can have better luck with another header, if present + } + if (contentlen >= 0) { + return contentlen; + } else { + return IDENTITY; + } + } + return this.implicitLen; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/entity/StrictContentLengthStrategy.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/entity/StrictContentLengthStrategy.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/entity/StrictContentLengthStrategy.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,115 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.entity; + +import org.apache.http.Header; +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolException; +import org.apache.http.annotation.Immutable; +import org.apache.http.entity.ContentLengthStrategy; +import org.apache.http.protocol.HTTP; + +/** + * The strict implementation of the content length strategy. This class + * will throw {@link ProtocolException} if it encounters an unsupported + * transfer encoding or a malformed Content-Length header + * value. + *

    + * This class recognizes "chunked" and "identitiy" transfer-coding only. + * + * @since 4.0 + */ +@Immutable +public class StrictContentLengthStrategy implements ContentLengthStrategy { + + private final int implicitLen; + + /** + * Creates StrictContentLengthStrategy instance with the given length used per default + * when content length is not explicitly specified in the message. + * + * @param implicitLen implicit content length. + * + * @since 4.2 + */ + public StrictContentLengthStrategy(int implicitLen) { + super(); + this.implicitLen = implicitLen; + } + + /** + * Creates StrictContentLengthStrategy instance. {@link ContentLengthStrategy#IDENTITY} + * is used per default when content length is not explicitly specified in the message. + */ + public StrictContentLengthStrategy() { + this(IDENTITY); + } + + public long determineLength(final HttpMessage message) throws HttpException { + if (message == null) { + throw new IllegalArgumentException("HTTP message may not be null"); + } + // Although Transfer-Encoding is specified as a list, in practice + // it is either missing or has the single value "chunked". So we + // treat it as a single-valued header here. + Header transferEncodingHeader = message.getFirstHeader(HTTP.TRANSFER_ENCODING); + if (transferEncodingHeader != null) { + String s = transferEncodingHeader.getValue(); + if (HTTP.CHUNK_CODING.equalsIgnoreCase(s)) { + if (message.getProtocolVersion().lessEquals(HttpVersion.HTTP_1_0)) { + throw new ProtocolException( + "Chunked transfer encoding not allowed for " + + message.getProtocolVersion()); + } + return CHUNKED; + } else if (HTTP.IDENTITY_CODING.equalsIgnoreCase(s)) { + return IDENTITY; + } else { + throw new ProtocolException( + "Unsupported transfer encoding: " + s); + } + } + Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN); + if (contentLengthHeader != null) { + String s = contentLengthHeader.getValue(); + try { + long len = Long.parseLong(s); + if (len < 0) { + throw new ProtocolException("Negative content length: " + s); + } + return len; + } catch (NumberFormatException e) { + throw new ProtocolException("Invalid content length: " + s); + } + } + return this.implicitLen; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/entity/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/entity/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/entity/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,38 @@ + + + + + +Default implementations for interfaces in +{@link org.apache.http.entity org.apache.http.entity} and provides utility +classes for serialization and deserialization of HTTP content entities. + + + Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractMessageParser.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractMessageParser.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractMessageParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,278 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.http.Header; +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.ParseException; +import org.apache.http.ProtocolException; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.HttpMessageParser; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.message.LineParser; +import org.apache.http.message.BasicLineParser; +import org.apache.http.params.CoreConnectionPNames; +import org.apache.http.params.HttpParams; +import org.apache.http.util.CharArrayBuffer; + +/** + * Abstract base class for HTTP message parsers that obtain input from + * an instance of {@link SessionInputBuffer}. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public abstract class AbstractMessageParser implements HttpMessageParser { + + private static final int HEAD_LINE = 0; + private static final int HEADERS = 1; + + private final SessionInputBuffer sessionBuffer; + private final int maxHeaderCount; + private final int maxLineLen; + private final List headerLines; + protected final LineParser lineParser; + + private int state; + private T message; + + /** + * Creates an instance of this class. + * + * @param buffer the session input buffer. + * @param parser the line parser. + * @param params HTTP parameters. + */ + public AbstractMessageParser( + final SessionInputBuffer buffer, + final LineParser parser, + final HttpParams params) { + super(); + if (buffer == null) { + throw new IllegalArgumentException("Session input buffer may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + this.sessionBuffer = buffer; + this.maxHeaderCount = params.getIntParameter( + CoreConnectionPNames.MAX_HEADER_COUNT, -1); + this.maxLineLen = params.getIntParameter( + CoreConnectionPNames.MAX_LINE_LENGTH, -1); + this.lineParser = (parser != null) ? parser : BasicLineParser.DEFAULT; + this.headerLines = new ArrayList(); + this.state = HEAD_LINE; + } + + /** + * Parses HTTP headers from the data receiver stream according to the generic + * format as given in Section 3.1 of RFC 822, RFC-2616 Section 4 and 19.3. + * + * @param inbuffer Session input buffer + * @param maxHeaderCount maximum number of headers allowed. If the number + * of headers received from the data stream exceeds maxCount value, an + * IOException will be thrown. Setting this parameter to a negative value + * or zero will disable the check. + * @param maxLineLen maximum number of characters for a header line, + * including the continuation lines. Setting this parameter to a negative + * value or zero will disable the check. + * @return array of HTTP headers + * @param parser line parser to use. Can be null, in which case + * the default implementation of this interface will be used. + * + * @throws IOException in case of an I/O error + * @throws HttpException in case of HTTP protocol violation + */ + public static Header[] parseHeaders( + final SessionInputBuffer inbuffer, + int maxHeaderCount, + int maxLineLen, + LineParser parser) + throws HttpException, IOException { + if (parser == null) { + parser = BasicLineParser.DEFAULT; + } + List headerLines = new ArrayList(); + return parseHeaders(inbuffer, maxHeaderCount, maxLineLen, parser, headerLines); + } + + /** + * Parses HTTP headers from the data receiver stream according to the generic + * format as given in Section 3.1 of RFC 822, RFC-2616 Section 4 and 19.3. + * + * @param inbuffer Session input buffer + * @param maxHeaderCount maximum number of headers allowed. If the number + * of headers received from the data stream exceeds maxCount value, an + * IOException will be thrown. Setting this parameter to a negative value + * or zero will disable the check. + * @param maxLineLen maximum number of characters for a header line, + * including the continuation lines. Setting this parameter to a negative + * value or zero will disable the check. + * @param parser line parser to use. + * @param headerLines List of header lines. This list will be used to store + * intermediate results. This makes it possible to resume parsing of + * headers in case of a {@link java.io.InterruptedIOException}. + * + * @return array of HTTP headers + * + * @throws IOException in case of an I/O error + * @throws HttpException in case of HTTP protocol violation + * + * @since 4.1 + */ + public static Header[] parseHeaders( + final SessionInputBuffer inbuffer, + int maxHeaderCount, + int maxLineLen, + final LineParser parser, + final List headerLines) + throws HttpException, IOException { + + if (inbuffer == null) { + throw new IllegalArgumentException("Session input buffer may not be null"); + } + if (parser == null) { + throw new IllegalArgumentException("Line parser may not be null"); + } + if (headerLines == null) { + throw new IllegalArgumentException("Header line list may not be null"); + } + + CharArrayBuffer current = null; + CharArrayBuffer previous = null; + for (;;) { + if (current == null) { + current = new CharArrayBuffer(64); + } else { + current.clear(); + } + int l = inbuffer.readLine(current); + if (l == -1 || current.length() < 1) { + break; + } + // Parse the header name and value + // Check for folded headers first + // Detect LWS-char see HTTP/1.0 or HTTP/1.1 Section 2.2 + // discussion on folded headers + if ((current.charAt(0) == ' ' || current.charAt(0) == '\t') && previous != null) { + // we have continuation folded header + // so append value + int i = 0; + while (i < current.length()) { + char ch = current.charAt(i); + if (ch != ' ' && ch != '\t') { + break; + } + i++; + } + if (maxLineLen > 0 + && previous.length() + 1 + current.length() - i > maxLineLen) { + throw new IOException("Maximum line length limit exceeded"); + } + previous.append(' '); + previous.append(current, i, current.length() - i); + } else { + headerLines.add(current); + previous = current; + current = null; + } + if (maxHeaderCount > 0 && headerLines.size() >= maxHeaderCount) { + throw new IOException("Maximum header count exceeded"); + } + } + Header[] headers = new Header[headerLines.size()]; + for (int i = 0; i < headerLines.size(); i++) { + CharArrayBuffer buffer = headerLines.get(i); + try { + headers[i] = parser.parseHeader(buffer); + } catch (ParseException ex) { + throw new ProtocolException(ex.getMessage()); + } + } + return headers; + } + + /** + * Subclasses must override this method to generate an instance of + * {@link HttpMessage} based on the initial input from the session buffer. + *

    + * Usually this method is expected to read just the very first line or + * the very first valid from the data stream and based on the input generate + * an appropriate instance of {@link HttpMessage}. + * + * @param sessionBuffer the session input buffer. + * @return HTTP message based on the input from the session buffer. + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation. + * @throws ParseException in case of a parse error. + */ + protected abstract T parseHead(SessionInputBuffer sessionBuffer) + throws IOException, HttpException, ParseException; + + public T parse() throws IOException, HttpException { + int st = this.state; + switch (st) { + case HEAD_LINE: + try { + this.message = parseHead(this.sessionBuffer); + } catch (ParseException px) { + throw new ProtocolException(px.getMessage(), px); + } + this.state = HEADERS; + //$FALL-THROUGH$ + case HEADERS: + Header[] headers = AbstractMessageParser.parseHeaders( + this.sessionBuffer, + this.maxHeaderCount, + this.maxLineLen, + this.lineParser, + this.headerLines); + this.message.setHeaders(headers); + T result = this.message; + this.message = null; + this.headerLines.clear(); + this.state = HEAD_LINE; + return result; + default: + throw new IllegalStateException("Inconsistent parser state"); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractMessageWriter.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractMessageWriter.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractMessageWriter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,100 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; + +import org.apache.http.Header; +import org.apache.http.HeaderIterator; +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.HttpMessageWriter; +import org.apache.http.io.SessionOutputBuffer; +import org.apache.http.message.LineFormatter; +import org.apache.http.message.BasicLineFormatter; +import org.apache.http.params.HttpParams; +import org.apache.http.util.CharArrayBuffer; + +/** + * Abstract base class for HTTP message writers that serialize output to + * an instance of {@link SessionOutputBuffer}. + * + * @since 4.0 + */ +@NotThreadSafe +public abstract class AbstractMessageWriter implements HttpMessageWriter { + + protected final SessionOutputBuffer sessionBuffer; + protected final CharArrayBuffer lineBuf; + protected final LineFormatter lineFormatter; + + /** + * Creates an instance of AbstractMessageWriter. + * + * @param buffer the session output buffer. + * @param formatter the line formatter. + * @param params HTTP parameters. + */ + public AbstractMessageWriter(final SessionOutputBuffer buffer, + final LineFormatter formatter, + final HttpParams params) { + super(); + if (buffer == null) { + throw new IllegalArgumentException("Session input buffer may not be null"); + } + this.sessionBuffer = buffer; + this.lineBuf = new CharArrayBuffer(128); + this.lineFormatter = (formatter != null) ? + formatter : BasicLineFormatter.DEFAULT; + } + + /** + * Subclasses must override this method to write out the first header line + * based on the {@link HttpMessage} passed as a parameter. + * + * @param message the message whose first line is to be written out. + * @throws IOException in case of an I/O error. + */ + protected abstract void writeHeadLine(T message) throws IOException; + + public void write(final T message) throws IOException, HttpException { + if (message == null) { + throw new IllegalArgumentException("HTTP message may not be null"); + } + writeHeadLine(message); + for (HeaderIterator it = message.headerIterator(); it.hasNext(); ) { + Header header = it.nextHeader(); + this.sessionBuffer.writeLine + (lineFormatter.formatHeader(this.lineBuf, header)); + } + this.lineBuf.clear(); + this.sessionBuffer.writeLine(this.lineBuf); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractSessionInputBuffer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractSessionInputBuffer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractSessionInputBuffer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,409 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.BufferInfo; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.io.HttpTransportMetrics; +import org.apache.http.params.CoreConnectionPNames; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.ByteArrayBuffer; +import org.apache.http.util.CharArrayBuffer; + +/** + * Abstract base class for session input buffers that stream data from + * an arbitrary {@link InputStream}. This class buffers input data in + * an internal byte array for optimal input performance. + *

    + * {@link #readLine(CharArrayBuffer)} and {@link #readLine()} methods of this + * class treat a lone LF as valid line delimiters in addition to CR-LF required + * by the HTTP specification. + * + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}
    • + *
    + * @since 4.0 + */ +@NotThreadSafe +public abstract class AbstractSessionInputBuffer implements SessionInputBuffer, BufferInfo { + + private static final Charset ASCII = Charset.forName("US-ASCII"); + + private InputStream instream; + private byte[] buffer; + private int bufferpos; + private int bufferlen; + + private ByteArrayBuffer linebuffer = null; + + private Charset charset; + private CharsetDecoder decoder; + private CharBuffer cbuf; + private boolean ascii = true; + private int maxLineLen = -1; + private int minChunkLimit = 512; + + private HttpTransportMetricsImpl metrics; + + private CodingErrorAction onMalformedInputAction; + private CodingErrorAction onUnMappableInputAction; + + /** + * Initializes this session input buffer. + * + * @param instream the source input stream. + * @param buffersize the size of the internal buffer. + * @param params HTTP parameters. + */ + protected void init(final InputStream instream, int buffersize, final HttpParams params) { + if (instream == null) { + throw new IllegalArgumentException("Input stream may not be null"); + } + if (buffersize <= 0) { + throw new IllegalArgumentException("Buffer size may not be negative or zero"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + this.instream = instream; + this.buffer = new byte[buffersize]; + this.bufferpos = 0; + this.bufferlen = 0; + this.linebuffer = new ByteArrayBuffer(buffersize); + this.charset = Charset.forName(HttpProtocolParams.getHttpElementCharset(params)); + this.ascii = this.charset.equals(ASCII); + this.decoder = null; + this.maxLineLen = params.getIntParameter(CoreConnectionPNames.MAX_LINE_LENGTH, -1); + this.minChunkLimit = params.getIntParameter(CoreConnectionPNames.MIN_CHUNK_LIMIT, 512); + this.metrics = createTransportMetrics(); + this.onMalformedInputAction = HttpProtocolParams.getMalformedInputAction(params); + this.onUnMappableInputAction = HttpProtocolParams.getUnmappableInputAction(params); + } + + /** + * @since 4.1 + */ + protected HttpTransportMetricsImpl createTransportMetrics() { + return new HttpTransportMetricsImpl(); + } + + /** + * @since 4.1 + */ + public int capacity() { + return this.buffer.length; + } + + /** + * @since 4.1 + */ + public int length() { + return this.bufferlen - this.bufferpos; + } + + /** + * @since 4.1 + */ + public int available() { + return capacity() - length(); + } + + protected int fillBuffer() throws IOException { + // compact the buffer if necessary + if (this.bufferpos > 0) { + int len = this.bufferlen - this.bufferpos; + if (len > 0) { + System.arraycopy(this.buffer, this.bufferpos, this.buffer, 0, len); + } + this.bufferpos = 0; + this.bufferlen = len; + } + int l; + int off = this.bufferlen; + int len = this.buffer.length - off; + l = this.instream.read(this.buffer, off, len); + if (l == -1) { + return -1; + } else { + this.bufferlen = off + l; + this.metrics.incrementBytesTransferred(l); + return l; + } + } + + protected boolean hasBufferedData() { + return this.bufferpos < this.bufferlen; + } + + public int read() throws IOException { + int noRead = 0; + while (!hasBufferedData()) { + noRead = fillBuffer(); + if (noRead == -1) { + return -1; + } + } + return this.buffer[this.bufferpos++] & 0xff; + } + + public int read(final byte[] b, int off, int len) throws IOException { + if (b == null) { + return 0; + } + if (hasBufferedData()) { + int chunk = Math.min(len, this.bufferlen - this.bufferpos); + System.arraycopy(this.buffer, this.bufferpos, b, off, chunk); + this.bufferpos += chunk; + return chunk; + } + // If the remaining capacity is big enough, read directly from the + // underlying input stream bypassing the buffer. + if (len > this.minChunkLimit) { + int read = this.instream.read(b, off, len); + if (read > 0) { + this.metrics.incrementBytesTransferred(read); + } + return read; + } else { + // otherwise read to the buffer first + while (!hasBufferedData()) { + int noRead = fillBuffer(); + if (noRead == -1) { + return -1; + } + } + int chunk = Math.min(len, this.bufferlen - this.bufferpos); + System.arraycopy(this.buffer, this.bufferpos, b, off, chunk); + this.bufferpos += chunk; + return chunk; + } + } + + public int read(final byte[] b) throws IOException { + if (b == null) { + return 0; + } + return read(b, 0, b.length); + } + + private int locateLF() { + for (int i = this.bufferpos; i < this.bufferlen; i++) { + if (this.buffer[i] == HTTP.LF) { + return i; + } + } + return -1; + } + + /** + * Reads a complete line of characters up to a line delimiter from this + * session buffer into the given line buffer. The number of chars actually + * read is returned as an integer. The line delimiter itself is discarded. + * If no char is available because the end of the stream has been reached, + * the value -1 is returned. This method blocks until input + * data is available, end of file is detected, or an exception is thrown. + *

    + * This method treats a lone LF as a valid line delimiters in addition + * to CR-LF required by the HTTP specification. + * + * @param charbuffer the line buffer. + * @return one line of characters + * @exception IOException if an I/O error occurs. + */ + public int readLine(final CharArrayBuffer charbuffer) throws IOException { + if (charbuffer == null) { + throw new IllegalArgumentException("Char array buffer may not be null"); + } + int noRead = 0; + boolean retry = true; + while (retry) { + // attempt to find end of line (LF) + int i = locateLF(); + if (i != -1) { + // end of line found. + if (this.linebuffer.isEmpty()) { + // the entire line is preset in the read buffer + return lineFromReadBuffer(charbuffer, i); + } + retry = false; + int len = i + 1 - this.bufferpos; + this.linebuffer.append(this.buffer, this.bufferpos, len); + this.bufferpos = i + 1; + } else { + // end of line not found + if (hasBufferedData()) { + int len = this.bufferlen - this.bufferpos; + this.linebuffer.append(this.buffer, this.bufferpos, len); + this.bufferpos = this.bufferlen; + } + noRead = fillBuffer(); + if (noRead == -1) { + retry = false; + } + } + if (this.maxLineLen > 0 && this.linebuffer.length() >= this.maxLineLen) { + throw new IOException("Maximum line length limit exceeded"); + } + } + if (noRead == -1 && this.linebuffer.isEmpty()) { + // indicate the end of stream + return -1; + } + return lineFromLineBuffer(charbuffer); + } + + /** + * Reads a complete line of characters up to a line delimiter from this + * session buffer. The line delimiter itself is discarded. If no char is + * available because the end of the stream has been reached, + * null is returned. This method blocks until input data is + * available, end of file is detected, or an exception is thrown. + *

    + * This method treats a lone LF as a valid line delimiters in addition + * to CR-LF required by the HTTP specification. + * + * @return HTTP line as a string + * @exception IOException if an I/O error occurs. + */ + private int lineFromLineBuffer(final CharArrayBuffer charbuffer) + throws IOException { + // discard LF if found + int len = this.linebuffer.length(); + if (len > 0) { + if (this.linebuffer.byteAt(len - 1) == HTTP.LF) { + len--; + } + // discard CR if found + if (len > 0) { + if (this.linebuffer.byteAt(len - 1) == HTTP.CR) { + len--; + } + } + } + if (this.ascii) { + charbuffer.append(this.linebuffer, 0, len); + } else { + ByteBuffer bbuf = ByteBuffer.wrap(this.linebuffer.buffer(), 0, len); + len = appendDecoded(charbuffer, bbuf); + } + this.linebuffer.clear(); + return len; + } + + private int lineFromReadBuffer(final CharArrayBuffer charbuffer, int pos) + throws IOException { + int off = this.bufferpos; + int len; + this.bufferpos = pos + 1; + if (pos > off && this.buffer[pos - 1] == HTTP.CR) { + // skip CR if found + pos--; + } + len = pos - off; + if (this.ascii) { + charbuffer.append(this.buffer, off, len); + } else { + ByteBuffer bbuf = ByteBuffer.wrap(this.buffer, off, len); + len = appendDecoded(charbuffer, bbuf); + } + return len; + } + + private int appendDecoded( + final CharArrayBuffer charbuffer, final ByteBuffer bbuf) throws IOException { + if (!bbuf.hasRemaining()) { + return 0; + } + if (this.decoder == null) { + this.decoder = this.charset.newDecoder(); + this.decoder.onMalformedInput(this.onMalformedInputAction); + this.decoder.onUnmappableCharacter(this.onUnMappableInputAction); + } + if (this.cbuf == null) { + this.cbuf = CharBuffer.allocate(1024); + } + this.decoder.reset(); + int len = 0; + while (bbuf.hasRemaining()) { + CoderResult result = this.decoder.decode(bbuf, this.cbuf, true); + len += handleDecodingResult(result, charbuffer, bbuf); + } + CoderResult result = this.decoder.flush(this.cbuf); + len += handleDecodingResult(result, charbuffer, bbuf); + this.cbuf.clear(); + return len; + } + + private int handleDecodingResult( + final CoderResult result, + final CharArrayBuffer charbuffer, + final ByteBuffer bbuf) throws IOException { + if (result.isError()) { + result.throwException(); + } + this.cbuf.flip(); + int len = this.cbuf.remaining(); + while (this.cbuf.hasRemaining()) { + charbuffer.append(this.cbuf.get()); + } + this.cbuf.compact(); + return len; + } + + public String readLine() throws IOException { + CharArrayBuffer charbuffer = new CharArrayBuffer(64); + int l = readLine(charbuffer); + if (l != -1) { + return charbuffer.toString(); + } else { + return null; + } + } + + public HttpTransportMetrics getMetrics() { + return this.metrics; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractSessionOutputBuffer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractSessionOutputBuffer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/AbstractSessionOutputBuffer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,295 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.BufferInfo; +import org.apache.http.io.SessionOutputBuffer; +import org.apache.http.io.HttpTransportMetrics; +import org.apache.http.params.CoreConnectionPNames; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.ByteArrayBuffer; +import org.apache.http.util.CharArrayBuffer; + +/** + * Abstract base class for session output buffers that stream data to + * an arbitrary {@link OutputStream}. This class buffers small chunks of + * output data in an internal byte array for optimal output performance. + *

    + * {@link #writeLine(CharArrayBuffer)} and {@link #writeLine(String)} methods + * of this class use CR-LF as a line delimiter. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}
    • + *
    + *

    + * + * @since 4.0 + */ +@NotThreadSafe +public abstract class AbstractSessionOutputBuffer implements SessionOutputBuffer, BufferInfo { + + private static final Charset ASCII = Charset.forName("US-ASCII"); + private static final byte[] CRLF = new byte[] {HTTP.CR, HTTP.LF}; + + private OutputStream outstream; + private ByteArrayBuffer buffer; + + private Charset charset; + private CharsetEncoder encoder; + private ByteBuffer bbuf; + private boolean ascii = true; + private int minChunkLimit = 512; + + private HttpTransportMetricsImpl metrics; + + private CodingErrorAction onMalformedInputAction; + private CodingErrorAction onUnMappableInputAction; + + /** + * Initializes this session output buffer. + * + * @param outstream the destination output stream. + * @param buffersize the size of the internal buffer. + * @param params HTTP parameters. + */ + protected void init(final OutputStream outstream, int buffersize, final HttpParams params) { + if (outstream == null) { + throw new IllegalArgumentException("Input stream may not be null"); + } + if (buffersize <= 0) { + throw new IllegalArgumentException("Buffer size may not be negative or zero"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + this.outstream = outstream; + this.buffer = new ByteArrayBuffer(buffersize); + this.charset = Charset.forName(HttpProtocolParams.getHttpElementCharset(params)); + this.ascii = this.charset.equals(ASCII); + this.encoder = null; + this.minChunkLimit = params.getIntParameter(CoreConnectionPNames.MIN_CHUNK_LIMIT, 512); + this.metrics = createTransportMetrics(); + this.onMalformedInputAction = HttpProtocolParams.getMalformedInputAction(params); + this.onUnMappableInputAction = HttpProtocolParams.getUnmappableInputAction(params); + } + + /** + * @since 4.1 + */ + protected HttpTransportMetricsImpl createTransportMetrics() { + return new HttpTransportMetricsImpl(); + } + + /** + * @since 4.1 + */ + public int capacity() { + return this.buffer.capacity(); + } + + /** + * @since 4.1 + */ + public int length() { + return this.buffer.length(); + } + + /** + * @since 4.1 + */ + public int available() { + return capacity() - length(); + } + + protected void flushBuffer() throws IOException { + int len = this.buffer.length(); + if (len > 0) { + this.outstream.write(this.buffer.buffer(), 0, len); + this.buffer.clear(); + this.metrics.incrementBytesTransferred(len); + } + } + + public void flush() throws IOException { + flushBuffer(); + this.outstream.flush(); + } + + public void write(final byte[] b, int off, int len) throws IOException { + if (b == null) { + return; + } + // Do not want to buffer large-ish chunks + // if the byte array is larger then MIN_CHUNK_LIMIT + // write it directly to the output stream + if (len > this.minChunkLimit || len > this.buffer.capacity()) { + // flush the buffer + flushBuffer(); + // write directly to the out stream + this.outstream.write(b, off, len); + this.metrics.incrementBytesTransferred(len); + } else { + // Do not let the buffer grow unnecessarily + int freecapacity = this.buffer.capacity() - this.buffer.length(); + if (len > freecapacity) { + // flush the buffer + flushBuffer(); + } + // buffer + this.buffer.append(b, off, len); + } + } + + public void write(final byte[] b) throws IOException { + if (b == null) { + return; + } + write(b, 0, b.length); + } + + public void write(int b) throws IOException { + if (this.buffer.isFull()) { + flushBuffer(); + } + this.buffer.append(b); + } + + /** + * Writes characters from the specified string followed by a line delimiter + * to this session buffer. + *

    + * This method uses CR-LF as a line delimiter. + * + * @param s the line. + * @exception IOException if an I/O error occurs. + */ + public void writeLine(final String s) throws IOException { + if (s == null) { + return; + } + if (s.length() > 0) { + if (this.ascii) { + for (int i = 0; i < s.length(); i++) { + write(s.charAt(i)); + } + } else { + CharBuffer cbuf = CharBuffer.wrap(s); + writeEncoded(cbuf); + } + } + write(CRLF); + } + + /** + * Writes characters from the specified char array followed by a line + * delimiter to this session buffer. + *

    + * This method uses CR-LF as a line delimiter. + * + * @param charbuffer the buffer containing chars of the line. + * @exception IOException if an I/O error occurs. + */ + public void writeLine(final CharArrayBuffer charbuffer) throws IOException { + if (charbuffer == null) { + return; + } + if (this.ascii) { + int off = 0; + int remaining = charbuffer.length(); + while (remaining > 0) { + int chunk = this.buffer.capacity() - this.buffer.length(); + chunk = Math.min(chunk, remaining); + if (chunk > 0) { + this.buffer.append(charbuffer, off, chunk); + } + if (this.buffer.isFull()) { + flushBuffer(); + } + off += chunk; + remaining -= chunk; + } + } else { + CharBuffer cbuf = CharBuffer.wrap(charbuffer.buffer(), 0, charbuffer.length()); + writeEncoded(cbuf); + } + write(CRLF); + } + + private void writeEncoded(final CharBuffer cbuf) throws IOException { + if (!cbuf.hasRemaining()) { + return; + } + if (this.encoder == null) { + this.encoder = this.charset.newEncoder(); + this.encoder.onMalformedInput(this.onMalformedInputAction); + this.encoder.onUnmappableCharacter(this.onUnMappableInputAction); + } + if (this.bbuf == null) { + this.bbuf = ByteBuffer.allocate(1024); + } + this.encoder.reset(); + while (cbuf.hasRemaining()) { + CoderResult result = this.encoder.encode(cbuf, this.bbuf, true); + handleEncodingResult(result); + } + CoderResult result = this.encoder.flush(this.bbuf); + handleEncodingResult(result); + this.bbuf.clear(); + } + + private void handleEncodingResult(final CoderResult result) throws IOException { + if (result.isError()) { + result.throwException(); + } + this.bbuf.flip(); + while (this.bbuf.hasRemaining()) { + write(this.bbuf.get()); + } + this.bbuf.compact(); + } + + public HttpTransportMetrics getMetrics() { + return this.metrics; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/ChunkedInputStream.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/ChunkedInputStream.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/ChunkedInputStream.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,312 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.http.Header; +import org.apache.http.HttpException; +import org.apache.http.MalformedChunkCodingException; +import org.apache.http.TruncatedChunkException; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.BufferInfo; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.util.CharArrayBuffer; + +/** + * Implements chunked transfer coding. The content is received in small chunks. + * Entities transferred using this input stream can be of unlimited length. + * After the stream is read to the end, it provides access to the trailers, + * if any. + *

    + * Note that this class NEVER closes the underlying stream, even when close + * gets called. Instead, it will read until the "end" of its chunking on + * close, which allows for the seamless execution of subsequent HTTP 1.1 + * requests, while not requiring the client to remember to read the entire + * contents of the response. + * + * + * @since 4.0 + * + */ +@NotThreadSafe +public class ChunkedInputStream extends InputStream { + + private static final int CHUNK_LEN = 1; + private static final int CHUNK_DATA = 2; + private static final int CHUNK_CRLF = 3; + + private static final int BUFFER_SIZE = 2048; + + /** The session input buffer */ + private final SessionInputBuffer in; + + private final CharArrayBuffer buffer; + + private int state; + + /** The chunk size */ + private int chunkSize; + + /** The current position within the current chunk */ + private int pos; + + /** True if we've reached the end of stream */ + private boolean eof = false; + + /** True if this stream is closed */ + private boolean closed = false; + + private Header[] footers = new Header[] {}; + + /** + * Wraps session input stream and reads chunk coded input. + * + * @param in The session input buffer + */ + public ChunkedInputStream(final SessionInputBuffer in) { + super(); + if (in == null) { + throw new IllegalArgumentException("Session input buffer may not be null"); + } + this.in = in; + this.pos = 0; + this.buffer = new CharArrayBuffer(16); + this.state = CHUNK_LEN; + } + + @Override + public int available() throws IOException { + if (this.in instanceof BufferInfo) { + int len = ((BufferInfo) this.in).length(); + return Math.min(len, this.chunkSize - this.pos); + } else { + return 0; + } + } + + /** + *

    Returns all the data in a chunked stream in coalesced form. A chunk + * is followed by a CRLF. The method returns -1 as soon as a chunksize of 0 + * is detected.

    + * + *

    Trailer headers are read automatically at the end of the stream and + * can be obtained with the getResponseFooters() method.

    + * + * @return -1 of the end of the stream has been reached or the next data + * byte + * @throws IOException in case of an I/O error + */ + @Override + public int read() throws IOException { + if (this.closed) { + throw new IOException("Attempted read from closed stream."); + } + if (this.eof) { + return -1; + } + if (state != CHUNK_DATA) { + nextChunk(); + if (this.eof) { + return -1; + } + } + int b = in.read(); + if (b != -1) { + pos++; + if (pos >= chunkSize) { + state = CHUNK_CRLF; + } + } + return b; + } + + /** + * Read some bytes from the stream. + * @param b The byte array that will hold the contents from the stream. + * @param off The offset into the byte array at which bytes will start to be + * placed. + * @param len the maximum number of bytes that can be returned. + * @return The number of bytes returned or -1 if the end of stream has been + * reached. + * @throws IOException in case of an I/O error + */ + @Override + public int read (byte[] b, int off, int len) throws IOException { + + if (closed) { + throw new IOException("Attempted read from closed stream."); + } + + if (eof) { + return -1; + } + if (state != CHUNK_DATA) { + nextChunk(); + if (eof) { + return -1; + } + } + len = Math.min(len, chunkSize - pos); + int bytesRead = in.read(b, off, len); + if (bytesRead != -1) { + pos += bytesRead; + if (pos >= chunkSize) { + state = CHUNK_CRLF; + } + return bytesRead; + } else { + eof = true; + throw new TruncatedChunkException("Truncated chunk " + + "( expected size: " + chunkSize + + "; actual size: " + pos + ")"); + } + } + + /** + * Read some bytes from the stream. + * @param b The byte array that will hold the contents from the stream. + * @return The number of bytes returned or -1 if the end of stream has been + * reached. + * @throws IOException in case of an I/O error + */ + @Override + public int read (byte[] b) throws IOException { + return read(b, 0, b.length); + } + + /** + * Read the next chunk. + * @throws IOException in case of an I/O error + */ + private void nextChunk() throws IOException { + chunkSize = getChunkSize(); + if (chunkSize < 0) { + throw new MalformedChunkCodingException("Negative chunk size"); + } + state = CHUNK_DATA; + pos = 0; + if (chunkSize == 0) { + eof = true; + parseTrailerHeaders(); + } + } + + /** + * Expects the stream to start with a chunksize in hex with optional + * comments after a semicolon. The line must end with a CRLF: "a3; some + * comment\r\n" Positions the stream at the start of the next line. + * + * @param in The new input stream. + * @param required true if a valid chunk must be present, + * false otherwise. + * + * @return the chunk size as integer + * + * @throws IOException when the chunk size could not be parsed + */ + private int getChunkSize() throws IOException { + int st = this.state; + switch (st) { + case CHUNK_CRLF: + this.buffer.clear(); + int i = this.in.readLine(this.buffer); + if (i == -1) { + return 0; + } + if (!this.buffer.isEmpty()) { + throw new MalformedChunkCodingException( + "Unexpected content at the end of chunk"); + } + state = CHUNK_LEN; + //$FALL-THROUGH$ + case CHUNK_LEN: + this.buffer.clear(); + i = this.in.readLine(this.buffer); + if (i == -1) { + return 0; + } + int separator = this.buffer.indexOf(';'); + if (separator < 0) { + separator = this.buffer.length(); + } + try { + return Integer.parseInt(this.buffer.substringTrimmed(0, separator), 16); + } catch (NumberFormatException e) { + throw new MalformedChunkCodingException("Bad chunk header"); + } + default: + throw new IllegalStateException("Inconsistent codec state"); + } + } + + /** + * Reads and stores the Trailer headers. + * @throws IOException in case of an I/O error + */ + private void parseTrailerHeaders() throws IOException { + try { + this.footers = AbstractMessageParser.parseHeaders + (in, -1, -1, null); + } catch (HttpException ex) { + IOException ioe = new MalformedChunkCodingException("Invalid footer: " + + ex.getMessage()); + ioe.initCause(ex); + throw ioe; + } + } + + /** + * Upon close, this reads the remainder of the chunked message, + * leaving the underlying socket at a position to start reading the + * next response without scanning. + * @throws IOException in case of an I/O error + */ + @Override + public void close() throws IOException { + if (!closed) { + try { + if (!eof) { + // read and discard the remainder of the message + byte buffer[] = new byte[BUFFER_SIZE]; + while (read(buffer) >= 0) { + } + } + } finally { + eof = true; + closed = true; + } + } + } + + public Header[] getFooters() { + return this.footers.clone(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/ChunkedOutputStream.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/ChunkedOutputStream.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/ChunkedOutputStream.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,192 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.SessionOutputBuffer; + +/** + * Implements chunked transfer coding. The content is sent in small chunks. + * Entities transferred using this output stream can be of unlimited length. + * Writes are buffered to an internal buffer (2048 default size). + *

    + * Note that this class NEVER closes the underlying stream, even when close + * gets called. Instead, the stream will be marked as closed and no further + * output will be permitted. + * + * + * @since 4.0 + */ +@NotThreadSafe +public class ChunkedOutputStream extends OutputStream { + + // ----------------------------------------------------- Instance Variables + private final SessionOutputBuffer out; + + private byte[] cache; + + private int cachePosition = 0; + + private boolean wroteLastChunk = false; + + /** True if the stream is closed. */ + private boolean closed = false; + + // ----------------------------------------------------------- Constructors + /** + * Wraps a session output buffer and chunk-encodes the output. + * + * @param out The session output buffer + * @param bufferSize The minimum chunk size (excluding last chunk) + * @throws IOException in case of an I/O error + */ + public ChunkedOutputStream(final SessionOutputBuffer out, int bufferSize) + throws IOException { + super(); + this.cache = new byte[bufferSize]; + this.out = out; + } + + /** + * Wraps a session output buffer and chunks the output. The default buffer + * size of 2048 was chosen because the chunk overhead is less than 0.5% + * + * @param out the output buffer to wrap + * @throws IOException in case of an I/O error + */ + public ChunkedOutputStream(final SessionOutputBuffer out) + throws IOException { + this(out, 2048); + } + + // ----------------------------------------------------------- Internal methods + /** + * Writes the cache out onto the underlying stream + */ + protected void flushCache() throws IOException { + if (this.cachePosition > 0) { + this.out.writeLine(Integer.toHexString(this.cachePosition)); + this.out.write(this.cache, 0, this.cachePosition); + this.out.writeLine(""); + this.cachePosition = 0; + } + } + + /** + * Writes the cache and bufferToAppend to the underlying stream + * as one large chunk + */ + protected void flushCacheWithAppend(byte bufferToAppend[], int off, int len) throws IOException { + this.out.writeLine(Integer.toHexString(this.cachePosition + len)); + this.out.write(this.cache, 0, this.cachePosition); + this.out.write(bufferToAppend, off, len); + this.out.writeLine(""); + this.cachePosition = 0; + } + + protected void writeClosingChunk() throws IOException { + // Write the final chunk. + this.out.writeLine("0"); + this.out.writeLine(""); + } + + // ----------------------------------------------------------- Public Methods + /** + * Must be called to ensure the internal cache is flushed and the closing + * chunk is written. + * @throws IOException in case of an I/O error + */ + public void finish() throws IOException { + if (!this.wroteLastChunk) { + flushCache(); + writeClosingChunk(); + this.wroteLastChunk = true; + } + } + + // -------------------------------------------- OutputStream Methods + @Override + public void write(int b) throws IOException { + if (this.closed) { + throw new IOException("Attempted write to closed stream."); + } + this.cache[this.cachePosition] = (byte) b; + this.cachePosition++; + if (this.cachePosition == this.cache.length) flushCache(); + } + + /** + * Writes the array. If the array does not fit within the buffer, it is + * not split, but rather written out as one large chunk. + */ + @Override + public void write(byte b[]) throws IOException { + write(b, 0, b.length); + } + + /** + * Writes the array. If the array does not fit within the buffer, it is + * not split, but rather written out as one large chunk. + */ + @Override + public void write(byte src[], int off, int len) throws IOException { + if (this.closed) { + throw new IOException("Attempted write to closed stream."); + } + if (len >= this.cache.length - this.cachePosition) { + flushCacheWithAppend(src, off, len); + } else { + System.arraycopy(src, off, cache, this.cachePosition, len); + this.cachePosition += len; + } + } + + /** + * Flushes the content buffer and the underlying stream. + */ + @Override + public void flush() throws IOException { + flushCache(); + this.out.flush(); + } + + /** + * Finishes writing to the underlying stream, but does NOT close the underlying stream. + */ + @Override + public void close() throws IOException { + if (!this.closed) { + this.closed = true; + finish(); + this.out.flush(); + } + } +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/ContentLengthInputStream.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/ContentLengthInputStream.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/ContentLengthInputStream.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,236 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.http.ConnectionClosedException; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.BufferInfo; +import org.apache.http.io.SessionInputBuffer; + +/** + * Input stream that cuts off after a defined number of bytes. This class + * is used to receive content of HTTP messages where the end of the content + * entity is determined by the value of the Content-Length header. + * Entities transferred using this stream can be maximum {@link Long#MAX_VALUE} + * long. + *

    + * Note that this class NEVER closes the underlying stream, even when close + * gets called. Instead, it will read until the "end" of its limit on + * close, which allows for the seamless execution of subsequent HTTP 1.1 + * requests, while not requiring the client to remember to read the entire + * contents of the response. + * + * + * @since 4.0 + */ +@NotThreadSafe +public class ContentLengthInputStream extends InputStream { + + private static final int BUFFER_SIZE = 2048; + /** + * The maximum number of bytes that can be read from the stream. Subsequent + * read operations will return -1. + */ + private long contentLength; + + /** The current position */ + private long pos = 0; + + /** True if the stream is closed. */ + private boolean closed = false; + + /** + * Wrapped input stream that all calls are delegated to. + */ + private SessionInputBuffer in = null; + + /** + * Wraps a session input buffer and cuts off output after a defined number + * of bytes. + * + * @param in The session input buffer + * @param contentLength The maximum number of bytes that can be read from + * the stream. Subsequent read operations will return -1. + */ + public ContentLengthInputStream(final SessionInputBuffer in, long contentLength) { + super(); + if (in == null) { + throw new IllegalArgumentException("Input stream may not be null"); + } + if (contentLength < 0) { + throw new IllegalArgumentException("Content length may not be negative"); + } + this.in = in; + this.contentLength = contentLength; + } + + /** + *

    Reads until the end of the known length of content.

    + * + *

    Does not close the underlying socket input, but instead leaves it + * primed to parse the next response.

    + * @throws IOException If an IO problem occurs. + */ + @Override + public void close() throws IOException { + if (!closed) { + try { + if (pos < contentLength) { + byte buffer[] = new byte[BUFFER_SIZE]; + while (read(buffer) >= 0) { + } + } + } finally { + // close after above so that we don't throw an exception trying + // to read after closed! + closed = true; + } + } + } + + @Override + public int available() throws IOException { + if (this.in instanceof BufferInfo) { + int len = ((BufferInfo) this.in).length(); + return Math.min(len, (int) (this.contentLength - this.pos)); + } else { + return 0; + } + } + + /** + * Read the next byte from the stream + * @return The next byte or -1 if the end of stream has been reached. + * @throws IOException If an IO problem occurs + * @see java.io.InputStream#read() + */ + @Override + public int read() throws IOException { + if (closed) { + throw new IOException("Attempted read from closed stream."); + } + + if (pos >= contentLength) { + return -1; + } + int b = this.in.read(); + if (b == -1) { + if (pos < contentLength) { + throw new ConnectionClosedException( + "Premature end of Content-Length delimited message body (expected: " + + contentLength + "; received: " + pos); + } + } else { + pos++; + } + return b; + } + + /** + * Does standard {@link InputStream#read(byte[], int, int)} behavior, but + * also notifies the watcher when the contents have been consumed. + * + * @param b The byte array to fill. + * @param off Start filling at this position. + * @param len The number of bytes to attempt to read. + * @return The number of bytes read, or -1 if the end of content has been + * reached. + * + * @throws java.io.IOException Should an error occur on the wrapped stream. + */ + @Override + public int read (byte[] b, int off, int len) throws java.io.IOException { + if (closed) { + throw new IOException("Attempted read from closed stream."); + } + + if (pos >= contentLength) { + return -1; + } + + if (pos + len > contentLength) { + len = (int) (contentLength - pos); + } + int count = this.in.read(b, off, len); + if (count == -1 && pos < contentLength) { + throw new ConnectionClosedException( + "Premature end of Content-Length delimited message body (expected: " + + contentLength + "; received: " + pos); + } + if (count > 0) { + pos += count; + } + return count; + } + + + /** + * Read more bytes from the stream. + * @param b The byte array to put the new data in. + * @return The number of bytes read into the buffer. + * @throws IOException If an IO problem occurs + * @see java.io.InputStream#read(byte[]) + */ + @Override + public int read(byte[] b) throws IOException { + return read(b, 0, b.length); + } + + /** + * Skips and discards a number of bytes from the input stream. + * @param n The number of bytes to skip. + * @return The actual number of bytes skipped. <= 0 if no bytes + * are skipped. + * @throws IOException If an error occurs while skipping bytes. + * @see InputStream#skip(long) + */ + @Override + public long skip(long n) throws IOException { + if (n <= 0) { + return 0; + } + byte[] buffer = new byte[BUFFER_SIZE]; + // make sure we don't skip more bytes than are + // still available + long remaining = Math.min(n, this.contentLength - this.pos); + // skip and keep track of the bytes actually skipped + long count = 0; + while (remaining > 0) { + int l = read(buffer, 0, (int)Math.min(BUFFER_SIZE, remaining)); + if (l == -1) { + break; + } + count += l; + remaining -= l; + } + return count; + } +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/ContentLengthOutputStream.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/ContentLengthOutputStream.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/ContentLengthOutputStream.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,140 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.SessionOutputBuffer; + +/** + * Output stream that cuts off after a defined number of bytes. This class + * is used to send content of HTTP messages where the end of the content entity + * is determined by the value of the Content-Length header. + * Entities transferred using this stream can be maximum {@link Long#MAX_VALUE} + * long. + *

    + * Note that this class NEVER closes the underlying stream, even when close + * gets called. Instead, the stream will be marked as closed and no further + * output will be permitted. + * + * @since 4.0 + */ +@NotThreadSafe +public class ContentLengthOutputStream extends OutputStream { + + /** + * Wrapped session output buffer. + */ + private final SessionOutputBuffer out; + + /** + * The maximum number of bytes that can be written the stream. Subsequent + * write operations will be ignored. + */ + private final long contentLength; + + /** Total bytes written */ + private long total = 0; + + /** True if the stream is closed. */ + private boolean closed = false; + + /** + * Wraps a session output buffer and cuts off output after a defined number + * of bytes. + * + * @param out The session output buffer + * @param contentLength The maximum number of bytes that can be written to + * the stream. Subsequent write operations will be ignored. + * + * @since 4.0 + */ + public ContentLengthOutputStream(final SessionOutputBuffer out, long contentLength) { + super(); + if (out == null) { + throw new IllegalArgumentException("Session output buffer may not be null"); + } + if (contentLength < 0) { + throw new IllegalArgumentException("Content length may not be negative"); + } + this.out = out; + this.contentLength = contentLength; + } + + /** + *

    Does not close the underlying socket output.

    + * + * @throws IOException If an I/O problem occurs. + */ + @Override + public void close() throws IOException { + if (!this.closed) { + this.closed = true; + this.out.flush(); + } + } + + @Override + public void flush() throws IOException { + this.out.flush(); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + if (this.closed) { + throw new IOException("Attempted write to closed stream."); + } + if (this.total < this.contentLength) { + long max = this.contentLength - this.total; + if (len > max) { + len = (int) max; + } + this.out.write(b, off, len); + this.total += len; + } + } + + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + } + + @Override + public void write(int b) throws IOException { + if (this.closed) { + throw new IOException("Attempted write to closed stream."); + } + if (this.total < this.contentLength) { + this.out.write(b); + this.total++; + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/DefaultHttpRequestParser.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/DefaultHttpRequestParser.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/DefaultHttpRequestParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,101 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; + +import org.apache.http.ConnectionClosedException; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestFactory; +import org.apache.http.RequestLine; +import org.apache.http.ParseException; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.message.LineParser; +import org.apache.http.message.ParserCursor; +import org.apache.http.params.HttpParams; +import org.apache.http.util.CharArrayBuffer; + +/** + * HTTP request parser that obtain its input from an instance + * of {@link SessionInputBuffer}. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    + * + * @since 4.2 + */ +@NotThreadSafe +public class DefaultHttpRequestParser extends AbstractMessageParser { + + private final HttpRequestFactory requestFactory; + private final CharArrayBuffer lineBuf; + + /** + * Creates an instance of this class. + * + * @param buffer the session input buffer. + * @param parser the line parser. + * @param requestFactory the factory to use to create + * {@link HttpRequest}s. + * @param params HTTP parameters. + */ + public DefaultHttpRequestParser( + final SessionInputBuffer buffer, + final LineParser parser, + final HttpRequestFactory requestFactory, + final HttpParams params) { + super(buffer, parser, params); + if (requestFactory == null) { + throw new IllegalArgumentException("Request factory may not be null"); + } + this.requestFactory = requestFactory; + this.lineBuf = new CharArrayBuffer(128); + } + + @Override + protected HttpRequest parseHead( + final SessionInputBuffer sessionBuffer) + throws IOException, HttpException, ParseException { + + this.lineBuf.clear(); + int i = sessionBuffer.readLine(this.lineBuf); + if (i == -1) { + throw new ConnectionClosedException("Client closed connection"); + } + ParserCursor cursor = new ParserCursor(0, this.lineBuf.length()); + RequestLine requestline = this.lineParser.parseRequestLine(this.lineBuf, cursor); + return this.requestFactory.newHttpRequest(requestline); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/DefaultHttpResponseParser.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/DefaultHttpResponseParser.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/DefaultHttpResponseParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,102 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseFactory; +import org.apache.http.NoHttpResponseException; +import org.apache.http.StatusLine; +import org.apache.http.ParseException; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.message.LineParser; +import org.apache.http.message.ParserCursor; +import org.apache.http.params.HttpParams; +import org.apache.http.util.CharArrayBuffer; + +/** + * HTTP response parser that obtain its input from an instance + * of {@link SessionInputBuffer}. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    + * + * @since 4.2 + */ +@NotThreadSafe +public class DefaultHttpResponseParser extends AbstractMessageParser { + + private final HttpResponseFactory responseFactory; + private final CharArrayBuffer lineBuf; + + /** + * Creates an instance of this class. + * + * @param buffer the session input buffer. + * @param parser the line parser. + * @param responseFactory the factory to use to create + * {@link HttpResponse}s. + * @param params HTTP parameters. + */ + public DefaultHttpResponseParser( + final SessionInputBuffer buffer, + final LineParser parser, + final HttpResponseFactory responseFactory, + final HttpParams params) { + super(buffer, parser, params); + if (responseFactory == null) { + throw new IllegalArgumentException("Response factory may not be null"); + } + this.responseFactory = responseFactory; + this.lineBuf = new CharArrayBuffer(128); + } + + @Override + protected HttpResponse parseHead( + final SessionInputBuffer sessionBuffer) + throws IOException, HttpException, ParseException { + + this.lineBuf.clear(); + int i = sessionBuffer.readLine(this.lineBuf); + if (i == -1) { + throw new NoHttpResponseException("The target server failed to respond"); + } + //create the status line from the status string + ParserCursor cursor = new ParserCursor(0, this.lineBuf.length()); + StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor); + return this.responseFactory.newHttpResponse(statusline, null); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpRequestParser.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpRequestParser.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpRequestParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,105 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; + +import org.apache.http.ConnectionClosedException; +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestFactory; +import org.apache.http.RequestLine; +import org.apache.http.ParseException; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.message.LineParser; +import org.apache.http.message.ParserCursor; +import org.apache.http.params.HttpParams; +import org.apache.http.util.CharArrayBuffer; + +/** + * HTTP request parser that obtain its input from an instance + * of {@link SessionInputBuffer}. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    + * + * @since 4.0 + * + * @deprecated (4.2) use {@link DefaultHttpRequestParser} + */ +@Deprecated +@NotThreadSafe +public class HttpRequestParser extends AbstractMessageParser { + + private final HttpRequestFactory requestFactory; + private final CharArrayBuffer lineBuf; + + /** + * Creates an instance of this class. + * + * @param buffer the session input buffer. + * @param parser the line parser. + * @param requestFactory the factory to use to create + * {@link HttpRequest}s. + * @param params HTTP parameters. + */ + public HttpRequestParser( + final SessionInputBuffer buffer, + final LineParser parser, + final HttpRequestFactory requestFactory, + final HttpParams params) { + super(buffer, parser, params); + if (requestFactory == null) { + throw new IllegalArgumentException("Request factory may not be null"); + } + this.requestFactory = requestFactory; + this.lineBuf = new CharArrayBuffer(128); + } + + @Override + protected HttpMessage parseHead( + final SessionInputBuffer sessionBuffer) + throws IOException, HttpException, ParseException { + + this.lineBuf.clear(); + int i = sessionBuffer.readLine(this.lineBuf); + if (i == -1) { + throw new ConnectionClosedException("Client closed connection"); + } + ParserCursor cursor = new ParserCursor(0, this.lineBuf.length()); + RequestLine requestline = this.lineParser.parseRequestLine(this.lineBuf, cursor); + return this.requestFactory.newHttpRequest(requestline); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpRequestWriter.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpRequestWriter.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpRequestWriter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,59 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; + +import org.apache.http.HttpRequest; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.SessionOutputBuffer; +import org.apache.http.message.LineFormatter; +import org.apache.http.params.HttpParams; + +/** + * HTTP request writer that serializes its output to an instance + * of {@link SessionOutputBuffer}. + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpRequestWriter extends AbstractMessageWriter { + + public HttpRequestWriter(final SessionOutputBuffer buffer, + final LineFormatter formatter, + final HttpParams params) { + super(buffer, formatter, params); + } + + @Override + protected void writeHeadLine(final HttpRequest message) throws IOException { + lineFormatter.formatRequestLine(this.lineBuf, message.getRequestLine()); + this.sessionBuffer.writeLine(this.lineBuf); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpResponseParser.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpResponseParser.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpResponseParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,106 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseFactory; +import org.apache.http.NoHttpResponseException; +import org.apache.http.StatusLine; +import org.apache.http.ParseException; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.message.LineParser; +import org.apache.http.message.ParserCursor; +import org.apache.http.params.HttpParams; +import org.apache.http.util.CharArrayBuffer; + +/** + * HTTP response parser that obtain its input from an instance + * of {@link SessionInputBuffer}. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_HEADER_COUNT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    + * + * @since 4.0 + * + * @deprecated (4.2) use {@link DefaultHttpResponseParser} + */ +@Deprecated +@NotThreadSafe +public class HttpResponseParser extends AbstractMessageParser { + + private final HttpResponseFactory responseFactory; + private final CharArrayBuffer lineBuf; + + /** + * Creates an instance of this class. + * + * @param buffer the session input buffer. + * @param parser the line parser. + * @param responseFactory the factory to use to create + * {@link HttpResponse}s. + * @param params HTTP parameters. + */ + public HttpResponseParser( + final SessionInputBuffer buffer, + final LineParser parser, + final HttpResponseFactory responseFactory, + final HttpParams params) { + super(buffer, parser, params); + if (responseFactory == null) { + throw new IllegalArgumentException("Response factory may not be null"); + } + this.responseFactory = responseFactory; + this.lineBuf = new CharArrayBuffer(128); + } + + @Override + protected HttpMessage parseHead( + final SessionInputBuffer sessionBuffer) + throws IOException, HttpException, ParseException { + + this.lineBuf.clear(); + int i = sessionBuffer.readLine(this.lineBuf); + if (i == -1) { + throw new NoHttpResponseException("The target server failed to respond"); + } + //create the status line from the status string + ParserCursor cursor = new ParserCursor(0, this.lineBuf.length()); + StatusLine statusline = lineParser.parseStatusLine(this.lineBuf, cursor); + return this.responseFactory.newHttpResponse(statusline, null); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpResponseWriter.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpResponseWriter.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpResponseWriter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,59 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; + +import org.apache.http.HttpResponse; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.SessionOutputBuffer; +import org.apache.http.message.LineFormatter; +import org.apache.http.params.HttpParams; + +/** + * HTTP response writer that serializes its output to an instance + * of {@link SessionOutputBuffer}. + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpResponseWriter extends AbstractMessageWriter { + + public HttpResponseWriter(final SessionOutputBuffer buffer, + final LineFormatter formatter, + final HttpParams params) { + super(buffer, formatter, params); + } + + @Override + protected void writeHeadLine(final HttpResponse message) throws IOException { + lineFormatter.formatStatusLine(this.lineBuf, message.getStatusLine()); + this.sessionBuffer.writeLine(this.lineBuf); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpTransportMetricsImpl.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpTransportMetricsImpl.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/HttpTransportMetricsImpl.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,63 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.HttpTransportMetrics; + +/** + * Default implementation of {@link HttpTransportMetrics}. + * + * @since 4.0 + */ +@NotThreadSafe +public class HttpTransportMetricsImpl implements HttpTransportMetrics { + + private long bytesTransferred = 0; + + public HttpTransportMetricsImpl() { + super(); + } + + public long getBytesTransferred() { + return this.bytesTransferred; + } + + public void setBytesTransferred(long count) { + this.bytesTransferred = count; + } + + public void incrementBytesTransferred(long count) { + this.bytesTransferred += count; + } + + public void reset() { + this.bytesTransferred = 0; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/IdentityInputStream.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/IdentityInputStream.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/IdentityInputStream.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,101 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.BufferInfo; +import org.apache.http.io.SessionInputBuffer; + +/** + * Input stream that reads data without any transformation. The end of the + * content entity is demarcated by closing the underlying connection + * (EOF condition). Entities transferred using this input stream can be of + * unlimited length. + *

    + * Note that this class NEVER closes the underlying stream, even when close + * gets called. Instead, it will read until the end of the stream (until + * -1 is returned). + * + * @since 4.0 + */ +@NotThreadSafe +public class IdentityInputStream extends InputStream { + + private final SessionInputBuffer in; + + private boolean closed = false; + + /** + * Wraps session input stream and reads input until the the end of stream. + * + * @param in The session input buffer + */ + public IdentityInputStream(final SessionInputBuffer in) { + super(); + if (in == null) { + throw new IllegalArgumentException("Session input buffer may not be null"); + } + this.in = in; + } + + @Override + public int available() throws IOException { + if (this.in instanceof BufferInfo) { + return ((BufferInfo) this.in).length(); + } else { + return 0; + } + } + + @Override + public void close() throws IOException { + this.closed = true; + } + + @Override + public int read() throws IOException { + if (this.closed) { + return -1; + } else { + return this.in.read(); + } + } + + @Override + public int read(final byte[] b, int off, int len) throws IOException { + if (this.closed) { + return -1; + } else { + return this.in.read(b, off, len); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/IdentityOutputStream.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/IdentityOutputStream.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/IdentityOutputStream.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,106 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.SessionOutputBuffer; + +/** + * Output stream that writes data without any transformation. The end of + * the content entity is demarcated by closing the underlying connection + * (EOF condition). Entities transferred using this input stream can be of + * unlimited length. + *

    + * Note that this class NEVER closes the underlying stream, even when close + * gets called. Instead, the stream will be marked as closed and no further + * output will be permitted. + * + * @since 4.0 + */ +@NotThreadSafe +public class IdentityOutputStream extends OutputStream { + + /** + * Wrapped session output buffer. + */ + private final SessionOutputBuffer out; + + /** True if the stream is closed. */ + private boolean closed = false; + + public IdentityOutputStream(final SessionOutputBuffer out) { + super(); + if (out == null) { + throw new IllegalArgumentException("Session output buffer may not be null"); + } + this.out = out; + } + + /** + *

    Does not close the underlying socket output.

    + * + * @throws IOException If an I/O problem occurs. + */ + @Override + public void close() throws IOException { + if (!this.closed) { + this.closed = true; + this.out.flush(); + } + } + + @Override + public void flush() throws IOException { + this.out.flush(); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + if (this.closed) { + throw new IOException("Attempted write to closed stream."); + } + this.out.write(b, off, len); + } + + @Override + public void write(byte[] b) throws IOException { + write(b, 0, b.length); + } + + @Override + public void write(int b) throws IOException { + if (this.closed) { + throw new IOException("Attempted write to closed stream."); + } + this.out.write(b); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/SocketInputBuffer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/SocketInputBuffer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/SocketInputBuffer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,116 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.net.Socket; +import java.net.SocketTimeoutException; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.EofSensor; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.params.HttpParams; + +/** + * {@link SessionInputBuffer} implementation bound to a {@link Socket}. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public class SocketInputBuffer extends AbstractSessionInputBuffer implements EofSensor { + + private final Socket socket; + + private boolean eof; + + /** + * Creates an instance of this class. + * + * @param socket the socket to read data from. + * @param buffersize the size of the internal buffer. If this number is less + * than 0 it is set to the value of + * {@link Socket#getReceiveBufferSize()}. If resultant number is less + * than 1024 it is set to 1024. + * @param params HTTP parameters. + */ + public SocketInputBuffer( + final Socket socket, + int buffersize, + final HttpParams params) throws IOException { + super(); + if (socket == null) { + throw new IllegalArgumentException("Socket may not be null"); + } + this.socket = socket; + this.eof = false; + if (buffersize < 0) { + buffersize = socket.getReceiveBufferSize(); + } + if (buffersize < 1024) { + buffersize = 1024; + } + init(socket.getInputStream(), buffersize, params); + } + + @Override + protected int fillBuffer() throws IOException { + int i = super.fillBuffer(); + this.eof = i == -1; + return i; + } + + public boolean isDataAvailable(int timeout) throws IOException { + boolean result = hasBufferedData(); + if (!result) { + int oldtimeout = this.socket.getSoTimeout(); + try { + this.socket.setSoTimeout(timeout); + fillBuffer(); + result = hasBufferedData(); + } catch (SocketTimeoutException ex) { + throw ex; + } finally { + socket.setSoTimeout(oldtimeout); + } + } + return result; + } + + public boolean isEof() { + return this.eof; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/SocketOutputBuffer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/SocketOutputBuffer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/SocketOutputBuffer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,79 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.net.Socket; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.io.SessionOutputBuffer; +import org.apache.http.params.HttpParams; + +/** + * {@link SessionOutputBuffer} implementation bound to a {@link Socket}. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MIN_CHUNK_LIMIT}
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public class SocketOutputBuffer extends AbstractSessionOutputBuffer { + + /** + * Creates an instance of this class. + * + * @param socket the socket to write data to. + * @param buffersize the size of the internal buffer. If this number is less + * than 0 it is set to the value of + * {@link Socket#getSendBufferSize()}. If resultant number is less + * than 1024 it is set to 1024. + * @param params HTTP parameters. + */ + public SocketOutputBuffer( + final Socket socket, + int buffersize, + final HttpParams params) throws IOException { + super(); + if (socket == null) { + throw new IllegalArgumentException("Socket may not be null"); + } + if (buffersize < 0) { + buffersize = socket.getSendBufferSize(); + } + if (buffersize < 1024) { + buffersize = 1024; + } + init(socket.getOutputStream(), buffersize, params); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/io/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/io/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/io/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,44 @@ + + + + + +Default implementations for interfaces in +{@link org.apache.http.io org.apache.http.io}. + +
    + +There are implementations of the transport encodings used by HTTP, +in particular the chunked coding for +{@link org.apache.http.impl.io.ChunkedOutputStream sending} and +{@link org.apache.http.impl.io.ChunkedInputStream receiving} entities. + + + Index: 3rdParty_sources/httpcore/org/apache/http/impl/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,37 @@ + + + + + +Default implementations for interfaces in +{@link org.apache.http org.apache.http}. + + + Index: 3rdParty_sources/httpcore/org/apache/http/impl/pool/BasicConnFactory.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/pool/BasicConnFactory.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/pool/BasicConnFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,107 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.pool; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; + +import javax.net.ssl.SSLSocketFactory; + +import org.apache.http.HttpClientConnection; +import org.apache.http.HttpHost; +import org.apache.http.annotation.Immutable; +import org.apache.http.impl.DefaultHttpClientConnection; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.apache.http.pool.ConnFactory; + +/** + * A very basic {@link ConnFactory} implementation that creates + * {@link HttpClientConnection} instances given a {@link HttpHost} instance. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    + * + * @see HttpHost + * @since 4.2 + */ +@Immutable +public class BasicConnFactory implements ConnFactory { + + private final SSLSocketFactory sslfactory; + private final HttpParams params; + + public BasicConnFactory(final SSLSocketFactory sslfactory, final HttpParams params) { + super(); + if (params == null) { + throw new IllegalArgumentException("HTTP params may not be null"); + } + this.sslfactory = sslfactory; + this.params = params; + } + + public BasicConnFactory(final HttpParams params) { + this(null, params); + } + + protected HttpClientConnection create(final Socket socket, final HttpParams params) throws IOException { + DefaultHttpClientConnection conn = new DefaultHttpClientConnection(); + conn.bind(socket, params); + return conn; + } + + public HttpClientConnection create(final HttpHost host) throws IOException { + String scheme = host.getSchemeName(); + Socket socket = null; + if ("http".equalsIgnoreCase(scheme)) { + socket = new Socket(); + } if ("https".equalsIgnoreCase(scheme)) { + if (this.sslfactory != null) { + socket = this.sslfactory.createSocket(); + } + } + if (socket == null) { + throw new IOException(scheme + " scheme is not supported"); + } + int connectTimeout = HttpConnectionParams.getConnectionTimeout(this.params); + int soTimeout = HttpConnectionParams.getSoTimeout(this.params); + + socket.setSoTimeout(soTimeout); + socket.connect(new InetSocketAddress(host.getHostName(), host.getPort()), connectTimeout); + return create(socket, this.params); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/pool/BasicConnPool.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/pool/BasicConnPool.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/pool/BasicConnPool.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,80 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.pool; + +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.http.HttpClientConnection; +import org.apache.http.HttpHost; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.params.HttpParams; +import org.apache.http.pool.AbstractConnPool; +import org.apache.http.pool.ConnFactory; +import org.apache.http.pool.ConnPool; + +/** + * A very basic {@link ConnPool} implementation that represents a pool + * of blocking {@link HttpClientConnection} connections identified by + * an {@link HttpHost} instance. Please note this pool implementation + * does not support complex routes via a proxy cannot differentiate between + * direct and proxied connections. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#HTTP_ELEMENT_CHARSET}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#TCP_NODELAY}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SO_TIMEOUT}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SO_LINGER}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#SOCKET_BUFFER_SIZE}
    • + *
    • {@link org.apache.http.params.CoreConnectionPNames#MAX_LINE_LENGTH}
    • + *
    + * + * @see HttpHost + * @since 4.2 + */ +@ThreadSafe +public class BasicConnPool extends AbstractConnPool { + + private static AtomicLong COUNTER = new AtomicLong(); + + public BasicConnPool(final ConnFactory connFactory) { + super(connFactory, 2, 20); + } + + public BasicConnPool(final HttpParams params) { + super(new BasicConnFactory(params), 2, 20); + } + + @Override + protected BasicPoolEntry createEntry( + final HttpHost host, + final HttpClientConnection conn) { + return new BasicPoolEntry(Long.toString(COUNTER.getAndIncrement()), host, conn); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/pool/BasicPoolEntry.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/pool/BasicPoolEntry.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/pool/BasicPoolEntry.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,64 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.impl.pool; + +import java.io.IOException; + +import org.apache.http.HttpClientConnection; +import org.apache.http.HttpHost; +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.pool.PoolEntry; + +/** + * A very basic {@link PoolEntry} implementation that represents an entry + * in a pool of blocking {@link HttpClientConnection}s identified by + * an {@link HttpHost} instance. + * + * @see HttpHost + * @since 4.2 + */ +@ThreadSafe +public class BasicPoolEntry extends PoolEntry { + + public BasicPoolEntry(final String id, final HttpHost route, final HttpClientConnection conn) { + super(id, route, conn); + } + + @Override + public void close() { + try { + this.getConnection().close(); + } catch (IOException ignore) { + } + } + + @Override + public boolean isClosed() { + return !this.getConnection().isOpen(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/impl/pool/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/impl/pool/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/impl/pool/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +Basic implementations for interfaces in +{@link org.apache.http.pool org.apache.http.pool}. + + Index: 3rdParty_sources/httpcore/org/apache/http/io/BufferInfo.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/io/BufferInfo.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/io/BufferInfo.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,58 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.io; + +/** + * Basic buffer properties. + * + * @since 4.1 + */ +public interface BufferInfo { + + /** + * Return length data stored in the buffer + * + * @return data length + */ + int length(); + + /** + * Returns total capacity of the buffer + * + * @return total capacity + */ + int capacity(); + + /** + * Returns available space in the buffer. + * + * @return available space. + */ + int available(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/io/EofSensor.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/io/EofSensor.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/io/EofSensor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,39 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.io; + +/** + * EOF sensor. + * + * @since 4.0 + */ +public interface EofSensor { + + boolean isEof(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/io/HttpMessageParser.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/io/HttpMessageParser.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/io/HttpMessageParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,54 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.io; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; + +/** + * Abstract message parser intended to build HTTP messages from an arbitrary + * data source. + * + * @since 4.0 + */ +public interface HttpMessageParser { + + /** + * Generates an instance of {@link HttpMessage} from the underlying data + * source. + * + * @return HTTP message + * @throws IOException in case of an I/O error + * @throws HttpException in case of HTTP protocol violation + */ + T parse() + throws IOException, HttpException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/io/HttpMessageWriter.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/io/HttpMessageWriter.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/io/HttpMessageWriter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,54 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.io; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpMessage; + +/** + * Abstract message writer intended to serialize HTTP messages to an arbitrary + * data sink. + * + * @since 4.0 + */ +public interface HttpMessageWriter { + + /** + * Serializes an instance of {@link HttpMessage} to the underlying data + * sink. + * + * @param message + * @throws IOException in case of an I/O error + * @throws HttpException in case of HTTP protocol violation + */ + void write(T message) + throws IOException, HttpException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/io/HttpTransportMetrics.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/io/HttpTransportMetrics.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/io/HttpTransportMetrics.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,48 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.io; + +/** + * The point of access to the statistics of {@link SessionInputBuffer} or + * {@link SessionOutputBuffer}. + * + * @since 4.0 + */ +public interface HttpTransportMetrics { + + /** + * Returns the number of bytes transferred. + */ + long getBytesTransferred(); + + /** + * Resets the counts + */ + void reset(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/io/SessionInputBuffer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/io/SessionInputBuffer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/io/SessionInputBuffer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,148 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.io; + +import java.io.IOException; + +import org.apache.http.util.CharArrayBuffer; + +/** + * Session input buffer for blocking connections. This interface is similar to + * InputStream class, but it also provides methods for reading lines of text. + *

    + * Implementing classes are also expected to manage intermediate data buffering + * for optimal input performance. + * + * @since 4.0 + */ +public interface SessionInputBuffer { + + /** + * Reads up to len bytes of data from the session buffer into + * an array of bytes. An attempt is made to read as many as + * len bytes, but a smaller number may be read, possibly + * zero. The number of bytes actually read is returned as an integer. + * + *

    This method blocks until input data is available, end of file is + * detected, or an exception is thrown. + * + *

    If off is negative, or len is negative, or + * off+len is greater than the length of the array + * b, then an IndexOutOfBoundsException is + * thrown. + * + * @param b the buffer into which the data is read. + * @param off the start offset in array b + * at which the data is written. + * @param len the maximum number of bytes to read. + * @return the total number of bytes read into the buffer, or + * -1 if there is no more data because the end of + * the stream has been reached. + * @exception IOException if an I/O error occurs. + */ + int read(byte[] b, int off, int len) throws IOException; + + /** + * Reads some number of bytes from the session buffer and stores them into + * the buffer array b. The number of bytes actually read is + * returned as an integer. This method blocks until input data is + * available, end of file is detected, or an exception is thrown. + * + * @param b the buffer into which the data is read. + * @return the total number of bytes read into the buffer, or + * -1 is there is no more data because the end of + * the stream has been reached. + * @exception IOException if an I/O error occurs. + */ + int read(byte[] b) throws IOException; + + /** + * Reads the next byte of data from this session buffer. The value byte is + * returned as an int in the range 0 to + * 255. If no byte is available because the end of the stream + * has been reached, the value -1 is returned. This method + * blocks until input data is available, the end of the stream is detected, + * or an exception is thrown. + * + * @return the next byte of data, or -1 if the end of the + * stream is reached. + * @exception IOException if an I/O error occurs. + */ + int read() throws IOException; + + /** + * Reads a complete line of characters up to a line delimiter from this + * session buffer into the given line buffer. The number of chars actually + * read is returned as an integer. The line delimiter itself is discarded. + * If no char is available because the end of the stream has been reached, + * the value -1 is returned. This method blocks until input + * data is available, end of file is detected, or an exception is thrown. + *

    + * The choice of a char encoding and line delimiter sequence is up to the + * specific implementations of this interface. + * + * @param buffer the line buffer. + * @return one line of characters + * @exception IOException if an I/O error occurs. + */ + int readLine(CharArrayBuffer buffer) throws IOException; + + /** + * Reads a complete line of characters up to a line delimiter from this + * session buffer. The line delimiter itself is discarded. If no char is + * available because the end of the stream has been reached, + * null is returned. This method blocks until input data is + * available, end of file is detected, or an exception is thrown. + *

    + * The choice of a char encoding and line delimiter sequence is up to the + * specific implementations of this interface. + * + * @return HTTP line as a string + * @exception IOException if an I/O error occurs. + */ + String readLine() throws IOException; + + /** Blocks until some data becomes available in the session buffer or the + * given timeout period in milliseconds elapses. If the timeout value is + * 0 this method blocks indefinitely. + * + * @param timeout in milliseconds. + * @return true if some data is available in the session + * buffer or false otherwise. + * @exception IOException if an I/O error occurs. + */ + boolean isDataAvailable(int timeout) throws IOException; + + /** + * Returns {@link HttpTransportMetrics} for this session buffer. + * + * @return transport metrics. + */ + HttpTransportMetrics getMetrics(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/io/SessionOutputBuffer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/io/SessionOutputBuffer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/io/SessionOutputBuffer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,120 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.io; + +import java.io.IOException; + +import org.apache.http.util.CharArrayBuffer; + +/** + * Session output buffer for blocking connections. This interface is similar to + * OutputStream class, but it also provides methods for writing lines of text. + *

    + * Implementing classes are also expected to manage intermediate data buffering + * for optimal output performance. + * + * @since 4.0 + */ +public interface SessionOutputBuffer { + + /** + * Writes len bytes from the specified byte array + * starting at offset off to this session buffer. + *

    + * If off is negative, or len is negative, or + * off+len is greater than the length of the array + * b, then an IndexOutOfBoundsException is thrown. + * + * @param b the data. + * @param off the start offset in the data. + * @param len the number of bytes to write. + * @exception IOException if an I/O error occurs. + */ + void write(byte[] b, int off, int len) throws IOException; + + /** + * Writes b.length bytes from the specified byte array + * to this session buffer. + * + * @param b the data. + * @exception IOException if an I/O error occurs. + */ + void write(byte[] b) throws IOException; + + /** + * Writes the specified byte to this session buffer. + * + * @param b the byte. + * @exception IOException if an I/O error occurs. + */ + void write(int b) throws IOException; + + /** + * Writes characters from the specified string followed by a line delimiter + * to this session buffer. + *

    + * The choice of a char encoding and line delimiter sequence is up to the + * specific implementations of this interface. + * + * @param s the line. + * @exception IOException if an I/O error occurs. + */ + void writeLine(String s) throws IOException; + + /** + * Writes characters from the specified char array followed by a line + * delimiter to this session buffer. + *

    + * The choice of a char encoding and line delimiter sequence is up to the + * specific implementations of this interface. + * + * @param buffer the buffer containing chars of the line. + * @exception IOException if an I/O error occurs. + */ + void writeLine(CharArrayBuffer buffer) throws IOException; + + /** + * Flushes this session buffer and forces any buffered output bytes + * to be written out. The general contract of flush is + * that calling it is an indication that, if any bytes previously + * written have been buffered by the implementation of the output + * stream, such bytes should immediately be written to their + * intended destination. + * + * @exception IOException if an I/O error occurs. + */ + void flush() throws IOException; + + /** + * Returns {@link HttpTransportMetrics} for this session buffer. + * + * @return transport metrics. + */ + HttpTransportMetrics getMetrics(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/io/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/io/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/io/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,38 @@ + + + + + +Blocking I/O session buffer, message parser / writer interfaces. +

    +This layer defines interfaces for transferring basic elements of +HTTP messages over connections. + + Index: 3rdParty_sources/httpcore/org/apache/http/message/AbstractHttpMessage.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/AbstractHttpMessage.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/AbstractHttpMessage.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,158 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.Header; +import org.apache.http.HeaderIterator; +import org.apache.http.HttpMessage; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.params.HttpParams; +import org.apache.http.params.BasicHttpParams; + +/** + * Basic implementation of {@link HttpMessage}. + * + * @since 4.0 + */ +@NotThreadSafe +public abstract class AbstractHttpMessage implements HttpMessage { + + protected HeaderGroup headergroup; + + protected HttpParams params; + + protected AbstractHttpMessage(final HttpParams params) { + super(); + this.headergroup = new HeaderGroup(); + this.params = params; + } + + protected AbstractHttpMessage() { + this(null); + } + + // non-javadoc, see interface HttpMessage + public boolean containsHeader(String name) { + return this.headergroup.containsHeader(name); + } + + // non-javadoc, see interface HttpMessage + public Header[] getHeaders(final String name) { + return this.headergroup.getHeaders(name); + } + + // non-javadoc, see interface HttpMessage + public Header getFirstHeader(final String name) { + return this.headergroup.getFirstHeader(name); + } + + // non-javadoc, see interface HttpMessage + public Header getLastHeader(final String name) { + return this.headergroup.getLastHeader(name); + } + + // non-javadoc, see interface HttpMessage + public Header[] getAllHeaders() { + return this.headergroup.getAllHeaders(); + } + + // non-javadoc, see interface HttpMessage + public void addHeader(final Header header) { + this.headergroup.addHeader(header); + } + + // non-javadoc, see interface HttpMessage + public void addHeader(final String name, final String value) { + if (name == null) { + throw new IllegalArgumentException("Header name may not be null"); + } + this.headergroup.addHeader(new BasicHeader(name, value)); + } + + // non-javadoc, see interface HttpMessage + public void setHeader(final Header header) { + this.headergroup.updateHeader(header); + } + + // non-javadoc, see interface HttpMessage + public void setHeader(final String name, final String value) { + if (name == null) { + throw new IllegalArgumentException("Header name may not be null"); + } + this.headergroup.updateHeader(new BasicHeader(name, value)); + } + + // non-javadoc, see interface HttpMessage + public void setHeaders(final Header[] headers) { + this.headergroup.setHeaders(headers); + } + + // non-javadoc, see interface HttpMessage + public void removeHeader(final Header header) { + this.headergroup.removeHeader(header); + } + + // non-javadoc, see interface HttpMessage + public void removeHeaders(final String name) { + if (name == null) { + return; + } + for (HeaderIterator i = this.headergroup.iterator(); i.hasNext(); ) { + Header header = i.nextHeader(); + if (name.equalsIgnoreCase(header.getName())) { + i.remove(); + } + } + } + + // non-javadoc, see interface HttpMessage + public HeaderIterator headerIterator() { + return this.headergroup.iterator(); + } + + // non-javadoc, see interface HttpMessage + public HeaderIterator headerIterator(String name) { + return this.headergroup.iterator(name); + } + + // non-javadoc, see interface HttpMessage + public HttpParams getParams() { + if (this.params == null) { + this.params = new BasicHttpParams(); + } + return this.params; + } + + // non-javadoc, see interface HttpMessage + public void setParams(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + this.params = params; + } +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicHeader.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicHeader.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicHeader.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,93 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.io.Serializable; + +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.ParseException; +import org.apache.http.annotation.Immutable; + +/** + * Basic implementation of {@link Header}. + * + * @since 4.0 + */ +@Immutable +public class BasicHeader implements Header, Cloneable, Serializable { + + private static final long serialVersionUID = -5427236326487562174L; + + private final String name; + private final String value; + + /** + * Constructor with name and value + * + * @param name the header name + * @param value the header value + */ + public BasicHeader(final String name, final String value) { + super(); + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + this.name = name; + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + @Override + public String toString() { + // no need for non-default formatting in toString() + return BasicLineFormatter.DEFAULT.formatHeader(null, this).toString(); + } + + public HeaderElement[] getElements() throws ParseException { + if (this.value != null) { + // result intentionally not cached, it's probably not used again + return BasicHeaderValueParser.parseElements(this.value, null); + } else { + return new HeaderElement[] {}; + } + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderElement.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderElement.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderElement.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,165 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.HeaderElement; +import org.apache.http.NameValuePair; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.util.LangUtils; + +/** + * Basic implementation of {@link HeaderElement} + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicHeaderElement implements HeaderElement, Cloneable { + + private final String name; + private final String value; + private final NameValuePair[] parameters; + + /** + * Constructor with name, value and parameters. + * + * @param name header element name + * @param value header element value. May be null + * @param parameters header element parameters. May be null. + * Parameters are copied by reference, not by value + */ + public BasicHeaderElement( + final String name, + final String value, + final NameValuePair[] parameters) { + super(); + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + this.name = name; + this.value = value; + if (parameters != null) { + this.parameters = parameters; + } else { + this.parameters = new NameValuePair[] {}; + } + } + + /** + * Constructor with name and value. + * + * @param name header element name + * @param value header element value. May be null + */ + public BasicHeaderElement(final String name, final String value) { + this(name, value, null); + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + public NameValuePair[] getParameters() { + return this.parameters.clone(); + } + + public int getParameterCount() { + return this.parameters.length; + } + + public NameValuePair getParameter(int index) { + // ArrayIndexOutOfBoundsException is appropriate + return this.parameters[index]; + } + + public NameValuePair getParameterByName(final String name) { + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + NameValuePair found = null; + for (int i = 0; i < this.parameters.length; i++) { + NameValuePair current = this.parameters[ i ]; + if (current.getName().equalsIgnoreCase(name)) { + found = current; + break; + } + } + return found; + } + + @Override + public boolean equals(final Object object) { + if (this == object) return true; + if (object instanceof HeaderElement) { + BasicHeaderElement that = (BasicHeaderElement) object; + return this.name.equals(that.name) + && LangUtils.equals(this.value, that.value) + && LangUtils.equals(this.parameters, that.parameters); + } else { + return false; + } + } + + @Override + public int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.name); + hash = LangUtils.hashCode(hash, this.value); + for (int i = 0; i < this.parameters.length; i++) { + hash = LangUtils.hashCode(hash, this.parameters[i]); + } + return hash; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append(this.name); + if (this.value != null) { + buffer.append("="); + buffer.append(this.value); + } + for (int i = 0; i < this.parameters.length; i++) { + buffer.append("; "); + buffer.append(this.parameters[i]); + } + return buffer.toString(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + // parameters array is considered immutable + // no need to make a copy of it + return super.clone(); + } + +} + Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderElementIterator.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderElementIterator.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderElementIterator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,156 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.util.NoSuchElementException; + +import org.apache.http.FormattedHeader; +import org.apache.http.Header; +import org.apache.http.HeaderElement; +import org.apache.http.HeaderElementIterator; +import org.apache.http.HeaderIterator; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.util.CharArrayBuffer; + +/** + * Basic implementation of a {@link HeaderElementIterator}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicHeaderElementIterator implements HeaderElementIterator { + + private final HeaderIterator headerIt; + private final HeaderValueParser parser; + + private HeaderElement currentElement = null; + private CharArrayBuffer buffer = null; + private ParserCursor cursor = null; + + /** + * Creates a new instance of BasicHeaderElementIterator + */ + public BasicHeaderElementIterator( + final HeaderIterator headerIterator, + final HeaderValueParser parser) { + if (headerIterator == null) { + throw new IllegalArgumentException("Header iterator may not be null"); + } + if (parser == null) { + throw new IllegalArgumentException("Parser may not be null"); + } + this.headerIt = headerIterator; + this.parser = parser; + } + + + public BasicHeaderElementIterator(final HeaderIterator headerIterator) { + this(headerIterator, BasicHeaderValueParser.DEFAULT); + } + + + private void bufferHeaderValue() { + this.cursor = null; + this.buffer = null; + while (this.headerIt.hasNext()) { + Header h = this.headerIt.nextHeader(); + if (h instanceof FormattedHeader) { + this.buffer = ((FormattedHeader) h).getBuffer(); + this.cursor = new ParserCursor(0, this.buffer.length()); + this.cursor.updatePos(((FormattedHeader) h).getValuePos()); + break; + } else { + String value = h.getValue(); + if (value != null) { + this.buffer = new CharArrayBuffer(value.length()); + this.buffer.append(value); + this.cursor = new ParserCursor(0, this.buffer.length()); + break; + } + } + } + } + + private void parseNextElement() { + // loop while there are headers left to parse + while (this.headerIt.hasNext() || this.cursor != null) { + if (this.cursor == null || this.cursor.atEnd()) { + // get next header value + bufferHeaderValue(); + } + // Anything buffered? + if (this.cursor != null) { + // loop while there is data in the buffer + while (!this.cursor.atEnd()) { + HeaderElement e = this.parser.parseHeaderElement(this.buffer, this.cursor); + if (!(e.getName().length() == 0 && e.getValue() == null)) { + // Found something + this.currentElement = e; + return; + } + } + // if at the end of the buffer + if (this.cursor.atEnd()) { + // discard it + this.cursor = null; + this.buffer = null; + } + } + } + } + + public boolean hasNext() { + if (this.currentElement == null) { + parseNextElement(); + } + return this.currentElement != null; + } + + public HeaderElement nextElement() throws NoSuchElementException { + if (this.currentElement == null) { + parseNextElement(); + } + + if (this.currentElement == null) { + throw new NoSuchElementException("No more header elements available"); + } + + HeaderElement element = this.currentElement; + this.currentElement = null; + return element; + } + + public final Object next() throws NoSuchElementException { + return nextElement(); + } + + public void remove() throws UnsupportedOperationException { + throw new UnsupportedOperationException("Remove not supported"); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderIterator.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderIterator.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderIterator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,176 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.util.NoSuchElementException; + +import org.apache.http.Header; +import org.apache.http.HeaderIterator; +import org.apache.http.annotation.NotThreadSafe; + +/** + * Basic implementation of a {@link HeaderIterator}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicHeaderIterator implements HeaderIterator { + + /** + * An array of headers to iterate over. + * Not all elements of this array are necessarily part of the iteration. + * This array will never be modified by the iterator. + * Derived implementations are expected to adhere to this restriction. + */ + protected final Header[] allHeaders; + + + /** + * The position of the next header in {@link #allHeaders allHeaders}. + * Negative if the iteration is over. + */ + protected int currentIndex; + + + /** + * The header name to filter by. + * null to iterate over all headers in the array. + */ + protected String headerName; + + + + /** + * Creates a new header iterator. + * + * @param headers an array of headers over which to iterate + * @param name the name of the headers over which to iterate, or + * null for any + */ + public BasicHeaderIterator(Header[] headers, String name) { + if (headers == null) { + throw new IllegalArgumentException + ("Header array must not be null."); + } + + this.allHeaders = headers; + this.headerName = name; + this.currentIndex = findNext(-1); + } + + + /** + * Determines the index of the next header. + * + * @param from one less than the index to consider first, + * -1 to search for the first header + * + * @return the index of the next header that matches the filter name, + * or negative if there are no more headers + */ + protected int findNext(int from) { + if (from < -1) + return -1; + + final int to = this.allHeaders.length-1; + boolean found = false; + while (!found && (from < to)) { + from++; + found = filterHeader(from); + } + return found ? from : -1; + } + + + /** + * Checks whether a header is part of the iteration. + * + * @param index the index of the header to check + * + * @return true if the header should be part of the + * iteration, false to skip + */ + protected boolean filterHeader(int index) { + return (this.headerName == null) || + this.headerName.equalsIgnoreCase(this.allHeaders[index].getName()); + } + + + // non-javadoc, see interface HeaderIterator + public boolean hasNext() { + return (this.currentIndex >= 0); + } + + + /** + * Obtains the next header from this iteration. + * + * @return the next header in this iteration + * + * @throws NoSuchElementException if there are no more headers + */ + public Header nextHeader() + throws NoSuchElementException { + + final int current = this.currentIndex; + if (current < 0) { + throw new NoSuchElementException("Iteration already finished."); + } + + this.currentIndex = findNext(current); + + return this.allHeaders[current]; + } + + + /** + * Returns the next header. + * Same as {@link #nextHeader nextHeader}, but not type-safe. + * + * @return the next header in this iteration + * + * @throws NoSuchElementException if there are no more headers + */ + public final Object next() + throws NoSuchElementException { + return nextHeader(); + } + + + /** + * Removing headers is not supported. + * + * @throws UnsupportedOperationException always + */ + public void remove() + throws UnsupportedOperationException { + + throw new UnsupportedOperationException + ("Removing headers is not supported."); + } +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderValueFormatter.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderValueFormatter.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderValueFormatter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,431 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.HeaderElement; +import org.apache.http.NameValuePair; +import org.apache.http.annotation.Immutable; +import org.apache.http.util.CharArrayBuffer; + +/** + * Basic implementation for formatting header value elements. + * Instances of this class are stateless and thread-safe. + * Derived classes are expected to maintain these properties. + * + * @since 4.0 + */ +@Immutable +public class BasicHeaderValueFormatter implements HeaderValueFormatter { + + /** + * A default instance of this class, for use as default or fallback. + * Note that {@link BasicHeaderValueFormatter} is not a singleton, there + * can be many instances of the class itself and of derived classes. + * The instance here provides non-customized, default behavior. + */ + public final static + BasicHeaderValueFormatter DEFAULT = new BasicHeaderValueFormatter(); + + + /** + * Special characters that can be used as separators in HTTP parameters. + * These special characters MUST be in a quoted string to be used within + * a parameter value . + */ + public final static String SEPARATORS = " ;,:@()<>\\\"/[]?={}\t"; + + + /** + * Unsafe special characters that must be escaped using the backslash + * character + */ + public final static String UNSAFE_CHARS = "\"\\"; + + + + // public default constructor + + + + /** + * Formats an array of header elements. + * + * @param elems the header elements to format + * @param quote true to always format with quoted values, + * false to use quotes only when necessary + * @param formatter the formatter to use, or null + * for the {@link #DEFAULT default} + * + * @return the formatted header elements + */ + public final static + String formatElements(final HeaderElement[] elems, + final boolean quote, + HeaderValueFormatter formatter) { + if (formatter == null) + formatter = BasicHeaderValueFormatter.DEFAULT; + return formatter.formatElements(null, elems, quote).toString(); + } + + + // non-javadoc, see interface HeaderValueFormatter + public CharArrayBuffer formatElements(CharArrayBuffer buffer, + final HeaderElement[] elems, + final boolean quote) { + if (elems == null) { + throw new IllegalArgumentException + ("Header element array must not be null."); + } + + int len = estimateElementsLen(elems); + if (buffer == null) { + buffer = new CharArrayBuffer(len); + } else { + buffer.ensureCapacity(len); + } + + for (int i=0; i 0) { + buffer.append(", "); + } + formatHeaderElement(buffer, elems[i], quote); + } + + return buffer; + } + + + /** + * Estimates the length of formatted header elements. + * + * @param elems the header elements to format, or null + * + * @return a length estimate, in number of characters + */ + protected int estimateElementsLen(final HeaderElement[] elems) { + if ((elems == null) || (elems.length < 1)) + return 0; + + int result = (elems.length-1) * 2; // elements separated by ", " + for (int i=0; itrue to always format with quoted values, + * false to use quotes only when necessary + * @param formatter the formatter to use, or null + * for the {@link #DEFAULT default} + * + * @return the formatted header element + */ + public final static + String formatHeaderElement(final HeaderElement elem, + boolean quote, + HeaderValueFormatter formatter) { + if (formatter == null) + formatter = BasicHeaderValueFormatter.DEFAULT; + return formatter.formatHeaderElement(null, elem, quote).toString(); + } + + + // non-javadoc, see interface HeaderValueFormatter + public CharArrayBuffer formatHeaderElement(CharArrayBuffer buffer, + final HeaderElement elem, + final boolean quote) { + if (elem == null) { + throw new IllegalArgumentException + ("Header element must not be null."); + } + + int len = estimateHeaderElementLen(elem); + if (buffer == null) { + buffer = new CharArrayBuffer(len); + } else { + buffer.ensureCapacity(len); + } + + buffer.append(elem.getName()); + final String value = elem.getValue(); + if (value != null) { + buffer.append('='); + doFormatValue(buffer, value, quote); + } + + final int parcnt = elem.getParameterCount(); + if (parcnt > 0) { + for (int i=0; inull + * + * @return a length estimate, in number of characters + */ + protected int estimateHeaderElementLen(final HeaderElement elem) { + if (elem == null) + return 0; + + int result = elem.getName().length(); // name + final String value = elem.getValue(); + if (value != null) { + // assume quotes, but no escaped characters + result += 3 + value.length(); // ="value" + } + + final int parcnt = elem.getParameterCount(); + if (parcnt > 0) { + for (int i=0; i + estimateNameValuePairLen(elem.getParameter(i)); + } + } + + return result; + } + + + + + /** + * Formats a set of parameters. + * + * @param nvps the parameters to format + * @param quote true to always format with quoted values, + * false to use quotes only when necessary + * @param formatter the formatter to use, or null + * for the {@link #DEFAULT default} + * + * @return the formatted parameters + */ + public final static + String formatParameters(final NameValuePair[] nvps, + final boolean quote, + HeaderValueFormatter formatter) { + if (formatter == null) + formatter = BasicHeaderValueFormatter.DEFAULT; + return formatter.formatParameters(null, nvps, quote).toString(); + } + + + // non-javadoc, see interface HeaderValueFormatter + public CharArrayBuffer formatParameters(CharArrayBuffer buffer, + NameValuePair[] nvps, + boolean quote) { + if (nvps == null) { + throw new IllegalArgumentException + ("Parameters must not be null."); + } + + int len = estimateParametersLen(nvps); + if (buffer == null) { + buffer = new CharArrayBuffer(len); + } else { + buffer.ensureCapacity(len); + } + + for (int i = 0; i < nvps.length; i++) { + if (i > 0) { + buffer.append("; "); + } + formatNameValuePair(buffer, nvps[i], quote); + } + + return buffer; + } + + + /** + * Estimates the length of formatted parameters. + * + * @param nvps the parameters to format, or null + * + * @return a length estimate, in number of characters + */ + protected int estimateParametersLen(final NameValuePair[] nvps) { + if ((nvps == null) || (nvps.length < 1)) + return 0; + + int result = (nvps.length-1) * 2; // "; " between the parameters + for (int i=0; itrue to always format with a quoted value, + * false to use quotes only when necessary + * @param formatter the formatter to use, or null + * for the {@link #DEFAULT default} + * + * @return the formatted name-value pair + */ + public final static + String formatNameValuePair(final NameValuePair nvp, + final boolean quote, + HeaderValueFormatter formatter) { + if (formatter == null) + formatter = BasicHeaderValueFormatter.DEFAULT; + return formatter.formatNameValuePair(null, nvp, quote).toString(); + } + + + // non-javadoc, see interface HeaderValueFormatter + public CharArrayBuffer formatNameValuePair(CharArrayBuffer buffer, + final NameValuePair nvp, + final boolean quote) { + if (nvp == null) { + throw new IllegalArgumentException + ("NameValuePair must not be null."); + } + + int len = estimateNameValuePairLen(nvp); + if (buffer == null) { + buffer = new CharArrayBuffer(len); + } else { + buffer.ensureCapacity(len); + } + + buffer.append(nvp.getName()); + final String value = nvp.getValue(); + if (value != null) { + buffer.append('='); + doFormatValue(buffer, value, quote); + } + + return buffer; + } + + + /** + * Estimates the length of a formatted name-value pair. + * + * @param nvp the name-value pair to format, or null + * + * @return a length estimate, in number of characters + */ + protected int estimateNameValuePairLen(final NameValuePair nvp) { + if (nvp == null) + return 0; + + int result = nvp.getName().length(); // name + final String value = nvp.getValue(); + if (value != null) { + // assume quotes, but no escaped characters + result += 3 + value.length(); // ="value" + } + return result; + } + + + /** + * Actually formats the value of a name-value pair. + * This does not include a leading = character. + * Called from {@link #formatNameValuePair formatNameValuePair}. + * + * @param buffer the buffer to append to, never null + * @param value the value to append, never null + * @param quote true to always format with quotes, + * false to use quotes only when necessary + */ + protected void doFormatValue(final CharArrayBuffer buffer, + final String value, + boolean quote) { + + if (!quote) { + for (int i = 0; (i < value.length()) && !quote; i++) { + quote = isSeparator(value.charAt(i)); + } + } + + if (quote) { + buffer.append('"'); + } + for (int i = 0; i < value.length(); i++) { + char ch = value.charAt(i); + if (isUnsafe(ch)) { + buffer.append('\\'); + } + buffer.append(ch); + } + if (quote) { + buffer.append('"'); + } + } + + + /** + * Checks whether a character is a {@link #SEPARATORS separator}. + * + * @param ch the character to check + * + * @return true if the character is a separator, + * false otherwise + */ + protected boolean isSeparator(char ch) { + return SEPARATORS.indexOf(ch) >= 0; + } + + + /** + * Checks whether a character is {@link #UNSAFE_CHARS unsafe}. + * + * @param ch the character to check + * + * @return true if the character is unsafe, + * false otherwise + */ + protected boolean isUnsafe(char ch) { + return UNSAFE_CHARS.indexOf(ch) >= 0; + } + + +} // class BasicHeaderValueFormatter Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderValueParser.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderValueParser.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicHeaderValueParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,403 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.util.List; +import java.util.ArrayList; + +import org.apache.http.HeaderElement; +import org.apache.http.NameValuePair; +import org.apache.http.ParseException; +import org.apache.http.annotation.Immutable; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.CharArrayBuffer; + +/** + * Basic implementation for parsing header values into elements. + * Instances of this class are stateless and thread-safe. + * Derived classes are expected to maintain these properties. + * + * @since 4.0 + */ +@Immutable +public class BasicHeaderValueParser implements HeaderValueParser { + + /** + * A default instance of this class, for use as default or fallback. + * Note that {@link BasicHeaderValueParser} is not a singleton, there + * can be many instances of the class itself and of derived classes. + * The instance here provides non-customized, default behavior. + */ + public final static + BasicHeaderValueParser DEFAULT = new BasicHeaderValueParser(); + + private final static char PARAM_DELIMITER = ';'; + private final static char ELEM_DELIMITER = ','; + private final static char[] ALL_DELIMITERS = new char[] { + PARAM_DELIMITER, + ELEM_DELIMITER + }; + + // public default constructor + + + /** + * Parses elements with the given parser. + * + * @param value the header value to parse + * @param parser the parser to use, or null for default + * + * @return array holding the header elements, never null + */ + public final static + HeaderElement[] parseElements(final String value, + HeaderValueParser parser) + throws ParseException { + + if (value == null) { + throw new IllegalArgumentException + ("Value to parse may not be null"); + } + + if (parser == null) + parser = BasicHeaderValueParser.DEFAULT; + + CharArrayBuffer buffer = new CharArrayBuffer(value.length()); + buffer.append(value); + ParserCursor cursor = new ParserCursor(0, value.length()); + return parser.parseElements(buffer, cursor); + } + + + // non-javadoc, see interface HeaderValueParser + public HeaderElement[] parseElements(final CharArrayBuffer buffer, + final ParserCursor cursor) { + + if (buffer == null) { + throw new IllegalArgumentException("Char array buffer may not be null"); + } + if (cursor == null) { + throw new IllegalArgumentException("Parser cursor may not be null"); + } + + List elements = new ArrayList(); + while (!cursor.atEnd()) { + HeaderElement element = parseHeaderElement(buffer, cursor); + if (!(element.getName().length() == 0 && element.getValue() == null)) { + elements.add(element); + } + } + return elements.toArray(new HeaderElement[elements.size()]); + } + + + /** + * Parses an element with the given parser. + * + * @param value the header element to parse + * @param parser the parser to use, or null for default + * + * @return the parsed header element + */ + public final static + HeaderElement parseHeaderElement(final String value, + HeaderValueParser parser) + throws ParseException { + + if (value == null) { + throw new IllegalArgumentException + ("Value to parse may not be null"); + } + + if (parser == null) + parser = BasicHeaderValueParser.DEFAULT; + + CharArrayBuffer buffer = new CharArrayBuffer(value.length()); + buffer.append(value); + ParserCursor cursor = new ParserCursor(0, value.length()); + return parser.parseHeaderElement(buffer, cursor); + } + + + // non-javadoc, see interface HeaderValueParser + public HeaderElement parseHeaderElement(final CharArrayBuffer buffer, + final ParserCursor cursor) { + + if (buffer == null) { + throw new IllegalArgumentException("Char array buffer may not be null"); + } + if (cursor == null) { + throw new IllegalArgumentException("Parser cursor may not be null"); + } + + NameValuePair nvp = parseNameValuePair(buffer, cursor); + NameValuePair[] params = null; + if (!cursor.atEnd()) { + char ch = buffer.charAt(cursor.getPos() - 1); + if (ch != ELEM_DELIMITER) { + params = parseParameters(buffer, cursor); + } + } + return createHeaderElement(nvp.getName(), nvp.getValue(), params); + } + + + /** + * Creates a header element. + * Called from {@link #parseHeaderElement}. + * + * @return a header element representing the argument + */ + protected HeaderElement createHeaderElement( + final String name, + final String value, + final NameValuePair[] params) { + return new BasicHeaderElement(name, value, params); + } + + + /** + * Parses parameters with the given parser. + * + * @param value the parameter list to parse + * @param parser the parser to use, or null for default + * + * @return array holding the parameters, never null + */ + public final static + NameValuePair[] parseParameters(final String value, + HeaderValueParser parser) + throws ParseException { + + if (value == null) { + throw new IllegalArgumentException + ("Value to parse may not be null"); + } + + if (parser == null) + parser = BasicHeaderValueParser.DEFAULT; + + CharArrayBuffer buffer = new CharArrayBuffer(value.length()); + buffer.append(value); + ParserCursor cursor = new ParserCursor(0, value.length()); + return parser.parseParameters(buffer, cursor); + } + + + + // non-javadoc, see interface HeaderValueParser + public NameValuePair[] parseParameters(final CharArrayBuffer buffer, + final ParserCursor cursor) { + + if (buffer == null) { + throw new IllegalArgumentException("Char array buffer may not be null"); + } + if (cursor == null) { + throw new IllegalArgumentException("Parser cursor may not be null"); + } + + int pos = cursor.getPos(); + int indexTo = cursor.getUpperBound(); + + while (pos < indexTo) { + char ch = buffer.charAt(pos); + if (HTTP.isWhitespace(ch)) { + pos++; + } else { + break; + } + } + cursor.updatePos(pos); + if (cursor.atEnd()) { + return new NameValuePair[] {}; + } + + List params = new ArrayList(); + while (!cursor.atEnd()) { + NameValuePair param = parseNameValuePair(buffer, cursor); + params.add(param); + char ch = buffer.charAt(cursor.getPos() - 1); + if (ch == ELEM_DELIMITER) { + break; + } + } + + return params.toArray(new NameValuePair[params.size()]); + } + + /** + * Parses a name-value-pair with the given parser. + * + * @param value the NVP to parse + * @param parser the parser to use, or null for default + * + * @return the parsed name-value pair + */ + public final static + NameValuePair parseNameValuePair(final String value, + HeaderValueParser parser) + throws ParseException { + + if (value == null) { + throw new IllegalArgumentException + ("Value to parse may not be null"); + } + + if (parser == null) + parser = BasicHeaderValueParser.DEFAULT; + + CharArrayBuffer buffer = new CharArrayBuffer(value.length()); + buffer.append(value); + ParserCursor cursor = new ParserCursor(0, value.length()); + return parser.parseNameValuePair(buffer, cursor); + } + + + // non-javadoc, see interface HeaderValueParser + public NameValuePair parseNameValuePair(final CharArrayBuffer buffer, + final ParserCursor cursor) { + return parseNameValuePair(buffer, cursor, ALL_DELIMITERS); + } + + private static boolean isOneOf(final char ch, final char[] chs) { + if (chs != null) { + for (int i = 0; i < chs.length; i++) { + if (ch == chs[i]) { + return true; + } + } + } + return false; + } + + public NameValuePair parseNameValuePair(final CharArrayBuffer buffer, + final ParserCursor cursor, + final char[] delimiters) { + + if (buffer == null) { + throw new IllegalArgumentException("Char array buffer may not be null"); + } + if (cursor == null) { + throw new IllegalArgumentException("Parser cursor may not be null"); + } + + boolean terminated = false; + + int pos = cursor.getPos(); + int indexFrom = cursor.getPos(); + int indexTo = cursor.getUpperBound(); + + // Find name + String name = null; + while (pos < indexTo) { + char ch = buffer.charAt(pos); + if (ch == '=') { + break; + } + if (isOneOf(ch, delimiters)) { + terminated = true; + break; + } + pos++; + } + + if (pos == indexTo) { + terminated = true; + name = buffer.substringTrimmed(indexFrom, indexTo); + } else { + name = buffer.substringTrimmed(indexFrom, pos); + pos++; + } + + if (terminated) { + cursor.updatePos(pos); + return createNameValuePair(name, null); + } + + // Find value + String value = null; + int i1 = pos; + + boolean qouted = false; + boolean escaped = false; + while (pos < indexTo) { + char ch = buffer.charAt(pos); + if (ch == '"' && !escaped) { + qouted = !qouted; + } + if (!qouted && !escaped && isOneOf(ch, delimiters)) { + terminated = true; + break; + } + if (escaped) { + escaped = false; + } else { + escaped = qouted && ch == '\\'; + } + pos++; + } + + int i2 = pos; + // Trim leading white spaces + while (i1 < i2 && (HTTP.isWhitespace(buffer.charAt(i1)))) { + i1++; + } + // Trim trailing white spaces + while ((i2 > i1) && (HTTP.isWhitespace(buffer.charAt(i2 - 1)))) { + i2--; + } + // Strip away quotes if necessary + if (((i2 - i1) >= 2) + && (buffer.charAt(i1) == '"') + && (buffer.charAt(i2 - 1) == '"')) { + i1++; + i2--; + } + value = buffer.substring(i1, i2); + if (terminated) { + pos++; + } + cursor.updatePos(pos); + return createNameValuePair(name, value); + } + + /** + * Creates a name-value pair. + * Called from {@link #parseNameValuePair}. + * + * @param name the name + * @param value the value, or null + * + * @return a name-value pair representing the arguments + */ + protected NameValuePair createNameValuePair(final String name, final String value) { + return new BasicNameValuePair(name, value); + } + +} + Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicHttpEntityEnclosingRequest.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicHttpEntityEnclosingRequest.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicHttpEntityEnclosingRequest.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,75 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.ProtocolVersion; +import org.apache.http.RequestLine; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.protocol.HTTP; + +/** + * Basic implementation of {@link HttpEntityEnclosingRequest}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicHttpEntityEnclosingRequest + extends BasicHttpRequest implements HttpEntityEnclosingRequest { + + private HttpEntity entity; + + public BasicHttpEntityEnclosingRequest(final String method, final String uri) { + super(method, uri); + } + + public BasicHttpEntityEnclosingRequest(final String method, final String uri, + final ProtocolVersion ver) { + super(method, uri, ver); + } + + public BasicHttpEntityEnclosingRequest(final RequestLine requestline) { + super(requestline); + } + + public HttpEntity getEntity() { + return this.entity; + } + + public void setEntity(final HttpEntity entity) { + this.entity = entity; + } + + public boolean expectContinue() { + Header expect = getFirstHeader(HTTP.EXPECT_DIRECTIVE); + return expect != null && HTTP.EXPECT_CONTINUE.equalsIgnoreCase(expect.getValue()); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicHttpRequest.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicHttpRequest.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicHttpRequest.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,137 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.HttpRequest; +import org.apache.http.ProtocolVersion; +import org.apache.http.RequestLine; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; + +/** + * Basic implementation of {@link HttpRequest}. + *

    + * The following parameters can be used to customize the behavior of this class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#PROTOCOL_VERSION}
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicHttpRequest extends AbstractHttpMessage implements HttpRequest { + + private final String method; + private final String uri; + + private RequestLine requestline; + + /** + * Creates an instance of this class using the given request method + * and URI. The HTTP protocol version will be obtained from the + * {@link HttpParams} instance associated with the object. + * The initialization will be deferred + * until {@link #getRequestLine()} is accessed for the first time. + * + * @param method request method. + * @param uri request URI. + */ + public BasicHttpRequest(final String method, final String uri) { + super(); + if (method == null) { + throw new IllegalArgumentException("Method name may not be null"); + } + if (uri == null) { + throw new IllegalArgumentException("Request URI may not be null"); + } + this.method = method; + this.uri = uri; + this.requestline = null; + } + + /** + * Creates an instance of this class using the given request method, URI + * and the HTTP protocol version. + * + * @param method request method. + * @param uri request URI. + * @param ver HTTP protocol version. + */ + public BasicHttpRequest(final String method, final String uri, final ProtocolVersion ver) { + this(new BasicRequestLine(method, uri, ver)); + } + + /** + * Creates an instance of this class using the given request line. + * + * @param requestline request line. + */ + public BasicHttpRequest(final RequestLine requestline) { + super(); + if (requestline == null) { + throw new IllegalArgumentException("Request line may not be null"); + } + this.requestline = requestline; + this.method = requestline.getMethod(); + this.uri = requestline.getUri(); + } + + /** + * Returns the HTTP protocol version to be used for this request. If an + * HTTP protocol version was not explicitly set at the construction time, + * this method will obtain it from the {@link HttpParams} instance + * associated with the object. + * + * @see #BasicHttpRequest(String, String) + */ + public ProtocolVersion getProtocolVersion() { + return getRequestLine().getProtocolVersion(); + } + + /** + * Returns the request line of this request. If an HTTP protocol version + * was not explicitly set at the construction time, this method will obtain + * it from the {@link HttpParams} instance associated with the object. + * + * @see #BasicHttpRequest(String, String) + */ + public RequestLine getRequestLine() { + if (this.requestline == null) { + ProtocolVersion ver = HttpProtocolParams.getVersion(getParams()); + this.requestline = new BasicRequestLine(this.method, this.uri, ver); + } + return this.requestline; + } + + @Override + public String toString() { + return this.method + " " + this.uri + " " + this.headergroup; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicHttpResponse.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicHttpResponse.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicHttpResponse.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,201 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.util.Locale; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolVersion; +import org.apache.http.StatusLine; +import org.apache.http.ReasonPhraseCatalog; +import org.apache.http.annotation.NotThreadSafe; + +/** + * Basic implementation of {@link HttpResponse}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicHttpResponse extends AbstractHttpMessage + implements HttpResponse { + + private StatusLine statusline; + private HttpEntity entity; + private ReasonPhraseCatalog reasonCatalog; + private Locale locale; + + + /** + * Creates a new response. + * This is the constructor to which all others map. + * + * @param statusline the status line + * @param catalog the reason phrase catalog, or + * null to disable automatic + * reason phrase lookup + * @param locale the locale for looking up reason phrases, or + * null for the system locale + */ + public BasicHttpResponse(final StatusLine statusline, + final ReasonPhraseCatalog catalog, + final Locale locale) { + super(); + if (statusline == null) { + throw new IllegalArgumentException("Status line may not be null."); + } + this.statusline = statusline; + this.reasonCatalog = catalog; + this.locale = (locale != null) ? locale : Locale.getDefault(); + } + + /** + * Creates a response from a status line. + * The response will not have a reason phrase catalog and + * use the system default locale. + * + * @param statusline the status line + */ + public BasicHttpResponse(final StatusLine statusline) { + this(statusline, null, null); + } + + /** + * Creates a response from elements of a status line. + * The response will not have a reason phrase catalog and + * use the system default locale. + * + * @param ver the protocol version of the response + * @param code the status code of the response + * @param reason the reason phrase to the status code, or + * null + */ + public BasicHttpResponse(final ProtocolVersion ver, + final int code, + final String reason) { + this(new BasicStatusLine(ver, code, reason), null, null); + } + + + // non-javadoc, see interface HttpMessage + public ProtocolVersion getProtocolVersion() { + return this.statusline.getProtocolVersion(); + } + + // non-javadoc, see interface HttpResponse + public StatusLine getStatusLine() { + return this.statusline; + } + + // non-javadoc, see interface HttpResponse + public HttpEntity getEntity() { + return this.entity; + } + + // non-javadoc, see interface HttpResponse + public Locale getLocale() { + return this.locale; + } + + // non-javadoc, see interface HttpResponse + public void setStatusLine(final StatusLine statusline) { + if (statusline == null) { + throw new IllegalArgumentException("Status line may not be null"); + } + this.statusline = statusline; + } + + // non-javadoc, see interface HttpResponse + public void setStatusLine(final ProtocolVersion ver, final int code) { + // arguments checked in BasicStatusLine constructor + this.statusline = new BasicStatusLine(ver, code, getReason(code)); + } + + // non-javadoc, see interface HttpResponse + public void setStatusLine(final ProtocolVersion ver, final int code, + final String reason) { + // arguments checked in BasicStatusLine constructor + this.statusline = new BasicStatusLine(ver, code, reason); + } + + // non-javadoc, see interface HttpResponse + public void setStatusCode(int code) { + // argument checked in BasicStatusLine constructor + ProtocolVersion ver = this.statusline.getProtocolVersion(); + this.statusline = new BasicStatusLine(ver, code, getReason(code)); + } + + // non-javadoc, see interface HttpResponse + public void setReasonPhrase(String reason) { + + if ((reason != null) && ((reason.indexOf('\n') >= 0) || + (reason.indexOf('\r') >= 0)) + ) { + throw new IllegalArgumentException("Line break in reason phrase."); + } + this.statusline = new BasicStatusLine(this.statusline.getProtocolVersion(), + this.statusline.getStatusCode(), + reason); + } + + // non-javadoc, see interface HttpResponse + public void setEntity(final HttpEntity entity) { + this.entity = entity; + } + + // non-javadoc, see interface HttpResponse + public void setLocale(Locale loc) { + if (loc == null) { + throw new IllegalArgumentException("Locale may not be null."); + } + this.locale = loc; + final int code = this.statusline.getStatusCode(); + this.statusline = new BasicStatusLine + (this.statusline.getProtocolVersion(), code, getReason(code)); + } + + /** + * Looks up a reason phrase. + * This method evaluates the currently set catalog and locale. + * It also handles a missing catalog. + * + * @param code the status code for which to look up the reason + * + * @return the reason phrase, or null if there is none + */ + protected String getReason(int code) { + return (this.reasonCatalog == null) ? + null : this.reasonCatalog.getReason(code, this.locale); + } + + @Override + public String toString() { + return this.statusline + " " + this.headergroup; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicLineFormatter.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicLineFormatter.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicLineFormatter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,332 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.ProtocolVersion; +import org.apache.http.RequestLine; +import org.apache.http.StatusLine; +import org.apache.http.Header; +import org.apache.http.FormattedHeader; +import org.apache.http.annotation.Immutable; +import org.apache.http.util.CharArrayBuffer; + +/** + * Interface for formatting elements of the HEAD section of an HTTP message. + * This is the complement to {@link LineParser}. + * There are individual methods for formatting a request line, a + * status line, or a header line. The formatting does not include the + * trailing line break sequence CR-LF. + * The formatted lines are returned in memory, the formatter does not depend + * on any specific IO mechanism. + * Instances of this interface are expected to be stateless and thread-safe. + * + * @since 4.0 + */ +@Immutable +public class BasicLineFormatter implements LineFormatter { + + /** + * A default instance of this class, for use as default or fallback. + * Note that {@link BasicLineFormatter} is not a singleton, there can + * be many instances of the class itself and of derived classes. + * The instance here provides non-customized, default behavior. + */ + public final static BasicLineFormatter DEFAULT = new BasicLineFormatter(); + + + + // public default constructor + + + /** + * Obtains a buffer for formatting. + * + * @param buffer a buffer already available, or null + * + * @return the cleared argument buffer if there is one, or + * a new empty buffer that can be used for formatting + */ + protected CharArrayBuffer initBuffer(CharArrayBuffer buffer) { + if (buffer != null) { + buffer.clear(); + } else { + buffer = new CharArrayBuffer(64); + } + return buffer; + } + + + /** + * Formats a protocol version. + * + * @param version the protocol version to format + * @param formatter the formatter to use, or + * null for the + * {@link #DEFAULT default} + * + * @return the formatted protocol version + */ + public final static + String formatProtocolVersion(final ProtocolVersion version, + LineFormatter formatter) { + if (formatter == null) + formatter = BasicLineFormatter.DEFAULT; + return formatter.appendProtocolVersion(null, version).toString(); + } + + + // non-javadoc, see interface LineFormatter + public CharArrayBuffer appendProtocolVersion(final CharArrayBuffer buffer, + final ProtocolVersion version) { + if (version == null) { + throw new IllegalArgumentException + ("Protocol version may not be null"); + } + + // can't use initBuffer, that would clear the argument! + CharArrayBuffer result = buffer; + final int len = estimateProtocolVersionLen(version); + if (result == null) { + result = new CharArrayBuffer(len); + } else { + result.ensureCapacity(len); + } + + result.append(version.getProtocol()); + result.append('/'); + result.append(Integer.toString(version.getMajor())); + result.append('.'); + result.append(Integer.toString(version.getMinor())); + + return result; + } + + + /** + * Guesses the length of a formatted protocol version. + * Needed to guess the length of a formatted request or status line. + * + * @param version the protocol version to format, or null + * + * @return the estimated length of the formatted protocol version, + * in characters + */ + protected int estimateProtocolVersionLen(final ProtocolVersion version) { + return version.getProtocol().length() + 4; // room for "HTTP/1.1" + } + + + /** + * Formats a request line. + * + * @param reqline the request line to format + * @param formatter the formatter to use, or + * null for the + * {@link #DEFAULT default} + * + * @return the formatted request line + */ + public final static String formatRequestLine(final RequestLine reqline, + LineFormatter formatter) { + if (formatter == null) + formatter = BasicLineFormatter.DEFAULT; + return formatter.formatRequestLine(null, reqline).toString(); + } + + + // non-javadoc, see interface LineFormatter + public CharArrayBuffer formatRequestLine(CharArrayBuffer buffer, + RequestLine reqline) { + if (reqline == null) { + throw new IllegalArgumentException + ("Request line may not be null"); + } + + CharArrayBuffer result = initBuffer(buffer); + doFormatRequestLine(result, reqline); + + return result; + } + + + /** + * Actually formats a request line. + * Called from {@link #formatRequestLine}. + * + * @param buffer the empty buffer into which to format, + * never null + * @param reqline the request line to format, never null + */ + protected void doFormatRequestLine(final CharArrayBuffer buffer, + final RequestLine reqline) { + final String method = reqline.getMethod(); + final String uri = reqline.getUri(); + + // room for "GET /index.html HTTP/1.1" + int len = method.length() + 1 + uri.length() + 1 + + estimateProtocolVersionLen(reqline.getProtocolVersion()); + buffer.ensureCapacity(len); + + buffer.append(method); + buffer.append(' '); + buffer.append(uri); + buffer.append(' '); + appendProtocolVersion(buffer, reqline.getProtocolVersion()); + } + + + + /** + * Formats a status line. + * + * @param statline the status line to format + * @param formatter the formatter to use, or + * null for the + * {@link #DEFAULT default} + * + * @return the formatted status line + */ + public final static String formatStatusLine(final StatusLine statline, + LineFormatter formatter) { + if (formatter == null) + formatter = BasicLineFormatter.DEFAULT; + return formatter.formatStatusLine(null, statline).toString(); + } + + + // non-javadoc, see interface LineFormatter + public CharArrayBuffer formatStatusLine(final CharArrayBuffer buffer, + final StatusLine statline) { + if (statline == null) { + throw new IllegalArgumentException + ("Status line may not be null"); + } + + CharArrayBuffer result = initBuffer(buffer); + doFormatStatusLine(result, statline); + + return result; + } + + + /** + * Actually formats a status line. + * Called from {@link #formatStatusLine}. + * + * @param buffer the empty buffer into which to format, + * never null + * @param statline the status line to format, never null + */ + protected void doFormatStatusLine(final CharArrayBuffer buffer, + final StatusLine statline) { + + int len = estimateProtocolVersionLen(statline.getProtocolVersion()) + + 1 + 3 + 1; // room for "HTTP/1.1 200 " + final String reason = statline.getReasonPhrase(); + if (reason != null) { + len += reason.length(); + } + buffer.ensureCapacity(len); + + appendProtocolVersion(buffer, statline.getProtocolVersion()); + buffer.append(' '); + buffer.append(Integer.toString(statline.getStatusCode())); + buffer.append(' '); // keep whitespace even if reason phrase is empty + if (reason != null) { + buffer.append(reason); + } + } + + + /** + * Formats a header. + * + * @param header the header to format + * @param formatter the formatter to use, or + * null for the + * {@link #DEFAULT default} + * + * @return the formatted header + */ + public final static String formatHeader(final Header header, + LineFormatter formatter) { + if (formatter == null) + formatter = BasicLineFormatter.DEFAULT; + return formatter.formatHeader(null, header).toString(); + } + + + // non-javadoc, see interface LineFormatter + public CharArrayBuffer formatHeader(CharArrayBuffer buffer, + Header header) { + if (header == null) { + throw new IllegalArgumentException + ("Header may not be null"); + } + CharArrayBuffer result = null; + + if (header instanceof FormattedHeader) { + // If the header is backed by a buffer, re-use the buffer + result = ((FormattedHeader)header).getBuffer(); + } else { + result = initBuffer(buffer); + doFormatHeader(result, header); + } + return result; + + } // formatHeader + + + /** + * Actually formats a header. + * Called from {@link #formatHeader}. + * + * @param buffer the empty buffer into which to format, + * never null + * @param header the header to format, never null + */ + protected void doFormatHeader(final CharArrayBuffer buffer, + final Header header) { + final String name = header.getName(); + final String value = header.getValue(); + + int len = name.length() + 2; + if (value != null) { + len += value.length(); + } + buffer.ensureCapacity(len); + + buffer.append(name); + buffer.append(": "); + if (value != null) { + buffer.append(value); + } + } + + +} // class BasicLineFormatter Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicLineParser.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicLineParser.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicLineParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,504 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.ParseException; +import org.apache.http.RequestLine; +import org.apache.http.StatusLine; +import org.apache.http.Header; +import org.apache.http.annotation.Immutable; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.CharArrayBuffer; + +/** + * Basic parser for lines in the head section of an HTTP message. + * There are individual methods for parsing a request line, a + * status line, or a header line. + * The lines to parse are passed in memory, the parser does not depend + * on any specific IO mechanism. + * Instances of this class are stateless and thread-safe. + * Derived classes MUST maintain these properties. + * + *

    + * Note: This class was created by refactoring parsing code located in + * various other classes. The author tags from those other classes have + * been replicated here, although the association with the parsing code + * taken from there has not been traced. + *

    + * + * @since 4.0 + */ +@Immutable +public class BasicLineParser implements LineParser { + + /** + * A default instance of this class, for use as default or fallback. + * Note that {@link BasicLineParser} is not a singleton, there can + * be many instances of the class itself and of derived classes. + * The instance here provides non-customized, default behavior. + */ + public final static BasicLineParser DEFAULT = new BasicLineParser(); + + + /** + * A version of the protocol to parse. + * The version is typically not relevant, but the protocol name. + */ + protected final ProtocolVersion protocol; + + + /** + * Creates a new line parser for the given HTTP-like protocol. + * + * @param proto a version of the protocol to parse, or + * null for HTTP. The actual version + * is not relevant, only the protocol name. + */ + public BasicLineParser(ProtocolVersion proto) { + if (proto == null) { + proto = HttpVersion.HTTP_1_1; + } + this.protocol = proto; + } + + + /** + * Creates a new line parser for HTTP. + */ + public BasicLineParser() { + this(null); + } + + + public final static + ProtocolVersion parseProtocolVersion(String value, + LineParser parser) + throws ParseException { + + if (value == null) { + throw new IllegalArgumentException + ("Value to parse may not be null."); + } + + if (parser == null) + parser = BasicLineParser.DEFAULT; + + CharArrayBuffer buffer = new CharArrayBuffer(value.length()); + buffer.append(value); + ParserCursor cursor = new ParserCursor(0, value.length()); + return parser.parseProtocolVersion(buffer, cursor); + } + + + // non-javadoc, see interface LineParser + public ProtocolVersion parseProtocolVersion(final CharArrayBuffer buffer, + final ParserCursor cursor) + throws ParseException { + + if (buffer == null) { + throw new IllegalArgumentException("Char array buffer may not be null"); + } + if (cursor == null) { + throw new IllegalArgumentException("Parser cursor may not be null"); + } + + final String protoname = this.protocol.getProtocol(); + final int protolength = protoname.length(); + + int indexFrom = cursor.getPos(); + int indexTo = cursor.getUpperBound(); + + skipWhitespace(buffer, cursor); + + int i = cursor.getPos(); + + // long enough for "HTTP/1.1"? + if (i + protolength + 4 > indexTo) { + throw new ParseException + ("Not a valid protocol version: " + + buffer.substring(indexFrom, indexTo)); + } + + // check the protocol name and slash + boolean ok = true; + for (int j=0; ok && (j buffer.length()) + return false; + + + // just check protocol name and slash, no need to analyse the version + boolean ok = true; + for (int j=0; ok && (j. + * + */ + +package org.apache.http.message; + +import java.util.List; +import java.util.NoSuchElementException; + +import org.apache.http.Header; +import org.apache.http.HeaderIterator; +import org.apache.http.annotation.NotThreadSafe; + +/** + * Implementation of a {@link HeaderIterator} based on a {@link List}. + * For use by {@link HeaderGroup}. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicListHeaderIterator implements HeaderIterator { + + /** + * A list of headers to iterate over. + * Not all elements of this array are necessarily part of the iteration. + */ + protected final List
    allHeaders; + + + /** + * The position of the next header in {@link #allHeaders allHeaders}. + * Negative if the iteration is over. + */ + protected int currentIndex; + + + /** + * The position of the last returned header. + * Negative if none has been returned so far. + */ + protected int lastIndex; + + + /** + * The header name to filter by. + * null to iterate over all headers in the array. + */ + protected String headerName; + + + + /** + * Creates a new header iterator. + * + * @param headers a list of headers over which to iterate + * @param name the name of the headers over which to iterate, or + * null for any + */ + public BasicListHeaderIterator(List
    headers, String name) { + if (headers == null) { + throw new IllegalArgumentException + ("Header list must not be null."); + } + + this.allHeaders = headers; + this.headerName = name; + this.currentIndex = findNext(-1); + this.lastIndex = -1; + } + + + /** + * Determines the index of the next header. + * + * @param from one less than the index to consider first, + * -1 to search for the first header + * + * @return the index of the next header that matches the filter name, + * or negative if there are no more headers + */ + protected int findNext(int from) { + if (from < -1) + return -1; + + final int to = this.allHeaders.size()-1; + boolean found = false; + while (!found && (from < to)) { + from++; + found = filterHeader(from); + } + return found ? from : -1; + } + + + /** + * Checks whether a header is part of the iteration. + * + * @param index the index of the header to check + * + * @return true if the header should be part of the + * iteration, false to skip + */ + protected boolean filterHeader(int index) { + if (this.headerName == null) + return true; + + // non-header elements, including null, will trigger exceptions + final String name = (this.allHeaders.get(index)).getName(); + + return this.headerName.equalsIgnoreCase(name); + } + + + // non-javadoc, see interface HeaderIterator + public boolean hasNext() { + return (this.currentIndex >= 0); + } + + + /** + * Obtains the next header from this iteration. + * + * @return the next header in this iteration + * + * @throws NoSuchElementException if there are no more headers + */ + public Header nextHeader() + throws NoSuchElementException { + + final int current = this.currentIndex; + if (current < 0) { + throw new NoSuchElementException("Iteration already finished."); + } + + this.lastIndex = current; + this.currentIndex = findNext(current); + + return this.allHeaders.get(current); + } + + + /** + * Returns the next header. + * Same as {@link #nextHeader nextHeader}, but not type-safe. + * + * @return the next header in this iteration + * + * @throws NoSuchElementException if there are no more headers + */ + public final Object next() + throws NoSuchElementException { + return nextHeader(); + } + + + /** + * Removes the header that was returned last. + */ + public void remove() + throws UnsupportedOperationException { + + if (this.lastIndex < 0) { + throw new IllegalStateException("No header to remove."); + } + this.allHeaders.remove(this.lastIndex); + this.lastIndex = -1; + this.currentIndex--; // adjust for the removed element + } +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicNameValuePair.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicNameValuePair.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicNameValuePair.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,113 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.io.Serializable; + +import org.apache.http.NameValuePair; +import org.apache.http.annotation.Immutable; +import org.apache.http.util.LangUtils; + +/** + * Basic implementation of {@link NameValuePair}. + * + * @since 4.0 + */ +@Immutable +public class BasicNameValuePair implements NameValuePair, Cloneable, Serializable { + + private static final long serialVersionUID = -6437800749411518984L; + + private final String name; + private final String value; + + /** + * Default Constructor taking a name and a value. The value may be null. + * + * @param name The name. + * @param value The value. + */ + public BasicNameValuePair(final String name, final String value) { + super(); + if (name == null) { + throw new IllegalArgumentException("Name may not be null"); + } + this.name = name; + this.value = value; + } + + public String getName() { + return this.name; + } + + public String getValue() { + return this.value; + } + + @Override + public String toString() { + // don't call complex default formatting for a simple toString + + if (this.value == null) { + return name; + } else { + int len = this.name.length() + 1 + this.value.length(); + StringBuilder buffer = new StringBuilder(len); + buffer.append(this.name); + buffer.append("="); + buffer.append(this.value); + return buffer.toString(); + } + } + + @Override + public boolean equals(final Object object) { + if (this == object) return true; + if (object instanceof NameValuePair) { + BasicNameValuePair that = (BasicNameValuePair) object; + return this.name.equals(that.name) + && LangUtils.equals(this.value, that.value); + } else { + return false; + } + } + + @Override + public int hashCode() { + int hash = LangUtils.HASH_SEED; + hash = LangUtils.hashCode(hash, this.name); + hash = LangUtils.hashCode(hash, this.value); + return hash; + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicRequestLine.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicRequestLine.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicRequestLine.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,95 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.io.Serializable; + +import org.apache.http.ProtocolVersion; +import org.apache.http.RequestLine; +import org.apache.http.annotation.Immutable; + +/** + * Basic implementation of {@link RequestLine}. + * + * @since 4.0 + */ +@Immutable +public class BasicRequestLine implements RequestLine, Cloneable, Serializable { + + private static final long serialVersionUID = 2810581718468737193L; + + private final ProtocolVersion protoversion; + private final String method; + private final String uri; + + public BasicRequestLine(final String method, + final String uri, + final ProtocolVersion version) { + super(); + if (method == null) { + throw new IllegalArgumentException + ("Method must not be null."); + } + if (uri == null) { + throw new IllegalArgumentException + ("URI must not be null."); + } + if (version == null) { + throw new IllegalArgumentException + ("Protocol version must not be null."); + } + this.method = method; + this.uri = uri; + this.protoversion = version; + } + + public String getMethod() { + return this.method; + } + + public ProtocolVersion getProtocolVersion() { + return this.protoversion; + } + + public String getUri() { + return this.uri; + } + + @Override + public String toString() { + // no need for non-default formatting in toString() + return BasicLineFormatter.DEFAULT + .formatRequestLine(null, this).toString(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicStatusLine.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicStatusLine.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicStatusLine.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,108 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.io.Serializable; + +import org.apache.http.ProtocolVersion; +import org.apache.http.StatusLine; +import org.apache.http.annotation.Immutable; + +/** + * Basic implementation of {@link StatusLine} + * + * @since 4.0 + */ +@Immutable +public class BasicStatusLine implements StatusLine, Cloneable, Serializable { + + private static final long serialVersionUID = -2443303766890459269L; + + // ----------------------------------------------------- Instance Variables + + /** The protocol version. */ + private final ProtocolVersion protoVersion; + + /** The status code. */ + private final int statusCode; + + /** The reason phrase. */ + private final String reasonPhrase; + + // ----------------------------------------------------------- Constructors + /** + * Creates a new status line with the given version, status, and reason. + * + * @param version the protocol version of the response + * @param statusCode the status code of the response + * @param reasonPhrase the reason phrase to the status code, or + * null + */ + public BasicStatusLine(final ProtocolVersion version, int statusCode, + final String reasonPhrase) { + super(); + if (version == null) { + throw new IllegalArgumentException + ("Protocol version may not be null."); + } + if (statusCode < 0) { + throw new IllegalArgumentException + ("Status code may not be negative."); + } + this.protoVersion = version; + this.statusCode = statusCode; + this.reasonPhrase = reasonPhrase; + } + + // --------------------------------------------------------- Public Methods + + public int getStatusCode() { + return this.statusCode; + } + + public ProtocolVersion getProtocolVersion() { + return this.protoVersion; + } + + public String getReasonPhrase() { + return this.reasonPhrase; + } + + @Override + public String toString() { + // no need for non-default formatting in toString() + return BasicLineFormatter.DEFAULT + .formatStatusLine(null, this).toString(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/BasicTokenIterator.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BasicTokenIterator.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BasicTokenIterator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,427 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.util.NoSuchElementException; + +import org.apache.http.HeaderIterator; +import org.apache.http.ParseException; +import org.apache.http.TokenIterator; +import org.apache.http.annotation.NotThreadSafe; + +/** + * Basic implementation of a {@link TokenIterator}. + * This implementation parses #token sequences as + * defined by RFC 2616, section 2. + * It extends that definition somewhat beyond US-ASCII. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicTokenIterator implements TokenIterator { + + /** The HTTP separator characters. Defined in RFC 2616, section 2.2. */ + // the order of the characters here is adjusted to put the + // most likely candidates at the beginning of the collection + public final static String HTTP_SEPARATORS = " ,;=()<>@:\\\"/[]?{}\t"; + + + /** The iterator from which to obtain the next header. */ + protected final HeaderIterator headerIt; + + /** + * The value of the current header. + * This is the header value that includes {@link #currentToken}. + * Undefined if the iteration is over. + */ + protected String currentHeader; + + /** + * The token to be returned by the next call to {@link #currentToken}. + * null if the iteration is over. + */ + protected String currentToken; + + /** + * The position after {@link #currentToken} in {@link #currentHeader}. + * Undefined if the iteration is over. + */ + protected int searchPos; + + + /** + * Creates a new instance of {@link BasicTokenIterator}. + * + * @param headerIterator the iterator for the headers to tokenize + */ + public BasicTokenIterator(final HeaderIterator headerIterator) { + if (headerIterator == null) { + throw new IllegalArgumentException + ("Header iterator must not be null."); + } + + this.headerIt = headerIterator; + this.searchPos = findNext(-1); + } + + + // non-javadoc, see interface TokenIterator + public boolean hasNext() { + return (this.currentToken != null); + } + + + /** + * Obtains the next token from this iteration. + * + * @return the next token in this iteration + * + * @throws NoSuchElementException if the iteration is already over + * @throws ParseException if an invalid header value is encountered + */ + public String nextToken() + throws NoSuchElementException, ParseException { + + if (this.currentToken == null) { + throw new NoSuchElementException("Iteration already finished."); + } + + final String result = this.currentToken; + // updates currentToken, may trigger ParseException: + this.searchPos = findNext(this.searchPos); + + return result; + } + + + /** + * Returns the next token. + * Same as {@link #nextToken}, but with generic return type. + * + * @return the next token in this iteration + * + * @throws NoSuchElementException if there are no more tokens + * @throws ParseException if an invalid header value is encountered + */ + public final Object next() + throws NoSuchElementException, ParseException { + return nextToken(); + } + + + /** + * Removing tokens is not supported. + * + * @throws UnsupportedOperationException always + */ + public final void remove() + throws UnsupportedOperationException { + + throw new UnsupportedOperationException + ("Removing tokens is not supported."); + } + + + /** + * Determines the next token. + * If found, the token is stored in {@link #currentToken}. + * The return value indicates the position after the token + * in {@link #currentHeader}. If necessary, the next header + * will be obtained from {@link #headerIt}. + * If not found, {@link #currentToken} is set to null. + * + * @param from the position in the current header at which to + * start the search, -1 to search in the first header + * + * @return the position after the found token in the current header, or + * negative if there was no next token + * + * @throws ParseException if an invalid header value is encountered + */ + protected int findNext(int from) + throws ParseException { + + if (from < 0) { + // called from the constructor, initialize the first header + if (!this.headerIt.hasNext()) { + return -1; + } + this.currentHeader = this.headerIt.nextHeader().getValue(); + from = 0; + } else { + // called after a token, make sure there is a separator + from = findTokenSeparator(from); + } + + int start = findTokenStart(from); + if (start < 0) { + this.currentToken = null; + return -1; // nothing found + } + + int end = findTokenEnd(start); + this.currentToken = createToken(this.currentHeader, start, end); + return end; + } + + + /** + * Creates a new token to be returned. + * Called from {@link #findNext findNext} after the token is identified. + * The default implementation simply calls + * {@link java.lang.String#substring String.substring}. + *
    + * If header values are significantly longer than tokens, and some + * tokens are permanently referenced by the application, there can + * be problems with garbage collection. A substring will hold a + * reference to the full characters of the original string and + * therefore occupies more memory than might be expected. + * To avoid this, override this method and create a new string + * instead of a substring. + * + * @param value the full header value from which to create a token + * @param start the index of the first token character + * @param end the index after the last token character + * + * @return a string representing the token identified by the arguments + */ + protected String createToken(String value, int start, int end) { + return value.substring(start, end); + } + + + /** + * Determines the starting position of the next token. + * This method will iterate over headers if necessary. + * + * @param from the position in the current header at which to + * start the search + * + * @return the position of the token start in the current header, + * negative if no token start could be found + */ + protected int findTokenStart(int from) { + if (from < 0) { + throw new IllegalArgumentException + ("Search position must not be negative: " + from); + } + + boolean found = false; + while (!found && (this.currentHeader != null)) { + + final int to = this.currentHeader.length(); + while (!found && (from < to)) { + + final char ch = this.currentHeader.charAt(from); + if (isTokenSeparator(ch) || isWhitespace(ch)) { + // whitspace and token separators are skipped + from++; + } else if (isTokenChar(this.currentHeader.charAt(from))) { + // found the start of a token + found = true; + } else { + throw new ParseException + ("Invalid character before token (pos " + from + + "): " + this.currentHeader); + } + } + if (!found) { + if (this.headerIt.hasNext()) { + this.currentHeader = this.headerIt.nextHeader().getValue(); + from = 0; + } else { + this.currentHeader = null; + } + } + } // while headers + + return found ? from : -1; + } + + + /** + * Determines the position of the next token separator. + * Because of multi-header joining rules, the end of a + * header value is a token separator. This method does + * therefore not need to iterate over headers. + * + * @param from the position in the current header at which to + * start the search + * + * @return the position of a token separator in the current header, + * or at the end + * + * @throws ParseException + * if a new token is found before a token separator. + * RFC 2616, section 2.1 explicitly requires a comma between + * tokens for #. + */ + protected int findTokenSeparator(int from) { + if (from < 0) { + throw new IllegalArgumentException + ("Search position must not be negative: " + from); + } + + boolean found = false; + final int to = this.currentHeader.length(); + while (!found && (from < to)) { + final char ch = this.currentHeader.charAt(from); + if (isTokenSeparator(ch)) { + found = true; + } else if (isWhitespace(ch)) { + from++; + } else if (isTokenChar(ch)) { + throw new ParseException + ("Tokens without separator (pos " + from + + "): " + this.currentHeader); + } else { + throw new ParseException + ("Invalid character after token (pos " + from + + "): " + this.currentHeader); + } + } + + return from; + } + + + /** + * Determines the ending position of the current token. + * This method will not leave the current header value, + * since the end of the header value is a token boundary. + * + * @param from the position of the first character of the token + * + * @return the position after the last character of the token. + * The behavior is undefined if from does not + * point to a token character in the current header value. + */ + protected int findTokenEnd(int from) { + if (from < 0) { + throw new IllegalArgumentException + ("Token start position must not be negative: " + from); + } + + final int to = this.currentHeader.length(); + int end = from+1; + while ((end < to) && isTokenChar(this.currentHeader.charAt(end))) { + end++; + } + + return end; + } + + + /** + * Checks whether a character is a token separator. + * RFC 2616, section 2.1 defines comma as the separator for + * #token sequences. The end of a header value will + * also separate tokens, but that is not a character check. + * + * @param ch the character to check + * + * @return true if the character is a token separator, + * false otherwise + */ + protected boolean isTokenSeparator(char ch) { + return (ch == ','); + } + + + /** + * Checks whether a character is a whitespace character. + * RFC 2616, section 2.2 defines space and horizontal tab as whitespace. + * The optional preceeding line break is irrelevant, since header + * continuation is handled transparently when parsing messages. + * + * @param ch the character to check + * + * @return true if the character is whitespace, + * false otherwise + */ + protected boolean isWhitespace(char ch) { + + // we do not use Character.isWhitspace(ch) here, since that allows + // many control characters which are not whitespace as per RFC 2616 + return ((ch == '\t') || Character.isSpaceChar(ch)); + } + + + /** + * Checks whether a character is a valid token character. + * Whitespace, control characters, and HTTP separators are not + * valid token characters. The HTTP specification (RFC 2616, section 2.2) + * defines tokens only for the US-ASCII character set, this + * method extends the definition to other character sets. + * + * @param ch the character to check + * + * @return true if the character is a valid token start, + * false otherwise + */ + protected boolean isTokenChar(char ch) { + + // common sense extension of ALPHA + DIGIT + if (Character.isLetterOrDigit(ch)) + return true; + + // common sense extension of CTL + if (Character.isISOControl(ch)) + return false; + + // no common sense extension for this + if (isHttpSeparator(ch)) + return false; + + // RFC 2616, section 2.2 defines a token character as + // "any CHAR except CTLs or separators". The controls + // and separators are included in the checks above. + // This will yield unexpected results for Unicode format characters. + // If that is a problem, overwrite isHttpSeparator(char) to filter + // out the false positives. + return true; + } + + + /** + * Checks whether a character is an HTTP separator. + * The implementation in this class checks only for the HTTP separators + * defined in RFC 2616, section 2.2. If you need to detect other + * separators beyond the US-ASCII character set, override this method. + * + * @param ch the character to check + * + * @return true if the character is an HTTP separator + */ + protected boolean isHttpSeparator(char ch) { + return (HTTP_SEPARATORS.indexOf(ch) >= 0); + } + + +} // class BasicTokenIterator + Index: 3rdParty_sources/httpcore/org/apache/http/message/BufferedHeader.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/BufferedHeader.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/BufferedHeader.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,133 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.io.Serializable; + +import org.apache.http.FormattedHeader; +import org.apache.http.HeaderElement; +import org.apache.http.ParseException; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.util.CharArrayBuffer; + +/** + * This class represents a raw HTTP header whose content is parsed 'on demand' + * only when the header value needs to be consumed. + * + * @since 4.0 + */ +@NotThreadSafe +public class BufferedHeader implements FormattedHeader, Cloneable, Serializable { + + private static final long serialVersionUID = -2768352615787625448L; + + /** + * Header name. + */ + private final String name; + + /** + * The buffer containing the entire header line. + */ + private final CharArrayBuffer buffer; + + /** + * The beginning of the header value in the buffer + */ + private final int valuePos; + + + /** + * Creates a new header from a buffer. + * The name of the header will be parsed immediately, + * the value only if it is accessed. + * + * @param buffer the buffer containing the header to represent + * + * @throws ParseException in case of a parse error + */ + public BufferedHeader(final CharArrayBuffer buffer) + throws ParseException { + + super(); + if (buffer == null) { + throw new IllegalArgumentException + ("Char array buffer may not be null"); + } + int colon = buffer.indexOf(':'); + if (colon == -1) { + throw new ParseException + ("Invalid header: " + buffer.toString()); + } + String s = buffer.substringTrimmed(0, colon); + if (s.length() == 0) { + throw new ParseException + ("Invalid header: " + buffer.toString()); + } + this.buffer = buffer; + this.name = s; + this.valuePos = colon + 1; + } + + + public String getName() { + return this.name; + } + + public String getValue() { + return this.buffer.substringTrimmed(this.valuePos, this.buffer.length()); + } + + public HeaderElement[] getElements() throws ParseException { + ParserCursor cursor = new ParserCursor(0, this.buffer.length()); + cursor.updatePos(this.valuePos); + return BasicHeaderValueParser.DEFAULT + .parseElements(this.buffer, cursor); + } + + public int getValuePos() { + return this.valuePos; + } + + public CharArrayBuffer getBuffer() { + return this.buffer; + } + + @Override + public String toString() { + return this.buffer.toString(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + // buffer is considered immutable + // no need to make a copy of it + return super.clone(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/HeaderGroup.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/HeaderGroup.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/HeaderGroup.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,304 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.apache.http.Header; +import org.apache.http.HeaderIterator; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.util.CharArrayBuffer; + +/** + * A class for combining a set of headers. + * This class allows for multiple headers with the same name and + * keeps track of the order in which headers were added. + * + * + * @since 4.0 + */ +@NotThreadSafe +public class HeaderGroup implements Cloneable, Serializable { + + private static final long serialVersionUID = 2608834160639271617L; + + /** The list of headers for this group, in the order in which they were added */ + private final List
    headers; + + /** + * Constructor for HeaderGroup. + */ + public HeaderGroup() { + this.headers = new ArrayList
    (16); + } + + /** + * Removes any contained headers. + */ + public void clear() { + headers.clear(); + } + + /** + * Adds the given header to the group. The order in which this header was + * added is preserved. + * + * @param header the header to add + */ + public void addHeader(Header header) { + if (header == null) { + return; + } + headers.add(header); + } + + /** + * Removes the given header. + * + * @param header the header to remove + */ + public void removeHeader(Header header) { + if (header == null) { + return; + } + headers.remove(header); + } + + /** + * Replaces the first occurence of the header with the same name. If no header with + * the same name is found the given header is added to the end of the list. + * + * @param header the new header that should replace the first header with the same + * name if present in the list. + */ + public void updateHeader(Header header) { + if (header == null) { + return; + } + for (int i = 0; i < this.headers.size(); i++) { + Header current = this.headers.get(i); + if (current.getName().equalsIgnoreCase(header.getName())) { + this.headers.set(i, header); + return; + } + } + this.headers.add(header); + } + + /** + * Sets all of the headers contained within this group overriding any + * existing headers. The headers are added in the order in which they appear + * in the array. + * + * @param headers the headers to set + */ + public void setHeaders(Header[] headers) { + clear(); + if (headers == null) { + return; + } + for (int i = 0; i < headers.length; i++) { + this.headers.add(headers[i]); + } + } + + /** + * Gets a header representing all of the header values with the given name. + * If more that one header with the given name exists the values will be + * combined with a "," as per RFC 2616. + * + *

    Header name comparison is case insensitive. + * + * @param name the name of the header(s) to get + * @return a header with a condensed value or null if no + * headers by the given name are present + */ + public Header getCondensedHeader(String name) { + Header[] headers = getHeaders(name); + + if (headers.length == 0) { + return null; + } else if (headers.length == 1) { + return headers[0]; + } else { + CharArrayBuffer valueBuffer = new CharArrayBuffer(128); + valueBuffer.append(headers[0].getValue()); + for (int i = 1; i < headers.length; i++) { + valueBuffer.append(", "); + valueBuffer.append(headers[i].getValue()); + } + + return new BasicHeader(name.toLowerCase(Locale.ENGLISH), valueBuffer.toString()); + } + } + + /** + * Gets all of the headers with the given name. The returned array + * maintains the relative order in which the headers were added. + * + *

    Header name comparison is case insensitive. + * + * @param name the name of the header(s) to get + * + * @return an array of length >= 0 + */ + public Header[] getHeaders(String name) { + List

    headersFound = new ArrayList
    (); + + for (int i = 0; i < headers.size(); i++) { + Header header = headers.get(i); + if (header.getName().equalsIgnoreCase(name)) { + headersFound.add(header); + } + } + + return headersFound.toArray(new Header[headersFound.size()]); + } + + /** + * Gets the first header with the given name. + * + *

    Header name comparison is case insensitive. + * + * @param name the name of the header to get + * @return the first header or null + */ + public Header getFirstHeader(String name) { + for (int i = 0; i < headers.size(); i++) { + Header header = headers.get(i); + if (header.getName().equalsIgnoreCase(name)) { + return header; + } + } + return null; + } + + /** + * Gets the last header with the given name. + * + *

    Header name comparison is case insensitive. + * + * @param name the name of the header to get + * @return the last header or null + */ + public Header getLastHeader(String name) { + // start at the end of the list and work backwards + for (int i = headers.size() - 1; i >= 0; i--) { + Header header = headers.get(i); + if (header.getName().equalsIgnoreCase(name)) { + return header; + } + } + + return null; + } + + /** + * Gets all of the headers contained within this group. + * + * @return an array of length >= 0 + */ + public Header[] getAllHeaders() { + return headers.toArray(new Header[headers.size()]); + } + + /** + * Tests if headers with the given name are contained within this group. + * + *

    Header name comparison is case insensitive. + * + * @param name the header name to test for + * @return true if at least one header with the name is + * contained, false otherwise + */ + public boolean containsHeader(String name) { + for (int i = 0; i < headers.size(); i++) { + Header header = headers.get(i); + if (header.getName().equalsIgnoreCase(name)) { + return true; + } + } + + return false; + } + + /** + * Returns an iterator over this group of headers. + * + * @return iterator over this group of headers. + * + * @since 4.0 + */ + public HeaderIterator iterator() { + return new BasicListHeaderIterator(this.headers, null); + } + + /** + * Returns an iterator over the headers with a given name in this group. + * + * @param name the name of the headers over which to iterate, or + * null for all headers + * + * @return iterator over some headers in this group. + * + * @since 4.0 + */ + public HeaderIterator iterator(final String name) { + return new BasicListHeaderIterator(this.headers, name); + } + + /** + * Returns a copy of this object + * + * @return copy of this object + * + * @since 4.0 + */ + public HeaderGroup copy() { + HeaderGroup clone = new HeaderGroup(); + clone.headers.addAll(this.headers); + return clone; + } + + @Override + public Object clone() throws CloneNotSupportedException { + HeaderGroup clone = (HeaderGroup) super.clone(); + clone.headers.clear(); + clone.headers.addAll(this.headers); + return clone; + } + + @Override + public String toString() { + return this.headers.toString(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/HeaderValueFormatter.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/HeaderValueFormatter.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/HeaderValueFormatter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,122 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.HeaderElement; +import org.apache.http.NameValuePair; +import org.apache.http.util.CharArrayBuffer; + +/** + * Interface for formatting elements of a header value. + * This is the complement to {@link HeaderValueParser}. + * Instances of this interface are expected to be stateless and thread-safe. + * + *

    + * All formatting methods accept an optional buffer argument. + * If a buffer is passed in, the formatted element will be appended + * and the modified buffer is returned. If no buffer is passed in, + * a new buffer will be created and filled with the formatted element. + * In both cases, the caller is allowed to modify the returned buffer. + *

    + * + * @since 4.0 + */ +public interface HeaderValueFormatter { + + /** + * Formats an array of header elements. + * + * @param buffer the buffer to append to, or + * null to create a new buffer + * @param elems the header elements to format + * @param quote true to always format with quoted values, + * false to use quotes only when necessary + * + * @return a buffer with the formatted header elements. + * If the buffer argument was not null, + * that buffer will be used and returned. + */ + CharArrayBuffer formatElements(CharArrayBuffer buffer, + HeaderElement[] elems, + boolean quote); + + /** + * Formats one header element. + * + * @param buffer the buffer to append to, or + * null to create a new buffer + * @param elem the header element to format + * @param quote true to always format with quoted values, + * false to use quotes only when necessary + * + * @return a buffer with the formatted header element. + * If the buffer argument was not null, + * that buffer will be used and returned. + */ + CharArrayBuffer formatHeaderElement(CharArrayBuffer buffer, + HeaderElement elem, + boolean quote); + + /** + * Formats the parameters of a header element. + * That's a list of name-value pairs, to be separated by semicolons. + * This method will not generate a leading semicolon. + * + * @param buffer the buffer to append to, or + * null to create a new buffer + * @param nvps the parameters (name-value pairs) to format + * @param quote true to always format with quoted values, + * false to use quotes only when necessary + * + * @return a buffer with the formatted parameters. + * If the buffer argument was not null, + * that buffer will be used and returned. + */ + CharArrayBuffer formatParameters(CharArrayBuffer buffer, + NameValuePair[] nvps, + boolean quote); + + /** + * Formats one name-value pair, where the value is optional. + * + * @param buffer the buffer to append to, or + * null to create a new buffer + * @param nvp the name-value pair to format + * @param quote true to always format with a quoted value, + * false to use quotes only when necessary + * + * @return a buffer with the formatted name-value pair. + * If the buffer argument was not null, + * that buffer will be used and returned. + */ + CharArrayBuffer formatNameValuePair(CharArrayBuffer buffer, + NameValuePair nvp, + boolean quote); + +} + Index: 3rdParty_sources/httpcore/org/apache/http/message/HeaderValueParser.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/HeaderValueParser.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/HeaderValueParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,134 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.HeaderElement; +import org.apache.http.NameValuePair; +import org.apache.http.ParseException; +import org.apache.http.util.CharArrayBuffer; + +/** + * Interface for parsing header values into elements. + * Instances of this interface are expected to be stateless and thread-safe. + * + * @since 4.0 + */ +public interface HeaderValueParser { + + /** + * Parses a header value into elements. + * Parse errors are indicated as RuntimeException. + *

    + * Some HTTP headers (such as the set-cookie header) have values that + * can be decomposed into multiple elements. In order to be processed + * by this parser, such headers must be in the following form: + *

    + *
    +     * header  = [ element ] *( "," [ element ] )
    +     * element = name [ "=" [ value ] ] *( ";" [ param ] )
    +     * param   = name [ "=" [ value ] ]
    +     *
    +     * name    = token
    +     * value   = ( token | quoted-string )
    +     *
    +     * token         = 1*<any char except "=", ",", ";", <"> and
    +     *                       white space>
    +     * quoted-string = <"> *( text | quoted-char ) <">
    +     * text          = any char except <">
    +     * quoted-char   = "\" char
    +     * 
    + *

    + * Any amount of white space is allowed between any part of the + * header, element or param and is ignored. A missing value in any + * element or param will be stored as the empty {@link String}; + * if the "=" is also missing null will be stored instead. + *

    + * + * @param buffer buffer holding the header value to parse + * @param cursor the parser cursor containing the current position and + * the bounds within the buffer for the parsing operation + * + * @return an array holding all elements of the header value + * + * @throws ParseException in case of a parse error + */ + HeaderElement[] parseElements( + CharArrayBuffer buffer, + ParserCursor cursor) throws ParseException; + + /** + * Parses a single header element. + * A header element consist of a semicolon-separate list + * of name=value definitions. + * + * @param buffer buffer holding the element to parse + * @param cursor the parser cursor containing the current position and + * the bounds within the buffer for the parsing operation + * + * @return the parsed element + * + * @throws ParseException in case of a parse error + */ + HeaderElement parseHeaderElement( + CharArrayBuffer buffer, + ParserCursor cursor) throws ParseException; + + /** + * Parses a list of name-value pairs. + * These lists are used to specify parameters to a header element. + * Parse errors are indicated as ParseException. + * + * @param buffer buffer holding the name-value list to parse + * @param cursor the parser cursor containing the current position and + * the bounds within the buffer for the parsing operation + * + * @return an array holding all items of the name-value list + * + * @throws ParseException in case of a parse error + */ + NameValuePair[] parseParameters( + CharArrayBuffer buffer, + ParserCursor cursor) throws ParseException; + + + /** + * Parses a name=value specification, where the = and value are optional. + * + * @param buffer the buffer holding the name-value pair to parse + * @param cursor the parser cursor containing the current position and + * the bounds within the buffer for the parsing operation + * + * @return the name-value pair, where the value is null + * if no value is specified + */ + NameValuePair parseNameValuePair( + CharArrayBuffer buffer, + ParserCursor cursor) throws ParseException; + +} + Index: 3rdParty_sources/httpcore/org/apache/http/message/LineFormatter.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/LineFormatter.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/LineFormatter.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,131 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.ProtocolVersion; +import org.apache.http.RequestLine; +import org.apache.http.StatusLine; +import org.apache.http.Header; +import org.apache.http.util.CharArrayBuffer; + +/** + * Interface for formatting elements of the HEAD section of an HTTP message. + * This is the complement to {@link LineParser}. + * There are individual methods for formatting a request line, a + * status line, or a header line. The formatting does not include the + * trailing line break sequence CR-LF. + * Instances of this interface are expected to be stateless and thread-safe. + * + *

    + * The formatted lines are returned in memory, the formatter does not depend + * on any specific IO mechanism. + * In order to avoid unnecessary creation of temporary objects, + * a buffer can be passed as argument to all formatting methods. + * The implementation may or may not actually use that buffer for formatting. + * If it is used, the buffer will first be cleared by the + * formatXXX methods. + * The argument buffer can always be re-used after the call. The buffer + * returned as the result, if it is different from the argument buffer, + * MUST NOT be modified. + *

    + * + * @since 4.0 + */ +public interface LineFormatter { + + /** + * Formats a protocol version. + * This method does not follow the general contract for + * buffer arguments. + * It does not clear the argument buffer, but appends instead. + * The returned buffer can always be modified by the caller. + * Because of these differing conventions, it is not named + * formatProtocolVersion. + * + * @param buffer a buffer to which to append, or null + * @param version the protocol version to format + * + * @return a buffer with the formatted protocol version appended. + * The caller is allowed to modify the result buffer. + * If the buffer argument is not null, + * the returned buffer is the argument buffer. + */ + CharArrayBuffer appendProtocolVersion(CharArrayBuffer buffer, + ProtocolVersion version); + + /** + * Formats a request line. + * + * @param buffer a buffer available for formatting, or + * null. + * The buffer will be cleared before use. + * @param reqline the request line to format + * + * @return the formatted request line + */ + CharArrayBuffer formatRequestLine(CharArrayBuffer buffer, + RequestLine reqline); + + /** + * Formats a status line. + * + * @param buffer a buffer available for formatting, or + * null. + * The buffer will be cleared before use. + * @param statline the status line to format + * + * @return the formatted status line + * + * @throws org.apache.http.ParseException in case of a parse error + */ + CharArrayBuffer formatStatusLine(CharArrayBuffer buffer, + StatusLine statline); + + /** + * Formats a header. + * Due to header continuation, the result may be multiple lines. + * In order to generate well-formed HTTP, the lines in the result + * must be separated by the HTTP line break sequence CR-LF. + * There is no trailing CR-LF in the result. + *
    + * See the class comment for details about the buffer argument. + * + * @param buffer a buffer available for formatting, or + * null. + * The buffer will be cleared before use. + * @param header the header to format + * + * @return a buffer holding the formatted header, never null. + * The returned buffer may be different from the argument buffer. + * + * @throws org.apache.http.ParseException in case of a parse error + */ + CharArrayBuffer formatHeader(CharArrayBuffer buffer, + Header header); + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/LineParser.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/LineParser.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/LineParser.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,137 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.ProtocolVersion; +import org.apache.http.ParseException; +import org.apache.http.RequestLine; +import org.apache.http.StatusLine; +import org.apache.http.Header; +import org.apache.http.util.CharArrayBuffer; + +/** + * Interface for parsing lines in the HEAD section of an HTTP message. + * There are individual methods for parsing a request line, a + * status line, or a header line. + * The lines to parse are passed in memory, the parser does not depend + * on any specific IO mechanism. + * Instances of this interface are expected to be stateless and thread-safe. + * + * @since 4.0 + */ +public interface LineParser { + + /** + * Parses the textual representation of a protocol version. + * This is needed for parsing request lines (last element) + * as well as status lines (first element). + * + * @param buffer a buffer holding the protocol version to parse + * @param cursor the parser cursor containing the current position and + * the bounds within the buffer for the parsing operation + * + * @return the parsed protocol version + * + * @throws ParseException in case of a parse error + */ + ProtocolVersion parseProtocolVersion( + CharArrayBuffer buffer, + ParserCursor cursor) throws ParseException; + + /** + * Checks whether there likely is a protocol version in a line. + * This method implements a heuristic to check for a + * likely protocol version specification. It does not + * guarantee that {@link #parseProtocolVersion} would not + * detect a parse error. + * This can be used to detect garbage lines before a request + * or status line. + * + * @param buffer a buffer holding the line to inspect + * @param cursor the cursor at which to check for a protocol version, or + * negative for "end of line". Whether the check tolerates + * whitespace before or after the protocol version is + * implementation dependent. + * + * @return true if there is a protocol version at the + * argument index (possibly ignoring whitespace), + * false otherwise + */ + boolean hasProtocolVersion( + CharArrayBuffer buffer, + ParserCursor cursor); + + /** + * Parses a request line. + * + * @param buffer a buffer holding the line to parse + * @param cursor the parser cursor containing the current position and + * the bounds within the buffer for the parsing operation + * + * @return the parsed request line + * + * @throws ParseException in case of a parse error + */ + RequestLine parseRequestLine( + CharArrayBuffer buffer, + ParserCursor cursor) throws ParseException; + + /** + * Parses a status line. + * + * @param buffer a buffer holding the line to parse + * @param cursor the parser cursor containing the current position and + * the bounds within the buffer for the parsing operation + * + * @return the parsed status line + * + * @throws ParseException in case of a parse error + */ + StatusLine parseStatusLine( + CharArrayBuffer buffer, + ParserCursor cursor) throws ParseException; + + /** + * Creates a header from a line. + * The full header line is expected here. Header continuation lines + * must be joined by the caller before invoking this method. + * + * @param buffer a buffer holding the full header line. + * This buffer MUST NOT be re-used afterwards, since + * the returned object may reference the contents later. + * + * @return the header in the argument buffer. + * The returned object MAY be a wrapper for the argument buffer. + * The argument buffer MUST NOT be re-used or changed afterwards. + * + * @throws ParseException in case of a parse error + */ + Header parseHeader(CharArrayBuffer buffer) + throws ParseException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/ParserCursor.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/ParserCursor.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/ParserCursor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,100 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.message; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * This class represents a context of a parsing operation: + *
      + *
    • the current position the parsing operation is expected to start at
    • + *
    • the bounds limiting the scope of the parsing operation
    • + *
    + * + * @since 4.0 + */ +@NotThreadSafe +public class ParserCursor { + + private final int lowerBound; + private final int upperBound; + private int pos; + + public ParserCursor(int lowerBound, int upperBound) { + super(); + if (lowerBound < 0) { + throw new IndexOutOfBoundsException("Lower bound cannot be negative"); + } + if (lowerBound > upperBound) { + throw new IndexOutOfBoundsException("Lower bound cannot be greater then upper bound"); + } + this.lowerBound = lowerBound; + this.upperBound = upperBound; + this.pos = lowerBound; + } + + public int getLowerBound() { + return this.lowerBound; + } + + public int getUpperBound() { + return this.upperBound; + } + + public int getPos() { + return this.pos; + } + + public void updatePos(int pos) { + if (pos < this.lowerBound) { + throw new IndexOutOfBoundsException("pos: "+pos+" < lowerBound: "+this.lowerBound); + } + if (pos > this.upperBound) { + throw new IndexOutOfBoundsException("pos: "+pos+" > upperBound: "+this.upperBound); + } + this.pos = pos; + } + + public boolean atEnd() { + return this.pos >= this.upperBound; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append('['); + buffer.append(Integer.toString(this.lowerBound)); + buffer.append('>'); + buffer.append(Integer.toString(this.pos)); + buffer.append('>'); + buffer.append(Integer.toString(this.upperBound)); + buffer.append(']'); + return buffer.toString(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/message/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/message/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/message/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,35 @@ + + + + + +Basic HTTP message implementations. + + Index: 3rdParty_sources/httpcore/org/apache/http/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,47 @@ + + + + + +Core HTTP components based on the blocking I/O model. + +These deal with the fundamental things required for using the +HTTP protocol, such as representing a +{@link org.apache.http.HttpMessage message} including it's +{@link org.apache.http.Header headers} and optional +{@link org.apache.http.HttpEntity entity}, and +{@link org.apache.http.HttpConnection connections} +over which messages are sent. In order to prepare messages +before sending or after receiving, there are interceptors for +{@link org.apache.http.HttpRequestInterceptor requests} and +{@link org.apache.http.HttpResponseInterceptor responses}. + + + Index: 3rdParty_sources/httpcore/org/apache/http/params/AbstractHttpParams.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/AbstractHttpParams.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/AbstractHttpParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,123 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +import java.util.Set; + +import org.apache.http.params.HttpParams; + + +/** + * Abstract base class for parameter collections. + * Type specific setters and getters are mapped to the abstract, + * generic getters and setters. + * + * @since 4.0 + */ +public abstract class AbstractHttpParams implements HttpParams, HttpParamsNames { + + /** + * Instantiates parameters. + */ + protected AbstractHttpParams() { + super(); + } + + public long getLongParameter(final String name, long defaultValue) { + Object param = getParameter(name); + if (param == null) { + return defaultValue; + } + return ((Long)param).longValue(); + } + + public HttpParams setLongParameter(final String name, long value) { + setParameter(name, new Long(value)); + return this; + } + + public int getIntParameter(final String name, int defaultValue) { + Object param = getParameter(name); + if (param == null) { + return defaultValue; + } + return ((Integer)param).intValue(); + } + + public HttpParams setIntParameter(final String name, int value) { + setParameter(name, new Integer(value)); + return this; + } + + public double getDoubleParameter(final String name, double defaultValue) { + Object param = getParameter(name); + if (param == null) { + return defaultValue; + } + return ((Double)param).doubleValue(); + } + + public HttpParams setDoubleParameter(final String name, double value) { + setParameter(name, new Double(value)); + return this; + } + + public boolean getBooleanParameter(final String name, boolean defaultValue) { + Object param = getParameter(name); + if (param == null) { + return defaultValue; + } + return ((Boolean)param).booleanValue(); + } + + public HttpParams setBooleanParameter(final String name, boolean value) { + setParameter(name, value ? Boolean.TRUE : Boolean.FALSE); + return this; + } + + public boolean isParameterTrue(final String name) { + return getBooleanParameter(name, false); + } + + public boolean isParameterFalse(final String name) { + return !getBooleanParameter(name, false); + } + + /** + * {@inheritDoc} + *

    + * Dummy implementation - must be overridden by subclasses. + * + * @since 4.2 + * @throws UnsupportedOperationException - always + */ + public Set getNames(){ + throw new UnsupportedOperationException(); + } + +} // class AbstractHttpParams Index: 3rdParty_sources/httpcore/org/apache/http/params/BasicHttpParams.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/BasicHttpParams.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/BasicHttpParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,186 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.params.HttpParams; + +/** + * Default implementation of {@link HttpParams} interface. + *

    + * Please note access to the internal structures of this class is not + * synchronized and therefore this class may be thread-unsafe. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicHttpParams extends AbstractHttpParams implements Serializable, Cloneable { + + private static final long serialVersionUID = -7086398485908701455L; + + /** Map of HTTP parameters that this collection contains. */ + private final HashMap parameters = new HashMap(); + + public BasicHttpParams() { + super(); + } + + public Object getParameter(final String name) { + return this.parameters.get(name); + } + + public HttpParams setParameter(final String name, final Object value) { + this.parameters.put(name, value); + return this; + } + + public boolean removeParameter(String name) { + //this is to avoid the case in which the key has a null value + if (this.parameters.containsKey(name)) { + this.parameters.remove(name); + return true; + } else { + return false; + } + } + + /** + * Assigns the value to all the parameter with the given names + * + * @param names array of parameter names + * @param value parameter value + */ + public void setParameters(final String[] names, final Object value) { + for (int i = 0; i < names.length; i++) { + setParameter(names[i], value); + } + } + + /** + * Is the parameter set? + *

    + * Uses {@link #getParameter(String)} (which is overrideable) to + * fetch the parameter value, if any. + *

    + * Also @see {@link #isParameterSetLocally(String)} + * + * @param name parameter name + * @return true if parameter is defined and non-null + */ + public boolean isParameterSet(final String name) { + return getParameter(name) != null; + } + + /** + * Is the parameter set in this object? + *

    + * The parameter value is fetched directly. + *

    + * Also @see {@link #isParameterSet(String)} + * + * @param name parameter name + * @return true if parameter is defined and non-null + */ + public boolean isParameterSetLocally(final String name) { + return this.parameters.get(name) != null; + } + + /** + * Removes all parameters from this collection. + */ + public void clear() { + this.parameters.clear(); + } + + /** + * Creates a copy of these parameters. + * This implementation calls {@link #clone()}. + * + * @return a new set of params holding a copy of the + * local parameters in this object. + * + * @deprecated (4.1) + * @throws UnsupportedOperationException if the clone() fails + */ + @Deprecated + public HttpParams copy() { + try { + return (HttpParams) clone(); + } catch (CloneNotSupportedException ex) { + throw new UnsupportedOperationException("Cloning not supported"); + } + } + + /** + * Clones the instance. + * Uses {@link #copyParams(HttpParams)} to copy the parameters. + */ + @Override + public Object clone() throws CloneNotSupportedException { + BasicHttpParams clone = (BasicHttpParams) super.clone(); + copyParams(clone); + return clone; + } + + /** + * Copies the locally defined parameters to the argument parameters. + * This method is called from {@link #clone()}. + * + * @param target the parameters to which to copy + * @since 4.2 + */ + public void copyParams(HttpParams target) { + Iterator> iter = this.parameters.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry me = iter.next(); + if (me.getKey() instanceof String) + target.setParameter(me.getKey(), me.getValue()); + } + } + + /** + * Returns the current set of names. + * + * Changes to the underlying HttpParams are not reflected + * in the set - it is a snapshot. + * + * @return the names, as a Set + * @since 4.2 + */ + @Override + public Set getNames() { + return new HashSet(this.parameters.keySet()); + } +} Index: 3rdParty_sources/httpcore/org/apache/http/params/CoreConnectionPNames.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/CoreConnectionPNames.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/CoreConnectionPNames.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,166 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +/** + * Defines parameter names for connections in HttpCore. + * + * @since 4.0 + */ +public interface CoreConnectionPNames { + + /** + * Defines the socket timeout (SO_TIMEOUT) in milliseconds, + * which is the timeout for waiting for data or, put differently, + * a maximum period inactivity between two consecutive data packets). + * A timeout value of zero is interpreted as an infinite timeout. + *

    + * This parameter expects a value of type {@link Integer}. + *

    + * @see java.net.SocketOptions#SO_TIMEOUT + */ + public static final String SO_TIMEOUT = "http.socket.timeout"; + + /** + * Determines whether Nagle's algorithm is to be used. The Nagle's algorithm + * tries to conserve bandwidth by minimizing the number of segments that are + * sent. When applications wish to decrease network latency and increase + * performance, they can disable Nagle's algorithm (that is enable + * TCP_NODELAY). Data will be sent earlier, at the cost of an increase + * in bandwidth consumption. + *

    + * This parameter expects a value of type {@link Boolean}. + *

    + * @see java.net.SocketOptions#TCP_NODELAY + */ + public static final String TCP_NODELAY = "http.tcp.nodelay"; + + /** + * Determines the size of the internal socket buffer used to buffer data + * while receiving / transmitting HTTP messages. + *

    + * This parameter expects a value of type {@link Integer}. + *

    + */ + public static final String SOCKET_BUFFER_SIZE = "http.socket.buffer-size"; + + /** + * Sets SO_LINGER with the specified linger time in seconds. The maximum + * timeout value is platform specific. Value 0 implies that + * the option is disabled. Value -1 implies that the JRE + * default is used. The setting only affects the socket close operation. + *

    + * This parameter expects a value of type {@link Integer}. + *

    + * @see java.net.SocketOptions#SO_LINGER + */ + public static final String SO_LINGER = "http.socket.linger"; + + /** + * Defines whether the socket can be bound even though a previous connection is + * still in a timeout state. + *

    + * This parameter expects a value of type {@link Boolean}. + *

    + * @see java.net.Socket#setReuseAddress(boolean) + * + * @since 4.1 + */ + public static final String SO_REUSEADDR = "http.socket.reuseaddr"; + + /** + * Determines the timeout in milliseconds until a connection is established. + * A timeout value of zero is interpreted as an infinite timeout. + *

    + * Please note this parameter can only be applied to connections that + * are bound to a particular local address. + *

    + * This parameter expects a value of type {@link Integer}. + *

    + */ + public static final String CONNECTION_TIMEOUT = "http.connection.timeout"; + + /** + * Determines whether stale connection check is to be used. The stale + * connection check can cause up to 30 millisecond overhead per request and + * should be used only when appropriate. For performance critical + * operations this check should be disabled. + *

    + * This parameter expects a value of type {@link Boolean}. + *

    + */ + public static final String STALE_CONNECTION_CHECK = "http.connection.stalecheck"; + + /** + * Determines the maximum line length limit. If set to a positive value, + * any HTTP line exceeding this limit will cause an IOException. A negative + * or zero value will effectively disable the check. + *

    + * This parameter expects a value of type {@link Integer}. + *

    + */ + public static final String MAX_LINE_LENGTH = "http.connection.max-line-length"; + + /** + * Determines the maximum HTTP header count allowed. If set to a positive + * value, the number of HTTP headers received from the data stream exceeding + * this limit will cause an IOException. A negative or zero value will + * effectively disable the check. + *

    + * This parameter expects a value of type {@link Integer}. + *

    + */ + public static final String MAX_HEADER_COUNT = "http.connection.max-header-count"; + + /** + * Defines the size limit below which data chunks should be buffered in a session I/O buffer + * in order to minimize native method invocations on the underlying network socket. + * The optimal value of this parameter can be platform specific and defines a trade-off + * between performance of memory copy operations and that of native method invocation. + *

    + * This parameter expects a value of type {@link Integer}. + *

    + * + * @since 4.1 + */ + public static final String MIN_CHUNK_LIMIT = "http.connection.min-chunk-limit"; + + + /** + * Defines whether or not TCP is to send automatically a keepalive probe to the peer + * after an interval of inactivity (no data exchanged in either direction) between this + * host and the peer. The purpose of this option is to detect if the peer host crashes. + *

    + * This parameter expects a value of type {@link Boolean}. + *

    + * @see java.net.SocketOptions#SO_KEEPALIVE + * @since 4.2 + */ + public static final String SO_KEEPALIVE = "http.socket.keepalive"; + +} Index: 3rdParty_sources/httpcore/org/apache/http/params/CoreProtocolPNames.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/CoreProtocolPNames.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/CoreProtocolPNames.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,150 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +import org.apache.http.ProtocolVersion; + +/** + * Defines parameter names for protocol execution in HttpCore. + * + * @since 4.0 + */ +public interface CoreProtocolPNames { + + /** + * Defines the {@link ProtocolVersion} used per default. + *

    + * This parameter expects a value of type {@link ProtocolVersion}. + *

    + */ + public static final String PROTOCOL_VERSION = "http.protocol.version"; + + /** + * Defines the charset to be used for encoding HTTP protocol elements. + *

    + * This parameter expects a value of type {@link String}. + *

    + */ + public static final String HTTP_ELEMENT_CHARSET = "http.protocol.element-charset"; + + /** + * Defines the charset to be used per default for encoding content body. + *

    + * This parameter expects a value of type {@link String}. + *

    + */ + public static final String HTTP_CONTENT_CHARSET = "http.protocol.content-charset"; + + /** + * Defines the content of the User-Agent header. + *

    + * This parameter expects a value of type {@link String}. + *

    + */ + public static final String USER_AGENT = "http.useragent"; + + /** + * Defines the content of the Server header. + *

    + * This parameter expects a value of type {@link String}. + *

    + */ + public static final String ORIGIN_SERVER = "http.origin-server"; + + /** + * Defines whether responses with an invalid Transfer-Encoding + * header should be rejected. + *

    + * This parameter expects a value of type {@link Boolean}. + *

    + */ + public static final String STRICT_TRANSFER_ENCODING = "http.protocol.strict-transfer-encoding"; + + /** + *

    + * Activates 'Expect: 100-Continue' handshake for the + * entity enclosing methods. The purpose of the 'Expect: 100-Continue' + * handshake is to allow a client that is sending a request message with + * a request body to determine if the origin server is willing to + * accept the request (based on the request headers) before the client + * sends the request body. + *

    + * + *

    + * The use of the 'Expect: 100-continue' handshake can result in + * a noticeable performance improvement for entity enclosing requests + * (such as POST and PUT) that require the target server's + * authentication. + *

    + * + *

    + * 'Expect: 100-continue' handshake should be used with + * caution, as it may cause problems with HTTP servers and + * proxies that do not support HTTP/1.1 protocol. + *

    + * + * This parameter expects a value of type {@link Boolean}. + */ + public static final String USE_EXPECT_CONTINUE = "http.protocol.expect-continue"; + + /** + *

    + * Defines the maximum period of time in milliseconds the client should spend + * waiting for a 100-continue response. + *

    + * + * This parameter expects a value of type {@link Integer}. + */ + public static final String WAIT_FOR_CONTINUE = "http.protocol.wait-for-continue"; + + /** + *

    + * Defines the action to perform upon receiving a malformed input. If the input byte sequence + * is not legal for this charset then the input is said to be malformed + *

    + * + * This parameter expects a value of type {@link java.nio.charset.CodingErrorAction} + * + * @since 4.2 + */ + public static final String HTTP_MALFORMED_INPUT_ACTION = "http.malformed.input.action"; + + /** + *

    + * Defines the action to perform upon receiving an unmappable input. If the input byte sequence + * is legal but cannot be mapped to a valid Unicode character then the input is said to be + * unmappable + *

    + * + * This parameter expects a value of type {@link java.nio.charset.CodingErrorAction} + * + * @since 4.2 + */ + public static final String HTTP_UNMAPPABLE_INPUT_ACTION = "http.unmappable.input.action"; + +} Index: 3rdParty_sources/httpcore/org/apache/http/params/DefaultedHttpParams.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/DefaultedHttpParams.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/DefaultedHttpParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,167 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.http.params.HttpParams; + +/** + * {@link HttpParams} implementation that delegates resolution of a parameter + * to the given default {@link HttpParams} instance if the parameter is not + * present in the local one. The state of the local collection can be mutated, + * whereas the default collection is treated as read-only. + * + * @since 4.0 + */ +public final class DefaultedHttpParams extends AbstractHttpParams { + + private final HttpParams local; + private final HttpParams defaults; + + /** + * Create the defaulted set of HttpParams. + * + * @param local the mutable set of HttpParams + * @param defaults the default set of HttpParams, not mutated by this class + */ + public DefaultedHttpParams(final HttpParams local, final HttpParams defaults) { + super(); + if (local == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + this.local = local; + this.defaults = defaults; + } + + /** + * Creates a copy of the local collection with the same default + * + * @deprecated (4.1) + */ + @Deprecated + public HttpParams copy() { + HttpParams clone = this.local.copy(); + return new DefaultedHttpParams(clone, this.defaults); + } + + /** + * Retrieves the value of the parameter from the local collection and, if the + * parameter is not set locally, delegates its resolution to the default + * collection. + */ + public Object getParameter(final String name) { + Object obj = this.local.getParameter(name); + if (obj == null && this.defaults != null) { + obj = this.defaults.getParameter(name); + } + return obj; + } + + /** + * Attempts to remove the parameter from the local collection. This method + * does not modify the default collection. + */ + public boolean removeParameter(final String name) { + return this.local.removeParameter(name); + } + + /** + * Sets the parameter in the local collection. This method does not + * modify the default collection. + */ + public HttpParams setParameter(final String name, final Object value) { + return this.local.setParameter(name, value); + } + + /** + * + * @return the default HttpParams collection + * @deprecated (4.1.1) do not use, will be removed in a later version + */ + @Deprecated + public HttpParams getDefaults() { + return this.defaults; + } + + /** + * Returns the current set of names + * from both the local and default HttpParams instances. + * + * Changes to the underlying HttpParams intances are not reflected + * in the set - it is a snapshot. + * + * @return the combined set of names, as a Set + * @since 4.2 + * @throws UnsupportedOperationException if either the local or default HttpParams instances do not implement HttpParamsNames + */ + @Override + public Set getNames() { + Set combined = new HashSet(getNames(defaults)); + combined.addAll(getNames(this.local)); + return combined ; + } + + /** + * Returns the current set of defaults names. + * + * Changes to the underlying HttpParams are not reflected + * in the set - it is a snapshot. + * + * @return the names, as a Set + * @since 4.2 + * @throws UnsupportedOperationException if the default HttpParams instance does not implement HttpParamsNames + */ + public Set getDefaultNames() { + return new HashSet(getNames(this.defaults)); + } + + /** + * Returns the current set of local names. + * + * Changes to the underlying HttpParams are not reflected + * in the set - it is a snapshot. + * + * @return the names, as a Set + * @since 4.2 + * @throws UnsupportedOperationException if the local HttpParams instance does not implement HttpParamsNames + */ + public Set getLocalNames() { + return new HashSet(getNames(this.local)); + } + + // Helper method + private Set getNames(HttpParams params) { + if (params instanceof HttpParamsNames) { + return ((HttpParamsNames) params).getNames(); + } + throw new UnsupportedOperationException("HttpParams instance does not implement HttpParamsNames"); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/params/HttpAbstractParamBean.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/HttpAbstractParamBean.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/HttpAbstractParamBean.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,43 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +/** + * @since 4.0 + */ +public abstract class HttpAbstractParamBean { + + protected final HttpParams params; + + public HttpAbstractParamBean (final HttpParams params) { + if (params == null) + throw new IllegalArgumentException("HTTP parameters may not be null"); + this.params = params; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/params/HttpConnectionParamBean.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/HttpConnectionParamBean.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/HttpConnectionParamBean.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +/** + * This is a Java Bean class that can be used to wrap an instance of + * {@link HttpParams} and manipulate HTTP connection parameters using Java Beans + * conventions. + * + * @since 4.0 + */ +public class HttpConnectionParamBean extends HttpAbstractParamBean { + + public HttpConnectionParamBean (final HttpParams params) { + super(params); + } + + public void setSoTimeout (int soTimeout) { + HttpConnectionParams.setSoTimeout(params, soTimeout); + } + + public void setTcpNoDelay (boolean tcpNoDelay) { + HttpConnectionParams.setTcpNoDelay(params, tcpNoDelay); + } + + public void setSocketBufferSize (int socketBufferSize) { + HttpConnectionParams.setSocketBufferSize(params, socketBufferSize); + } + + public void setLinger (int linger) { + HttpConnectionParams.setLinger(params, linger); + } + + public void setConnectionTimeout (int connectionTimeout) { + HttpConnectionParams.setConnectionTimeout(params, connectionTimeout); + } + + public void setStaleCheckingEnabled (boolean staleCheckingEnabled) { + HttpConnectionParams.setStaleCheckingEnabled(params, staleCheckingEnabled); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/params/HttpConnectionParams.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/HttpConnectionParams.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/HttpConnectionParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,278 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +/** + * Utility class for accessing connection parameters in {@link HttpParams}. + * + * @since 4.0 + */ +public final class HttpConnectionParams implements CoreConnectionPNames { + + private HttpConnectionParams() { + super(); + } + + /** + * Obtains value of the {@link CoreConnectionPNames#SO_TIMEOUT} parameter. + * If not set, defaults to 0. + * + * @param params HTTP parameters. + * @return SO_TIMEOUT. + */ + public static int getSoTimeout(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getIntParameter(CoreConnectionPNames.SO_TIMEOUT, 0); + } + + /** + * Sets value of the {@link CoreConnectionPNames#SO_TIMEOUT} parameter. + * + * @param params HTTP parameters. + * @param timeout SO_TIMEOUT. + */ + public static void setSoTimeout(final HttpParams params, int timeout) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, timeout); + + } + + /** + * Obtains value of the {@link CoreConnectionPNames#SO_REUSEADDR} parameter. + * If not set, defaults to false. + * + * @param params HTTP parameters. + * @return SO_REUSEADDR. + * + * @since 4.1 + */ + public static boolean getSoReuseaddr(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getBooleanParameter(CoreConnectionPNames.SO_REUSEADDR, false); + } + + /** + * Sets value of the {@link CoreConnectionPNames#SO_REUSEADDR} parameter. + * + * @param params HTTP parameters. + * @param reuseaddr SO_REUSEADDR. + * + * @since 4.1 + */ + public static void setSoReuseaddr(final HttpParams params, boolean reuseaddr) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setBooleanParameter(CoreConnectionPNames.SO_REUSEADDR, reuseaddr); + } + + /** + * Obtains value of the {@link CoreConnectionPNames#TCP_NODELAY} parameter. + * If not set, defaults to true. + * + * @param params HTTP parameters. + * @return Nagle's algorithm flag + */ + public static boolean getTcpNoDelay(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getBooleanParameter + (CoreConnectionPNames.TCP_NODELAY, true); + } + + /** + * Sets value of the {@link CoreConnectionPNames#TCP_NODELAY} parameter. + * + * @param params HTTP parameters. + * @param value Nagle's algorithm flag + */ + public static void setTcpNoDelay(final HttpParams params, boolean value) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, value); + } + + /** + * Obtains value of the {@link CoreConnectionPNames#SOCKET_BUFFER_SIZE} + * parameter. If not set, defaults to -1. + * + * @param params HTTP parameters. + * @return socket buffer size + */ + public static int getSocketBufferSize(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getIntParameter + (CoreConnectionPNames.SOCKET_BUFFER_SIZE, -1); + } + + /** + * Sets value of the {@link CoreConnectionPNames#SOCKET_BUFFER_SIZE} + * parameter. + * + * @param params HTTP parameters. + * @param size socket buffer size + */ + public static void setSocketBufferSize(final HttpParams params, int size) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, size); + } + + /** + * Obtains value of the {@link CoreConnectionPNames#SO_LINGER} parameter. + * If not set, defaults to -1. + * + * @param params HTTP parameters. + * @return SO_LINGER. + */ + public static int getLinger(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getIntParameter(CoreConnectionPNames.SO_LINGER, -1); + } + + /** + * Sets value of the {@link CoreConnectionPNames#SO_LINGER} parameter. + * + * @param params HTTP parameters. + * @param value SO_LINGER. + */ + public static void setLinger(final HttpParams params, int value) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setIntParameter(CoreConnectionPNames.SO_LINGER, value); + } + + /** + * Obtains value of the {@link CoreConnectionPNames#CONNECTION_TIMEOUT} + * parameter. If not set, defaults to 0. + * + * @param params HTTP parameters. + * @return connect timeout. + */ + public static int getConnectionTimeout(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getIntParameter + (CoreConnectionPNames.CONNECTION_TIMEOUT, 0); + } + + /** + * Sets value of the {@link CoreConnectionPNames#CONNECTION_TIMEOUT} + * parameter. + * + * @param params HTTP parameters. + * @param timeout connect timeout. + */ + public static void setConnectionTimeout(final HttpParams params, int timeout) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setIntParameter + (CoreConnectionPNames.CONNECTION_TIMEOUT, timeout); + } + + /** + * Obtains value of the {@link CoreConnectionPNames#STALE_CONNECTION_CHECK} + * parameter. If not set, defaults to true. + * + * @param params HTTP parameters. + * @return stale connection check flag. + */ + public static boolean isStaleCheckingEnabled(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getBooleanParameter + (CoreConnectionPNames.STALE_CONNECTION_CHECK, true); + } + + /** + * Sets value of the {@link CoreConnectionPNames#STALE_CONNECTION_CHECK} + * parameter. + * + * @param params HTTP parameters. + * @param value stale connection check flag. + */ + public static void setStaleCheckingEnabled(final HttpParams params, boolean value) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setBooleanParameter + (CoreConnectionPNames.STALE_CONNECTION_CHECK, value); + } + + /** + * Obtains value of the {@link CoreConnectionPNames#SO_KEEPALIVE} parameter. + * If not set, defaults to false. + * + * @param params HTTP parameters. + * @return SO_KEEPALIVE. + * + * @since 4.2 + */ + public static boolean getSoKeepalive(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getBooleanParameter(CoreConnectionPNames.SO_KEEPALIVE, false); + } + + /** + * Sets value of the {@link CoreConnectionPNames#SO_KEEPALIVE} parameter. + * + * @param params HTTP parameters. + * @param enableKeepalive SO_KEEPALIVE. + * + * @since 4.2 + */ + public static void setSoKeepalive(final HttpParams params, boolean enableKeepalive) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setBooleanParameter(CoreConnectionPNames.SO_KEEPALIVE, enableKeepalive); + } + + + + +} Index: 3rdParty_sources/httpcore/org/apache/http/params/HttpParams.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/HttpParams.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/HttpParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,196 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +/** + * HttpParams interface represents a collection of immutable values that define + * a runtime behavior of a component. HTTP parameters should be simple objects: + * integers, doubles, strings, collections and objects that remain immutable + * at runtime. HttpParams is expected to be used in 'write once - read many' mode. + * Once initialized, HTTP parameters are not expected to mutate in + * the course of HTTP message processing. + *

    + * The purpose of this interface is to define a behavior of other components. + * Usually each complex component has its own HTTP parameter collection. + *

    + * Instances of this interface can be linked together to form a hierarchy. + * In the simplest form one set of parameters can use content of another one + * to obtain default values of parameters not present in the local set. + * + * @see DefaultedHttpParams + * + * @since 4.0 + */ +public interface HttpParams { + + /** + * Obtains the value of the given parameter. + * + * @param name the parent name. + * + * @return an object that represents the value of the parameter, + * null if the parameter is not set or if it + * is explicitly set to null + * + * @see #setParameter(String, Object) + */ + Object getParameter(String name); + + /** + * Assigns the value to the parameter with the given name. + * + * @param name parameter name + * @param value parameter value + */ + HttpParams setParameter(String name, Object value); + + /** + * Creates a copy of these parameters. + * + * @return a new set of parameters holding the same values as this one + * + * @deprecated (4.1) + */ + @Deprecated + HttpParams copy(); + + /** + * Removes the parameter with the specified name. + * + * @param name parameter name + * + * @return true if the parameter existed and has been removed, false else. + */ + boolean removeParameter(String name); + + /** + * Returns a {@link Long} parameter value with the given name. + * If the parameter is not explicitly set, the default value is returned. + * + * @param name the parent name. + * @param defaultValue the default value. + * + * @return a {@link Long} that represents the value of the parameter. + * + * @see #setLongParameter(String, long) + */ + long getLongParameter(String name, long defaultValue); + + /** + * Assigns a {@link Long} to the parameter with the given name + * + * @param name parameter name + * @param value parameter value + */ + HttpParams setLongParameter(String name, long value); + + /** + * Returns an {@link Integer} parameter value with the given name. + * If the parameter is not explicitly set, the default value is returned. + * + * @param name the parent name. + * @param defaultValue the default value. + * + * @return a {@link Integer} that represents the value of the parameter. + * + * @see #setIntParameter(String, int) + */ + int getIntParameter(String name, int defaultValue); + + /** + * Assigns an {@link Integer} to the parameter with the given name + * + * @param name parameter name + * @param value parameter value + */ + HttpParams setIntParameter(String name, int value); + + /** + * Returns a {@link Double} parameter value with the given name. + * If the parameter is not explicitly set, the default value is returned. + * + * @param name the parent name. + * @param defaultValue the default value. + * + * @return a {@link Double} that represents the value of the parameter. + * + * @see #setDoubleParameter(String, double) + */ + double getDoubleParameter(String name, double defaultValue); + + /** + * Assigns a {@link Double} to the parameter with the given name + * + * @param name parameter name + * @param value parameter value + */ + HttpParams setDoubleParameter(String name, double value); + + /** + * Returns a {@link Boolean} parameter value with the given name. + * If the parameter is not explicitly set, the default value is returned. + * + * @param name the parent name. + * @param defaultValue the default value. + * + * @return a {@link Boolean} that represents the value of the parameter. + * + * @see #setBooleanParameter(String, boolean) + */ + boolean getBooleanParameter(String name, boolean defaultValue); + + /** + * Assigns a {@link Boolean} to the parameter with the given name + * + * @param name parameter name + * @param value parameter value + */ + HttpParams setBooleanParameter(String name, boolean value); + + /** + * Checks if a boolean parameter is set to true. + * + * @param name parameter name + * + * @return true if the parameter is set to value true, + * false if it is not set or set to false + */ + boolean isParameterTrue(String name); + + /** + * Checks if a boolean parameter is not set or false. + * + * @param name parameter name + * + * @return true if the parameter is either not set or + * set to value false, + * false if it is set to true + */ + boolean isParameterFalse(String name); + +} Index: 3rdParty_sources/httpcore/org/apache/http/params/HttpParamsNames.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/HttpParamsNames.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/HttpParamsNames.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,53 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +import java.util.Set; + +/** + * Gives access to the full set of parameter names. + * + * @see HttpParams + * + * @since 4.2 + */ +public interface HttpParamsNames { + + /** + * Returns the current set of names; + * in the case of stacked parameters, returns the names + * from all the participating HttpParams instances. + * + * Changes to the underlying HttpParams are not reflected + * in the set - it is a snapshot. + * + * @return the names, as a Set + */ + Set getNames(); + +} Index: 3rdParty_sources/httpcore/org/apache/http/params/HttpProtocolParamBean.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/HttpProtocolParamBean.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/HttpProtocolParamBean.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,65 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +import org.apache.http.HttpVersion; + +/** + * This is a Java Bean class that can be used to wrap an instance of + * {@link HttpParams} and manipulate HTTP protocol parameters using Java Beans + * conventions. + * + * @since 4.0 + */ +public class HttpProtocolParamBean extends HttpAbstractParamBean { + + public HttpProtocolParamBean (final HttpParams params) { + super(params); + } + + public void setHttpElementCharset (final String httpElementCharset) { + HttpProtocolParams.setHttpElementCharset(params, httpElementCharset); + } + + public void setContentCharset (final String contentCharset) { + HttpProtocolParams.setContentCharset(params, contentCharset); + } + + public void setVersion (final HttpVersion version) { + HttpProtocolParams.setVersion(params, version); + } + + public void setUserAgent (final String userAgent) { + HttpProtocolParams.setUserAgent(params, userAgent); + } + + public void setUseExpectContinue (boolean useExpectContinue) { + HttpProtocolParams.setUseExpectContinue(params, useExpectContinue); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/params/HttpProtocolParams.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/HttpProtocolParams.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/HttpProtocolParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,265 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.params; + +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.protocol.HTTP; + +import java.nio.charset.CodingErrorAction; + +/** + * Utility class for accessing protocol parameters in {@link HttpParams}. + * + * @since 4.0 + * + * @see CoreProtocolPNames + */ +public final class HttpProtocolParams implements CoreProtocolPNames { + + private HttpProtocolParams() { + super(); + } + + /** + * Obtains value of the {@link CoreProtocolPNames#HTTP_ELEMENT_CHARSET} parameter. + * If not set, defaults to US-ASCII. + * + * @param params HTTP parameters. + * @return HTTP element charset. + */ + public static String getHttpElementCharset(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + String charset = (String) params.getParameter + (CoreProtocolPNames.HTTP_ELEMENT_CHARSET); + if (charset == null) { + charset = HTTP.DEF_PROTOCOL_CHARSET.name(); + } + return charset; + } + + /** + * Sets value of the {@link CoreProtocolPNames#HTTP_ELEMENT_CHARSET} parameter. + * + * @param params HTTP parameters. + * @param charset HTTP element charset. + */ + public static void setHttpElementCharset(final HttpParams params, final String charset) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setParameter(CoreProtocolPNames.HTTP_ELEMENT_CHARSET, charset); + } + + /** + * Obtains value of the {@link CoreProtocolPNames#HTTP_CONTENT_CHARSET} parameter. + * If not set, defaults to ISO-8859-1. + * + * @param params HTTP parameters. + * @return HTTP content charset. + */ + public static String getContentCharset(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + String charset = (String) params.getParameter + (CoreProtocolPNames.HTTP_CONTENT_CHARSET); + if (charset == null) { + charset = HTTP.DEF_CONTENT_CHARSET.name(); + } + return charset; + } + + /** + * Sets value of the {@link CoreProtocolPNames#HTTP_CONTENT_CHARSET} parameter. + * + * @param params HTTP parameters. + * @param charset HTTP content charset. + */ + public static void setContentCharset(final HttpParams params, final String charset) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, charset); + } + + /** + * Obtains value of the {@link CoreProtocolPNames#PROTOCOL_VERSION} parameter. + * If not set, defaults to {@link HttpVersion#HTTP_1_1}. + * + * @param params HTTP parameters. + * @return HTTP protocol version. + */ + public static ProtocolVersion getVersion(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + Object param = params.getParameter + (CoreProtocolPNames.PROTOCOL_VERSION); + if (param == null) { + return HttpVersion.HTTP_1_1; + } + return (ProtocolVersion)param; + } + + /** + * Sets value of the {@link CoreProtocolPNames#PROTOCOL_VERSION} parameter. + * + * @param params HTTP parameters. + * @param version HTTP protocol version. + */ + public static void setVersion(final HttpParams params, final ProtocolVersion version) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, version); + } + + /** + * Obtains value of the {@link CoreProtocolPNames#USER_AGENT} parameter. + * If not set, returns null. + * + * @param params HTTP parameters. + * @return User agent string. + */ + public static String getUserAgent(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return (String) params.getParameter(CoreProtocolPNames.USER_AGENT); + } + + /** + * Sets value of the {@link CoreProtocolPNames#USER_AGENT} parameter. + * + * @param params HTTP parameters. + * @param useragent User agent string. + */ + public static void setUserAgent(final HttpParams params, final String useragent) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setParameter(CoreProtocolPNames.USER_AGENT, useragent); + } + + /** + * Obtains value of the {@link CoreProtocolPNames#USE_EXPECT_CONTINUE} parameter. + * If not set, returns false. + * + * @param params HTTP parameters. + * @return User agent string. + */ + public static boolean useExpectContinue(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + return params.getBooleanParameter + (CoreProtocolPNames.USE_EXPECT_CONTINUE, false); + } + + /** + * Sets value of the {@link CoreProtocolPNames#USE_EXPECT_CONTINUE} parameter. + * + * @param params HTTP parameters. + * @param b expect-continue flag. + */ + public static void setUseExpectContinue(final HttpParams params, boolean b) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, b); + } + + /** + * Obtains value of the {@link CoreProtocolPNames#HTTP_MALFORMED_INPUT_ACTION} parameter. + * @param params HTTP parameters. + * @return Action to perform upon receiving a malformed input + * + * @since 4.2 + */ + public static CodingErrorAction getMalformedInputAction(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + Object param = params.getParameter(CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION); + if (param == null) { + // the default CodingErrorAction + return CodingErrorAction.REPORT; + } + return (CodingErrorAction) param; + } + + /** + * Sets value of the {@link CoreProtocolPNames#HTTP_MALFORMED_INPUT_ACTION} parameter. + * @param params HTTP parameters + * @param action action to perform on malformed inputs + * + * @since 4.2 + */ + public static void setMalformedInputAction(final HttpParams params, CodingErrorAction action) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + params.setParameter(CoreProtocolPNames.HTTP_MALFORMED_INPUT_ACTION, action); + } + + /** + * Obtains the value of the {@link CoreProtocolPNames#HTTP_UNMAPPABLE_INPUT_ACTION} parameter. + * @param params HTTP parameters + * @return Action to perform upon receiving a unmapped input + * + * @since 4.2 + */ + public static CodingErrorAction getUnmappableInputAction(final HttpParams params) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + Object param = params.getParameter(CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION); + if (param == null) { + // the default CodingErrorAction + return CodingErrorAction.REPORT; + } + return (CodingErrorAction) param; + } + + /** + * Sets the value of the {@link CoreProtocolPNames#HTTP_UNMAPPABLE_INPUT_ACTION} parameter. + * @param params HTTP parameters + * @param action action to perform on un mappable inputs + * + * @since 4.2 + */ + public static void setUnmappableInputAction(final HttpParams params, CodingErrorAction action) { + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may no be null"); + } + params.setParameter(CoreProtocolPNames.HTTP_UNMAPPABLE_INPUT_ACTION, action); + } +} Index: 3rdParty_sources/httpcore/org/apache/http/params/SyncBasicHttpParams.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/SyncBasicHttpParams.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/SyncBasicHttpParams.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,85 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.http.params; + +import org.apache.http.annotation.ThreadSafe; + +/** + * Thread-safe extension of the {@link BasicHttpParams}. + * + * @since 4.1 + */ +@ThreadSafe +public class SyncBasicHttpParams extends BasicHttpParams { + + private static final long serialVersionUID = 5387834869062660642L; + + public SyncBasicHttpParams() { + super(); + } + + @Override + public synchronized boolean removeParameter(final String name) { + return super.removeParameter(name); + } + + @Override + public synchronized HttpParams setParameter(final String name, final Object value) { + return super.setParameter(name, value); + } + + @Override + public synchronized Object getParameter(final String name) { + return super.getParameter(name); + } + + @Override + public synchronized boolean isParameterSet(final String name) { + return super.isParameterSet(name); + } + + @Override + public synchronized boolean isParameterSetLocally(final String name) { + return super.isParameterSetLocally(name); + } + + @Override + public synchronized void setParameters(final String[] names, final Object value) { + super.setParameters(names, value); + } + + @Override + public synchronized void clear() { + super.clear(); + } + + @Override + public synchronized Object clone() throws CloneNotSupportedException { + return super.clone(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/params/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/params/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/params/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +The parameterization framework for HTTP components. This package also provides +core protocol and I/O parameters. + + Index: 3rdParty_sources/httpcore/org/apache/http/pool/AbstractConnPool.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/pool/AbstractConnPool.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/pool/AbstractConnPool.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,510 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.pool; + +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.concurrent.FutureCallback; + +/** + * Abstract synchronous (blocking) pool of connections. + *

    + * Please note that this class does not maintain its own pool of execution {@link Thread}s. + * Therefore, one must call {@link Future#get()} or {@link Future#get(long, TimeUnit)} + * method on the {@link Future} object returned by the + * {@link #lease(Object, Object, FutureCallback)} method in order for the lease operation + * to complete. + * + * @param the route type that represents the opposite endpoint of a pooled + * connection. + * @param the connection type. + * @param the type of the pool entry containing a pooled connection. + * @since 4.2 + */ +@ThreadSafe +public abstract class AbstractConnPool> + implements ConnPool, ConnPoolControl { + + private final Lock lock; + private final ConnFactory connFactory; + private final Map> routeToPool; + private final Set leased; + private final LinkedList available; + private final LinkedList> pending; + private final Map maxPerRoute; + + private volatile boolean isShutDown; + private volatile int defaultMaxPerRoute; + private volatile int maxTotal; + + public AbstractConnPool( + final ConnFactory connFactory, + int defaultMaxPerRoute, + int maxTotal) { + super(); + if (connFactory == null) { + throw new IllegalArgumentException("Connection factory may not null"); + } + if (defaultMaxPerRoute <= 0) { + throw new IllegalArgumentException("Max per route value may not be negative or zero"); + } + if (maxTotal <= 0) { + throw new IllegalArgumentException("Max total value may not be negative or zero"); + } + this.lock = new ReentrantLock(); + this.connFactory = connFactory; + this.routeToPool = new HashMap>(); + this.leased = new HashSet(); + this.available = new LinkedList(); + this.pending = new LinkedList>(); + this.maxPerRoute = new HashMap(); + this.defaultMaxPerRoute = defaultMaxPerRoute; + this.maxTotal = maxTotal; + } + + /** + * Creates a new entry for the given connection with the given route. + */ + protected abstract E createEntry(T route, C conn); + + public boolean isShutdown() { + return this.isShutDown; + } + + /** + * Shuts down the pool. + */ + public void shutdown() throws IOException { + if (this.isShutDown) { + return ; + } + this.isShutDown = true; + this.lock.lock(); + try { + for (E entry: this.available) { + entry.close(); + } + for (E entry: this.leased) { + entry.close(); + } + for (RouteSpecificPool pool: this.routeToPool.values()) { + pool.shutdown(); + } + this.routeToPool.clear(); + this.leased.clear(); + this.available.clear(); + } finally { + this.lock.unlock(); + } + } + + private RouteSpecificPool getPool(final T route) { + RouteSpecificPool pool = this.routeToPool.get(route); + if (pool == null) { + pool = new RouteSpecificPool(route) { + + @Override + protected E createEntry(C conn) { + return AbstractConnPool.this.createEntry(route, conn); + } + + }; + this.routeToPool.put(route, pool); + } + return pool; + } + + /** + * {@inheritDoc} + *

    + * Please note that this class does not maintain its own pool of execution + * {@link Thread}s. Therefore, one must call {@link Future#get()} + * or {@link Future#get(long, TimeUnit)} method on the {@link Future} + * returned by this method in order for the lease operation to complete. + */ + public Future lease(final T route, final Object state, final FutureCallback callback) { + if (route == null) { + throw new IllegalArgumentException("Route may not be null"); + } + if (this.isShutDown) { + throw new IllegalStateException("Connection pool shut down"); + } + return new PoolEntryFuture(this.lock, callback) { + + @Override + public E getPoolEntry( + long timeout, + TimeUnit tunit) + throws InterruptedException, TimeoutException, IOException { + return getPoolEntryBlocking(route, state, timeout, tunit, this); + } + + }; + } + + /** + * Attempts to lease a connection for the given route and with the given + * state from the pool. + *

    + * Please note that this class does not maintain its own pool of execution + * {@link Thread}s. Therefore, one must call {@link Future#get()} + * or {@link Future#get(long, TimeUnit)} method on the {@link Future} + * returned by this method in order for the lease operation to complete. + * + * @param route route of the connection. + * @param state arbitrary object that represents a particular state + * (usually a security principal or a unique token identifying + * the user whose credentials have been used while establishing the connection). + * May be null. + * @return future for a leased pool entry. + */ + public Future lease(final T route, final Object state) { + return lease(route, state, null); + } + + private E getPoolEntryBlocking( + final T route, final Object state, + final long timeout, final TimeUnit tunit, + final PoolEntryFuture future) + throws IOException, InterruptedException, TimeoutException { + + Date deadline = null; + if (timeout > 0) { + deadline = new Date + (System.currentTimeMillis() + tunit.toMillis(timeout)); + } + + this.lock.lock(); + try { + RouteSpecificPool pool = getPool(route); + E entry = null; + while (entry == null) { + if (this.isShutDown) { + throw new IllegalStateException("Connection pool shut down"); + } + for (;;) { + entry = pool.getFree(state); + if (entry == null) { + break; + } + if (entry.isClosed() || entry.isExpired(System.currentTimeMillis())) { + entry.close(); + this.available.remove(entry); + pool.free(entry, false); + } else { + break; + } + } + if (entry != null) { + this.available.remove(entry); + this.leased.add(entry); + return entry; + } + + // New connection is needed + int maxPerRoute = getMax(route); + // Shrink the pool prior to allocating a new connection + int excess = Math.max(0, pool.getAllocatedCount() + 1 - maxPerRoute); + if (excess > 0) { + for (int i = 0; i < excess; i++) { + E lastUsed = pool.getLastUsed(); + if (lastUsed == null) { + break; + } + lastUsed.close(); + this.available.remove(lastUsed); + pool.remove(lastUsed); + } + } + + if (pool.getAllocatedCount() < maxPerRoute) { + int totalUsed = this.leased.size(); + int freeCapacity = Math.max(this.maxTotal - totalUsed, 0); + if (freeCapacity > 0) { + int totalAvailable = this.available.size(); + if (totalAvailable > freeCapacity - 1) { + if (!this.available.isEmpty()) { + E lastUsed = this.available.removeLast(); + lastUsed.close(); + RouteSpecificPool otherpool = getPool(lastUsed.getRoute()); + otherpool.remove(lastUsed); + } + } + C conn = this.connFactory.create(route); + entry = pool.add(conn); + this.leased.add(entry); + return entry; + } + } + + boolean success = false; + try { + pool.queue(future); + this.pending.add(future); + success = future.await(deadline); + } finally { + // In case of 'success', we were woken up by the + // connection pool and should now have a connection + // waiting for us, or else we're shutting down. + // Just continue in the loop, both cases are checked. + pool.unqueue(future); + this.pending.remove(future); + } + // check for spurious wakeup vs. timeout + if (!success && (deadline != null) && + (deadline.getTime() <= System.currentTimeMillis())) { + break; + } + } + throw new TimeoutException("Timeout waiting for connection"); + } finally { + this.lock.unlock(); + } + } + + private void notifyPending(final RouteSpecificPool pool) { + PoolEntryFuture future = pool.nextPending(); + if (future != null) { + this.pending.remove(future); + } else { + future = this.pending.poll(); + } + if (future != null) { + future.wakeup(); + } + } + + public void release(E entry, boolean reusable) { + this.lock.lock(); + try { + if (this.leased.remove(entry)) { + RouteSpecificPool pool = getPool(entry.getRoute()); + pool.free(entry, reusable); + if (reusable && !this.isShutDown) { + this.available.addFirst(entry); + } else { + entry.close(); + } + notifyPending(pool); + } + } finally { + this.lock.unlock(); + } + } + + private int getMax(final T route) { + Integer v = this.maxPerRoute.get(route); + if (v != null) { + return v.intValue(); + } else { + return this.defaultMaxPerRoute; + } + } + + public void setMaxTotal(int max) { + if (max <= 0) { + throw new IllegalArgumentException("Max value may not be negative or zero"); + } + this.lock.lock(); + try { + this.maxTotal = max; + } finally { + this.lock.unlock(); + } + } + + public int getMaxTotal() { + this.lock.lock(); + try { + return this.maxTotal; + } finally { + this.lock.unlock(); + } + } + + public void setDefaultMaxPerRoute(int max) { + if (max <= 0) { + throw new IllegalArgumentException("Max value may not be negative or zero"); + } + this.lock.lock(); + try { + this.defaultMaxPerRoute = max; + } finally { + this.lock.unlock(); + } + } + + public int getDefaultMaxPerRoute() { + this.lock.lock(); + try { + return this.defaultMaxPerRoute; + } finally { + this.lock.unlock(); + } + } + + public void setMaxPerRoute(final T route, int max) { + if (route == null) { + throw new IllegalArgumentException("Route may not be null"); + } + if (max <= 0) { + throw new IllegalArgumentException("Max value may not be negative or zero"); + } + this.lock.lock(); + try { + this.maxPerRoute.put(route, max); + } finally { + this.lock.unlock(); + } + } + + public int getMaxPerRoute(T route) { + if (route == null) { + throw new IllegalArgumentException("Route may not be null"); + } + this.lock.lock(); + try { + return getMax(route); + } finally { + this.lock.unlock(); + } + } + + public PoolStats getTotalStats() { + this.lock.lock(); + try { + return new PoolStats( + this.leased.size(), + this.pending.size(), + this.available.size(), + this.maxTotal); + } finally { + this.lock.unlock(); + } + } + + public PoolStats getStats(final T route) { + if (route == null) { + throw new IllegalArgumentException("Route may not be null"); + } + this.lock.lock(); + try { + RouteSpecificPool pool = getPool(route); + return new PoolStats( + pool.getLeasedCount(), + pool.getPendingCount(), + pool.getAvailableCount(), + getMax(route)); + } finally { + this.lock.unlock(); + } + } + + /** + * Closes connections that have been idle longer than the given period + * of time and evicts them from the pool. + * + * @param idletime maximum idle time. + * @param tunit time unit. + */ + public void closeIdle(long idletime, final TimeUnit tunit) { + if (tunit == null) { + throw new IllegalArgumentException("Time unit must not be null."); + } + long time = tunit.toMillis(idletime); + if (time < 0) { + time = 0; + } + long deadline = System.currentTimeMillis() - time; + this.lock.lock(); + try { + Iterator it = this.available.iterator(); + while (it.hasNext()) { + E entry = it.next(); + if (entry.getUpdated() <= deadline) { + entry.close(); + RouteSpecificPool pool = getPool(entry.getRoute()); + pool.remove(entry); + it.remove(); + notifyPending(pool); + } + } + } finally { + this.lock.unlock(); + } + } + + /** + * Closes expired connections and evicts them from the pool. + */ + public void closeExpired() { + long now = System.currentTimeMillis(); + this.lock.lock(); + try { + Iterator it = this.available.iterator(); + while (it.hasNext()) { + E entry = it.next(); + if (entry.isExpired(now)) { + entry.close(); + RouteSpecificPool pool = getPool(entry.getRoute()); + pool.remove(entry); + it.remove(); + notifyPending(pool); + } + } + } finally { + this.lock.unlock(); + } + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("[leased: "); + buffer.append(this.leased); + buffer.append("][available: "); + buffer.append(this.available); + buffer.append("][pending: "); + buffer.append(this.pending); + buffer.append("]"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/pool/ConnFactory.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/pool/ConnFactory.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/pool/ConnFactory.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,44 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.pool; + +import java.io.IOException; + +/** + * Factory for poolable blocking connections. + * + * @param the route type that represents the opposite endpoint of a pooled + * connection. + * @param the connection type. + * @since 4.2 + */ +public interface ConnFactory { + + C create(T route) throws IOException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/pool/ConnPool.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/pool/ConnPool.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/pool/ConnPool.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,68 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.pool; + +import java.util.concurrent.Future; + +import org.apache.http.concurrent.FutureCallback; + +/** + * ConnPool represents a shared pool connections can be leased from + * and released back to. + * + * @param the route type that represents the opposite endpoint of a pooled + * connection. + * @param the type of the pool entry containing a pooled connection. + * @since 4.2 + */ +public interface ConnPool { + + /** + * Attempts to lease a connection for the given route and with the given + * state from the pool. + * + * @param route route of the connection. + * @param state arbitrary object that represents a particular state + * (usually a security principal or a unique token identifying + * the user whose credentials have been used while establishing the connection). + * May be null. + * @param callback operation completion callback. + * + * @return future for a leased pool entry. + */ + Future lease(final T route, final Object state, final FutureCallback callback); + + /** + * Releases the pool entry back to the pool. + * + * @param entry pool entry leased from the pool + * @param reusable flag indicating whether or not the released connection + * is in a consistent state and is safe for further use. + */ + void release(E entry, boolean reusable); + +} Index: 3rdParty_sources/httpcore/org/apache/http/pool/ConnPoolControl.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/pool/ConnPoolControl.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/pool/ConnPoolControl.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,56 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.pool; + +/** + * Interface to control runtime properties of a {@link ConnPool} such as + * maximum total number of connections or maximum connections per route + * allowed. + * + * @param the route type that represents the opposite endpoint of a pooled + * connection. + * @since 4.2 + */ +public interface ConnPoolControl { + + void setMaxTotal(int max); + + int getMaxTotal(); + + void setDefaultMaxPerRoute(int max); + + int getDefaultMaxPerRoute(); + + void setMaxPerRoute(final T route, int max); + + int getMaxPerRoute(final T route); + + PoolStats getTotalStats(); + + PoolStats getStats(final T route); + +} Index: 3rdParty_sources/httpcore/org/apache/http/pool/PoolEntry.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/pool/PoolEntry.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/pool/PoolEntry.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,190 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.pool; + +import java.util.concurrent.TimeUnit; + +import org.apache.http.annotation.GuardedBy; +import org.apache.http.annotation.ThreadSafe; + +/** + * Pool entry containing a pool connection object along with its route. + *

    + * The connection contained by the pool entry may have an expiration time which + * can be either set upon construction time or updated with + * the {@link #updateExpiry(long, TimeUnit)}. + *

    + * Pool entry may also have an object associated with it that represents + * a connection state (usually a security principal or a unique token identifying + * the user whose credentials have been used while establishing the connection). + * + * @param the route type that represents the opposite endpoint of a pooled + * connection. + * @param the connection type. + * @since 4.2 + */ +@ThreadSafe +public abstract class PoolEntry { + + private final String id; + private final T route; + private final C conn; + private final long created; + private final long validUnit; + + @GuardedBy("this") + private long updated; + + @GuardedBy("this") + private long expiry; + + private volatile Object state; + + /** + * Creates new PoolEntry instance. + * + * @param id unique identifier of the pool entry. May be null. + * @param route route to the opposite endpoint. + * @param conn the connection. + * @param timeToLive maximum time to live. May be zero if the connection + * does not have an expiry deadline. + * @param tunit time unit. + */ + public PoolEntry(final String id, final T route, final C conn, + final long timeToLive, final TimeUnit tunit) { + super(); + if (route == null) { + throw new IllegalArgumentException("Route may not be null"); + } + if (conn == null) { + throw new IllegalArgumentException("Connection may not be null"); + } + if (tunit == null) { + throw new IllegalArgumentException("Time unit may not be null"); + } + this.id = id; + this.route = route; + this.conn = conn; + this.created = System.currentTimeMillis(); + if (timeToLive > 0) { + this.validUnit = this.created + tunit.toMillis(timeToLive); + } else { + this.validUnit = Long.MAX_VALUE; + } + this.expiry = this.validUnit; + } + + /** + * Creates new PoolEntry instance without an expiry deadline. + * + * @param id unique identifier of the pool entry. May be null. + * @param route route to the opposite endpoint. + * @param conn the connection. + */ + public PoolEntry(final String id, final T route, final C conn) { + this(id, route, conn, 0, TimeUnit.MILLISECONDS); + } + + public String getId() { + return this.id; + } + + public T getRoute() { + return this.route; + } + + public C getConnection() { + return this.conn; + } + + public long getCreated() { + return this.created; + } + + public long getValidUnit() { + return this.validUnit; + } + + public Object getState() { + return this.state; + } + + public void setState(final Object state) { + this.state = state; + } + + public synchronized long getUpdated() { + return this.updated; + } + + public synchronized long getExpiry() { + return this.expiry; + } + + public synchronized void updateExpiry(final long time, final TimeUnit tunit) { + if (tunit == null) { + throw new IllegalArgumentException("Time unit may not be null"); + } + this.updated = System.currentTimeMillis(); + long newExpiry; + if (time > 0) { + newExpiry = this.updated + tunit.toMillis(time); + } else { + newExpiry = Long.MAX_VALUE; + } + this.expiry = Math.min(newExpiry, this.validUnit); + } + + public synchronized boolean isExpired(final long now) { + return now >= this.expiry; + } + + /** + * Invalidates the pool entry and closes the pooled connection associated + * with it. + */ + public abstract void close(); + + /** + * Returns true if the pool entry has been invalidated. + */ + public abstract boolean isClosed(); + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("[id:"); + buffer.append(this.id); + buffer.append("][route:"); + buffer.append(this.route); + buffer.append("][state:"); + buffer.append(this.state); + buffer.append("]"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/pool/PoolEntryFuture.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/pool/PoolEntryFuture.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/pool/PoolEntryFuture.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,153 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.pool; + +import java.io.IOException; +import java.util.Date; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; + +import org.apache.http.annotation.ThreadSafe; +import org.apache.http.concurrent.FutureCallback; + +@ThreadSafe +abstract class PoolEntryFuture implements Future { + + private final Lock lock; + private final FutureCallback callback; + private final Condition condition; + private volatile boolean cancelled; + private volatile boolean completed; + private T result; + + PoolEntryFuture(final Lock lock, final FutureCallback callback) { + super(); + this.lock = lock; + this.condition = lock.newCondition(); + this.callback = callback; + } + + public boolean cancel(boolean mayInterruptIfRunning) { + this.lock.lock(); + try { + if (this.completed) { + return false; + } + this.completed = true; + this.cancelled = true; + if (this.callback != null) { + this.callback.cancelled(); + } + this.condition.signalAll(); + return true; + } finally { + this.lock.unlock(); + } + } + + public boolean isCancelled() { + return this.cancelled; + } + + public boolean isDone() { + return this.completed; + } + + public T get() throws InterruptedException, ExecutionException { + try { + return get(0, TimeUnit.MILLISECONDS); + } catch (TimeoutException ex) { + throw new ExecutionException(ex); + } + } + + public T get( + long timeout, + final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + this.lock.lock(); + try { + if (this.completed) { + return this.result; + } + this.result = getPoolEntry(timeout, unit); + this.completed = true; + if (this.callback != null) { + this.callback.completed(this.result); + } + return result; + } catch (IOException ex) { + this.completed = true; + this.result = null; + if (this.callback != null) { + this.callback.failed(ex); + } + throw new ExecutionException(ex); + } finally { + this.lock.unlock(); + } + } + + protected abstract T getPoolEntry( + long timeout, TimeUnit unit) throws IOException, InterruptedException, TimeoutException; + + public boolean await(final Date deadline) throws InterruptedException { + this.lock.lock(); + try { + if (this.cancelled) { + throw new InterruptedException("Operation interrupted"); + } + boolean success = false; + if (deadline != null) { + success = this.condition.awaitUntil(deadline); + } else { + this.condition.await(); + success = true; + } + if (this.cancelled) { + throw new InterruptedException("Operation interrupted"); + } + return success; + } finally { + this.lock.unlock(); + } + + } + + public void wakeup() { + this.lock.lock(); + try { + this.condition.signalAll(); + } finally { + this.lock.unlock(); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/pool/PoolStats.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/pool/PoolStats.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/pool/PoolStats.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,84 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.pool; + +import org.apache.http.annotation.Immutable; + +/** + * Pool statistics. + * + * @since 4.2 + * + */ +@Immutable +public class PoolStats { + + private final int leased; + private final int pending; + private final int available; + private final int max; + + public PoolStats(int leased, int pending, int free, int max) { + super(); + this.leased = leased; + this.pending = pending; + this.available = free; + this.max = max; + } + + public int getLeased() { + return this.leased; + } + + public int getPending() { + return this.pending; + } + + public int getAvailable() { + return this.available; + } + + public int getMax() { + return this.max; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("[leased: "); + buffer.append(this.leased); + buffer.append("; pending: "); + buffer.append(this.pending); + buffer.append("; available: "); + buffer.append(this.available); + buffer.append("; max: "); + buffer.append(this.max); + buffer.append("]"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/pool/RouteSpecificPool.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/pool/RouteSpecificPool.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/pool/RouteSpecificPool.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,188 @@ +/* + * ==================================================================== + * + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.pool; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Set; + +import org.apache.http.annotation.NotThreadSafe; + +@NotThreadSafe +abstract class RouteSpecificPool> { + + private final T route; + private final Set leased; + private final LinkedList available; + private final LinkedList> pending; + + RouteSpecificPool(final T route) { + super(); + this.route = route; + this.leased = new HashSet(); + this.available = new LinkedList(); + this.pending = new LinkedList>(); + } + + protected abstract E createEntry(C conn); + + public final T getRoute() { + return route; + } + + public int getLeasedCount() { + return this.leased.size(); + } + + public int getPendingCount() { + return this.pending.size(); + } + + public int getAvailableCount() { + return this.available.size(); + } + + public int getAllocatedCount() { + return this.available.size() + this.leased.size(); + } + + public E getFree(final Object state) { + if (!this.available.isEmpty()) { + if (state != null) { + Iterator it = this.available.iterator(); + while (it.hasNext()) { + E entry = it.next(); + if (state.equals(entry.getState())) { + it.remove(); + this.leased.add(entry); + return entry; + } + } + } + Iterator it = this.available.iterator(); + while (it.hasNext()) { + E entry = it.next(); + if (entry.getState() == null) { + it.remove(); + this.leased.add(entry); + return entry; + } + } + } + return null; + } + + public E getLastUsed() { + if (!this.available.isEmpty()) { + return this.available.getLast(); + } else { + return null; + } + } + + public boolean remove(final E entry) { + if (entry == null) { + throw new IllegalArgumentException("Pool entry may not be null"); + } + if (!this.available.remove(entry)) { + if (!this.leased.remove(entry)) { + return false; + } + } + return true; + } + + public void free(final E entry, boolean reusable) { + if (entry == null) { + throw new IllegalArgumentException("Pool entry may not be null"); + } + boolean found = this.leased.remove(entry); + if (!found) { + throw new IllegalStateException("Entry " + entry + + " has not been leased from this pool"); + } + if (reusable) { + this.available.addFirst(entry); + } + } + + public E add(final C conn) { + E entry = createEntry(conn); + this.leased.add(entry); + return entry; + } + + public void queue(final PoolEntryFuture future) { + if (future == null) { + return; + } + this.pending.add(future); + } + + public PoolEntryFuture nextPending() { + return this.pending.poll(); + } + + public void unqueue(final PoolEntryFuture future) { + if (future == null) + return; + + this.pending.remove(future); + } + + public void shutdown() { + for (PoolEntryFuture future: this.pending) { + future.cancel(true); + } + this.pending.clear(); + for (E entry: this.available) { + entry.close(); + } + this.available.clear(); + for (E entry: this.leased) { + entry.close(); + } + this.leased.clear(); + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + buffer.append("[route: "); + buffer.append(this.route); + buffer.append("][leased: "); + buffer.append(this.leased.size()); + buffer.append("][available: "); + buffer.append(this.available.size()); + buffer.append("][pending: "); + buffer.append(this.pending.size()); + buffer.append("]"); + return buffer.toString(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/pool/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/pool/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/pool/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,35 @@ + + + + + +Synchronous (blocking) connection pool components. + + Index: 3rdParty_sources/httpcore/org/apache/http/protocol/BasicHttpContext.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/BasicHttpContext.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/BasicHttpContext.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,110 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * Default implementation of {@link HttpContext}. + *

    + * Please note methods of this class are not synchronized and therefore may + * be threading unsafe. + * + * @since 4.0 + */ +@NotThreadSafe +public class BasicHttpContext implements HttpContext { + + private final HttpContext parentContext; + private Map map = null; + + public BasicHttpContext() { + this(null); + } + + public BasicHttpContext(final HttpContext parentContext) { + super(); + this.parentContext = parentContext; + } + + public Object getAttribute(final String id) { + if (id == null) { + throw new IllegalArgumentException("Id may not be null"); + } + Object obj = null; + if (this.map != null) { + obj = this.map.get(id); + } + if (obj == null && this.parentContext != null) { + obj = this.parentContext.getAttribute(id); + } + return obj; + } + + public void setAttribute(final String id, final Object obj) { + if (id == null) { + throw new IllegalArgumentException("Id may not be null"); + } + if (this.map == null) { + this.map = new HashMap(); + } + this.map.put(id, obj); + } + + public Object removeAttribute(final String id) { + if (id == null) { + throw new IllegalArgumentException("Id may not be null"); + } + if (this.map != null) { + return this.map.remove(id); + } else { + return null; + } + } + + /** + * @since 4.2 + */ + public void clear() { + if (this.map != null) { + this.map.clear(); + } + } + + @Override + public String toString() { + if (this.map != null) { + return this.map.toString(); + } else { + return "{}"; + } + } +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/BasicHttpProcessor.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/BasicHttpProcessor.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/BasicHttpProcessor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,247 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.annotation.NotThreadSafe; + +/** + * Default implementation of {@link HttpProcessor}. + *

    + * Please note access to the internal structures of this class is not + * synchronized and therefore this class may be thread-unsafe. + * + * @since 4.0 + */ +@NotThreadSafe +public final class BasicHttpProcessor implements + HttpProcessor, HttpRequestInterceptorList, HttpResponseInterceptorList, Cloneable { + + // Don't allow direct access, as nulls are not allowed + protected final List requestInterceptors = new ArrayList(); + protected final List responseInterceptors = new ArrayList(); + + public void addRequestInterceptor(final HttpRequestInterceptor itcp) { + if (itcp == null) { + return; + } + this.requestInterceptors.add(itcp); + } + + public void addRequestInterceptor( + final HttpRequestInterceptor itcp, int index) { + if (itcp == null) { + return; + } + this.requestInterceptors.add(index, itcp); + } + + public void addResponseInterceptor( + final HttpResponseInterceptor itcp, int index) { + if (itcp == null) { + return; + } + this.responseInterceptors.add(index, itcp); + } + + public void removeRequestInterceptorByClass(final Class clazz) { + for (Iterator it = this.requestInterceptors.iterator(); + it.hasNext(); ) { + Object request = it.next(); + if (request.getClass().equals(clazz)) { + it.remove(); + } + } + } + + public void removeResponseInterceptorByClass(final Class clazz) { + for (Iterator it = this.responseInterceptors.iterator(); + it.hasNext(); ) { + Object request = it.next(); + if (request.getClass().equals(clazz)) { + it.remove(); + } + } + } + + public final void addInterceptor(final HttpRequestInterceptor interceptor) { + addRequestInterceptor(interceptor); + } + + public final void addInterceptor(final HttpRequestInterceptor interceptor, int index) { + addRequestInterceptor(interceptor, index); + } + + public int getRequestInterceptorCount() { + return this.requestInterceptors.size(); + } + + public HttpRequestInterceptor getRequestInterceptor(int index) { + if ((index < 0) || (index >= this.requestInterceptors.size())) + return null; + return this.requestInterceptors.get(index); + } + + public void clearRequestInterceptors() { + this.requestInterceptors.clear(); + } + + public void addResponseInterceptor(final HttpResponseInterceptor itcp) { + if (itcp == null) { + return; + } + this.responseInterceptors.add(itcp); + } + + public final void addInterceptor(final HttpResponseInterceptor interceptor) { + addResponseInterceptor(interceptor); + } + + public final void addInterceptor(final HttpResponseInterceptor interceptor, int index) { + addResponseInterceptor(interceptor, index); + } + + public int getResponseInterceptorCount() { + return this.responseInterceptors.size(); + } + + public HttpResponseInterceptor getResponseInterceptor(int index) { + if ((index < 0) || (index >= this.responseInterceptors.size())) + return null; + return this.responseInterceptors.get(index); + } + + public void clearResponseInterceptors() { + this.responseInterceptors.clear(); + } + + /** + * Sets the interceptor lists. + * First, both interceptor lists maintained by this processor + * will be cleared. + * Subsequently, + * elements of the argument list that are request interceptors will be + * added to the request interceptor list. + * Elements that are response interceptors will be + * added to the response interceptor list. + * Elements that are both request and response interceptor will be + * added to both lists. + * Elements that are neither request nor response interceptor + * will be ignored. + * + * @param list the list of request and response interceptors + * from which to initialize + */ + public void setInterceptors(final List list) { + if (list == null) { + throw new IllegalArgumentException("List must not be null."); + } + this.requestInterceptors.clear(); + this.responseInterceptors.clear(); + for (int i = 0; i < list.size(); i++) { + Object obj = list.get(i); + if (obj instanceof HttpRequestInterceptor) { + addInterceptor((HttpRequestInterceptor)obj); + } + if (obj instanceof HttpResponseInterceptor) { + addInterceptor((HttpResponseInterceptor)obj); + } + } + } + + /** + * Clears both interceptor lists maintained by this processor. + */ + public void clearInterceptors() { + clearRequestInterceptors(); + clearResponseInterceptors(); + } + + public void process( + final HttpRequest request, + final HttpContext context) + throws IOException, HttpException { + for (int i = 0; i < this.requestInterceptors.size(); i++) { + HttpRequestInterceptor interceptor = + this.requestInterceptors.get(i); + interceptor.process(request, context); + } + } + + public void process( + final HttpResponse response, + final HttpContext context) + throws IOException, HttpException { + for (int i = 0; i < this.responseInterceptors.size(); i++) { + HttpResponseInterceptor interceptor = + this.responseInterceptors.get(i); + interceptor.process(response, context); + } + } + + /** + * Sets up the target to have the same list of interceptors + * as the current instance. + * + * @param target object to be initialised + */ + protected void copyInterceptors(final BasicHttpProcessor target) { + target.requestInterceptors.clear(); + target.requestInterceptors.addAll(this.requestInterceptors); + target.responseInterceptors.clear(); + target.responseInterceptors.addAll(this.responseInterceptors); + } + + /** + * Creates a copy of this instance + * + * @return new instance of the BasicHttpProcessor + */ + public BasicHttpProcessor copy() { + BasicHttpProcessor clone = new BasicHttpProcessor(); + copyInterceptors(clone); + return clone; + } + + @Override + public Object clone() throws CloneNotSupportedException { + BasicHttpProcessor clone = (BasicHttpProcessor) super.clone(); + copyInterceptors(clone); + return clone; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/DefaultedHttpContext.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/DefaultedHttpContext.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/DefaultedHttpContext.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,85 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * {@link HttpContext} implementation that delegates resolution of an attribute + * to the given default {@link HttpContext} instance if the attribute is not + * present in the local one. The state of the local context can be mutated, + * whereas the default context is treated as read-only. + * + * @since 4.0 + */ +@NotThreadSafe +public final class DefaultedHttpContext implements HttpContext { + + private final HttpContext local; + private final HttpContext defaults; + + public DefaultedHttpContext(final HttpContext local, final HttpContext defaults) { + super(); + if (local == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + this.local = local; + this.defaults = defaults; + } + + public Object getAttribute(final String id) { + Object obj = this.local.getAttribute(id); + if (obj == null) { + return this.defaults.getAttribute(id); + } else { + return obj; + } + } + + public Object removeAttribute(final String id) { + return this.local.removeAttribute(id); + } + + public void setAttribute(final String id, final Object obj) { + this.local.setAttribute(id, obj); + } + + public HttpContext getDefaults() { + return this.defaults; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("[local: ").append(this.local); + buf.append("defaults: ").append(this.defaults); + buf.append("]"); + return buf.toString(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/ExecutionContext.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/ExecutionContext.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/ExecutionContext.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +/** + * {@link HttpContext} attribute names for protocol execution. + * + * @since 4.0 + */ +public interface ExecutionContext { + + /** + * Attribute name of a {@link org.apache.http.HttpConnection} object that + * represents the actual HTTP connection. + */ + public static final String HTTP_CONNECTION = "http.connection"; + + /** + * Attribute name of a {@link org.apache.http.HttpRequest} object that + * represents the actual HTTP request. + */ + public static final String HTTP_REQUEST = "http.request"; + + /** + * Attribute name of a {@link org.apache.http.HttpResponse} object that + * represents the actual HTTP response. + */ + public static final String HTTP_RESPONSE = "http.response"; + + /** + * Attribute name of a {@link org.apache.http.HttpHost} object that + * represents the connection target. + */ + public static final String HTTP_TARGET_HOST = "http.target_host"; + + /** + * Attribute name of a {@link org.apache.http.HttpHost} object that + * represents the connection proxy. + */ + public static final String HTTP_PROXY_HOST = "http.proxy_host"; + + /** + * Attribute name of a {@link Boolean} object that represents the + * the flag indicating whether the actual request has been fully transmitted + * to the target host. + */ + public static final String HTTP_REQ_SENT = "http.request_sent"; + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HTTP.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HTTP.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HTTP.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,135 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.nio.charset.Charset; + +import org.apache.http.Consts; + +/** + * Constants and static helpers related to the HTTP protocol. + * + * @since 4.0 + */ +public final class HTTP { + + public static final int CR = 13; // + public static final int LF = 10; // + public static final int SP = 32; // + public static final int HT = 9; // + + /** HTTP header definitions */ + public static final String TRANSFER_ENCODING = "Transfer-Encoding"; + public static final String CONTENT_LEN = "Content-Length"; + public static final String CONTENT_TYPE = "Content-Type"; + public static final String CONTENT_ENCODING = "Content-Encoding"; + public static final String EXPECT_DIRECTIVE = "Expect"; + public static final String CONN_DIRECTIVE = "Connection"; + public static final String TARGET_HOST = "Host"; + public static final String USER_AGENT = "User-Agent"; + public static final String DATE_HEADER = "Date"; + public static final String SERVER_HEADER = "Server"; + + /** HTTP expectations */ + public static final String EXPECT_CONTINUE = "100-continue"; + + /** HTTP connection control */ + public static final String CONN_CLOSE = "Close"; + public static final String CONN_KEEP_ALIVE = "Keep-Alive"; + + /** Transfer encoding definitions */ + public static final String CHUNK_CODING = "chunked"; + public static final String IDENTITY_CODING = "identity"; + + public static final Charset DEF_CONTENT_CHARSET = Consts.ISO_8859_1; + public static final Charset DEF_PROTOCOL_CHARSET = Consts.ASCII; + + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String UTF_8 = "UTF-8"; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String UTF_16 = "UTF-16"; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String US_ASCII = "US-ASCII"; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String ASCII = "ASCII"; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String ISO_8859_1 = "ISO-8859-1"; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String DEFAULT_CONTENT_CHARSET = ISO_8859_1; + /** + * @deprecated (4.2) + */ + @Deprecated + public static final String DEFAULT_PROTOCOL_CHARSET = US_ASCII; + /** + * @deprecated (4.2) + */ + @Deprecated + public final static String OCTET_STREAM_TYPE = "application/octet-stream"; + /** + * @deprecated (4.2) + */ + @Deprecated + public final static String PLAIN_TEXT_TYPE = "text/plain"; + /** + * @deprecated (4.2) + */ + @Deprecated + public final static String CHARSET_PARAM = "; charset="; + /** + * @deprecated (4.2) + */ + @Deprecated + public final static String DEFAULT_CONTENT_TYPE = OCTET_STREAM_TYPE; + + public static boolean isWhitespace(char ch) { + return ch == SP || ch == HT || ch == CR || ch == LF; + } + + private HTTP() { + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpContext.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpContext.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpContext.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.util.HashMap; + +/** + * HttpContext represents execution state of an HTTP process. It is a structure + * that can be used to map an attribute name to an attribute value. Internally + * HTTP context implementations are usually backed by a {@link HashMap}. + *

    + * The primary purpose of the HTTP context is to facilitate information sharing + * among various logically related components. HTTP context can be used + * to store a processing state for one message or several consecutive messages. + * Multiple logically related messages can participate in a logical session + * if the same context is reused between consecutive messages. + * + * @since 4.0 + */ +public interface HttpContext { + + /** The prefix reserved for use by HTTP components. "http." */ + public static final String RESERVED_PREFIX = "http."; + + /** + * Obtains attribute with the given name. + * + * @param id the attribute name. + * @return attribute value, or null if not set. + */ + Object getAttribute(String id); + + /** + * Sets value of the attribute with the given name. + * + * @param id the attribute name. + * @param obj the attribute value. + */ + void setAttribute(String id, Object obj); + + /** + * Removes attribute with the given name from the context. + * + * @param id the attribute name. + * @return attribute value, or null if not set. + */ + Object removeAttribute(String id); + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpDateGenerator.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpDateGenerator.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpDateGenerator.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,77 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import org.apache.http.annotation.GuardedBy; +import org.apache.http.annotation.ThreadSafe; + +/** + * Generates a date in the format required by the HTTP protocol. + * + * @since 4.0 + */ +@ThreadSafe +public class HttpDateGenerator { + + /** Date format pattern used to generate the header in RFC 1123 format. */ + public static final + String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; + + /** The time zone to use in the date header. */ + public static final TimeZone GMT = TimeZone.getTimeZone("GMT"); + + @GuardedBy("this") + private final DateFormat dateformat; + @GuardedBy("this") + private long dateAsLong = 0L; + @GuardedBy("this") + private String dateAsText = null; + + public HttpDateGenerator() { + super(); + this.dateformat = new SimpleDateFormat(PATTERN_RFC1123, Locale.US); + this.dateformat.setTimeZone(GMT); + } + + public synchronized String getCurrentDate() { + long now = System.currentTimeMillis(); + if (now - this.dateAsLong > 1000) { + // Generate new date string + this.dateAsText = this.dateformat.format(new Date(now)); + this.dateAsLong = now; + } + return this.dateAsText; + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpExpectationVerifier.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpExpectationVerifier.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpExpectationVerifier.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,81 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; + +/** + * Defines an interface to verify whether an incoming HTTP request meets + * the target server's expectations. + *

    + * The Expect request-header field is used to indicate that particular + * server behaviors are required by the client. + *

    + *
    + *    Expect       =  "Expect" ":" 1#expectation
    + *
    + *    expectation  =  "100-continue" | expectation-extension
    + *    expectation-extension =  token [ "=" ( token | quoted-string )
    + *                             *expect-params ]
    + *    expect-params =  ";" token [ "=" ( token | quoted-string ) ]
    + *
    + *

    + * A server that does not understand or is unable to comply with any of + * the expectation values in the Expect field of a request MUST respond + * with appropriate error status. The server MUST respond with a 417 + * (Expectation Failed) status if any of the expectations cannot be met + * or, if there are other problems with the request, some other 4xx + * status. + *

    + * + * @since 4.0 + */ +public interface HttpExpectationVerifier { + + /** + * Verifies whether the given request meets the server's expectations. + *

    + * If the request fails to meet particular criteria, this method can + * trigger a terminal response back to the client by setting the status + * code of the response object to a value greater or equal to + * 200. In this case the client will not have to transmit + * the request body. If the request meets expectations this method can + * terminate without modifying the response object. Per default the status + * code of the response object will be set to 100. + * + * @param request the HTTP request. + * @param response the HTTP response. + * @param context the HTTP context. + * @throws HttpException in case of an HTTP protocol violation. + */ + void verify(HttpRequest request, HttpResponse response, HttpContext context) + throws HttpException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpProcessor.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpProcessor.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpProcessor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,55 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponseInterceptor; + +/** + * HTTP protocol processor is a collection of protocol interceptors that + * implements the 'Chain of Responsibility' pattern, where each individual + * protocol interceptor is expected to work on a particular aspect of the HTTP + * protocol the interceptor is responsible for. + *

    + * Usually the order in which interceptors are executed should not matter as + * long as they do not depend on a particular state of the execution context. + * If protocol interceptors have interdependencies and therefore must be + * executed in a particular order, they should be added to the protocol + * processor in the same sequence as their expected execution order. + *

    + * Protocol interceptors must be implemented as thread-safe. Similarly to + * servlets, protocol interceptors should not use instance variables unless + * access to those variables is synchronized. + * + * @since 4.0 + */ +public interface HttpProcessor + extends HttpRequestInterceptor, HttpResponseInterceptor { + + // no additional methods +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestExecutor.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestExecutor.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestExecutor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,348 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpClientConnection; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolException; +import org.apache.http.ProtocolVersion; +import org.apache.http.annotation.Immutable; +import org.apache.http.params.CoreProtocolPNames; + +/** + * HttpRequestExecutor is a client side HTTP protocol handler based + * on the blocking (classic) I/O model. + *

    + * HttpRequestExecutor relies on {@link HttpProcessor} to generate + * mandatory protocol headers for all outgoing messages and apply common, + * cross-cutting message transformations to all incoming and outgoing messages. + * Application specific processing can be implemented outside + * HttpRequestExecutor once the request has been executed and + * a response has been received. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#WAIT_FOR_CONTINUE}
    • + *
    + * + * @since 4.0 + */ +@Immutable +public class HttpRequestExecutor { + + /** + * Create a new request executor. + */ + public HttpRequestExecutor() { + super(); + } + + /** + * Decide whether a response comes with an entity. + * The implementation in this class is based on RFC 2616. + *
    + * Derived executors can override this method to handle + * methods and response codes not specified in RFC 2616. + * + * @param request the request, to obtain the executed method + * @param response the response, to obtain the status code + */ + protected boolean canResponseHaveBody(final HttpRequest request, + final HttpResponse response) { + + if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) { + return false; + } + int status = response.getStatusLine().getStatusCode(); + return status >= HttpStatus.SC_OK + && status != HttpStatus.SC_NO_CONTENT + && status != HttpStatus.SC_NOT_MODIFIED + && status != HttpStatus.SC_RESET_CONTENT; + } + + /** + * Sends the request and obtain a response. + * + * @param request the request to execute. + * @param conn the connection over which to execute the request. + * + * @return the response to the request. + * + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + public HttpResponse execute( + final HttpRequest request, + final HttpClientConnection conn, + final HttpContext context) + throws IOException, HttpException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (conn == null) { + throw new IllegalArgumentException("Client connection may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + try { + HttpResponse response = doSendRequest(request, conn, context); + if (response == null) { + response = doReceiveResponse(request, conn, context); + } + return response; + } catch (IOException ex) { + closeConnection(conn); + throw ex; + } catch (HttpException ex) { + closeConnection(conn); + throw ex; + } catch (RuntimeException ex) { + closeConnection(conn); + throw ex; + } + } + + private final static void closeConnection(final HttpClientConnection conn) { + try { + conn.close(); + } catch (IOException ignore) { + } + } + + /** + * Pre-process the given request using the given protocol processor and + * initiates the process of request execution. + * + * @param request the request to prepare + * @param processor the processor to use + * @param context the context for sending the request + * + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + public void preProcess( + final HttpRequest request, + final HttpProcessor processor, + final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (processor == null) { + throw new IllegalArgumentException("HTTP processor may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + context.setAttribute(ExecutionContext.HTTP_REQUEST, request); + processor.process(request, context); + } + + /** + * Send the given request over the given connection. + *

    + * This method also handles the expect-continue handshake if necessary. + * If it does not have to handle an expect-continue handshake, it will + * not use the connection for reading or anything else that depends on + * data coming in over the connection. + * + * @param request the request to send, already + * {@link #preProcess preprocessed} + * @param conn the connection over which to send the request, + * already established + * @param context the context for sending the request + * + * @return a terminal response received as part of an expect-continue + * handshake, or + * null if the expect-continue handshake is not used + * + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + protected HttpResponse doSendRequest( + final HttpRequest request, + final HttpClientConnection conn, + final HttpContext context) + throws IOException, HttpException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (conn == null) { + throw new IllegalArgumentException("HTTP connection may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + HttpResponse response = null; + + context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn); + context.setAttribute(ExecutionContext.HTTP_REQ_SENT, Boolean.FALSE); + + conn.sendRequestHeader(request); + if (request instanceof HttpEntityEnclosingRequest) { + // Check for expect-continue handshake. We have to flush the + // headers and wait for an 100-continue response to handle it. + // If we get a different response, we must not send the entity. + boolean sendentity = true; + final ProtocolVersion ver = + request.getRequestLine().getProtocolVersion(); + if (((HttpEntityEnclosingRequest) request).expectContinue() && + !ver.lessEquals(HttpVersion.HTTP_1_0)) { + + conn.flush(); + // As suggested by RFC 2616 section 8.2.3, we don't wait for a + // 100-continue response forever. On timeout, send the entity. + int tms = request.getParams().getIntParameter( + CoreProtocolPNames.WAIT_FOR_CONTINUE, 2000); + + if (conn.isResponseAvailable(tms)) { + response = conn.receiveResponseHeader(); + if (canResponseHaveBody(request, response)) { + conn.receiveResponseEntity(response); + } + int status = response.getStatusLine().getStatusCode(); + if (status < 200) { + if (status != HttpStatus.SC_CONTINUE) { + throw new ProtocolException( + "Unexpected response: " + response.getStatusLine()); + } + // discard 100-continue + response = null; + } else { + sendentity = false; + } + } + } + if (sendentity) { + conn.sendRequestEntity((HttpEntityEnclosingRequest) request); + } + } + conn.flush(); + context.setAttribute(ExecutionContext.HTTP_REQ_SENT, Boolean.TRUE); + return response; + } + + /** + * Waits for and receives a response. + * This method will automatically ignore intermediate responses + * with status code 1xx. + * + * @param request the request for which to obtain the response + * @param conn the connection over which the request was sent + * @param context the context for receiving the response + * + * @return the terminal response, not yet post-processed + * + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + protected HttpResponse doReceiveResponse( + final HttpRequest request, + final HttpClientConnection conn, + final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (conn == null) { + throw new IllegalArgumentException("HTTP connection may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + HttpResponse response = null; + int statuscode = 0; + + while (response == null || statuscode < HttpStatus.SC_OK) { + + response = conn.receiveResponseHeader(); + if (canResponseHaveBody(request, response)) { + conn.receiveResponseEntity(response); + } + statuscode = response.getStatusLine().getStatusCode(); + + } // while intermediate response + + return response; + + } + + /** + * Post-processes the given response using the given protocol processor and + * completes the process of request execution. + *

    + * This method does not read the response entity, if any. + * The connection over which content of the response entity is being + * streamed from cannot be reused until + * {@link org.apache.http.util.EntityUtils#consume(HttpEntity)} + * has been invoked. + * + * @param response the response object to post-process + * @param processor the processor to use + * @param context the context for post-processing the response + * + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + public void postProcess( + final HttpResponse response, + final HttpProcessor processor, + final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + if (processor == null) { + throw new IllegalArgumentException("HTTP processor may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + context.setAttribute(ExecutionContext.HTTP_RESPONSE, response); + processor.process(response, context); + } + +} // class HttpRequestExecutor Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestHandler.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestHandler.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestHandler.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,62 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; + +/** + * HttpRequestHandler represents a routine for processing of a specific group + * of HTTP requests. Protocol handlers are designed to take care of protocol + * specific aspects, whereas individual request handlers are expected to take + * care of application specific HTTP processing. The main purpose of a request + * handler is to generate a response object with a content entity to be sent + * back to the client in response to the given request + * + * @since 4.0 + */ +public interface HttpRequestHandler { + + /** + * Handles the request and produces a response to be sent back to + * the client. + * + * @param request the HTTP request. + * @param response the HTTP response. + * @param context the HTTP execution context. + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + void handle(HttpRequest request, HttpResponse response, HttpContext context) + throws HttpException, IOException; + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestHandlerRegistry.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestHandlerRegistry.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestHandlerRegistry.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,108 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.util.Map; + +import org.apache.http.annotation.ThreadSafe; + +/** + * Maintains a map of HTTP request handlers keyed by a request URI pattern. + *
    + * Patterns may have three formats: + *

      + *
    • *
    • + *
    • *<uri>
    • + *
    • <uri>*
    • + *
    + *
    + * This class can be used to resolve an instance of + * {@link HttpRequestHandler} matching a particular request URI. Usually the + * resolved request handler will be used to process the request with the + * specified request URI. + * + * @since 4.0 + */ +@ThreadSafe // provided injected dependencies are thread-safe +public class HttpRequestHandlerRegistry implements HttpRequestHandlerResolver { + + private final UriPatternMatcher matcher; + + public HttpRequestHandlerRegistry() { + matcher = new UriPatternMatcher(); + } + + /** + * Registers the given {@link HttpRequestHandler} as a handler for URIs + * matching the given pattern. + * + * @param pattern the pattern to register the handler for. + * @param handler the handler. + */ + public void register(final String pattern, final HttpRequestHandler handler) { + if (pattern == null) { + throw new IllegalArgumentException("URI request pattern may not be null"); + } + if (handler == null) { + throw new IllegalArgumentException("Request handler may not be null"); + } + matcher.register(pattern, handler); + } + + /** + * Removes registered handler, if exists, for the given pattern. + * + * @param pattern the pattern to unregister the handler for. + */ + public void unregister(final String pattern) { + matcher.unregister(pattern); + } + + /** + * Sets handlers from the given map. + * @param map the map containing handlers keyed by their URI patterns. + */ + public void setHandlers(final Map map) { + matcher.setObjects(map); + } + + /** + * Get the handler map. + * @return The map of handlers and their associated URI patterns. + * + * @since 4.2 + */ + public Map getHandlers() { + return matcher.getObjects(); + } + + public HttpRequestHandler lookup(final String requestURI) { + return matcher.lookup(requestURI); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestHandlerResolver.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestHandlerResolver.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestHandlerResolver.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,49 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +/** + * HttpRequestHandlerResolver can be used to resolve an instance of + * {@link HttpRequestHandler} matching a particular request URI. Usually the + * resolved request handler will be used to process the request with the + * specified request URI. + * + * @since 4.0 + */ +public interface HttpRequestHandlerResolver { + + /** + * Looks up a handler matching the given request URI. + * + * @param requestURI the request URI + * @return HTTP request handler or null if no match + * is found. + */ + HttpRequestHandler lookup(String requestURI); + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestInterceptorList.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestInterceptorList.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpRequestInterceptorList.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,100 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.util.List; + +import org.apache.http.HttpRequestInterceptor; + +/** + * Provides access to an ordered list of request interceptors. + * Lists are expected to be built upfront and used read-only afterwards + * for {@link HttpProcessor processing}. + * + * @since 4.0 + */ +public interface HttpRequestInterceptorList { + + /** + * Appends a request interceptor to this list. + * + * @param interceptor the request interceptor to add + */ + void addRequestInterceptor(HttpRequestInterceptor interceptor); + + /** + * Inserts a request interceptor at the specified index. + * + * @param interceptor the request interceptor to add + * @param index the index to insert the interceptor at + */ + void addRequestInterceptor(HttpRequestInterceptor interceptor, int index); + + /** + * Obtains the current size of this list. + * + * @return the number of request interceptors in this list + */ + int getRequestInterceptorCount(); + + /** + * Obtains a request interceptor from this list. + * + * @param index the index of the interceptor to obtain, + * 0 for first + * + * @return the interceptor at the given index, or + * null if the index is out of range + */ + HttpRequestInterceptor getRequestInterceptor(int index); + + /** + * Removes all request interceptors from this list. + */ + void clearRequestInterceptors(); + + /** + * Removes all request interceptor of the specified class + * + * @param clazz the class of the instances to be removed. + */ + void removeRequestInterceptorByClass(Class clazz); + + /** + * Sets the request interceptors in this list. + * This list will be cleared and re-initialized to contain + * all request interceptors from the argument list. + * If the argument list includes elements that are not request + * interceptors, the behavior is implementation dependent. + * + * @param list the list of request interceptors + */ + void setInterceptors(List list); + +} + Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpResponseInterceptorList.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpResponseInterceptorList.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpResponseInterceptorList.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,100 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.util.List; + +import org.apache.http.HttpResponseInterceptor; + +/** + * Provides access to an ordered list of response interceptors. + * Lists are expected to be built upfront and used read-only afterwards + * for {@link HttpProcessor processing}. + * + * @since 4.0 + */ +public interface HttpResponseInterceptorList { + + /** + * Appends a response interceptor to this list. + * + * @param interceptor the response interceptor to add + */ + void addResponseInterceptor(HttpResponseInterceptor interceptor); + + /** + * Inserts a response interceptor at the specified index. + * + * @param interceptor the response interceptor to add + * @param index the index to insert the interceptor at + */ + void addResponseInterceptor(HttpResponseInterceptor interceptor, int index); + + /** + * Obtains the current size of this list. + * + * @return the number of response interceptors in this list + */ + int getResponseInterceptorCount(); + + /** + * Obtains a response interceptor from this list. + * + * @param index the index of the interceptor to obtain, + * 0 for first + * + * @return the interceptor at the given index, or + * null if the index is out of range + */ + HttpResponseInterceptor getResponseInterceptor(int index); + + /** + * Removes all response interceptors from this list. + */ + void clearResponseInterceptors(); + + /** + * Removes all response interceptor of the specified class + * + * @param clazz the class of the instances to be removed. + */ + void removeResponseInterceptorByClass(Class clazz); + + /** + * Sets the response interceptors in this list. + * This list will be cleared and re-initialized to contain + * all response interceptors from the argument list. + * If the argument list includes elements that are not response + * interceptors, the behavior is implementation dependent. + * + * @param list the list of response interceptors + */ + void setInterceptors(List list); + +} + Index: 3rdParty_sources/httpcore/org/apache/http/protocol/HttpService.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/HttpService.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/HttpService.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,381 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseFactory; +import org.apache.http.HttpServerConnection; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.MethodNotSupportedException; +import org.apache.http.ProtocolException; +import org.apache.http.UnsupportedHttpVersionException; +import org.apache.http.annotation.Immutable; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.params.HttpParams; +import org.apache.http.params.DefaultedHttpParams; +import org.apache.http.util.EncodingUtils; +import org.apache.http.util.EntityUtils; + +/** + * HttpService is a server side HTTP protocol handler based on + * the classic (blocking) I/O model. + *

    + * HttpService relies on {@link HttpProcessor} to generate mandatory + * protocol headers for all outgoing messages and apply common, cross-cutting + * message transformations to all incoming and outgoing messages, whereas + * individual {@link HttpRequestHandler}s are expected to implement + * application specific content generation and processing. + *

    + * HttpService uses {@link HttpRequestHandlerResolver} to resolve + * matching request handler for a particular request URI of an incoming HTTP + * request. + *

    + * HttpService can use optional {@link HttpExpectationVerifier} + * to ensure that incoming requests meet server's expectations. + * + * @since 4.0 + */ +@Immutable // provided injected dependencies are immutable and deprecated methods are not used +public class HttpService { + + /** + * TODO: make all variables final in the next major version + */ + private volatile HttpParams params = null; + private volatile HttpProcessor processor = null; + private volatile HttpRequestHandlerResolver handlerResolver = null; + private volatile ConnectionReuseStrategy connStrategy = null; + private volatile HttpResponseFactory responseFactory = null; + private volatile HttpExpectationVerifier expectationVerifier = null; + + /** + * Create a new HTTP service. + * + * @param processor the processor to use on requests and responses + * @param connStrategy the connection reuse strategy + * @param responseFactory the response factory + * @param handlerResolver the handler resolver. May be null. + * @param expectationVerifier the expectation verifier. May be null. + * @param params the HTTP parameters + * + * @since 4.1 + */ + public HttpService( + final HttpProcessor processor, + final ConnectionReuseStrategy connStrategy, + final HttpResponseFactory responseFactory, + final HttpRequestHandlerResolver handlerResolver, + final HttpExpectationVerifier expectationVerifier, + final HttpParams params) { + super(); + if (processor == null) { + throw new IllegalArgumentException("HTTP processor may not be null"); + } + if (connStrategy == null) { + throw new IllegalArgumentException("Connection reuse strategy may not be null"); + } + if (responseFactory == null) { + throw new IllegalArgumentException("Response factory may not be null"); + } + if (params == null) { + throw new IllegalArgumentException("HTTP parameters may not be null"); + } + this.processor = processor; + this.connStrategy = connStrategy; + this.responseFactory = responseFactory; + this.handlerResolver = handlerResolver; + this.expectationVerifier = expectationVerifier; + this.params = params; + } + + /** + * Create a new HTTP service. + * + * @param processor the processor to use on requests and responses + * @param connStrategy the connection reuse strategy + * @param responseFactory the response factory + * @param handlerResolver the handler resolver. May be null. + * @param params the HTTP parameters + * + * @since 4.1 + */ + public HttpService( + final HttpProcessor processor, + final ConnectionReuseStrategy connStrategy, + final HttpResponseFactory responseFactory, + final HttpRequestHandlerResolver handlerResolver, + final HttpParams params) { + this(processor, connStrategy, responseFactory, handlerResolver, null, params); + } + + /** + * Create a new HTTP service. + * + * @param proc the processor to use on requests and responses + * @param connStrategy the connection reuse strategy + * @param responseFactory the response factory + * + * @deprecated (4.1) use {@link HttpService#HttpService(HttpProcessor, + * ConnectionReuseStrategy, HttpResponseFactory, HttpRequestHandlerResolver, HttpParams)} + */ + @Deprecated + public HttpService( + final HttpProcessor proc, + final ConnectionReuseStrategy connStrategy, + final HttpResponseFactory responseFactory) { + super(); + setHttpProcessor(proc); + setConnReuseStrategy(connStrategy); + setResponseFactory(responseFactory); + } + + /** + * @deprecated (4.1) set {@link HttpProcessor} using constructor + */ + @Deprecated + public void setHttpProcessor(final HttpProcessor processor) { + if (processor == null) { + throw new IllegalArgumentException("HTTP processor may not be null"); + } + this.processor = processor; + } + + /** + * @deprecated (4.1) set {@link ConnectionReuseStrategy} using constructor + */ + @Deprecated + public void setConnReuseStrategy(final ConnectionReuseStrategy connStrategy) { + if (connStrategy == null) { + throw new IllegalArgumentException("Connection reuse strategy may not be null"); + } + this.connStrategy = connStrategy; + } + + /** + * @deprecated (4.1) set {@link HttpResponseFactory} using constructor + */ + @Deprecated + public void setResponseFactory(final HttpResponseFactory responseFactory) { + if (responseFactory == null) { + throw new IllegalArgumentException("Response factory may not be null"); + } + this.responseFactory = responseFactory; + } + + /** + * @deprecated (4.1) set {@link HttpResponseFactory} using constructor + */ + @Deprecated + public void setParams(final HttpParams params) { + this.params = params; + } + + /** + * @deprecated (4.1) set {@link HttpRequestHandlerResolver} using constructor + */ + @Deprecated + public void setHandlerResolver(final HttpRequestHandlerResolver handlerResolver) { + this.handlerResolver = handlerResolver; + } + + /** + * @deprecated (4.1) set {@link HttpExpectationVerifier} using constructor + */ + @Deprecated + public void setExpectationVerifier(final HttpExpectationVerifier expectationVerifier) { + this.expectationVerifier = expectationVerifier; + } + + public HttpParams getParams() { + return this.params; + } + + /** + * Handles receives one HTTP request over the given connection within the + * given execution context and sends a response back to the client. + * + * @param conn the active connection to the client + * @param context the actual execution context. + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + public void handleRequest( + final HttpServerConnection conn, + final HttpContext context) throws IOException, HttpException { + + context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn); + + HttpResponse response = null; + + try { + + HttpRequest request = conn.receiveRequestHeader(); + request.setParams( + new DefaultedHttpParams(request.getParams(), this.params)); + + if (request instanceof HttpEntityEnclosingRequest) { + + if (((HttpEntityEnclosingRequest) request).expectContinue()) { + response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, + HttpStatus.SC_CONTINUE, context); + response.setParams( + new DefaultedHttpParams(response.getParams(), this.params)); + + if (this.expectationVerifier != null) { + try { + this.expectationVerifier.verify(request, response, context); + } catch (HttpException ex) { + response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_0, + HttpStatus.SC_INTERNAL_SERVER_ERROR, context); + response.setParams( + new DefaultedHttpParams(response.getParams(), this.params)); + handleException(ex, response); + } + } + if (response.getStatusLine().getStatusCode() < 200) { + // Send 1xx response indicating the server expections + // have been met + conn.sendResponseHeader(response); + conn.flush(); + response = null; + conn.receiveRequestEntity((HttpEntityEnclosingRequest) request); + } + } else { + conn.receiveRequestEntity((HttpEntityEnclosingRequest) request); + } + } + + context.setAttribute(ExecutionContext.HTTP_REQUEST, request); + + if (response == null) { + response = this.responseFactory.newHttpResponse(HttpVersion.HTTP_1_1, + HttpStatus.SC_OK, context); + response.setParams( + new DefaultedHttpParams(response.getParams(), this.params)); + this.processor.process(request, context); + doService(request, response, context); + } + + // Make sure the request content is fully consumed + if (request instanceof HttpEntityEnclosingRequest) { + HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); + EntityUtils.consume(entity); + } + + } catch (HttpException ex) { + response = this.responseFactory.newHttpResponse + (HttpVersion.HTTP_1_0, HttpStatus.SC_INTERNAL_SERVER_ERROR, + context); + response.setParams( + new DefaultedHttpParams(response.getParams(), this.params)); + handleException(ex, response); + } + + context.setAttribute(ExecutionContext.HTTP_RESPONSE, response); + + this.processor.process(response, context); + conn.sendResponseHeader(response); + conn.sendResponseEntity(response); + conn.flush(); + + if (!this.connStrategy.keepAlive(response, context)) { + conn.close(); + } + } + + /** + * Handles the given exception and generates an HTTP response to be sent + * back to the client to inform about the exceptional condition encountered + * in the course of the request processing. + * + * @param ex the exception. + * @param response the HTTP response. + */ + protected void handleException(final HttpException ex, final HttpResponse response) { + if (ex instanceof MethodNotSupportedException) { + response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED); + } else if (ex instanceof UnsupportedHttpVersionException) { + response.setStatusCode(HttpStatus.SC_HTTP_VERSION_NOT_SUPPORTED); + } else if (ex instanceof ProtocolException) { + response.setStatusCode(HttpStatus.SC_BAD_REQUEST); + } else { + response.setStatusCode(HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + String message = ex.getMessage(); + if (message == null) { + message = ex.toString(); + } + byte[] msg = EncodingUtils.getAsciiBytes(message); + ByteArrayEntity entity = new ByteArrayEntity(msg); + entity.setContentType("text/plain; charset=US-ASCII"); + response.setEntity(entity); + } + + /** + * The default implementation of this method attempts to resolve an + * {@link HttpRequestHandler} for the request URI of the given request + * and, if found, executes its + * {@link HttpRequestHandler#handle(HttpRequest, HttpResponse, HttpContext)} + * method. + *

    + * Super-classes can override this method in order to provide a custom + * implementation of the request processing logic. + * + * @param request the HTTP request. + * @param response the HTTP response. + * @param context the execution context. + * @throws IOException in case of an I/O error. + * @throws HttpException in case of HTTP protocol violation or a processing + * problem. + */ + protected void doService( + final HttpRequest request, + final HttpResponse response, + final HttpContext context) throws HttpException, IOException { + HttpRequestHandler handler = null; + if (this.handlerResolver != null) { + String requestURI = request.getRequestLine().getUri(); + handler = this.handlerResolver.lookup(requestURI); + } + if (handler != null) { + handler.handle(request, response, context); + } else { + response.setStatusCode(HttpStatus.SC_NOT_IMPLEMENTED); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/ImmutableHttpProcessor.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/ImmutableHttpProcessor.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/ImmutableHttpProcessor.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,121 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.annotation.ThreadSafe; + +/** + * Immutable {@link HttpProcessor}. + * + * @since 4.1 + */ +@ThreadSafe // provided injected dependencies are immutable +public final class ImmutableHttpProcessor implements HttpProcessor { + + private final HttpRequestInterceptor[] requestInterceptors; + private final HttpResponseInterceptor[] responseInterceptors; + + public ImmutableHttpProcessor( + final HttpRequestInterceptor[] requestInterceptors, + final HttpResponseInterceptor[] responseInterceptors) { + super(); + if (requestInterceptors != null) { + int count = requestInterceptors.length; + this.requestInterceptors = new HttpRequestInterceptor[count]; + for (int i = 0; i < count; i++) { + this.requestInterceptors[i] = requestInterceptors[i]; + } + } else { + this.requestInterceptors = new HttpRequestInterceptor[0]; + } + if (responseInterceptors != null) { + int count = responseInterceptors.length; + this.responseInterceptors = new HttpResponseInterceptor[count]; + for (int i = 0; i < count; i++) { + this.responseInterceptors[i] = responseInterceptors[i]; + } + } else { + this.responseInterceptors = new HttpResponseInterceptor[0]; + } + } + + public ImmutableHttpProcessor( + final HttpRequestInterceptorList requestInterceptors, + final HttpResponseInterceptorList responseInterceptors) { + super(); + if (requestInterceptors != null) { + int count = requestInterceptors.getRequestInterceptorCount(); + this.requestInterceptors = new HttpRequestInterceptor[count]; + for (int i = 0; i < count; i++) { + this.requestInterceptors[i] = requestInterceptors.getRequestInterceptor(i); + } + } else { + this.requestInterceptors = new HttpRequestInterceptor[0]; + } + if (responseInterceptors != null) { + int count = responseInterceptors.getResponseInterceptorCount(); + this.responseInterceptors = new HttpResponseInterceptor[count]; + for (int i = 0; i < count; i++) { + this.responseInterceptors[i] = responseInterceptors.getResponseInterceptor(i); + } + } else { + this.responseInterceptors = new HttpResponseInterceptor[0]; + } + } + + public ImmutableHttpProcessor(final HttpRequestInterceptor[] requestInterceptors) { + this(requestInterceptors, null); + } + + public ImmutableHttpProcessor(final HttpResponseInterceptor[] responseInterceptors) { + this(null, responseInterceptors); + } + + public void process( + final HttpRequest request, + final HttpContext context) throws IOException, HttpException { + for (int i = 0; i < this.requestInterceptors.length; i++) { + this.requestInterceptors[i].process(request, context); + } + } + + public void process( + final HttpResponse response, + final HttpContext context) throws IOException, HttpException { + for (int i = 0; i < this.responseInterceptors.length; i++) { + this.responseInterceptors[i].process(response, context); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/RequestConnControl.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/RequestConnControl.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/RequestConnControl.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,70 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.annotation.Immutable; + +/** + * RequestConnControl is responsible for adding Connection header + * to the outgoing requests, which is essential for managing persistence of + * HTTP/1.0 connections. This interceptor is recommended for + * client side protocol processors. + * + * @since 4.0 + */ +@Immutable +public class RequestConnControl implements HttpRequestInterceptor { + + public RequestConnControl() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + + String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase("CONNECT")) { + return; + } + + if (!request.containsHeader(HTTP.CONN_DIRECTIVE)) { + // Default policy is to keep connection alive + // whenever possible + request.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/RequestContent.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/RequestContent.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/RequestContent.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,128 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.ProtocolException; +import org.apache.http.annotation.Immutable; + +/** + * RequestContent is the most important interceptor for outgoing requests. + * It is responsible for delimiting content length by adding + * Content-Length or Transfer-Content headers based + * on the properties of the enclosed entity and the protocol version. + * This interceptor is required for correct functioning of client side protocol + * processors. + * + * @since 4.0 + */ +@Immutable +public class RequestContent implements HttpRequestInterceptor { + + private final boolean overwrite; + + /** + * Default constructor. The Content-Length or Transfer-Encoding + * will cause the interceptor to throw {@link ProtocolException} if already present in the + * response message. + */ + public RequestContent() { + this(false); + } + + /** + * Constructor that can be used to fine-tune behavior of this interceptor. + * + * @param overwrite If set to true the Content-Length and + * Transfer-Encoding headers will be created or updated if already present. + * If set to false the Content-Length and + * Transfer-Encoding headers will cause the interceptor to throw + * {@link ProtocolException} if already present in the response message. + * + * @since 4.2 + */ + public RequestContent(boolean overwrite) { + super(); + this.overwrite = overwrite; + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (request instanceof HttpEntityEnclosingRequest) { + if (this.overwrite) { + request.removeHeaders(HTTP.TRANSFER_ENCODING); + request.removeHeaders(HTTP.CONTENT_LEN); + } else { + if (request.containsHeader(HTTP.TRANSFER_ENCODING)) { + throw new ProtocolException("Transfer-encoding header already present"); + } + if (request.containsHeader(HTTP.CONTENT_LEN)) { + throw new ProtocolException("Content-Length header already present"); + } + } + ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); + HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); + if (entity == null) { + request.addHeader(HTTP.CONTENT_LEN, "0"); + return; + } + // Must specify a transfer encoding or a content length + if (entity.isChunked() || entity.getContentLength() < 0) { + if (ver.lessEquals(HttpVersion.HTTP_1_0)) { + throw new ProtocolException( + "Chunked transfer encoding not allowed for " + ver); + } + request.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING); + } else { + request.addHeader(HTTP.CONTENT_LEN, Long.toString(entity.getContentLength())); + } + // Specify a content type if known + if (entity.getContentType() != null && !request.containsHeader( + HTTP.CONTENT_TYPE )) { + request.addHeader(entity.getContentType()); + } + // Specify a content encoding if known + if (entity.getContentEncoding() != null && !request.containsHeader( + HTTP.CONTENT_ENCODING)) { + request.addHeader(entity.getContentEncoding()); + } + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/RequestDate.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/RequestDate.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/RequestDate.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,67 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.annotation.ThreadSafe; + +/** + * RequestDate interceptor is responsible for adding Date header + * to the outgoing requests This interceptor is optional for client side + * protocol processors. + * + * @since 4.0 + */ +@ThreadSafe +public class RequestDate implements HttpRequestInterceptor { + + private static final HttpDateGenerator DATE_GENERATOR = new HttpDateGenerator(); + + public RequestDate() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException + ("HTTP request may not be null."); + } + if ((request instanceof HttpEntityEnclosingRequest) && + !request.containsHeader(HTTP.DATE_HEADER)) { + String httpdate = DATE_GENERATOR.getCurrentDate(); + request.setHeader(HTTP.DATE_HEADER, httpdate); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/RequestExpectContinue.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/RequestExpectContinue.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/RequestExpectContinue.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,80 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.annotation.Immutable; +import org.apache.http.params.HttpProtocolParams; + +/** + * RequestExpectContinue is responsible for enabling the 'expect-continue' + * handshake by adding Expect header. This interceptor is + * recommended for client side protocol processors. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#USE_EXPECT_CONTINUE}
    • + *
    + * + * @since 4.0 + */ +@Immutable +public class RequestExpectContinue implements HttpRequestInterceptor { + + public RequestExpectContinue() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (request instanceof HttpEntityEnclosingRequest) { + HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); + // Do not send the expect header if request body is known to be empty + if (entity != null && entity.getContentLength() != 0) { + ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); + if (HttpProtocolParams.useExpectContinue(request.getParams()) + && !ver.lessEquals(HttpVersion.HTTP_1_0)) { + request.addHeader(HTTP.EXPECT_DIRECTIVE, HTTP.EXPECT_CONTINUE); + } + } + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/RequestTargetHost.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/RequestTargetHost.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/RequestTargetHost.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,99 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; +import java.net.InetAddress; + +import org.apache.http.HttpConnection; +import org.apache.http.HttpException; +import org.apache.http.HttpHost; +import org.apache.http.HttpInetConnection; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.ProtocolException; +import org.apache.http.annotation.Immutable; + +/** + * RequestTargetHost is responsible for adding Host header. This + * interceptor is required for client side protocol processors. + * + * @since 4.0 + */ +@Immutable +public class RequestTargetHost implements HttpRequestInterceptor { + + public RequestTargetHost() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + + ProtocolVersion ver = request.getRequestLine().getProtocolVersion(); + String method = request.getRequestLine().getMethod(); + if (method.equalsIgnoreCase("CONNECT") && ver.lessEquals(HttpVersion.HTTP_1_0)) { + return; + } + + if (!request.containsHeader(HTTP.TARGET_HOST)) { + HttpHost targethost = (HttpHost) context + .getAttribute(ExecutionContext.HTTP_TARGET_HOST); + if (targethost == null) { + HttpConnection conn = (HttpConnection) context + .getAttribute(ExecutionContext.HTTP_CONNECTION); + if (conn instanceof HttpInetConnection) { + // Populate the context with a default HTTP host based on the + // inet address of the target host + InetAddress address = ((HttpInetConnection) conn).getRemoteAddress(); + int port = ((HttpInetConnection) conn).getRemotePort(); + if (address != null) { + targethost = new HttpHost(address.getHostName(), port); + } + } + if (targethost == null) { + if (ver.lessEquals(HttpVersion.HTTP_1_0)) { + return; + } else { + throw new ProtocolException("Target host missing"); + } + } + } + request.addHeader(HTTP.TARGET_HOST, targethost.toHostString()); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/RequestUserAgent.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/RequestUserAgent.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/RequestUserAgent.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,70 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.annotation.Immutable; +import org.apache.http.params.HttpProtocolParams; + +/** + * RequestUserAgent is responsible for adding User-Agent header. + * This interceptor is recommended for client side protocol processors. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#USER_AGENT}
    • + *
    + * + * @since 4.0 + */ +@Immutable +public class RequestUserAgent implements HttpRequestInterceptor { + + public RequestUserAgent() { + super(); + } + + public void process(final HttpRequest request, final HttpContext context) + throws HttpException, IOException { + if (request == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (!request.containsHeader(HTTP.USER_AGENT)) { + String useragent = HttpProtocolParams.getUserAgent(request.getParams()); + if (useragent != null) { + request.addHeader(HTTP.USER_AGENT, useragent); + } + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseConnControl.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseConnControl.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseConnControl.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,107 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.annotation.Immutable; + +/** + * ResponseConnControl is responsible for adding Connection header + * to the outgoing responses, which is essential for managing persistence of + * HTTP/1.0 connections. This interceptor is recommended for + * server side protocol processors. + * + * @since 4.0 + */ +@Immutable +public class ResponseConnControl implements HttpResponseInterceptor { + + public ResponseConnControl() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + if (context == null) { + throw new IllegalArgumentException("HTTP context may not be null"); + } + // Always drop connection after certain type of responses + int status = response.getStatusLine().getStatusCode(); + if (status == HttpStatus.SC_BAD_REQUEST || + status == HttpStatus.SC_REQUEST_TIMEOUT || + status == HttpStatus.SC_LENGTH_REQUIRED || + status == HttpStatus.SC_REQUEST_TOO_LONG || + status == HttpStatus.SC_REQUEST_URI_TOO_LONG || + status == HttpStatus.SC_SERVICE_UNAVAILABLE || + status == HttpStatus.SC_NOT_IMPLEMENTED) { + response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); + return; + } + Header explicit = response.getFirstHeader(HTTP.CONN_DIRECTIVE); + if (explicit != null && HTTP.CONN_CLOSE.equalsIgnoreCase(explicit.getValue())) { + // Connection persistence explicitly disabled + return; + } + // Always drop connection for HTTP/1.0 responses and below + // if the content body cannot be correctly delimited + HttpEntity entity = response.getEntity(); + if (entity != null) { + ProtocolVersion ver = response.getStatusLine().getProtocolVersion(); + if (entity.getContentLength() < 0 && + (!entity.isChunked() || ver.lessEquals(HttpVersion.HTTP_1_0))) { + response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); + return; + } + } + // Drop connection if requested by the client or request was <= 1.0 + HttpRequest request = (HttpRequest) + context.getAttribute(ExecutionContext.HTTP_REQUEST); + if (request != null) { + Header header = request.getFirstHeader(HTTP.CONN_DIRECTIVE); + if (header != null) { + response.setHeader(HTTP.CONN_DIRECTIVE, header.getValue()); + } else if (request.getProtocolVersion().lessEquals(HttpVersion.HTTP_1_0)) { + response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE); + } + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseContent.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseContent.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseContent.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,134 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.ProtocolVersion; +import org.apache.http.ProtocolException; +import org.apache.http.annotation.Immutable; + +/** + * ResponseContent is the most important interceptor for outgoing responses. + * It is responsible for delimiting content length by adding + * Content-Length or Transfer-Content headers based + * on the properties of the enclosed entity and the protocol version. + * This interceptor is required for correct functioning of server side protocol + * processors. + * + * @since 4.0 + */ +@Immutable +public class ResponseContent implements HttpResponseInterceptor { + + private final boolean overwrite; + + /** + * Default constructor. The Content-Length or Transfer-Encoding + * will cause the interceptor to throw {@link ProtocolException} if already present in the + * response message. + */ + public ResponseContent() { + this(false); + } + + /** + * Constructor that can be used to fine-tune behavior of this interceptor. + * + * @param overwrite If set to true the Content-Length and + * Transfer-Encoding headers will be created or updated if already present. + * If set to false the Content-Length and + * Transfer-Encoding headers will cause the interceptor to throw + * {@link ProtocolException} if already present in the response message. + * + * @since 4.2 + */ + public ResponseContent(boolean overwrite) { + super(); + this.overwrite = overwrite; + } + + /** + * Processes the response (possibly updating or inserting) Content-Length and Transfer-Encoding headers. + * @param response The HttpResponse to modify. + * @param context Unused. + * @throws ProtocolException If either the Content-Length or Transfer-Encoding headers are found. + * @throws IllegalArgumentException If the response is null. + */ + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP response may not be null"); + } + if (this.overwrite) { + response.removeHeaders(HTTP.TRANSFER_ENCODING); + response.removeHeaders(HTTP.CONTENT_LEN); + } else { + if (response.containsHeader(HTTP.TRANSFER_ENCODING)) { + throw new ProtocolException("Transfer-encoding header already present"); + } + if (response.containsHeader(HTTP.CONTENT_LEN)) { + throw new ProtocolException("Content-Length header already present"); + } + } + ProtocolVersion ver = response.getStatusLine().getProtocolVersion(); + HttpEntity entity = response.getEntity(); + if (entity != null) { + long len = entity.getContentLength(); + if (entity.isChunked() && !ver.lessEquals(HttpVersion.HTTP_1_0)) { + response.addHeader(HTTP.TRANSFER_ENCODING, HTTP.CHUNK_CODING); + } else if (len >= 0) { + response.addHeader(HTTP.CONTENT_LEN, Long.toString(entity.getContentLength())); + } + // Specify a content type if known + if (entity.getContentType() != null && !response.containsHeader( + HTTP.CONTENT_TYPE )) { + response.addHeader(entity.getContentType()); + } + // Specify a content encoding if known + if (entity.getContentEncoding() != null && !response.containsHeader( + HTTP.CONTENT_ENCODING)) { + response.addHeader(entity.getContentEncoding()); + } + } else { + int status = response.getStatusLine().getStatusCode(); + if (status != HttpStatus.SC_NO_CONTENT + && status != HttpStatus.SC_NOT_MODIFIED + && status != HttpStatus.SC_RESET_CONTENT) { + response.addHeader(HTTP.CONTENT_LEN, "0"); + } + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseDate.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseDate.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseDate.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,68 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.HttpStatus; +import org.apache.http.annotation.ThreadSafe; + +/** + * ResponseDate is responsible for adding Date header to the + * outgoing responses. This interceptor is recommended for server side protocol + * processors. + * + * @since 4.0 + */ +@ThreadSafe +public class ResponseDate implements HttpResponseInterceptor { + + private static final HttpDateGenerator DATE_GENERATOR = new HttpDateGenerator(); + + public ResponseDate() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException + ("HTTP response may not be null."); + } + int status = response.getStatusLine().getStatusCode(); + if ((status >= HttpStatus.SC_OK) && + !response.containsHeader(HTTP.DATE_HEADER)) { + String httpdate = DATE_GENERATOR.getCurrentDate(); + response.setHeader(HTTP.DATE_HEADER, httpdate); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseServer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseServer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/ResponseServer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,71 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.io.IOException; + +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.annotation.Immutable; +import org.apache.http.params.CoreProtocolPNames; + +/** + * ResponseServer is responsible for adding Server header. This + * interceptor is recommended for server side protocol processors. + *

    + * The following parameters can be used to customize the behavior of this + * class: + *

      + *
    • {@link org.apache.http.params.CoreProtocolPNames#ORIGIN_SERVER}
    • + *
    + * + * @since 4.0 + */ +@Immutable +public class ResponseServer implements HttpResponseInterceptor { + + public ResponseServer() { + super(); + } + + public void process(final HttpResponse response, final HttpContext context) + throws HttpException, IOException { + if (response == null) { + throw new IllegalArgumentException("HTTP request may not be null"); + } + if (!response.containsHeader(HTTP.SERVER_HEADER)) { + String s = (String) response.getParams().getParameter( + CoreProtocolPNames.ORIGIN_SERVER); + if (s != null) { + response.addHeader(HTTP.SERVER_HEADER, s); + } + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/SyncBasicHttpContext.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/SyncBasicHttpContext.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/SyncBasicHttpContext.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,74 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +/** + * Thread-safe extension of the {@link BasicHttpContext}. + * + * @since 4.0 + * + * @deprecated (4.2) HttpContext instances may not be shared by multiple threads + */ +@Deprecated +public class SyncBasicHttpContext extends BasicHttpContext { + + public SyncBasicHttpContext(final HttpContext parentContext) { + super(parentContext); + } + + /** + * @since 4.2 + */ + public SyncBasicHttpContext() { + super(); + } + + @Override + public synchronized Object getAttribute(final String id) { + return super.getAttribute(id); + } + + @Override + public synchronized void setAttribute(final String id, final Object obj) { + super.setAttribute(id, obj); + } + + @Override + public synchronized Object removeAttribute(final String id) { + return super.removeAttribute(id); + } + + /** + * @since 4.2 + */ + @Override + public synchronized void clear() { + super.clear(); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/UriPatternMatcher.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/UriPatternMatcher.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/UriPatternMatcher.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,177 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.protocol; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.apache.http.annotation.GuardedBy; +import org.apache.http.annotation.ThreadSafe; + +/** + * Maintains a map of objects keyed by a request URI pattern. + *
    + * Patterns may have three formats: + *
      + *
    • *
    • + *
    • *<uri>
    • + *
    • <uri>*
    • + *
    + *
    + * This class can be used to resolve an object matching a particular request + * URI. + * + * @since 4.0 + */ +@ThreadSafe +public class UriPatternMatcher { + + @GuardedBy("this") + private final Map map; + + public UriPatternMatcher() { + super(); + this.map = new HashMap(); + } + + /** + * Registers the given object for URIs matching the given pattern. + * + * @param pattern the pattern to register the handler for. + * @param obj the object. + */ + public synchronized void register(final String pattern, final T obj) { + if (pattern == null) { + throw new IllegalArgumentException("URI request pattern may not be null"); + } + this.map.put(pattern, obj); + } + + /** + * Removes registered object, if exists, for the given pattern. + * + * @param pattern the pattern to unregister. + */ + public synchronized void unregister(final String pattern) { + if (pattern == null) { + return; + } + this.map.remove(pattern); + } + + /** + * @deprecated (4.1) use {@link #setObjects(Map)} + */ + @Deprecated + public synchronized void setHandlers(final Map map) { + if (map == null) { + throw new IllegalArgumentException("Map of handlers may not be null"); + } + this.map.clear(); + this.map.putAll(map); + } + + /** + * Sets objects from the given map. + * @param map the map containing objects keyed by their URI patterns. + */ + public synchronized void setObjects(final Map map) { + if (map == null) { + throw new IllegalArgumentException("Map of handlers may not be null"); + } + this.map.clear(); + this.map.putAll(map); + } + + /** + * Returns the objects map. + * @return The map of objects. + * + * @since 4.2 + */ + public synchronized Map getObjects() { + return this.map; + } + + /** + * Looks up an object matching the given request URI. + * + * @param requestURI the request URI + * @return object or null if no match is found. + */ + public synchronized T lookup(String requestURI) { + if (requestURI == null) { + throw new IllegalArgumentException("Request URI may not be null"); + } + //Strip away the query part part if found + int index = requestURI.indexOf("?"); + if (index != -1) { + requestURI = requestURI.substring(0, index); + } + + // direct match? + T obj = this.map.get(requestURI); + if (obj == null) { + // pattern match? + String bestMatch = null; + for (Iterator it = this.map.keySet().iterator(); it.hasNext();) { + String pattern = it.next(); + if (matchUriRequestPattern(pattern, requestURI)) { + // we have a match. is it any better? + if (bestMatch == null + || (bestMatch.length() < pattern.length()) + || (bestMatch.length() == pattern.length() && pattern.endsWith("*"))) { + obj = this.map.get(pattern); + bestMatch = pattern; + } + } + } + } + return obj; + } + + /** + * Tests if the given request URI matches the given pattern. + * + * @param pattern the pattern + * @param requestUri the request URI + * @return true if the request URI matches the pattern, + * false otherwise. + */ + protected boolean matchUriRequestPattern(final String pattern, final String requestUri) { + if (pattern.equals("*")) { + return true; + } else { + return + (pattern.endsWith("*") && requestUri.startsWith(pattern.substring(0, pattern.length() - 1))) || + (pattern.startsWith("*") && requestUri.endsWith(pattern.substring(1, pattern.length()))); + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/protocol/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/protocol/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/protocol/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,36 @@ + + + + + +HTTP protocol execution framework and synchronous HTTP protocol handlers +based on the blocking I/O model. + + Index: 3rdParty_sources/httpcore/org/apache/http/util/ByteArrayBuffer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/util/ByteArrayBuffer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/util/ByteArrayBuffer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,347 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.util; + +import java.io.Serializable; + +import org.apache.http.annotation.NotThreadSafe; + +/** + * A resizable byte array. + * + * @since 4.0 + */ +@NotThreadSafe +public final class ByteArrayBuffer implements Serializable { + + private static final long serialVersionUID = 4359112959524048036L; + + private byte[] buffer; + private int len; + + /** + * Creates an instance of {@link ByteArrayBuffer} with the given initial + * capacity. + * + * @param capacity the capacity + */ + public ByteArrayBuffer(int capacity) { + super(); + if (capacity < 0) { + throw new IllegalArgumentException("Buffer capacity may not be negative"); + } + this.buffer = new byte[capacity]; + } + + private void expand(int newlen) { + byte newbuffer[] = new byte[Math.max(this.buffer.length << 1, newlen)]; + System.arraycopy(this.buffer, 0, newbuffer, 0, this.len); + this.buffer = newbuffer; + } + + /** + * Appends len bytes to this buffer from the given source + * array starting at index off. The capacity of the buffer + * is increased, if necessary, to accommodate all len bytes. + * + * @param b the bytes to be appended. + * @param off the index of the first byte to append. + * @param len the number of bytes to append. + * @throws IndexOutOfBoundsException if off if out of + * range, len is negative, or + * off + len is out of range. + */ + public void append(final byte[] b, int off, int len) { + if (b == null) { + return; + } + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) < 0) || ((off + len) > b.length)) { + throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length); + } + if (len == 0) { + return; + } + int newlen = this.len + len; + if (newlen > this.buffer.length) { + expand(newlen); + } + System.arraycopy(b, off, this.buffer, this.len, len); + this.len = newlen; + } + + /** + * Appends b byte to this buffer. The capacity of the buffer + * is increased, if necessary, to accommodate the additional byte. + * + * @param b the byte to be appended. + */ + public void append(int b) { + int newlen = this.len + 1; + if (newlen > this.buffer.length) { + expand(newlen); + } + this.buffer[this.len] = (byte)b; + this.len = newlen; + } + + /** + * Appends len chars to this buffer from the given source + * array starting at index off. The capacity of the buffer + * is increased if necessary to accommodate all len chars. + *

    + * The chars are converted to bytes using simple cast. + * + * @param b the chars to be appended. + * @param off the index of the first char to append. + * @param len the number of bytes to append. + * @throws IndexOutOfBoundsException if off if out of + * range, len is negative, or + * off + len is out of range. + */ + public void append(final char[] b, int off, int len) { + if (b == null) { + return; + } + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) < 0) || ((off + len) > b.length)) { + throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length); + } + if (len == 0) { + return; + } + int oldlen = this.len; + int newlen = oldlen + len; + if (newlen > this.buffer.length) { + expand(newlen); + } + for (int i1 = off, i2 = oldlen; i2 < newlen; i1++, i2++) { + this.buffer[i2] = (byte) b[i1]; + } + this.len = newlen; + } + + /** + * Appends len chars to this buffer from the given source + * char array buffer starting at index off. The capacity + * of the buffer is increased if necessary to accommodate all + * len chars. + *

    + * The chars are converted to bytes using simple cast. + * + * @param b the chars to be appended. + * @param off the index of the first char to append. + * @param len the number of bytes to append. + * @throws IndexOutOfBoundsException if off if out of + * range, len is negative, or + * off + len is out of range. + */ + public void append(final CharArrayBuffer b, int off, int len) { + if (b == null) { + return; + } + append(b.buffer(), off, len); + } + + /** + * Clears content of the buffer. The underlying byte array is not resized. + */ + public void clear() { + this.len = 0; + } + + /** + * Converts the content of this buffer to an array of bytes. + * + * @return byte array + */ + public byte[] toByteArray() { + byte[] b = new byte[this.len]; + if (this.len > 0) { + System.arraycopy(this.buffer, 0, b, 0, this.len); + } + return b; + } + + /** + * Returns the byte value in this buffer at the specified + * index. The index argument must be greater than or equal to + * 0, and less than the length of this buffer. + * + * @param i the index of the desired byte value. + * @return the byte value at the specified index. + * @throws IndexOutOfBoundsException if index is + * negative or greater than or equal to {@link #length()}. + */ + public int byteAt(int i) { + return this.buffer[i]; + } + + /** + * Returns the current capacity. The capacity is the amount of storage + * available for newly appended bytes, beyond which an allocation + * will occur. + * + * @return the current capacity + */ + public int capacity() { + return this.buffer.length; + } + + /** + * Returns the length of the buffer (byte count). + * + * @return the length of the buffer + */ + public int length() { + return this.len; + } + + /** + * Ensures that the capacity is at least equal to the specified minimum. + * If the current capacity is less than the argument, then a new internal + * array is allocated with greater capacity. If the required + * argument is non-positive, this method takes no action. + * + * @param required the minimum required capacity. + * + * @since 4.1 + */ + public void ensureCapacity(int required) { + if (required <= 0) { + return; + } + int available = this.buffer.length - this.len; + if (required > available) { + expand(this.len + required); + } + } + + /** + * Returns reference to the underlying byte array. + * + * @return the byte array. + */ + public byte[] buffer() { + return this.buffer; + } + + /** + * Sets the length of the buffer. The new length value is expected to be + * less than the current capacity and greater than or equal to + * 0. + * + * @param len the new length + * @throws IndexOutOfBoundsException if the + * len argument is greater than the current + * capacity of the buffer or less than 0. + */ + public void setLength(int len) { + if (len < 0 || len > this.buffer.length) { + throw new IndexOutOfBoundsException("len: "+len+" < 0 or > buffer len: "+this.buffer.length); + } + this.len = len; + } + + /** + * Returns true if this buffer is empty, that is, its + * {@link #length()} is equal to 0. + * @return true if this buffer is empty, false + * otherwise. + */ + public boolean isEmpty() { + return this.len == 0; + } + + /** + * Returns true if this buffer is full, that is, its + * {@link #length()} is equal to its {@link #capacity()}. + * @return true if this buffer is full, false + * otherwise. + */ + public boolean isFull() { + return this.len == this.buffer.length; + } + + /** + * Returns the index within this buffer of the first occurrence of the + * specified byte, starting the search at the specified + * beginIndex and finishing at endIndex. + * If no such byte occurs in this buffer within the specified bounds, + * -1 is returned. + *

    + * There is no restriction on the value of beginIndex and + * endIndex. If beginIndex is negative, + * it has the same effect as if it were zero. If endIndex is + * greater than {@link #length()}, it has the same effect as if it were + * {@link #length()}. If the beginIndex is greater than + * the endIndex, -1 is returned. + * + * @param b the byte to search for. + * @param beginIndex the index to start the search from. + * @param endIndex the index to finish the search at. + * @return the index of the first occurrence of the byte in the buffer + * within the given bounds, or -1 if the byte does + * not occur. + * + * @since 4.1 + */ + public int indexOf(byte b, int beginIndex, int endIndex) { + if (beginIndex < 0) { + beginIndex = 0; + } + if (endIndex > this.len) { + endIndex = this.len; + } + if (beginIndex > endIndex) { + return -1; + } + for (int i = beginIndex; i < endIndex; i++) { + if (this.buffer[i] == b) { + return i; + } + } + return -1; + } + + /** + * Returns the index within this buffer of the first occurrence of the + * specified byte, starting the search at 0 and finishing + * at {@link #length()}. If no such byte occurs in this buffer within + * those bounds, -1 is returned. + * + * @param b the byte to search for. + * @return the index of the first occurrence of the byte in the + * buffer, or -1 if the byte does not occur. + * + * @since 4.1 + */ + public int indexOf(byte b) { + return indexOf(b, 0, this.len); + } +} Index: 3rdParty_sources/httpcore/org/apache/http/util/CharArrayBuffer.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/util/CharArrayBuffer.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/util/CharArrayBuffer.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,464 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.util; + +import java.io.Serializable; + +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.protocol.HTTP; + +/** + * A resizable char array. + * + * @since 4.0 + */ +@NotThreadSafe +public final class CharArrayBuffer implements Serializable { + + private static final long serialVersionUID = -6208952725094867135L; + + private char[] buffer; + private int len; + + /** + * Creates an instance of {@link CharArrayBuffer} with the given initial + * capacity. + * + * @param capacity the capacity + */ + public CharArrayBuffer(int capacity) { + super(); + if (capacity < 0) { + throw new IllegalArgumentException("Buffer capacity may not be negative"); + } + this.buffer = new char[capacity]; + } + + private void expand(int newlen) { + char newbuffer[] = new char[Math.max(this.buffer.length << 1, newlen)]; + System.arraycopy(this.buffer, 0, newbuffer, 0, this.len); + this.buffer = newbuffer; + } + + /** + * Appends len chars to this buffer from the given source + * array starting at index off. The capacity of the buffer + * is increased, if necessary, to accommodate all len chars. + * + * @param b the chars to be appended. + * @param off the index of the first char to append. + * @param len the number of chars to append. + * @throws IndexOutOfBoundsException if off is out of + * range, len is negative, or + * off + len is out of range. + */ + public void append(final char[] b, int off, int len) { + if (b == null) { + return; + } + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) < 0) || ((off + len) > b.length)) { + throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length); + } + if (len == 0) { + return; + } + int newlen = this.len + len; + if (newlen > this.buffer.length) { + expand(newlen); + } + System.arraycopy(b, off, this.buffer, this.len, len); + this.len = newlen; + } + + /** + * Appends chars of the given string to this buffer. The capacity of the + * buffer is increased, if necessary, to accommodate all chars. + * + * @param str the string. + */ + public void append(String str) { + if (str == null) { + str = "null"; + } + int strlen = str.length(); + int newlen = this.len + strlen; + if (newlen > this.buffer.length) { + expand(newlen); + } + str.getChars(0, strlen, this.buffer, this.len); + this.len = newlen; + } + + /** + * Appends len chars to this buffer from the given source + * buffer starting at index off. The capacity of the + * destination buffer is increased, if necessary, to accommodate all + * len chars. + * + * @param b the source buffer to be appended. + * @param off the index of the first char to append. + * @param len the number of chars to append. + * @throws IndexOutOfBoundsException if off is out of + * range, len is negative, or + * off + len is out of range. + */ + public void append(final CharArrayBuffer b, int off, int len) { + if (b == null) { + return; + } + append(b.buffer, off, len); + } + + /** + * Appends all chars to this buffer from the given source buffer starting + * at index 0. The capacity of the destination buffer is + * increased, if necessary, to accommodate all {@link #length()} chars. + * + * @param b the source buffer to be appended. + */ + public void append(final CharArrayBuffer b) { + if (b == null) { + return; + } + append(b.buffer,0, b.len); + } + + /** + * Appends ch char to this buffer. The capacity of the buffer + * is increased, if necessary, to accommodate the additional char. + * + * @param ch the char to be appended. + */ + public void append(char ch) { + int newlen = this.len + 1; + if (newlen > this.buffer.length) { + expand(newlen); + } + this.buffer[this.len] = ch; + this.len = newlen; + } + + /** + * Appends len bytes to this buffer from the given source + * array starting at index off. The capacity of the buffer + * is increased, if necessary, to accommodate all len bytes. + *

    + * The bytes are converted to chars using simple cast. + * + * @param b the bytes to be appended. + * @param off the index of the first byte to append. + * @param len the number of bytes to append. + * @throws IndexOutOfBoundsException if off is out of + * range, len is negative, or + * off + len is out of range. + */ + public void append(final byte[] b, int off, int len) { + if (b == null) { + return; + } + if ((off < 0) || (off > b.length) || (len < 0) || + ((off + len) < 0) || ((off + len) > b.length)) { + throw new IndexOutOfBoundsException("off: "+off+" len: "+len+" b.length: "+b.length); + } + if (len == 0) { + return; + } + int oldlen = this.len; + int newlen = oldlen + len; + if (newlen > this.buffer.length) { + expand(newlen); + } + for (int i1 = off, i2 = oldlen; i2 < newlen; i1++, i2++) { + this.buffer[i2] = (char) (b[i1] & 0xff); + } + this.len = newlen; + } + + /** + * Appends len bytes to this buffer from the given source + * array starting at index off. The capacity of the buffer + * is increased, if necessary, to accommodate all len bytes. + *

    + * The bytes are converted to chars using simple cast. + * + * @param b the bytes to be appended. + * @param off the index of the first byte to append. + * @param len the number of bytes to append. + * @throws IndexOutOfBoundsException if off is out of + * range, len is negative, or + * off + len is out of range. + */ + public void append(final ByteArrayBuffer b, int off, int len) { + if (b == null) { + return; + } + append(b.buffer(), off, len); + } + + /** + * Appends chars of the textual representation of the given object to this + * buffer. The capacity of the buffer is increased, if necessary, to + * accommodate all chars. + * + * @param obj the object. + */ + public void append(final Object obj) { + append(String.valueOf(obj)); + } + + /** + * Clears content of the buffer. The underlying char array is not resized. + */ + public void clear() { + this.len = 0; + } + + /** + * Converts the content of this buffer to an array of chars. + * + * @return char array + */ + public char[] toCharArray() { + char[] b = new char[this.len]; + if (this.len > 0) { + System.arraycopy(this.buffer, 0, b, 0, this.len); + } + return b; + } + + /** + * Returns the char value in this buffer at the specified + * index. The index argument must be greater than or equal to + * 0, and less than the length of this buffer. + * + * @param i the index of the desired char value. + * @return the char value at the specified index. + * @throws IndexOutOfBoundsException if index is + * negative or greater than or equal to {@link #length()}. + */ + public char charAt(int i) { + return this.buffer[i]; + } + + /** + * Returns reference to the underlying char array. + * + * @return the char array. + */ + public char[] buffer() { + return this.buffer; + } + + /** + * Returns the current capacity. The capacity is the amount of storage + * available for newly appended chars, beyond which an allocation will + * occur. + * + * @return the current capacity + */ + public int capacity() { + return this.buffer.length; + } + + /** + * Returns the length of the buffer (char count). + * + * @return the length of the buffer + */ + public int length() { + return this.len; + } + + /** + * Ensures that the capacity is at least equal to the specified minimum. + * If the current capacity is less than the argument, then a new internal + * array is allocated with greater capacity. If the required + * argument is non-positive, this method takes no action. + * + * @param required the minimum required capacity. + */ + public void ensureCapacity(int required) { + if (required <= 0) { + return; + } + int available = this.buffer.length - this.len; + if (required > available) { + expand(this.len + required); + } + } + + /** + * Sets the length of the buffer. The new length value is expected to be + * less than the current capacity and greater than or equal to + * 0. + * + * @param len the new length + * @throws IndexOutOfBoundsException if the + * len argument is greater than the current + * capacity of the buffer or less than 0. + */ + public void setLength(int len) { + if (len < 0 || len > this.buffer.length) { + throw new IndexOutOfBoundsException("len: "+len+" < 0 or > buffer len: "+this.buffer.length); + } + this.len = len; + } + + /** + * Returns true if this buffer is empty, that is, its + * {@link #length()} is equal to 0. + * @return true if this buffer is empty, false + * otherwise. + */ + public boolean isEmpty() { + return this.len == 0; + } + + /** + * Returns true if this buffer is full, that is, its + * {@link #length()} is equal to its {@link #capacity()}. + * @return true if this buffer is full, false + * otherwise. + */ + public boolean isFull() { + return this.len == this.buffer.length; + } + + /** + * Returns the index within this buffer of the first occurrence of the + * specified character, starting the search at the specified + * beginIndex and finishing at endIndex. + * If no such character occurs in this buffer within the specified bounds, + * -1 is returned. + *

    + * There is no restriction on the value of beginIndex and + * endIndex. If beginIndex is negative, + * it has the same effect as if it were zero. If endIndex is + * greater than {@link #length()}, it has the same effect as if it were + * {@link #length()}. If the beginIndex is greater than + * the endIndex, -1 is returned. + * + * @param ch the char to search for. + * @param beginIndex the index to start the search from. + * @param endIndex the index to finish the search at. + * @return the index of the first occurrence of the character in the buffer + * within the given bounds, or -1 if the character does + * not occur. + */ + public int indexOf(int ch, int beginIndex, int endIndex) { + if (beginIndex < 0) { + beginIndex = 0; + } + if (endIndex > this.len) { + endIndex = this.len; + } + if (beginIndex > endIndex) { + return -1; + } + for (int i = beginIndex; i < endIndex; i++) { + if (this.buffer[i] == ch) { + return i; + } + } + return -1; + } + + /** + * Returns the index within this buffer of the first occurrence of the + * specified character, starting the search at 0 and finishing + * at {@link #length()}. If no such character occurs in this buffer within + * those bounds, -1 is returned. + * + * @param ch the char to search for. + * @return the index of the first occurrence of the character in the + * buffer, or -1 if the character does not occur. + */ + public int indexOf(int ch) { + return indexOf(ch, 0, this.len); + } + + /** + * Returns a substring of this buffer. The substring begins at the specified + * beginIndex and extends to the character at index + * endIndex - 1. + * + * @param beginIndex the beginning index, inclusive. + * @param endIndex the ending index, exclusive. + * @return the specified substring. + * @exception StringIndexOutOfBoundsException if the + * beginIndex is negative, or + * endIndex is larger than the length of this + * buffer, or beginIndex is larger than + * endIndex. + */ + public String substring(int beginIndex, int endIndex) { + return new String(this.buffer, beginIndex, endIndex - beginIndex); + } + + /** + * Returns a substring of this buffer with leading and trailing whitespace + * omitted. The substring begins with the first non-whitespace character + * from beginIndex and extends to the last + * non-whitespace character with the index lesser than + * endIndex. + * + * @param beginIndex the beginning index, inclusive. + * @param endIndex the ending index, exclusive. + * @return the specified substring. + * @exception IndexOutOfBoundsException if the + * beginIndex is negative, or + * endIndex is larger than the length of this + * buffer, or beginIndex is larger than + * endIndex. + */ + public String substringTrimmed(int beginIndex, int endIndex) { + if (beginIndex < 0) { + throw new IndexOutOfBoundsException("Negative beginIndex: "+beginIndex); + } + if (endIndex > this.len) { + throw new IndexOutOfBoundsException("endIndex: "+endIndex+" > length: "+this.len); + } + if (beginIndex > endIndex) { + throw new IndexOutOfBoundsException("beginIndex: "+beginIndex+" > endIndex: "+endIndex); + } + while (beginIndex < endIndex && HTTP.isWhitespace(this.buffer[beginIndex])) { + beginIndex++; + } + while (endIndex > beginIndex && HTTP.isWhitespace(this.buffer[endIndex - 1])) { + endIndex--; + } + return new String(this.buffer, beginIndex, endIndex - beginIndex); + } + + @Override + public String toString() { + return new String(this.buffer, 0, this.len); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/util/EncodingUtils.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/util/EncodingUtils.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/util/EncodingUtils.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,179 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.util; + +import java.io.UnsupportedEncodingException; + +import org.apache.http.Consts; + +/** + * The home for utility methods that handle various encoding tasks. + * + * + * @since 4.0 + */ +public final class EncodingUtils { + + /** + * Converts the byte array of HTTP content characters to a string. If + * the specified charset is not supported, default system encoding + * is used. + * + * @param data the byte array to be encoded + * @param offset the index of the first byte to encode + * @param length the number of bytes to encode + * @param charset the desired character encoding + * @return The result of the conversion. + */ + public static String getString( + final byte[] data, + int offset, + int length, + String charset + ) { + + if (data == null) { + throw new IllegalArgumentException("Parameter may not be null"); + } + + if (charset == null || charset.length() == 0) { + throw new IllegalArgumentException("charset may not be null or empty"); + } + + try { + return new String(data, offset, length, charset); + } catch (UnsupportedEncodingException e) { + return new String(data, offset, length); + } + } + + + /** + * Converts the byte array of HTTP content characters to a string. If + * the specified charset is not supported, default system encoding + * is used. + * + * @param data the byte array to be encoded + * @param charset the desired character encoding + * @return The result of the conversion. + */ + public static String getString(final byte[] data, final String charset) { + if (data == null) { + throw new IllegalArgumentException("Parameter may not be null"); + } + return getString(data, 0, data.length, charset); + } + + /** + * Converts the specified string to a byte array. If the charset is not supported the + * default system charset is used. + * + * @param data the string to be encoded + * @param charset the desired character encoding + * @return The resulting byte array. + */ + public static byte[] getBytes(final String data, final String charset) { + + if (data == null) { + throw new IllegalArgumentException("data may not be null"); + } + + if (charset == null || charset.length() == 0) { + throw new IllegalArgumentException("charset may not be null or empty"); + } + + try { + return data.getBytes(charset); + } catch (UnsupportedEncodingException e) { + return data.getBytes(); + } + } + + /** + * Converts the specified string to byte array of ASCII characters. + * + * @param data the string to be encoded + * @return The string as a byte array. + */ + public static byte[] getAsciiBytes(final String data) { + + if (data == null) { + throw new IllegalArgumentException("Parameter may not be null"); + } + + try { + return data.getBytes(Consts.ASCII.name()); + } catch (UnsupportedEncodingException e) { + throw new Error("HttpClient requires ASCII support"); + } + } + + /** + * Converts the byte array of ASCII characters to a string. This method is + * to be used when decoding content of HTTP elements (such as response + * headers) + * + * @param data the byte array to be encoded + * @param offset the index of the first byte to encode + * @param length the number of bytes to encode + * @return The string representation of the byte array + */ + public static String getAsciiString(final byte[] data, int offset, int length) { + + if (data == null) { + throw new IllegalArgumentException("Parameter may not be null"); + } + + try { + return new String(data, offset, length, Consts.ASCII.name()); + } catch (UnsupportedEncodingException e) { + throw new Error("HttpClient requires ASCII support"); + } + } + + /** + * Converts the byte array of ASCII characters to a string. This method is + * to be used when decoding content of HTTP elements (such as response + * headers) + * + * @param data the byte array to be encoded + * @return The string representation of the byte array + */ + public static String getAsciiString(final byte[] data) { + if (data == null) { + throw new IllegalArgumentException("Parameter may not be null"); + } + return getAsciiString(data, 0, data.length); + } + + /** + * This class should not be instantiated. + */ + private EncodingUtils() { + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/util/EntityUtils.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/util/EntityUtils.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/util/EntityUtils.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,267 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; + +import org.apache.http.HeaderElement; +import org.apache.http.HttpEntity; +import org.apache.http.NameValuePair; +import org.apache.http.ParseException; +import org.apache.http.entity.ContentType; +import org.apache.http.protocol.HTTP; + +/** + * Static helpers for dealing with {@link HttpEntity}s. + * + * @since 4.0 + */ +public final class EntityUtils { + + private EntityUtils() { + } + + /** + * Ensures that the entity content is fully consumed and the content stream, if exists, + * is closed. The process is done, quietly , without throwing any IOException. + * + * @param entity + * + * + * @since 4.2 + */ + public static void consumeQuietly(final HttpEntity entity) { + try { + consume(entity); + } catch (IOException ioex) { + } + } + + /** + * Ensures that the entity content is fully consumed and the content stream, if exists, + * is closed. + * + * @param entity + * @throws IOException if an error occurs reading the input stream + * + * @since 4.1 + */ + public static void consume(final HttpEntity entity) throws IOException { + if (entity == null) { + return; + } + if (entity.isStreaming()) { + InputStream instream = entity.getContent(); + if (instream != null) { + instream.close(); + } + } + } + + /** + * Read the contents of an entity and return it as a byte array. + * + * @param entity + * @return byte array containing the entity content. May be null if + * {@link HttpEntity#getContent()} is null. + * @throws IOException if an error occurs reading the input stream + * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE + */ + public static byte[] toByteArray(final HttpEntity entity) throws IOException { + if (entity == null) { + throw new IllegalArgumentException("HTTP entity may not be null"); + } + InputStream instream = entity.getContent(); + if (instream == null) { + return null; + } + try { + if (entity.getContentLength() > Integer.MAX_VALUE) { + throw new IllegalArgumentException("HTTP entity too large to be buffered in memory"); + } + int i = (int)entity.getContentLength(); + if (i < 0) { + i = 4096; + } + ByteArrayBuffer buffer = new ByteArrayBuffer(i); + byte[] tmp = new byte[4096]; + int l; + while((l = instream.read(tmp)) != -1) { + buffer.append(tmp, 0, l); + } + return buffer.toByteArray(); + } finally { + instream.close(); + } + } + + /** + * Obtains character set of the entity, if known. + * + * @param entity must not be null + * @return the character set, or null if not found + * @throws ParseException if header elements cannot be parsed + * @throws IllegalArgumentException if entity is null + * + * @deprecated (4.1.3) use {@link ContentType#getOrDefault(HttpEntity)} + */ + @Deprecated + public static String getContentCharSet(final HttpEntity entity) throws ParseException { + if (entity == null) { + throw new IllegalArgumentException("HTTP entity may not be null"); + } + String charset = null; + if (entity.getContentType() != null) { + HeaderElement values[] = entity.getContentType().getElements(); + if (values.length > 0) { + NameValuePair param = values[0].getParameterByName("charset"); + if (param != null) { + charset = param.getValue(); + } + } + } + return charset; + } + + /** + * Obtains mime type of the entity, if known. + * + * @param entity must not be null + * @return the character set, or null if not found + * @throws ParseException if header elements cannot be parsed + * @throws IllegalArgumentException if entity is null + * + * @since 4.1 + * + * @deprecated (4.1.3) use {@link ContentType#getOrDefault(HttpEntity)} + */ + @Deprecated + public static String getContentMimeType(final HttpEntity entity) throws ParseException { + if (entity == null) { + throw new IllegalArgumentException("HTTP entity may not be null"); + } + String mimeType = null; + if (entity.getContentType() != null) { + HeaderElement values[] = entity.getContentType().getElements(); + if (values.length > 0) { + mimeType = values[0].getName(); + } + } + return mimeType; + } + + /** + * Get the entity content as a String, using the provided default character set + * if none is found in the entity. + * If defaultCharset is null, the default "ISO-8859-1" is used. + * + * @param entity must not be null + * @param defaultCharset character set to be applied if none found in the entity + * @return the entity content as a String. May be null if + * {@link HttpEntity#getContent()} is null. + * @throws ParseException if header elements cannot be parsed + * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE + * @throws IOException if an error occurs reading the input stream + */ + public static String toString( + final HttpEntity entity, final Charset defaultCharset) throws IOException, ParseException { + if (entity == null) { + throw new IllegalArgumentException("HTTP entity may not be null"); + } + InputStream instream = entity.getContent(); + if (instream == null) { + return null; + } + try { + if (entity.getContentLength() > Integer.MAX_VALUE) { + throw new IllegalArgumentException("HTTP entity too large to be buffered in memory"); + } + int i = (int)entity.getContentLength(); + if (i < 0) { + i = 4096; + } + ContentType contentType = ContentType.getOrDefault(entity); + Charset charset = contentType.getCharset(); + if (charset == null) { + charset = defaultCharset; + } + if (charset == null) { + charset = HTTP.DEF_CONTENT_CHARSET; + } + Reader reader = new InputStreamReader(instream, charset); + CharArrayBuffer buffer = new CharArrayBuffer(i); + char[] tmp = new char[1024]; + int l; + while((l = reader.read(tmp)) != -1) { + buffer.append(tmp, 0, l); + } + return buffer.toString(); + } finally { + instream.close(); + } + } + + /** + * Get the entity content as a String, using the provided default character set + * if none is found in the entity. + * If defaultCharset is null, the default "ISO-8859-1" is used. + * + * @param entity must not be null + * @param defaultCharset character set to be applied if none found in the entity + * @return the entity content as a String. May be null if + * {@link HttpEntity#getContent()} is null. + * @throws ParseException if header elements cannot be parsed + * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE + * @throws IOException if an error occurs reading the input stream + */ + public static String toString( + final HttpEntity entity, final String defaultCharset) throws IOException, ParseException { + return toString(entity, Charset.forName(defaultCharset)); + } + + /** + * Read the contents of an entity and return it as a String. + * The content is converted using the character set from the entity (if any), + * failing that, "ISO-8859-1" is used. + * + * @param entity + * @return String containing the content. + * @throws ParseException if header elements cannot be parsed + * @throws IllegalArgumentException if entity is null or if content length > Integer.MAX_VALUE + * @throws IOException if an error occurs reading the input stream + */ + public static String toString(final HttpEntity entity) + throws IOException, ParseException { + return toString(entity, (Charset)null); + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/util/ExceptionUtils.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/util/ExceptionUtils.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/util/ExceptionUtils.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,82 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ +package org.apache.http.util; + +import java.lang.reflect.Method; + +/** + * The home for utility methods that handle various exception-related tasks. + * + * + * @since 4.0 + * + * @deprecated (4.2) no longer used + */ +@Deprecated +public final class ExceptionUtils { + + /** A reference to Throwable's initCause method, or null if it's not there in this JVM */ + static private final Method INIT_CAUSE_METHOD = getInitCauseMethod(); + + /** + * Returns a Method allowing access to + * {@link Throwable#initCause(Throwable) initCause} method of {@link Throwable}, + * or null if the method + * does not exist. + * + * @return A Method for Throwable.initCause, or + * null if unavailable. + */ + static private Method getInitCauseMethod() { + try { + Class[] paramsClasses = new Class[] { Throwable.class }; + return Throwable.class.getMethod("initCause", paramsClasses); + } catch (NoSuchMethodException e) { + return null; + } + } + + /** + * If we're running on JDK 1.4 or later, initialize the cause for the given throwable. + * + * @param throwable The throwable. + * @param cause The cause of the throwable. + */ + public static void initCause(Throwable throwable, Throwable cause) { + if (INIT_CAUSE_METHOD != null) { + try { + INIT_CAUSE_METHOD.invoke(throwable, new Object[] { cause }); + } catch (Exception e) { + // Well, with no logging, the only option is to munch the exception + } + } + } + + private ExceptionUtils() { + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/util/LangUtils.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/util/LangUtils.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/util/LangUtils.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,105 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.util; + +/** + * A set of utility methods to help produce consistent + * {@link Object#equals equals} and {@link Object#hashCode hashCode} methods. + * + * + * @since 4.0 + */ +public final class LangUtils { + + public static final int HASH_SEED = 17; + public static final int HASH_OFFSET = 37; + + /** Disabled default constructor. */ + private LangUtils() { + } + + public static int hashCode(final int seed, final int hashcode) { + return seed * HASH_OFFSET + hashcode; + } + + public static int hashCode(final int seed, final boolean b) { + return hashCode(seed, b ? 1 : 0); + } + + public static int hashCode(final int seed, final Object obj) { + return hashCode(seed, obj != null ? obj.hashCode() : 0); + } + + /** + * Check if two objects are equal. + * + * @param obj1 first object to compare, may be {@code null} + * @param obj2 second object to compare, may be {@code null} + * @return {@code true} if the objects are equal or both null + */ + public static boolean equals(final Object obj1, final Object obj2) { + return obj1 == null ? obj2 == null : obj1.equals(obj2); + } + + /** + * Check if two object arrays are equal. + *

    + *

      + *
    • If both parameters are null, return {@code true}
    • + *
    • If one parameter is null, return {@code false}
    • + *
    • If the array lengths are different, return {@code false}
    • + *
    • Compare array elements using .equals(); return {@code false} if any comparisons fail.
    • + *
    • Return {@code true}
    • + *
    + * + * @param a1 first array to compare, may be {@code null} + * @param a2 second array to compare, may be {@code null} + * @return {@code true} if the arrays are equal or both null + */ + public static boolean equals(final Object[] a1, final Object[] a2) { + if (a1 == null) { + if (a2 == null) { + return true; + } else { + return false; + } + } else { + if (a2 != null && a1.length == a2.length) { + for (int i = 0; i < a1.length; i++) { + if (!equals(a1[i], a2[i])) { + return false; + } + } + return true; + } else { + return false; + } + } + } + +} Index: 3rdParty_sources/httpcore/org/apache/http/util/VersionInfo.java =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/util/VersionInfo.java (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/util/VersionInfo.java (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,311 @@ +/* + * ==================================================================== + * 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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.util; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.ArrayList; + + +/** + * Provides access to version information for HTTP components. + * Static methods are used to extract version information from property + * files that are automatically packaged with HTTP component release JARs. + *
    + * All available version information is provided in strings, where + * the string format is informal and subject to change without notice. + * Version information is provided for debugging output and interpretation + * by humans, not for automated processing in applications. + * + * @since 4.0 + */ +public class VersionInfo { + + /** A string constant for unavailable information. */ + public final static String UNAVAILABLE = "UNAVAILABLE"; + + /** The filename of the version information files. */ + public final static String VERSION_PROPERTY_FILE = "version.properties"; + + // the property names + public final static String PROPERTY_MODULE = "info.module"; + public final static String PROPERTY_RELEASE = "info.release"; + public final static String PROPERTY_TIMESTAMP = "info.timestamp"; + + + /** The package that contains the version information. */ + private final String infoPackage; + + /** The module from the version info. */ + private final String infoModule; + + /** The release from the version info. */ + private final String infoRelease; + + /** The timestamp from the version info. */ + private final String infoTimestamp; + + /** The classloader from which the version info was obtained. */ + private final String infoClassloader; + + + /** + * Instantiates version information. + * + * @param pckg the package + * @param module the module, or null + * @param release the release, or null + * @param time the build time, or null + * @param clsldr the class loader, or null + */ + protected VersionInfo(String pckg, String module, + String release, String time, String clsldr) { + if (pckg == null) { + throw new IllegalArgumentException + ("Package identifier must not be null."); + } + + infoPackage = pckg; + infoModule = (module != null) ? module : UNAVAILABLE; + infoRelease = (release != null) ? release : UNAVAILABLE; + infoTimestamp = (time != null) ? time : UNAVAILABLE; + infoClassloader = (clsldr != null) ? clsldr : UNAVAILABLE; + } + + + /** + * Obtains the package name. + * The package name identifies the module or informal unit. + * + * @return the package name, never null + */ + public final String getPackage() { + return infoPackage; + } + + /** + * Obtains the name of the versioned module or informal unit. + * This data is read from the version information for the package. + * + * @return the module name, never null + */ + public final String getModule() { + return infoModule; + } + + /** + * Obtains the release of the versioned module or informal unit. + * This data is read from the version information for the package. + * + * @return the release version, never null + */ + public final String getRelease() { + return infoRelease; + } + + /** + * Obtains the timestamp of the versioned module or informal unit. + * This data is read from the version information for the package. + * + * @return the timestamp, never null + */ + public final String getTimestamp() { + return infoTimestamp; + } + + /** + * Obtains the classloader used to read the version information. + * This is just the toString output of the classloader, + * since the version information should not keep a reference to + * the classloader itself. That could prevent garbage collection. + * + * @return the classloader description, never null + */ + public final String getClassloader() { + return infoClassloader; + } + + + /** + * Provides the version information in human-readable format. + * + * @return a string holding this version information + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder + (20 + infoPackage.length() + infoModule.length() + + infoRelease.length() + infoTimestamp.length() + + infoClassloader.length()); + + sb.append("VersionInfo(") + .append(infoPackage).append(':').append(infoModule); + + // If version info is missing, a single "UNAVAILABLE" for the module + // is sufficient. Everything else just clutters the output. + if (!UNAVAILABLE.equals(infoRelease)) + sb.append(':').append(infoRelease); + if (!UNAVAILABLE.equals(infoTimestamp)) + sb.append(':').append(infoTimestamp); + + sb.append(')'); + + if (!UNAVAILABLE.equals(infoClassloader)) + sb.append('@').append(infoClassloader); + + return sb.toString(); + } + + + /** + * Loads version information for a list of packages. + * + * @param pckgs the packages for which to load version info + * @param clsldr the classloader to load from, or + * null for the thread context classloader + * + * @return the version information for all packages found, + * never null + */ + public final static VersionInfo[] loadVersionInfo(String[] pckgs, + ClassLoader clsldr) { + if (pckgs == null) { + throw new IllegalArgumentException + ("Package identifier list must not be null."); + } + + List vil = new ArrayList(pckgs.length); + for (int i=0; inull
    for the thread context classloader + * + * @return the version information for the argument package, or + * null if not available + */ + public final static VersionInfo loadVersionInfo(final String pckg, + ClassLoader clsldr) { + if (pckg == null) { + throw new IllegalArgumentException + ("Package identifier must not be null."); + } + + if (clsldr == null) + clsldr = Thread.currentThread().getContextClassLoader(); + + Properties vip = null; // version info properties, if available + try { + // org.apache.http becomes + // org/apache/http/version.properties + InputStream is = clsldr.getResourceAsStream + (pckg.replace('.', '/') + "/" + VERSION_PROPERTY_FILE); + if (is != null) { + try { + Properties props = new Properties(); + props.load(is); + vip = props; + } finally { + is.close(); + } + } + } catch (IOException ex) { + // shamelessly munch this exception + } + + VersionInfo result = null; + if (vip != null) + result = fromMap(pckg, vip, clsldr); + + return result; + } + + + /** + * Instantiates version information from properties. + * + * @param pckg the package for the version information + * @param info the map from string keys to string values, + * for example {@link java.util.Properties} + * @param clsldr the classloader, or null + * + * @return the version information + */ + protected final static VersionInfo fromMap(String pckg, Map info, + ClassLoader clsldr) { + if (pckg == null) { + throw new IllegalArgumentException + ("Package identifier must not be null."); + } + + String module = null; + String release = null; + String timestamp = null; + + if (info != null) { + module = (String) info.get(PROPERTY_MODULE); + if ((module != null) && (module.length() < 1)) + module = null; + + release = (String) info.get(PROPERTY_RELEASE); + if ((release != null) && ((release.length() < 1) || + (release.equals("${pom.version}")))) + release = null; + + timestamp = (String) info.get(PROPERTY_TIMESTAMP); + if ((timestamp != null) && + ((timestamp.length() < 1) || + (timestamp.equals("${mvn.timestamp}"))) + ) + timestamp = null; + } // if info + + String clsldrstr = null; + if (clsldr != null) + clsldrstr = clsldr.toString(); + + return new VersionInfo(pckg, module, release, timestamp, clsldrstr); + } + +} // class VersionInfo Index: 3rdParty_sources/httpcore/org/apache/http/util/package.html =================================================================== diff -u --- 3rdParty_sources/httpcore/org/apache/http/util/package.html (revision 0) +++ 3rdParty_sources/httpcore/org/apache/http/util/package.html (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -0,0 +1,38 @@ + + + + + +Resizable +{@link org.apache.http.util.ByteArrayBuffer byte} and +{@link org.apache.http.util.CharArrayBuffer char} arrays +and various utility classes with static helper methods. + + Index: 3rdParty_sources/versions.txt =================================================================== diff -u -r864762d59065fedfcb5f10ecee5e8186870f7d68 -r96f14f440726936ee35b0547416534e59d3db24c --- 3rdParty_sources/versions.txt (.../versions.txt) (revision 864762d59065fedfcb5f10ecee5e8186870f7d68) +++ 3rdParty_sources/versions.txt (.../versions.txt) (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -7,8 +7,10 @@ CKEditor Java 2.6 -Commons HttpClient 3.1 +Apache HttpClient 4.2.1 +Apache HttpCore 4.2.1 + Commons Lang 2.6 Commons IO 2.4 Index: lams_central/.classpath =================================================================== diff -u -rde884cf8c730a25d2f2296f7a768d3fd45508c99 -r96f14f440726936ee35b0547416534e59d3db24c --- lams_central/.classpath (.../.classpath) (revision de884cf8c730a25d2f2296f7a768d3fd45508c99) +++ lams_central/.classpath (.../.classpath) (revision 96f14f440726936ee35b0547416534e59d3db24c) @@ -33,8 +33,8 @@ - - + +