diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml
new file mode 100644
index 0000000000..2586cf3c6f
--- /dev/null
+++ b/.github/workflows/builds.yml
@@ -0,0 +1,59 @@
+name: Build Check
+
+on:
+ schedule:
+ - cron: '0 12 * * *'
+
+jobs:
+ Verify:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Grant Permission
+ run: chmod +x ./mvnw
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'corretto'
+ java-version: '11'
+ - name: Verify
+ run: ./mvnw -B -ntp clean verify -DskipTests -Dgpg.skip=true
+
+ RunOnLinux:
+ runs-on: ubuntu-latest
+ needs: Verify
+ steps:
+ - uses: actions/checkout@v4
+ - name: Grant Permission
+ run: chmod +x ./mvnw
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'corretto'
+ java-version: '11'
+ - name: Run Tests
+ run: ./mvnw -B -ntp test
+
+ RunOnMacOs:
+ runs-on: macos-latest
+ needs: Verify
+ steps:
+ - uses: actions/checkout@v4
+ - name: Grant Permission
+ run: chmod +x ./mvnw
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'corretto'
+ java-version: '11'
+ - name: Run Tests
+ run: ./mvnw -B -ntp test
+
+ RunOnWindows:
+ runs-on: windows-latest
+ needs: Verify
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'corretto'
+ java-version: '11'
+ - name: Run Tests
+ run: ./mvnw.cmd -B -ntp test
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
new file mode 100644
index 0000000000..1f49d31122
--- /dev/null
+++ b/.github/workflows/maven.yml
@@ -0,0 +1,55 @@
+# This workflow is designed to build PRs for AHC. Note that it does not actually publish AHC, just builds and test it.
+# Docs: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
+
+name: Build PR
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+ workflow_dispatch:
+ inputs:
+ name:
+ description: 'Github Actions'
+ required: true
+ default: 'Github Actions'
+
+jobs:
+ RunOnLinux:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Grant Permission
+ run: sudo chmod +x ./mvnw
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'corretto'
+ java-version: '11'
+ - name: Run Tests
+ run: ./mvnw -B -ntp clean test
+
+ RunOnMacOs:
+ runs-on: macos-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Grant Permission
+ run: sudo chmod +x ./mvnw
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'corretto'
+ java-version: '11'
+ - name: Run Tests
+ run: ./mvnw -B -ntp clean test
+
+ RunOnWindows:
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'corretto'
+ java-version: '11'
+ - name: Run Tests
+ run: ./mvnw.cmd -B -ntp clean test
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000000..b175fa865c
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,52 @@
+name: Release
+
+on:
+ workflow_dispatch:
+ inputs:
+ name:
+ description: 'Github Actions - Release'
+ required: true
+ default: 'Github Actions - Release'
+
+jobs:
+
+ Publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Grant Permission
+ run: sudo chmod +x ./mvnw
+
+ - uses: actions/setup-java@v4
+ with:
+ distribution: 'corretto'
+ java-version: '11'
+
+ - name: Remove old Maven Settings
+ run: rm -f /home/runner/.m2/settings.xml
+
+ - name: Maven Settings
+ uses: s4u/maven-settings-action@v3.1.0
+ with:
+ servers: |
+ [{
+ "id": "ossrh",
+ "username": "${{ secrets.OSSRH_USERNAME }}",
+ "password": "${{ secrets.OSSRH_PASSWORD }}"
+ }]
+
+ - name: Import GPG
+ uses: crazy-max/ghaction-import-gpg@v6.3.0
+ with:
+ gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
+ passphrase: ${{ secrets.GPG_PASSPHRASE }}
+
+ - name: Build
+ run: mvn -ntp -B clean verify install -DskipTests
+
+ - name: Publish to Maven Central
+ env:
+ GPG_KEY_NAME: ${{ secrets.GPG_KEY_NAME }}
+ GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+ run: mvn -ntp -B deploy -DskipTests -Dgpg.keyname=${GPG_KEY_NAME} -Dgpg.passphrase=${GPG_PASSPHRASE}
diff --git a/.gitignore b/.gitignore
index b023787595..d424b2597a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@ test-output
MANIFEST.MF
work
atlassian-ide-plugin.xml
+/bom/.flattened-pom.xml
diff --git a/.mvn/jvm.config b/.mvn/jvm.config
new file mode 100644
index 0000000000..32599cefea
--- /dev/null
+++ b/.mvn/jvm.config
@@ -0,0 +1,10 @@
+--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED
+--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED
+--add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
new file mode 100644
index 0000000000..c1dd12f176
Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
new file mode 100644
index 0000000000..4a95a1367b
--- /dev/null
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
diff --git a/CHANGES.md b/CHANGES.md
new file mode 100644
index 0000000000..d548766a4e
--- /dev/null
+++ b/CHANGES.md
@@ -0,0 +1,29 @@
+## From 2.2 to 2.3
+
+* New `isFilterInsecureCipherSuites` config to disable unsecure and weak ciphers filtering performed internally in Netty.
+
+## From 2.1 to 2.2
+
+* New [Typesafe config](https://github.com/lightbend/config) extra module
+* new `enableWebSocketCompression` config to enable per-message and per-frame WebSocket compression extension
+
+## From 2.0 to 2.1
+
+* AHC 2.1 targets Netty 4.1.
+* `org.asynchttpclient.HttpResponseHeaders` was [dropped](https://github.com/AsyncHttpClient/async-http-client/commit/f4786f3ac7699f8f8664e7c7db0b7097585a0786) in favor
+ of `io.netty.handler.codec.http.HttpHeaders`.
+* `org.asynchttpclient.cookie.Cookie` was [dropped](https://github.com/AsyncHttpClient/async-http-client/commit/a6d659ea0cc11fa5131304d8a04a7ba89c7a66af) in favor
+ of `io.netty.handler.codec.http.cookie.Cookie` as AHC's cookie parsers were contributed to Netty.
+* AHC now has a RFC6265 `CookieStore` that is enabled by default. Implementation can be changed in `AsyncHttpClientConfig`.
+* `AsyncHttpClient` now exposes stats with `getClientStats`.
+* `AsyncHandlerExtensions` was [dropped](https://github.com/AsyncHttpClient/async-http-client/commit/1972c9b9984d6d9f9faca6edd4f2159013205aea) in favor of default methods
+ in `AsyncHandler`.
+* `WebSocket` and `WebSocketListener` methods were renamed to mention frames
+* `AsyncHttpClientConfig` various changes:
+ * new `getCookieStore` now lets you configure a CookieStore (enabled by default)
+ * new `isAggregateWebSocketFrameFragments` now lets you disable WebSocket fragmented frames aggregation
+ * new `isUseLaxCookieEncoder` lets you loosen cookie chars validation
+ * `isAcceptAnyCertificate` was dropped, as it didn't do what its name stated
+ * new `isUseInsecureTrustManager` lets you use a permissive TrustManager, that would typically let you accept self-signed certificates
+ * new `isDisableHttpsEndpointIdentificationAlgorithm` disables setting `HTTPS` algorithm on the SSLEngines, typically disables SNI and HTTPS hostname verification
+ * new `isAggregateWebSocketFrameFragments` lets you disable fragmented WebSocket frames aggregation
diff --git a/LICENSE-2.0.txt b/LICENSE-2.0.txt
deleted file mode 100644
index d645695673..0000000000
--- a/LICENSE-2.0.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000000..85a16d3d06
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,13 @@
+ Copyright (c) 2014-2024 AsyncHttpClient Project. All rights reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/LICENSES/LICENSE.zstd-jni.txt b/LICENSES/LICENSE.zstd-jni.txt
new file mode 100644
index 0000000000..66abb8ae78
--- /dev/null
+++ b/LICENSES/LICENSE.zstd-jni.txt
@@ -0,0 +1,26 @@
+Zstd-jni: JNI bindings to Zstd Library
+
+Copyright (c) 2015-present, Luben Karavelov/ All rights reserved.
+
+BSD License
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
index 561933cd2f..0272134ed1 100644
--- a/README.md
+++ b/README.md
@@ -1,184 +1,263 @@
-Async Http Client
------------------
+# Async Http Client
+[](https://github.com/AsyncHttpClient/async-http-client/actions/workflows/builds.yml)
+
-Getting started [HTML](http://sonatype.github.com/async-http-client/) [PDF](http://is.gd/kexrN)
- With [WebSockets](http://jfarcand.wordpress.com/2011/12/21/writing-websocket-clients-using-asynchttpclient/)
+Follow [@AsyncHttpClient](https://twitter.com/AsyncHttpClient) on Twitter.
-Async Http Client library purpose is to allow Java applications to easily execute HTTP requests and asynchronously process the HTTP responses. The library also supports the WebSocket Protocol. The Async HTTP Client library is simple to use. First, in order to add it to your Maven project, simply add this dependency:
+The AsyncHttpClient (AHC) library allows Java applications to easily execute HTTP requests and asynchronously process HTTP responses.
+The library also supports the WebSocket Protocol.
+It's built on top of [Netty](https://github.com/netty/netty). It's compiled with Java 11.
+
+## Installation
+
+Binaries are deployed on Maven Central.
+Add a dependency on the main AsyncHttpClient artifact:
+
+Maven:
```xml
-
- * Callback methods get invoked in the following order:
- *
- *
- *
- * Returning a {@link AsyncHandler.STATE#ABORT} from any of those callback methods will interrupt asynchronous response
- * processing, after that only {@link #onCompleted()} is going to be called.
- *
- *
- * AsyncHandler aren't thread safe, hence you should avoid re-using the same instance when doing concurrent requests.
- * As an exmaple, the following may produce unexpected results:
- *
- * It is recommended to create a new instance instead.
- *
- * @param
- * AsyncHandler ah = new AsyncHandler() {....};
- * AsyncHttpClient client = new AsyncHttpClient();
- * client.prepareGet("http://.../").execute(ah);
- * client.prepareGet("http://.../").execute(ah);
- *
- *
- */
-public interface AsyncHandlerExtensions {
-
- /**
- * Notify the callback when a request is being written on the wire.
- * If the original request causes multiple requests to be sent, for example, because of authorization or retry,
- * it will be notified multiple times.
- * Currently only supported by the Netty provider.
- */
- void onRequestSent();
-
- /**
- * Notify the callback every time a request is being retried.
- */
- void onRetry();
-}
diff --git a/api/src/main/java/org/asynchttpclient/AsyncHttpClient.java b/api/src/main/java/org/asynchttpclient/AsyncHttpClient.java
deleted file mode 100755
index 85e19adc55..0000000000
--- a/api/src/main/java/org/asynchttpclient/AsyncHttpClient.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright 2010 Ning, Inc.
- *
- * Ning licenses this file to you under the Apache License, version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.asynchttpclient;
-
-import org.asynchttpclient.filter.FilterContext;
-import org.asynchttpclient.filter.FilterException;
-import org.asynchttpclient.filter.RequestFilter;
-import org.asynchttpclient.resumable.ResumableAsyncHandler;
-
-import java.io.Closeable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Future;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * This class support asynchronous and synchronous HTTP request.
- *
- * To execute synchronous HTTP request, you just need to do
- *
- * The code above will block until the response is fully received. To execute asynchronous HTTP request, you
- * create an {@link AsyncHandler} or its abstract implementation, {@link AsyncCompletionHandler}
- *
- *
- * AsyncHttpClient c = new AsyncHttpClient();
- * Future
- * You can also have more control about the how the response is asynchronously processed by using a {@link AsyncHandler}
- *
- * AsyncHttpClient c = new AsyncHttpClient();
- * Future
- * This class can also be used without the need of {@link AsyncHandler}
- * AsyncHttpClient c = new AsyncHttpClient();
- * Future
- * - * Finally, you can configure the AsyncHttpClient using an {@link AsyncHttpClientConfig} instance - *- * AsyncHttpClient c = new AsyncHttpClient(); - * Futuref = c.prepareGet(TARGET_URL).execute(); - * Response r = f.get(); - *
- * - * An instance of this class will cache every HTTP 1.1 connections and close them when the {@link AsyncHttpClientConfig#getIdleConnectionTimeoutInMs()} - * expires. This object can hold many persistent connections to different host. - */ -public class AsyncHttpClient implements Closeable { - - /** - * Providers that will be searched for, on the classpath, in order when no - * provider is explicitly specified by the developer. - */ - private static final String[] DEFAULT_PROVIDERS = { - "org.asynchttpclient.providers.netty.NettyAsyncHttpProvider", - "org.asynchttpclient.providers.grizzly.GrizzlyAsyncHttpProvider" - }; - - private final AsyncHttpProvider httpProvider; - private final AsyncHttpClientConfig config; - private final static Logger logger = LoggerFactory.getLogger(AsyncHttpClient.class); - private final AtomicBoolean isClosed = new AtomicBoolean(false); - - /** - * Default signature calculator to use for all requests constructed by this client instance. - * - * @since 1.1 - */ - protected SignatureCalculator signatureCalculator; - - /** - * Create a new HTTP Asynchronous Client using the default {@link AsyncHttpClientConfig} configuration. The - * default {@link AsyncHttpProvider} that will be used will be based on the classpath configuration. - * - * The default providers will be searched for in this order: - *- * AsyncHttpClient c = new AsyncHttpClient(new AsyncHttpClientConfig.Builder().setRequestTimeoutInMs(...).build()); - * Futuref = c.prepareGet(TARGET_URL).execute(); - * Response r = f.get(); - *
null
- */
- public ExecutorService executorService() {
- return applicationThreadPool;
- }
-
- /**
- * An instance of {@link ProxyServer} used by an {@link AsyncHttpClient}
- *
- * @return instance of {@link ProxyServer}
- */
- public ProxyServerSelector getProxyServerSelector() {
- return proxyServerSelector;
- }
-
- /**
- * Return an instance of {@link SSLContext} used for SSL connection.
- *
- * @return an instance of {@link SSLContext} used for SSL connection.
- */
- public SSLContext getSSLContext() {
- return sslContext;
- }
-
- /**
- * Return an instance of {@link ConnectionsPool}
- *
- * @return an instance of {@link ConnectionsPool}
- */
- public ConnectionsPool, ?> getConnectionsPool() {
- return connectionsPool;
- }
-
- /**
- * Return an instance of {@link SSLEngineFactory} used for SSL connection.
- *
- * @return an instance of {@link SSLEngineFactory} used for SSL connection.
- */
- public SSLEngineFactory getSSLEngineFactory() {
- if (sslEngineFactory == null) {
- return new SSLEngineFactory() {
- public SSLEngine newSSLEngine() {
- if (sslContext != null) {
- SSLEngine sslEngine = sslContext.createSSLEngine();
- sslEngine.setUseClientMode(true);
- return sslEngine;
- } else {
- return null;
- }
- }
- };
- }
- return sslEngineFactory;
- }
-
- /**
- * Return the {@link AsyncHttpProviderConfig}
- *
- * @return the {@link AsyncHttpProviderConfig}
- */
- public AsyncHttpProviderConfig, ?> getAsyncHttpProviderConfig() {
- return providerConfig;
- }
-
- /**
- * Return the current {@link Realm}}
- *
- * @return the current {@link Realm}}
- */
- public Realm getRealm() {
- return realm;
- }
-
- /**
- * @return true
if {@link RequestFilter}s have been defined.
- *
- * @since 2.0.0
- */
- public boolean hasRequestFilters() {
- return !requestFilters.isEmpty();
- }
-
- /**
- * Return the list of {@link RequestFilter}
- *
- * @return Unmodifiable list of {@link ResponseFilter}
- */
- public Listtrue
if {@link ResponseFilter}s have been defined.
- * @since 2.0.0
- */
- public boolean hasResponseFilters() {
- return !responseFilters.isEmpty();
- }
-
- /**
- * Return the list of {@link ResponseFilter}
- *
- * @return Unmodifiable list of {@link ResponseFilter}
- */
- public Listtrue
if both the application and reaper thread pools
- * haven't yet been shutdown.
- * @since 1.7.21
- */
- public boolean isValid() {
- boolean atpRunning = true;
- try {
- atpRunning = applicationThreadPool.isShutdown();
- } catch (Exception ignore) {
- // isShutdown() will thrown an exception in an EE7 environment
- // when using a ManagedExecutorService.
- // When this is the case, we assume it's running.
- }
- return (atpRunning && !reaper.isShutdown());
- }
-
- /**
- * Return the {@link HostnameVerifier}
- *
- * @return the {@link HostnameVerifier}
- */
- public HostnameVerifier getHostnameVerifier() {
- return hostnameVerifier;
- }
-
- /**
- * @return number to multiply by availableProcessors() that will determine # of NioWorkers to use
- */
- public int getIoThreadMultiplier() {
- return ioThreadMultiplier;
- }
-
- /**
- * - * In the case of a POST/Redirect/Get scenario where the server uses a 302 - * for the redirect, should AHC respond to the redirect with a GET or - * whatever the original method was. Unless configured otherwise, - * for a 302, AHC, will use a GET for this case. - *
- * - * @returntrue
if string 302 handling is to be used,
- * otherwise false
.
- *
- * @since 1.7.2
- */
- public boolean isStrict302Handling() {
- return strict302Handling;
- }
-
- /**
- * @returntrue
if AHC should use relative URIs instead of absolute ones when talking with a SSL proxy,
- * otherwise false
.
- *
- * @since 1.7.12
- */
- public boolean isUseRelativeURIsWithSSLProxies() {
- return useRelativeURIsWithSSLProxies;
- }
-
- /**
- * Return the maximum time in millisecond an {@link AsyncHttpClient} will keep connection in the pool, or -1 to keep connection while possible.
- *
- * @return the maximum time in millisecond an {@link AsyncHttpClient} will keep connection in the pool, or -1 to keep connection while possible.
- */
- public int getMaxConnectionLifeTimeInMs() {
- return maxConnectionLifeTimeInMs;
- }
-
- /**
- * @returntrue
if AHC should use rfc6265 for encoding client side cookies, otherwise false
.
- *
- * @since 1.7.18
- */
- public boolean isRfc6265CookieEncoding() {
- return rfc6265CookieEncoding;
- }
-
- /**
- * @return true
if the underlying provider should make new connections asynchronously or not. By default
- * new connections are made synchronously.
- *
- * @since 2.0.0
- */
- public boolean isAsyncConnectMode() {
- return asyncConnectMode;
- }
-
- /**
- * Builder for an {@link AsyncHttpClient}
- */
- public static class Builder {
- private int defaultMaxTotalConnections = Integer.getInteger(ASYNC_CLIENT + "defaultMaxTotalConnections", -1);
- private int defaultMaxConnectionPerHost = Integer.getInteger(ASYNC_CLIENT + "defaultMaxConnectionsPerHost", -1);
- private int defaultConnectionTimeOutInMs = Integer.getInteger(ASYNC_CLIENT + "defaultConnectionTimeoutInMS", 60 * 1000);
- private int defaultWebsocketIdleTimeoutInMs = Integer.getInteger(ASYNC_CLIENT + "defaultWebsocketTimoutInMS", 15 * 60 * 1000);
- private int defaultIdleConnectionInPoolTimeoutInMs = Integer.getInteger(ASYNC_CLIENT + "defaultIdleConnectionInPoolTimeoutInMS", 60 * 1000);
- private int defaultIdleConnectionTimeoutInMs = Integer.getInteger(ASYNC_CLIENT + "defaultIdleConnectionTimeoutInMS", 60 * 1000);
- private int defaultRequestTimeoutInMs = Integer.getInteger(ASYNC_CLIENT + "defaultRequestTimeoutInMS", 60 * 1000);
- private int defaultMaxConnectionLifeTimeInMs = Integer.getInteger(ASYNC_CLIENT + "defaultMaxConnectionLifeTimeInMs", -1);
- private boolean redirectEnabled = Boolean.getBoolean(ASYNC_CLIENT + "defaultRedirectsEnabled");
- private int maxDefaultRedirects = Integer.getInteger(ASYNC_CLIENT + "defaultMaxRedirects", 5);
- private boolean compressionEnabled = Boolean.getBoolean(ASYNC_CLIENT + "compressionEnabled");
- private String userAgent = System.getProperty(ASYNC_CLIENT + "userAgent", "AsyncHttpClient/" + AHC_VERSION);
- private boolean useProxyProperties = Boolean.getBoolean(ASYNC_CLIENT + "useProxyProperties");
- private boolean useProxySelector = Boolean.getBoolean(ASYNC_CLIENT + "useProxySelector");
- private boolean allowPoolingConnection = true;
- private boolean useRelativeURIsWithSSLProxies = Boolean.getBoolean(ASYNC_CLIENT + "useRelativeURIsWithSSLProxies");
- private ScheduledExecutorService reaper;
- private ExecutorService applicationThreadPool;
- private ProxyServerSelector proxyServerSelector = null;
- private SSLContext sslContext;
- private SSLEngineFactory sslEngineFactory;
- private AsyncHttpProviderConfig, ?> providerConfig;
- private ConnectionsPool, ?> connectionsPool;
- private Realm realm;
- private int requestCompressionLevel = -1;
- private int maxRequestRetry = 5;
- private final Listtrue
but {@link #setProxyServer(ProxyServer)}
- * was used to explicitly set a proxy server, the latter is preferred.
- *
- * See http://docs.oracle.com/javase/7/docs/api/java/net/ProxySelector.html
- */
- public Builder setUseProxySelector(boolean useProxySelector) {
- this.useProxySelector = useProxySelector;
- return this;
- }
-
- /**
- * Sets whether AHC should use the default http.proxy* system properties
- * to obtain proxy information. This differs from {@link #setUseProxySelector(boolean)}
- * in that AsyncHttpClient will use its own logic to handle the system properties,
- * potentially supporting other protocols that the the JDK ProxySelector doesn't.
- *
- * If useProxyProperties is set to true
but {@link #setUseProxySelector(boolean)}
- * was also set to true, the latter is preferred.
- *
- * See http://download.oracle.com/javase/1.4.2/docs/guide/net/properties.html
- */
- public Builder setUseProxyProperties(boolean useProxyProperties) {
- this.useProxyProperties = useProxyProperties;
- return this;
- }
-
- public Builder setIOThreadMultiplier(int multiplier) {
- this.ioThreadMultiplier = multiplier;
- return this;
- }
-
- /**
- * Set the {@link HostnameVerifier}
- *
- * @param hostnameVerifier {@link HostnameVerifier}
- * @return this
- */
- public Builder setHostnameVerifier(HostnameVerifier hostnameVerifier) {
- this.hostnameVerifier = hostnameVerifier;
- return this;
- }
-
- /**
- * Configures this AHC instance to be strict in it's handling of 302 redirects
- * in a POST/Redirect/GET situation.
- *
- * @param strict302Handling strict handling
- *
- * @return this
- *
- * @since 1.7.2
- */
- public Builder setStrict302Handling(final boolean strict302Handling) {
- this.strict302Handling = strict302Handling;
- return this;
- }
-
- /**
- * Set the maximum time in millisecond connection can be added to the pool for further reuse
- *
- * @param maxConnectionLifeTimeInMs the maximum time in millisecond connection can be added to the pool for further reuse
- * @return a {@link Builder}
- */
- public Builder setMaxConnectionLifeTimeInMs(int maxConnectionLifeTimeInMs) {
- this.defaultMaxConnectionLifeTimeInMs = maxConnectionLifeTimeInMs;
- return this;
- }
-
- /**
- * Configures this AHC instance to use relative URIs instead of absolute ones when talking with a SSL proxy.
- *
- * @param useRelativeURIsWithSSLProxies
- * @return this
- *
- * @since 1.7.2
- */
- public Builder setUseRelativeURIsWithSSLProxies(boolean useRelativeURIsWithSSLProxies) {
- this.useRelativeURIsWithSSLProxies = useRelativeURIsWithSSLProxies;
- return this;
- }
-
- /**
- * Enables SPDY support. Note that doing so, will currently disable WebSocket support
- * for this client instance. If not explicitly enabled, spdy will not be used.
- *
- * @param spdyEnabled configures spdy support.
- *
- * @return this
- *
- * @since 2.0
- */
- public Builder setSpdyEnabled(boolean spdyEnabled) {
- this.spdyEnabled = spdyEnabled;
- return this;
- }
-
- /**
- * Configures the initial window size for the SPDY session.
- *
- * @param spdyInitialWindowSize the initial window size.
- *
- * @return this
- *
- * @since 2.0
- */
- public Builder setSpdyInitialWindowSize(int spdyInitialWindowSize) {
- this.spdyInitialWindowSize = spdyInitialWindowSize;
- return this;
- }
-
- /**
- * Configures the maximum number of concurrent streams over a single
- * SPDY session.
- *
- * @param spdyMaxConcurrentStreams the maximum number of concurrent
- * streams over a single SPDY session.
- *
- * @return this
- *
- * @since 2.0
- */
- public Builder setSpdyMaxConcurrentStreams(int spdyMaxConcurrentStreams) {
- this.spdyMaxConcurrentStreams = spdyMaxConcurrentStreams;
- return this;
- }
-
- /**
- * Configures this AHC instance to use RFC 6265 cookie encoding style
- *
- * @param rfc6265CookieEncoding
- * @return this
- *
- * @since 1.7.18
- */
- public Builder setRfc6265CookieEncoding(boolean rfc6265CookieEncoding) {
- this.rfc6265CookieEncoding = rfc6265CookieEncoding;
- return this;
- }
-
- /**
- * Configures how the underlying providers make new connections. By default,
- * connections will be made synchronously.
- *
- * @param asyncConnectMode pass true
to enable async connect mode.
- *
- * @return this
- *
- * @since 2.0.0
- */
- public Builder setAsyncConnectMode(boolean asyncConnectMode) {
- this.asyncConnectMode = asyncConnectMode;
- return this;
- }
-
- /**
- * Create a config builder with values taken from the given prototype configuration.
- *
- * @param prototype the configuration to use as a prototype.
- */
- public Builder(AsyncHttpClientConfig prototype) {
- allowPoolingConnection = prototype.getAllowPoolingConnection();
- providerConfig = prototype.getAsyncHttpProviderConfig();
- connectionsPool = prototype.getConnectionsPool();
- defaultConnectionTimeOutInMs = prototype.getConnectionTimeoutInMs();
- defaultIdleConnectionInPoolTimeoutInMs = prototype.getIdleConnectionInPoolTimeoutInMs();
- defaultIdleConnectionTimeoutInMs = prototype.getIdleConnectionTimeoutInMs();
- defaultMaxConnectionPerHost = prototype.getMaxConnectionPerHost();
- defaultMaxConnectionLifeTimeInMs = prototype.getMaxConnectionLifeTimeInMs();
- maxDefaultRedirects = prototype.getMaxRedirects();
- defaultMaxTotalConnections = prototype.getMaxTotalConnections();
- proxyServerSelector = prototype.getProxyServerSelector();
- realm = prototype.getRealm();
- defaultRequestTimeoutInMs = prototype.getRequestTimeoutInMs();
- sslContext = prototype.getSSLContext();
- sslEngineFactory = prototype.getSSLEngineFactory();
- userAgent = prototype.getUserAgent();
- redirectEnabled = prototype.isRedirectEnabled();
- compressionEnabled = prototype.isCompressionEnabled();
- reaper = prototype.reaper();
- applicationThreadPool = prototype.executorService();
-
- requestFilters.clear();
- responseFilters.clear();
- ioExceptionFilters.clear();
-
- requestFilters.addAll(prototype.getRequestFilters());
- responseFilters.addAll(prototype.getResponseFilters());
- ioExceptionFilters.addAll(prototype.getIOExceptionFilters());
-
- requestCompressionLevel = prototype.getRequestCompressionLevel();
- useRawUrl = prototype.isUseRawUrl();
- ioThreadMultiplier = prototype.getIoThreadMultiplier();
- maxRequestRetry = prototype.getMaxRequestRetry();
- allowSslConnectionPool = prototype.getAllowPoolingConnection();
- removeQueryParamOnRedirect = prototype.isRemoveQueryParamOnRedirect();
- hostnameVerifier = prototype.getHostnameVerifier();
- strict302Handling = prototype.isStrict302Handling();
- useRelativeURIsWithSSLProxies = prototype.isUseRelativeURIsWithSSLProxies();
- rfc6265CookieEncoding = prototype.isRfc6265CookieEncoding();
- asyncConnectMode = prototype.isAsyncConnectMode();
- }
-
- /**
- * Build an {@link AsyncHttpClientConfig}
- *
- * @return an {@link AsyncHttpClientConfig}
- */
- public AsyncHttpClientConfig build() {
-
- if (reaper == null) {
- reaper = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
- public Thread newThread(Runnable r) {
- Thread t = new Thread(r, "AsyncHttpClient-Reaper");
- t.setDaemon(true);
- return t;
- }
- });
- }
-
- if (proxyServerSelector == null && useProxySelector) {
- proxyServerSelector = ProxyUtils.getJdkDefaultProxyServerSelector();
- }
-
- if (proxyServerSelector == null && useProxyProperties) {
- proxyServerSelector = ProxyUtils.createProxyServerSelector(System.getProperties());
- }
-
- if (proxyServerSelector == null) {
- proxyServerSelector = ProxyServerSelector.NO_PROXY_SELECTOR;
- }
-
- return new AsyncHttpClientConfig(defaultMaxTotalConnections,
- defaultMaxConnectionPerHost,
- defaultConnectionTimeOutInMs,
- defaultWebsocketIdleTimeoutInMs,
- defaultIdleConnectionInPoolTimeoutInMs,
- defaultIdleConnectionTimeoutInMs,
- defaultRequestTimeoutInMs,
- defaultMaxConnectionLifeTimeInMs,
- redirectEnabled,
- maxDefaultRedirects,
- compressionEnabled,
- userAgent,
- allowPoolingConnection,
- reaper,
- applicationThreadPool,
- proxyServerSelector,
- sslContext,
- sslEngineFactory,
- providerConfig,
- connectionsPool,
- realm,
- requestFilters,
- responseFilters,
- ioExceptionFilters,
- requestCompressionLevel,
- maxRequestRetry,
- allowSslConnectionPool,
- useRawUrl,
- removeQueryParamOnRedirect,
- hostnameVerifier,
- ioThreadMultiplier,
- strict302Handling,
- useRelativeURIsWithSSLProxies,
- spdyEnabled,
- spdyInitialWindowSize,
- spdyMaxConcurrentStreams,
- rfc6265CookieEncoding,
- asyncConnectMode);
- }
- }
-}
-
diff --git a/api/src/main/java/org/asynchttpclient/AsyncHttpClientConfigBean.java b/api/src/main/java/org/asynchttpclient/AsyncHttpClientConfigBean.java
deleted file mode 100644
index b5944629a5..0000000000
--- a/api/src/main/java/org/asynchttpclient/AsyncHttpClientConfigBean.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Sonatype, Inc. All rights reserved.
- *
- * This program is licensed to you under the Apache License Version 2.0,
- * and you may not use this file except in compliance with the Apache License Version 2.0.
- * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the Apache License Version 2.0 is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
- */
-package org.asynchttpclient;
-
-import org.asynchttpclient.filter.IOExceptionFilter;
-import org.asynchttpclient.filter.RequestFilter;
-import org.asynchttpclient.filter.ResponseFilter;
-import org.asynchttpclient.util.ProxyUtils;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import java.util.LinkedList;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-
-/**
- * Simple JavaBean version of {@link AsyncHttpClientConfig}
- */
-public class AsyncHttpClientConfigBean extends AsyncHttpClientConfig {
-
- public AsyncHttpClientConfigBean() {
- configureExecutors();
- configureDefaults();
- configureFilters();
- }
-
- void configureFilters() {
- requestFilters = new LinkedList- */ -public interface Request { - - /** - * Return the request's method name (GET, POST, etc.) - * - * @return the request's method name (GET, POST, etc.) - */ - public String getMethod(); - - /** - * Return the decoded url - * - * @return the decoded url - */ - public String getUrl(); - - public URI getOriginalURI(); - public URI getURI(); - public URI getRawURI(); - - /** - * Return the InetAddress to override - * - * @return the InetAddress - */ - public InetAddress getInetAddress(); - - public InetAddress getLocalAddress(); - - /** - * Return the undecoded url - * - * @return the undecoded url - */ - public String getRawUrl(); - - /** - * Return the current set of Headers. - * - * @return a {@link FluentCaseInsensitiveStringsMap} contains headers. - */ - public FluentCaseInsensitiveStringsMap getHeaders(); - - /** - * @return return- * Request r = new RequestBuilder().setUrl("url") - * .setRealm((new Realm.RealmBuilder()).setPrincipal(user) - * .setPassword(admin) - * .setRealmName("MyRealm") - * .setScheme(Realm.AuthScheme.DIGEST).build()); - * r.execute(); - *
true
if request headers have been added,
- * otherwise, returns false
.
- *
- * @since 2.0
- */
- boolean hasHeaders();
-
- /**
- * Return Coookie.
- *
- * @return an unmodifiable Collection of Cookies
- */
- public Collection- * or - *- * SimpleAsyncHttpClient client = new SimpleAsyncHttpClient.Builder() - * .setIdleConnectionInPoolTimeoutInMs(100) - * .setMaximumConnectionsTotal(50) - * .setRequestTimeoutInMs(5 * 60 * 1000) - * .setUrl(getTargetUrl()) - * .setHeader("Content-Type", "text/html").build(); - * - * StringBuilder s = new StringBuilder(); - * Futurefuture = client.post(new InputStreamBodyGenerator(new ByteArrayInputStream(MY_MESSAGE.getBytes())), new AppendableBodyConsumer(s)); - *
- */ -public class SimpleAsyncHttpClient implements Closeable { - - private final static Logger logger = LoggerFactory.getLogger(SimpleAsyncHttpClient.class); - private final AsyncHttpClientConfig config; - private final RequestBuilder requestBuilder; - private AsyncHttpClient asyncHttpClient; - private final ThrowableHandler defaultThrowableHandler; - private final boolean resumeEnabled; - private final ErrorDocumentBehaviour errorDocumentBehaviour; - private final SimpleAHCTransferListener listener; - private final boolean derived; - private final String providerClass; - - private SimpleAsyncHttpClient(AsyncHttpClientConfig config, RequestBuilder requestBuilder, ThrowableHandler defaultThrowableHandler, ErrorDocumentBehaviour errorDocumentBehaviour, boolean resumeEnabled, AsyncHttpClient ahc, SimpleAHCTransferListener listener, String providerClass) { - this.config = config; - this.requestBuilder = requestBuilder; - this.defaultThrowableHandler = defaultThrowableHandler; - this.resumeEnabled = resumeEnabled; - this.errorDocumentBehaviour = errorDocumentBehaviour; - this.asyncHttpClient = ahc; - this.listener = listener; - this.providerClass = providerClass; - - this.derived = ahc != null; - } - - public Future- * public void ByteArrayOutputStreamBodyConsumerTest() throws Throwable { - * - * SimpleAsyncHttpClient client = new SimpleAsyncHttpClient.Builder() - * .setUrl(getTargetUrl()) - * .build(); - * - * ByteArrayOutputStream o = new ByteArrayOutputStream(10); - * Futurefuture = client.post(new FileodyGenerator(myFile), new OutputStreamBodyConsumer(o)); - *
An abstract base implementation of the listener support provided by
- * {@link ListenableFuture}. This class uses an {@link ExecutionList} to
- * guarantee that all registered listeners will be executed. Listener/Executor
- * pairs are stored in the execution list and executed in the order in which
- * they were added, but because of thread scheduling issues there is no
- * guarantee that the JVM will execute them in order. In addition, listeners
- * added after the task is complete will be executed immediately, even if some
- * previously added listeners have not yet been executed.
- *
- * @author Sven Mawson
- * @since 1
- */
-public abstract class AbstractListenableFuture A list of ({@code Runnable}, {@code Executor}) pairs that guarantees
- * that every {@code Runnable} that is added using the add method will be
- * executed in its associated {@code Executor} after {@link #run()} is called.
- * {@code Runnable}s added after {@code run} is called are still guaranteed to
- * execute.
- *
- * @author Nishant Thakkar
- * @author Sven Mawson
- * @since 1
- */
-public final class ExecutionList implements Runnable {
-
- // Logger to log exceptions caught when running runnables.
- private static final Logger log =
- Logger.getLogger(ExecutionList.class.getName());
-
- // The runnable,executor pairs to execute.
- private final Queue
- * This encoder is stateful. It maintains an internal data structure that
- * holds the {@link Cookie}s added by the {@link #addCookie(String, String)}
- * method. Once {@link #encode()} is called, all added {@link Cookie}s are
- * encoded into an HTTP header value and all {@link Cookie}s in the internal
- * data structure are removed so that the encoder can start over.
- * null
the {@link #DEFAULT_CONTENT_TYPE default} is used
- * @param charset the charset encoding for this part, if null
the {@link #DEFAULT_CHARSET default} is used
- * @param contentId
- */
- public FilePart(String name, PartSource partSource, String contentType, String charset, String contentId) {
-
- super(name, contentType == null ? DEFAULT_CONTENT_TYPE : contentType, charset == null ? "ISO-8859-1" : charset, DEFAULT_TRANSFER_ENCODING, contentId);
-
- if (partSource == null) {
- throw new IllegalArgumentException("Source may not be null");
- }
- this.source = partSource;
- }
-
- public FilePart(String name, PartSource partSource, String contentType, String charset) {
- this(name, partSource, contentType, charset, null);
- }
-
- /**
- * FilePart Constructor.
- *
- * @param name the name for this part
- * @param partSource the source for this part
- */
- public FilePart(String name, PartSource partSource) {
- this(name, partSource, null, null);
- }
-
- /**
- * FilePart Constructor.
- *
- * @param name the name of the file part
- * @param file the file to post
- * @throws java.io.FileNotFoundException if the file is not a normal file or if it is not readable.
- */
- public FilePart(String name, File file) throws FileNotFoundException {
- this(name, new FilePartSource(file), null, null);
- }
-
- /**
- * FilePart Constructor.
- *
- * @param name the name of the file part
- * @param file the file to post
- * @param contentType the content type for this part, if null
the {@link #DEFAULT_CONTENT_TYPE default} is used
- * @param charset the charset encoding for this part, if null
the {@link #DEFAULT_CHARSET default} is used
- * @throws FileNotFoundException if the file is not a normal file or if it is not readable.
- */
- public FilePart(String name, File file, String contentType, String charset) throws FileNotFoundException {
- this(name, new FilePartSource(file), contentType, charset);
- }
-
- /**
- * FilePart Constructor.
- *
- * @param name the name of the file part
- * @param fileName the file name
- * @param file the file to post
- * @throws FileNotFoundException if the file is not a normal file or if it is not readable.
- */
- public FilePart(String name, String fileName, File file) throws FileNotFoundException {
- this(name, new FilePartSource(fileName, file), null, null);
- }
-
- /**
- * FilePart Constructor.
- *
- * @param name the name of the file part
- * @param fileName the file name
- * @param file the file to post
- * @param contentType the content type for this part, if null
the {@link #DEFAULT_CONTENT_TYPE default} is used
- * @param charset the charset encoding for this part, if null
the {@link #DEFAULT_CHARSET default} is used
- * @throws FileNotFoundException if the file is not a normal file or if it is not readable.
- */
- public FilePart(String name, String fileName, File file, String contentType, String charset) throws FileNotFoundException {
- this(name, new FilePartSource(fileName, file), contentType, charset);
- }
-
- /**
- * Write the disposition header to the output stream
- *
- * @param out The output stream
- * @throws java.io.IOException If an IO problem occurs
- */
- protected void sendDispositionHeader(OutputStream out) throws IOException {
- super.sendDispositionHeader(out);
- String filename = this.source.getFileName();
- if (filename != null) {
- out.write(FILE_NAME_BYTES);
- out.write(QUOTE_BYTES);
- out.write(MultipartEncodingUtil.getAsciiBytes(filename));
- out.write(QUOTE_BYTES);
- }
- }
-
- /**
- * Write the data in "source" to the specified stream.
- *
- * @param out The output stream.
- * @throws IOException if an IO problem occurs.
- */
- protected void sendData(OutputStream out) throws IOException {
- if (lengthOfData() == 0) {
-
- // this file contains no data, so there is nothing to send.
- // we don't want to create a zero length buffer as this will
- // cause an infinite loop when reading.
- return;
- }
-
- byte[] tmp = new byte[4096];
- InputStream instream = source.createInputStream();
- try {
- int len;
- while ((len = instream.read(tmp)) >= 0) {
- out.write(tmp, 0, len);
- }
- } finally {
- // we're done with the stream, close it
- instream.close();
- }
- }
-
- public void setStalledTime(long ms) {
- _stalledTime = ms;
- }
-
- public long getStalledTime() {
- return _stalledTime;
- }
-
- /**
- * Returns the source of the file part.
- *
- * @return The source.
- */
- protected PartSource getSource() {
- return this.source;
- }
-
- /**
- * Return the length of the data.
- *
- * @return The length.
- * @throws IOException if an IO problem occurs
- */
- protected long lengthOfData() throws IOException {
- return source.getLength();
- }
-
- private long _stalledTime = -1;
-
-}
diff --git a/api/src/main/java/org/asynchttpclient/multipart/FilePartSource.java b/api/src/main/java/org/asynchttpclient/multipart/FilePartSource.java
deleted file mode 100644
index 0e9a74991a..0000000000
--- a/api/src/main/java/org/asynchttpclient/multipart/FilePartSource.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright 2010 Ning, Inc.
- *
- * Ning licenses this file to you under the Apache License, version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package org.asynchttpclient.multipart;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * This class is an adaptation of the Apache HttpClient implementation
- *
- * @link http://hc.apache.org/httpclient-3.x/
- */
-public class FilePartSource implements PartSource {
-
- /**
- * File part file.
- */
- private File file = null;
-
- /**
- * File part file name.
- */
- private String fileName = null;
-
- /**
- * Constructor for FilePartSource.
- *
- * @param file the FilePart source File.
- * @throws java.io.FileNotFoundException if the file does not exist or cannot be read
- */
- public FilePartSource(File file) throws FileNotFoundException {
- this.file = file;
- if (file != null) {
- if (!file.isFile()) {
- final String errorMessage = String.format("File is not a normal file (%s).", file.getAbsolutePath());
- throw new FileNotFoundException(errorMessage);
- }
- if (!file.canRead()) {
- final String errorMessage = String.format("File is not readable (%s).", file.getAbsolutePath());
- throw new FileNotFoundException(errorMessage);
- }
- this.fileName = file.getName();
- }
- }
-
- /**
- * Constructor for FilePartSource.
- *
- * @param fileName the file name of the FilePart
- * @param file the source File for the FilePart
- * @throws FileNotFoundException if the file does not exist or cannot be read
- */
- public FilePartSource(String fileName, File file) throws FileNotFoundException {
- this(file);
- this.fileName = fileName;
- }
-
- /**
- * Return the length of the file
- *
- * @return the length of the file.
- * @see PartSource#getLength()
- */
- public long getLength() {
- if (this.file != null) {
- return this.file.length();
- } else {
- return 0;
- }
- }
-
- /**
- * Return the current filename
- *
- * @return the filename.
- * @see PartSource#getFileName()
- */
- public String getFileName() {
- return fileName;
- }
-
- /**
- * Return a new {@link java.io.FileInputStream} for the current filename.
- *
- * @return the new input stream.
- * @throws java.io.IOException If an IO problem occurs.
- * @see PartSource#createInputStream()
- */
- public InputStream createInputStream() throws IOException {
- if (this.file != null) {
- return new FileInputStream(this.file);
- } else {
- return new ByteArrayInputStream(new byte[] {});
- }
- }
-
- public File getFile() {
- return file;
- }
-
-}
diff --git a/api/src/main/java/org/asynchttpclient/multipart/FilePartStallHandler.java b/api/src/main/java/org/asynchttpclient/multipart/FilePartStallHandler.java
deleted file mode 100644
index d52db46af3..0000000000
--- a/api/src/main/java/org/asynchttpclient/multipart/FilePartStallHandler.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Sonatype, Inc. All rights reserved.
- *
- * This program is licensed to you under the Apache License Version 2.0,
- * and you may not use this file except in compliance with the Apache License Version 2.0.
- * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the Apache License Version 2.0 is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
- */
-package org.asynchttpclient.multipart;
-
-import java.util.Timer;
-import java.util.TimerTask;
-
-/**
- * @author Gail Hernandez
- */
-public class FilePartStallHandler extends TimerTask {
- public FilePartStallHandler(long waitTime, FilePart filePart) {
- _waitTime = waitTime;
- _failed = false;
- _written = false;
- }
-
- public void completed() {
- if(_waitTime > 0) {
- _timer.cancel();
- }
- }
-
- public boolean isFailed() {
- return _failed;
- }
-
- public void run() {
- if(!_written) {
- _failed = true;
- _timer.cancel();
- }
- _written = false;
- }
-
- public void start() {
- if(_waitTime > 0) {
- _timer = new Timer();
- _timer.scheduleAtFixedRate(this, _waitTime, _waitTime);
- }
- }
-
- public void writeHappened() {
- _written = true;
- }
-
- private long _waitTime;
- private Timer _timer;
- private boolean _failed;
- private boolean _written;
-}
diff --git a/api/src/main/java/org/asynchttpclient/multipart/FileUploadStalledException.java b/api/src/main/java/org/asynchttpclient/multipart/FileUploadStalledException.java
deleted file mode 100644
index 031f9354a7..0000000000
--- a/api/src/main/java/org/asynchttpclient/multipart/FileUploadStalledException.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-* Copyright (c) 2010-2012 Sonatype, Inc. All rights reserved.
-*
-* This program is licensed to you under the Apache License Version 2.0,
-* and you may not use this file except in compliance with the Apache License Version 2.0.
-* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the Apache License Version 2.0 is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
-*/
-package org.asynchttpclient.multipart;
-
-import java.io.IOException;
-
-/**
- * @author Gail Hernandez
- */
-@SuppressWarnings("serial")
-public class FileUploadStalledException extends IOException {
-}
diff --git a/api/src/main/java/org/asynchttpclient/multipart/MultipartBody.java b/api/src/main/java/org/asynchttpclient/multipart/MultipartBody.java
deleted file mode 100644
index 99525d0a21..0000000000
--- a/api/src/main/java/org/asynchttpclient/multipart/MultipartBody.java
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Sonatype, Inc. All rights reserved.
- *
- * This program is licensed to you under the Apache License Version 2.0,
- * and you may not use this file except in compliance with the Apache License Version 2.0.
- * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the Apache License Version 2.0 is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
- */
-package org.asynchttpclient.multipart;
-
-import org.asynchttpclient.RandomAccessBody;
-
-import org.asynchttpclient.ByteArrayPart;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.*;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-public class MultipartBody implements RandomAccessBody {
-
- private byte[] boundary;
- private long contentLength;
- private Listtrue
if all parts are repeatable, false
otherwise.
- */
- public boolean isRepeatable() {
- for (int i = 0; i < parts.length; i++) {
- if (!parts[i].isRepeatable()) {
- return false;
- }
- }
- return true;
- }
-
- public void writeRequest(OutputStream out) throws IOException {
- Part.sendParts(out, parts, multipartBoundary);
- }
-
- public long getContentLength() {
- try {
- return Part.getLengthOfParts(parts, multipartBoundary);
- } catch (Exception e) {
- log.error("An exception occurred while getting the length of the parts", e);
- return 0;
- }
- }
-
- public String getContentType() {
- return contentType;
- }
-}
-
diff --git a/api/src/main/java/org/asynchttpclient/multipart/Part.java b/api/src/main/java/org/asynchttpclient/multipart/Part.java
deleted file mode 100644
index 40d8b90382..0000000000
--- a/api/src/main/java/org/asynchttpclient/multipart/Part.java
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Copyright 2010 Ning, Inc.
- *
- * Ning licenses this file to you under the Apache License, version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package org.asynchttpclient.multipart;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * This class is an adaptation of the Apache HttpClient implementation
- *
- * @link http://hc.apache.org/httpclient-3.x/
- */
-public abstract class Part implements org.asynchttpclient.Part {
-
- /**
- * The boundary
- */
- protected static final String BOUNDARY = "----------------314159265358979323846";
-
- /**
- * The default boundary to be used if etBoundaryBytes(byte[]) has not been called.
- */
- private static final byte[] DEFAULT_BOUNDARY_BYTES = MultipartEncodingUtil.getAsciiBytes(BOUNDARY);
-
- /**
- * Carriage return/linefeed
- */
- protected static final String CRLF = "\r\n";
-
- /**
- * Carriage return/linefeed as a byte array
- */
- static final byte[] CRLF_BYTES = MultipartEncodingUtil.getAsciiBytes(CRLF);
-
- /**
- * Content dispostion characters
- */
- protected static final String QUOTE = "\"";
-
- /**
- * Content dispostion as a byte array
- */
- static final byte[] QUOTE_BYTES = MultipartEncodingUtil.getAsciiBytes(QUOTE);
-
- /**
- * Extra characters
- */
- protected static final String EXTRA = "--";
-
- /**
- * Extra characters as a byte array
- */
- static final byte[] EXTRA_BYTES = MultipartEncodingUtil.getAsciiBytes(EXTRA);
-
- /**
- * Content dispostion characters
- */
- protected static final String CONTENT_DISPOSITION = "Content-Disposition: form-data; name=";
-
- /**
- * Content dispostion as a byte array
- */
- static final byte[] CONTENT_DISPOSITION_BYTES = MultipartEncodingUtil.getAsciiBytes(CONTENT_DISPOSITION);
-
- /**
- * Content type header
- */
- protected static final String CONTENT_TYPE = "Content-Type: ";
-
- /**
- * Content type header as a byte array
- */
- static final byte[] CONTENT_TYPE_BYTES = MultipartEncodingUtil.getAsciiBytes(CONTENT_TYPE);
-
- /**
- * Content charset
- */
- protected static final String CHARSET = "; charset=";
-
- /**
- * Content charset as a byte array
- */
- static final byte[] CHARSET_BYTES = MultipartEncodingUtil.getAsciiBytes(CHARSET);
-
- /**
- * Content type header
- */
- protected static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding: ";
-
- /**
- * Content type header as a byte array
- */
- static final byte[] CONTENT_TRANSFER_ENCODING_BYTES = MultipartEncodingUtil.getAsciiBytes(CONTENT_TRANSFER_ENCODING);
-
- /**
- * Content type header
- */
- protected static final String CONTENT_ID = "Content-ID: ";
-
- /**
- * Content type header as a byte array
- */
- static final byte[] CONTENT_ID_BYTES = MultipartEncodingUtil.getAsciiBytes(CONTENT_ID);
-
- /**
- * The ASCII bytes to use as the multipart boundary.
- */
- private byte[] boundaryBytes;
-
- /**
- * Return the name of this part.
- *
- * @return The name.
- */
- public abstract String getName();
-
- /**
- * Returns the content type of this part.
- *
- * @return the content type, or null
to exclude the content type header
- */
- public abstract String getContentType();
-
- /**
- * Return the character encoding of this part.
- *
- * @return the character encoding, or null
to exclude the character encoding header
- */
- public abstract String getCharSet();
-
- /**
- * Return the transfer encoding of this part.
- *
- * @return the transfer encoding, or null
to exclude the transfer encoding header
- */
- public abstract String getTransferEncoding();
-
- public abstract String getContentId();
-
- /**
- * Gets the part boundary to be used.
- *
- * @return the part boundary as an array of bytes.
- */
- protected byte[] getPartBoundary() {
- if (boundaryBytes == null) {
- // custom boundary bytes have not been set, use the default.
- return DEFAULT_BOUNDARY_BYTES;
- } else {
- return boundaryBytes;
- }
- }
-
- /**
- * Sets the part boundary. Only meant to be used by {@link Part#sendParts(java.io.OutputStream, Part[], byte[])} and {@link Part#getLengthOfParts(Part[], byte[])}
- *
- * @param boundaryBytes An array of ASCII bytes.
- * @since 3.0
- */
- void setPartBoundary(byte[] boundaryBytes) {
- this.boundaryBytes = boundaryBytes;
- }
-
- /**
- * Tests if this part can be sent more than once.
- *
- * @return true
if {@link #sendData(java.io.OutputStream)} can be successfully called more than once.
- * @since 3.0
- */
- public boolean isRepeatable() {
- return true;
- }
-
- /**
- * Write the start to the specified output stream
- *
- * @param out The output stream
- * @throws java.io.IOException If an IO problem occurs.
- */
- protected void sendStart(OutputStream out) throws IOException {
- out.write(EXTRA_BYTES);
- out.write(getPartBoundary());
- }
-
- /**
- * Write the content disposition header to the specified output stream
- *
- * @param out The output stream
- * @throws IOException If an IO problem occurs.
- */
- protected void sendDispositionHeader(OutputStream out) throws IOException {
- if (getName() != null) {
- out.write(CRLF_BYTES);
- out.write(CONTENT_DISPOSITION_BYTES);
- out.write(QUOTE_BYTES);
- out.write(MultipartEncodingUtil.getAsciiBytes(getName()));
- out.write(QUOTE_BYTES);
- }
- }
-
- /**
- * Write the content type header to the specified output stream
- *
- * @param out The output stream
- * @throws IOException If an IO problem occurs.
- */
- protected void sendContentTypeHeader(OutputStream out) throws IOException {
- String contentType = getContentType();
- if (contentType != null) {
- out.write(CRLF_BYTES);
- out.write(CONTENT_TYPE_BYTES);
- out.write(MultipartEncodingUtil.getAsciiBytes(contentType));
- String charSet = getCharSet();
- if (charSet != null) {
- out.write(CHARSET_BYTES);
- out.write(MultipartEncodingUtil.getAsciiBytes(charSet));
- }
- }
- }
-
- /**
- * Write the content transfer encoding header to the specified output stream
- *
- * @param out The output stream
- * @throws IOException If an IO problem occurs.
- */
- protected void sendTransferEncodingHeader(OutputStream out) throws IOException {
- String transferEncoding = getTransferEncoding();
- if (transferEncoding != null) {
- out.write(CRLF_BYTES);
- out.write(CONTENT_TRANSFER_ENCODING_BYTES);
- out.write(MultipartEncodingUtil.getAsciiBytes(transferEncoding));
- }
- }
-
- /**
- * Write the content ID header to the specified output stream
- *
- * @param out The output stream
- * @throws IOException If an IO problem occurs.
- */
- protected void sendContentIdHeader(OutputStream out) throws IOException {
- String contentId = getContentId();
- if (contentId != null) {
- out.write(CRLF_BYTES);
- out.write(CONTENT_ID_BYTES);
- out.write(MultipartEncodingUtil.getAsciiBytes(contentId));
- }
- }
-
- /**
- * Write the end of the header to the output stream
- *
- * @param out The output stream
- * @throws IOException If an IO problem occurs.
- */
- protected void sendEndOfHeader(OutputStream out) throws IOException {
- out.write(CRLF_BYTES);
- out.write(CRLF_BYTES);
- }
-
- /**
- * Write the data to the specified output stream
- *
- * @param out The output stream
- * @throws IOException If an IO problem occurs.
- */
- protected abstract void sendData(OutputStream out) throws IOException;
-
- /**
- * Return the length of the main content
- *
- * @return long The length.
- * @throws IOException If an IO problem occurs
- */
- protected abstract long lengthOfData() throws IOException;
-
- /**
- * Write the end data to the output stream.
- *
- * @param out The output stream
- * @throws IOException If an IO problem occurs.
- */
- protected void sendEnd(OutputStream out) throws IOException {
- out.write(CRLF_BYTES);
- }
-
- /**
- * Write all the data to the output stream. If you override this method make sure to override #length() as well
- *
- * @param out The output stream
- * @throws IOException If an IO problem occurs.
- */
- public void send(OutputStream out) throws IOException {
- sendStart(out);
- sendDispositionHeader(out);
- sendContentTypeHeader(out);
- sendTransferEncodingHeader(out);
- sendEndOfHeader(out);
- sendData(out);
- sendEnd(out);
- }
-
- /**
- * Return the full length of all the data. If you override this method make sure to override #send(OutputStream) as well
- *
- * @return long The length.
- * @throws IOException If an IO problem occurs
- */
- public long length() throws IOException {
- if (lengthOfData() < 0) {
- return -1;
- }
- ByteArrayOutputStream overhead = new ByteArrayOutputStream();
- sendStart(overhead);
- sendDispositionHeader(overhead);
- sendContentTypeHeader(overhead);
- sendTransferEncodingHeader(overhead);
- sendContentIdHeader(overhead);
- sendEndOfHeader(overhead);
- sendEnd(overhead);
- return overhead.size() + lengthOfData();
- }
-
- /**
- * Return a string representation of this object.
- *
- * @return A string representation of this object.
- * @see java.lang.Object#toString()
- */
- public String toString() {
- return this.getName();
- }
-
- /**
- * Write all parts and the last boundary to the specified output stream.
- *
- * @param out The stream to write to.
- * @param parts The parts to write.
- * @throws IOException If an I/O error occurs while writing the parts.
- */
- public static void sendParts(OutputStream out, final Part[] parts) throws IOException {
- sendParts(out, parts, DEFAULT_BOUNDARY_BYTES);
- }
-
- /**
- * Write all parts and the last boundary to the specified output stream.
- *
- * @param out The stream to write to.
- * @param parts The parts to write.
- * @param partBoundary The ASCII bytes to use as the part boundary.
- * @throws IOException If an I/O error occurs while writing the parts.
- * @since 3.0
- */
- public static void sendParts(OutputStream out, Part[] parts, byte[] partBoundary) throws IOException {
-
- if (parts == null) {
- throw new IllegalArgumentException("Parts may not be null");
- }
- if (partBoundary == null || partBoundary.length == 0) {
- throw new IllegalArgumentException("partBoundary may not be empty");
- }
- for (Part part : parts) {
- // set the part boundary before the part is sent
- part.setPartBoundary(partBoundary);
- part.send(out);
- }
- out.write(EXTRA_BYTES);
- out.write(partBoundary);
- out.write(EXTRA_BYTES);
- out.write(CRLF_BYTES);
- }
-
- public static void sendMessageEnd(OutputStream out, byte[] partBoundary) throws IOException {
-
- if (partBoundary == null || partBoundary.length == 0) {
- throw new IllegalArgumentException("partBoundary may not be empty");
- }
-
- out.write(EXTRA_BYTES);
- out.write(partBoundary);
- out.write(EXTRA_BYTES);
- out.write(CRLF_BYTES);
- }
-
- /**
- * Write all parts and the last boundary to the specified output stream.
- *
- * @param out The stream to write to.
- * @param part The part to write.
- * @throws IOException If an I/O error occurs while writing the parts.
- * @since N/A
- */
- public static void sendPart(OutputStream out, Part part, byte[] partBoundary) throws IOException {
-
- if (part == null) {
- throw new IllegalArgumentException("Parts may not be null");
- }
-
- part.setPartBoundary(partBoundary);
- part.send(out);
- }
-
- /**
- * Return the total sum of all parts and that of the last boundary
- *
- * @param parts The parts.
- * @return The total length
- * @throws IOException If an I/O error occurs while writing the parts.
- */
- public static long getLengthOfParts(Part[] parts) throws IOException {
- return getLengthOfParts(parts, DEFAULT_BOUNDARY_BYTES);
- }
-
- /**
- * Gets the length of the multipart message including the given parts.
- *
- * @param parts The parts.
- * @param partBoundary The ASCII bytes to use as the part boundary.
- * @return The total length
- * @throws IOException If an I/O error occurs while writing the parts.
- * @since 3.0
- */
- public static long getLengthOfParts(Part[] parts, byte[] partBoundary) throws IOException {
- if (parts == null) {
- throw new IllegalArgumentException("Parts may not be null");
- }
- long total = 0;
- for (Part part : parts) {
- // set the part boundary before we calculate the part's length
- part.setPartBoundary(partBoundary);
- long l = part.length();
- if (l < 0) {
- return -1;
- }
- total += l;
- }
- total += EXTRA_BYTES.length;
- total += partBoundary.length;
- total += EXTRA_BYTES.length;
- total += CRLF_BYTES.length;
- return total;
- }
-}
diff --git a/api/src/main/java/org/asynchttpclient/multipart/PartBase.java b/api/src/main/java/org/asynchttpclient/multipart/PartBase.java
deleted file mode 100644
index c65c006685..0000000000
--- a/api/src/main/java/org/asynchttpclient/multipart/PartBase.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright 2010 Ning, Inc.
- *
- * Ning licenses this file to you under the Apache License, version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package org.asynchttpclient.multipart;
-
-/**
- * This class is an adaptation of the Apache HttpClient implementation
- *
- * @link http://hc.apache.org/httpclient-3.x/
- */
-public abstract class PartBase extends Part {
-
- /**
- * Name of the file part.
- */
- private String name;
-
- /**
- * Content type of the file part.
- */
- private String contentType;
-
- /**
- * Content encoding of the file part.
- */
- private String charSet;
-
- /**
- * The transfer encoding.
- */
- private String transferEncoding;
-
- private String contentId;
-
- /**
- * Constructor.
- *
- * @param name The name of the part
- * @param contentType The content type, or null
- * @param charSet The character encoding, or null
- * @param transferEncoding The transfer encoding, or null
- * @param contentId The content id, or null
- */
- public PartBase(String name, String contentType, String charSet, String transferEncoding, String contentId) {
-
- if (name == null) {
- throw new IllegalArgumentException("Name must not be null");
- }
- this.name = name;
- this.contentType = contentType;
- this.charSet = charSet;
- this.transferEncoding = transferEncoding;
- this.contentId = contentId;
- }
-
- /**
- * Returns the name.
- *
- * @return The name.
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Returns the content type of this part.
- *
- * @return String The name.
- */
- public String getContentType() {
- return this.contentType;
- }
-
- /**
- * Return the character encoding of this part.
- *
- * @return String The name.
- */
- public String getCharSet() {
- return this.charSet;
- }
-
- /**
- * Returns the transfer encoding of this part.
- *
- * @return String The name.
- */
- public String getTransferEncoding() {
- return transferEncoding;
- }
-
- /**
- * Sets the character encoding.
- *
- * @param charSet the character encoding, or null
to exclude the character encoding header
- */
- public void setCharSet(String charSet) {
- this.charSet = charSet;
- }
-
- /**
- * Sets the content type.
- *
- * @param contentType the content type, or null
to exclude the content type header
- */
- public void setContentType(String contentType) {
- this.contentType = contentType;
- }
-
- /**
- * Sets the part name.
- *
- * @param name
- */
- public void setName(String name) {
- if (name == null) {
- throw new IllegalArgumentException("Name must not be null");
- }
- this.name = name;
- }
-
- /**
- * Sets the transfer encoding.
- *
- * @param transferEncoding the transfer encoding, or null
to exclude the transfer encoding header
- */
- public void setTransferEncoding(String transferEncoding) {
- this.transferEncoding = transferEncoding;
- }
-
- public String getContentId() {
- return contentId;
- }
-
- public void setContentId(String contentId) {
- this.contentId = contentId;
- }
-}
diff --git a/api/src/main/java/org/asynchttpclient/multipart/PartSource.java b/api/src/main/java/org/asynchttpclient/multipart/PartSource.java
deleted file mode 100644
index 798ae16eb0..0000000000
--- a/api/src/main/java/org/asynchttpclient/multipart/PartSource.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2010 Ning, Inc.
- *
- * Ning licenses this file to you under the Apache License, version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package org.asynchttpclient.multipart;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * This class is an adaptation of the Apache HttpClient implementation
- *
- * @link http://hc.apache.org/httpclient-3.x/
- */
-public interface PartSource {
-
- /**
- * Gets the number of bytes contained in this source.
- *
- * @return a value >= 0
- */
- long getLength();
-
- /**
- * Gets the name of the file this source represents.
- *
- * @return the fileName used for posting a MultiPart file part
- */
- String getFileName();
-
- /**
- * Gets a new InputStream for reading this source. This method can be
- * called more than once and should therefore return a new stream every
- * time.
- *
- * @return a new InputStream
- * @throws java.io.IOException if an error occurs when creating the InputStream
- */
- InputStream createInputStream() throws IOException;
-
-}
diff --git a/api/src/main/java/org/asynchttpclient/multipart/RequestEntity.java b/api/src/main/java/org/asynchttpclient/multipart/RequestEntity.java
deleted file mode 100644
index 99bf7bbf4a..0000000000
--- a/api/src/main/java/org/asynchttpclient/multipart/RequestEntity.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2010 Ning, Inc.
- *
- * Ning licenses this file to you under the Apache License, version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package org.asynchttpclient.multipart;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * This class is an adaptation of the Apache HttpClient implementation
- *
- * @link http://hc.apache.org/httpclient-3.x/
- */
-public interface RequestEntity {
-
- /**
- * Tests if {@link #writeRequest(java.io.OutputStream)} can be called more than once.
- *
- * @return true if the entity can be written to {@link java.io.OutputStream} more than once,
- * false otherwise.
- */
- boolean isRepeatable();
-
- /**
- * Writes the request entity to the given stream.
- *
- * @param out
- * @throws java.io.IOException
- */
- void writeRequest(OutputStream out) throws IOException;
-
- /**
- * Gets the request entity's length. This method should return a non-negative value if the content
- * length is known or a negative value if it is not. In the latter case the
- * EntityEnclosingMethod will use chunk encoding to
- * transmit the request entity.
- *
- * @return a non-negative value when content length is known or a negative value when content length
- * is not known
- */
- long getContentLength();
-
- /**
- * Gets the entity's content type. This content type will be used as the value for the
- * "Content-Type" header.
- *
- * @return the entity's content type
- */
- String getContentType();
-
-}
diff --git a/api/src/main/java/org/asynchttpclient/multipart/StringPart.java b/api/src/main/java/org/asynchttpclient/multipart/StringPart.java
deleted file mode 100644
index 447d54035c..0000000000
--- a/api/src/main/java/org/asynchttpclient/multipart/StringPart.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2010 Ning, Inc.
- *
- * Ning licenses this file to you under the Apache License, version 2.0
- * (the "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-package org.asynchttpclient.multipart;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * This class is an adaptation of the Apache HttpClient implementation
- *
- * @link http://hc.apache.org/httpclient-3.x/
- */
-public class StringPart extends PartBase {
-
- /**
- * Default content encoding of string parameters.
- */
- public static final String DEFAULT_CONTENT_TYPE = "text/plain";
-
- /**
- * Default charset of string parameters
- */
- public static final String DEFAULT_CHARSET = "US-ASCII";
-
- /**
- * Default transfer encoding of string parameters
- */
- public static final String DEFAULT_TRANSFER_ENCODING = "8bit";
-
- /**
- * Contents of this StringPart.
- */
- private byte[] content;
-
- /**
- * The String value of this part.
- */
- private final String value;
-
- /**
- * Constructor.
- *
- * @param name The name of the part
- * @param value the string to post
- * @param charset the charset to be used to encode the string, if null
the {@link #DEFAULT_CHARSET default} is used
- * @param contentId the content id
- */
- public StringPart(String name, String value, String charset, String contentId) {
-
- super(name, DEFAULT_CONTENT_TYPE, charset == null ? DEFAULT_CHARSET : charset, DEFAULT_TRANSFER_ENCODING, contentId);
- if (value == null) {
- throw new IllegalArgumentException("Value may not be null");
- }
- if (value.indexOf(0) != -1) {
- // See RFC 2048, 2.8. "8bit Data"
- throw new IllegalArgumentException("NULs may not be present in string parts");
- }
- this.value = value;
- }
-
- public StringPart(String name, String value, String charset) {
- this(name, value, charset, null);
- }
-
- /**
- * Constructor.
- *
- * @param name The name of the part
- * @param value the string to post
- */
- public StringPart(String name, String value) {
- this(name, value, null, null);
- }
-
- /**
- * Gets the content in bytes. Bytes are lazily created to allow the charset to be changed after the part is created.
- *
- * @return the content in bytes
- */
- private byte[] getContent() {
- if (content == null) {
- content = MultipartEncodingUtil.getBytes(value, getCharSet());
- }
- return content;
- }
-
- /**
- * Writes the data to the given OutputStream.
- *
- * @param out the OutputStream to write to
- * @throws java.io.IOException if there is a write error
- */
- protected void sendData(OutputStream out) throws IOException {
- out.write(getContent());
- }
-
- /**
- * Return the length of the data.
- *
- * @return The length of the data.
- * @throws IOException If an IO problem occurs
- */
- protected long lengthOfData() throws IOException {
- return getContent().length;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.commons.httpclient.methods.multipart.BasePart#setCharSet(java.lang.String)
- */
- public void setCharSet(String charSet) {
- super.setCharSet(charSet);
- this.content = null;
- }
-
-}
diff --git a/api/src/main/java/org/asynchttpclient/ntlm/NTLMEngine.java b/api/src/main/java/org/asynchttpclient/ntlm/NTLMEngine.java
deleted file mode 100644
index f09ac1fb81..0000000000
--- a/api/src/main/java/org/asynchttpclient/ntlm/NTLMEngine.java
+++ /dev/null
@@ -1,1352 +0,0 @@
-/*
- * Copyright (c) 2010-2013 Sonatype, Inc. All rights reserved.
- *
- * This program is licensed to you under the Apache License Version 2.0,
- * and you may not use this file except in compliance with the Apache License Version 2.0.
- * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the Apache License Version 2.0 is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
- */
-/*
- * ====================================================================
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- *
- * {@link HttpRequest} req = ...;
- * String value = req.getHeader("Cookie");
- * Set<{@link Cookie}> cookies = new {@link CookieDecoder}().decode(value);
- *
- *
- * @see CookieEncoder
- *
- * @apiviz.stereotype utility
- * @apiviz.has org.jboss.netty.handler.codec.http.Cookie oneway - - decodes
- */
-public class CookieDecoder {
-
- private static final char COMMA = ',';
-
- /**
- * Creates a new decoder.
- */
- private CookieDecoder() {
- }
-
- /**
- * Decodes the specified HTTP header value into {@link Cookie}s.
- *
- * @return the decoded {@link Cookie}s
- */
- public static Set
- * // Client-side example
- * {@link HttpRequest} req = ...;
- * {@link CookieEncoder} encoder = new {@link CookieEncoder}(false);
- * encoder.addCookie("JSESSIONID", "1234");
- * res.setHeader("Cookie", encoder.encode());
- *
- * // Server-side example
- * {@link HttpResponse} res = ...;
- * {@link CookieEncoder} encoder = new {@link CookieEncoder}(true);
- * encoder.addCookie("JSESSIONID", "1234");
- * res.setHeader("Set-Cookie", encoder.encode());
- *
- *
- * @see CookieDecoder
- *
- * @apiviz.stereotype utility
- * @apiviz.has org.jboss.netty.handler.codec.http.Cookie oneway - - encodes
- */
-// This fork brings support for RFC6265, that's used if the Cookie has a raw value
-public final class CookieEncoder {
-
- private CookieEncoder() {
- }
-
- public static String encodeClientSide(Collection