Skip to content

Commit 99fbfdd

Browse files
committed
Merge pull request AsyncHttpClient#60 from simonetripodi/master
Moving the documentation from MS Word/PDF to Git site
2 parents c3ec1d6 + 976795d commit 99fbfdd

19 files changed

+952
-2
lines changed

docs/AHCQuickStartGuide.docx

-103 KB
Binary file not shown.

docs/AHCQuickStartGuide.pdf

-171 KB
Binary file not shown.

pom.xml

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@
5050
<name>Hubert Iwaniuk</name>
5151
</developer>
5252
</developers>
53+
<contributors>
54+
<contributor>
55+
<name>Simone Tripodi</name>
56+
<email>[email protected]</email>
57+
</contributor>
58+
</contributors>
5359
<licenses>
5460
<license>
5561
<name>Apache License 2.0</name>
@@ -198,6 +204,21 @@
198204
<artifactId>wagon-ssh-external</artifactId>
199205
<version>1.0-beta-6</version>
200206
</extension>
207+
<extension>
208+
<groupId>org.apache.maven.scm</groupId>
209+
<artifactId>maven-scm-provider-gitexe</artifactId>
210+
<version>1.6</version>
211+
</extension>
212+
<extension>
213+
<groupId>org.apache.maven.scm</groupId>
214+
<artifactId>maven-scm-manager-plexus</artifactId>
215+
<version>1.6</version>
216+
</extension>
217+
<extension>
218+
<groupId>org.kathrynhuxtable.maven.wagon</groupId>
219+
<artifactId>wagon-gitsite</artifactId>
220+
<version>0.3.1</version>
221+
</extension>
201222
</extensions>
202223
<defaultGoal>install</defaultGoal>
203224
<plugins>
@@ -220,7 +241,7 @@
220241
<plugin>
221242
<groupId>org.apache.maven.plugins</groupId>
222243
<artifactId>maven-surefire-plugin</artifactId>
223-
<version>2.8.1</version>
244+
<version>${surefire.version}</version>
224245
<configuration>
225246
<redirectTestOutputToFile>${surefire.redirectTestOutputToFile}</redirectTestOutputToFile>
226247
</configuration>
@@ -340,10 +361,15 @@
340361
</execution>
341362
</executions>
342363
</plugin>
364+
<plugin>
365+
<groupId>org.apache.maven.plugins</groupId>
366+
<artifactId>maven-site-plugin</artifactId>
367+
<version>3.0</version>
368+
</plugin>
343369
<plugin>
344370
<groupId>org.apache.maven.plugins</groupId>
345371
<artifactId>maven-javadoc-plugin</artifactId>
346-
<version>2.7</version>
372+
<version>2.8.1</version>
347373
<configuration>
348374
<aggregate>true</aggregate>
349375
<source>1.6</source>
@@ -431,6 +457,30 @@
431457
</plugin>
432458
</plugins>
433459
</build>
460+
<reporting>
461+
<plugins>
462+
<plugin>
463+
<groupId>org.apache.maven.plugins</groupId>
464+
<artifactId>maven-javadoc-plugin</artifactId>
465+
<version>2.8.1</version>
466+
<configuration>
467+
<aggregate>true</aggregate>
468+
<source>1.6</source>
469+
<encoding>UTF-8</encoding>
470+
<maxmemory>1g</maxmemory>
471+
<links>
472+
<link>http://java.sun.com/javase/6/docs/api/</link>
473+
</links>
474+
<excludePackageNames>${javadoc.package.exclude}</excludePackageNames>
475+
</configuration>
476+
</plugin>
477+
<plugin>
478+
<groupId>org.apache.maven.plugins</groupId>
479+
<artifactId>maven-surefire-report-plugin</artifactId>
480+
<version>${surefire.version}</version>
481+
</plugin>
482+
</plugins>
483+
</reporting>
434484
<profiles>
435485
<profile>
436486
<id>grizzly</id>
@@ -526,6 +576,10 @@
526576
<name>sonatype-nexus-snapshots</name>
527577
<url>${distMgmtSnapshotsUrl}</url>
528578
</snapshotRepository>
579+
<site>
580+
<id>github</id>
581+
<url>gitsite:[email protected]/sonatype/async-http-client.git</url>
582+
</site>
529583
</distributionManagement>
530584
<properties>
531585
<distMgmtSnapshotsUrl>http://oss.sonatype.org/content/repositories/snapshots</distMgmtSnapshotsUrl>
@@ -535,6 +589,7 @@
535589
<javadoc.package.exclude>com.ning.http.client.providers.grizzly</javadoc.package.exclude>
536590
<source.property>1.5</source.property>
537591
<target.property>1.5</target.property>
592+
<surefire.version>2.12</surefire.version>
538593
</properties>
539594
</project>
540595

src/site/apt/auth.apt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
------
2+
Async Http Client - Configuring Authentication: BASIC, DIGEST or NTLM
3+
------
4+
Jeanfrancois Arcand
5+
------
6+
2012
7+
8+
Configuring Authentication: BASIC, DIGEST or NTLM
9+
10+
Configuring authentication with AsyncHttpClient is simple. You can configure it at the <<<Request>>> level using the
11+
<<<RealmBuilder>>>:
12+
13+
+-----+
14+
AsyncHttpClient client = new AsyncHttpClient();
15+
Realm realm = new Realm.RealmBuilder()
16+
.setPrincipal(user)
17+
.setPassword(admin)
18+
.setUsePreemptiveAuth(true)
19+
.setScheme(AuthScheme.BASIC)
20+
.build();
21+
client.prepareGet("http://...").setRealm(realm).execute();
22+
+-----+
23+
24+
You can also set the realm at the AsyncHttpClientConfig level:
25+
26+
+-----+
27+
Builder builder = new AsyncHttpClientConfig.Builder();
28+
Realm realm = new Realm.RealmBuilder()
29+
.setPrincipal(user)
30+
.setPassword(admin)
31+
.setUsePreemptiveAuth(true)
32+
.setScheme(AuthScheme.BASIC)
33+
.build();
34+
builder.setRealm(realm).build();
35+
AsyncHttpClient client = new AsyncHttpClient(builder.build());
36+
+-----+
37+
38+
The authentication type supported are <<<BASIC>>>, <<<DIGEST>>> and <<<NTLM>>>. You can also customize your own
39+
authentication mechanism by using the Response Filter.

src/site/apt/configuring.apt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
------
2+
Async Http Client - Configuring the AsyncHttpClient
3+
------
4+
Jeanfrancois Arcand
5+
------
6+
2012
7+
8+
Configuring the AsyncHttpClient.
9+
10+
You can configure the <<<AsyncHttpClient>>> class using the <<<AsyncHttpClientConfig>>>'s Builder:
11+
12+
+-----+
13+
Builder builder = new AsyncHttpClientConfig.Builder();
14+
builder.setCompressionEnabled(true)
15+
.setAllowPoolingConnection(true)
16+
.setRequestTimesout(30000)
17+
.build();
18+
19+
AsyncHttpClient client = new AsyncHttpClient(builder.build());
20+
+-----+
21+
22+
You can set the ExecutorServices as well if you don't want to use the default, which is a cached threads pool:
23+
24+
+-----+
25+
Builder builder = new AsyncHttpClientConfig.Builder();
26+
builder.setExecutorService(myOwnThreadPool);
27+
AsyncHttpClient client = new AsyncHttpClient(builder.build());
28+
+-----+
29+
30+
You can also configure the connection pool the library is using and implement your own polling strategy:
31+
32+
+-----+
33+
Builder builder = new AsyncHttpClientConfig.Builder();
34+
builder.setConnectionsPool(new ConnectionsPoo<U,V>() {
35+
public boolean offer(U uri, V connection) {...}
36+
37+
public V poll(U uri) {...}
38+
39+
public boolean removeAll(V connection) {...}
40+
41+
public boolean canCacheConnection() {...}
42+
43+
public void destroy() {...}
44+
});
45+
AsyncHttpClient client = new AsyncHttpClient(builder.build());
46+
+-----+
47+
48+
It is recommended to use the default connections pool for performance reason, but you are always free to design a better one.
49+
50+
You can also set the SSL information, Filters, etc. Those topics will be covered inside their own section.

src/site/apt/filters.apt

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
------
2+
Async Http Client - Using Filters
3+
------
4+
Jeanfrancois Arcand
5+
------
6+
2012
7+
8+
Using Filters
9+
10+
The library supports three types of <<<Filter>>> who can intercept, transform, decorate and replay transactions:
11+
<<<Request>>>, <<<Response>>> and <<<IOException>>>.
12+
13+
* Request Filter
14+
15+
Request Filters are useful if you need to manipulate the Request or AsyncHandler object before the request is made. As an example, you can throttle requests using the following RequestFilter implementation:
16+
17+
+-----+
18+
public class ThrottleRequestFilter implements RequestFilter {
19+
private final int maxConnections;
20+
private final Semaphore available;
21+
private final int maxWait;
22+
23+
public ThrottleRequestFilter(int maxConnections) {
24+
this.maxConnections = maxConnections;
25+
this.maxWait = Integer.MAX_VALUE;
26+
available = new Semaphore(maxConnections, true);
27+
}
28+
29+
public ThrottleRequestFilter(int maxConnections, int maxWait) {
30+
this.maxConnections = maxConnections;
31+
this.maxWait = maxWait;
32+
available = new Semaphore(maxConnections, true);
33+
}
34+
35+
public FilterContext filter(FilterContext ctx) throws FilterException {
36+
try {
37+
if (!available.tryAcquire(maxWait, TimeUnit.MILLISECONDS))
38+
throw new FilterException(String.format("No slot available for Request %s with AsyncHandler %s",
39+
ctx.getRequest(),
40+
ctx.getAsyncHandler()));
41+
}
42+
} catch (InterruptedException e) {
43+
throw new FilterException( String.format("Interrupted Request %s with AsyncHandler %s",
44+
ctx.getRequest(),
45+
ctx.getAsyncHandler()));
46+
}
47+
48+
return new FilterContext(new AsyncHandlerWrapper(ctx.getAsyncHandler()), ctx.getRequest());
49+
}
50+
51+
}
52+
53+
private class AsyncHandlerWrapper implements AsyncHandler<T> {
54+
private final AsyncHandler asyncHandler;
55+
56+
public AsyncHandlerWrapper(AsyncHandler asyncHandler) {
57+
this.asyncHandler = asyncHandler;
58+
}
59+
60+
public void onThrowable(Throwable t) {
61+
asyncHandler.onThrowable(t);
62+
}
63+
64+
public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
65+
return asyncHandler.onBodyPartReceived(bodyPart);
66+
}
67+
68+
public STATE onStatusReceived(HttpResponseStatus responseStatus) throws Exception {
69+
return asyncHandler.onStatusReceived(responseStatus);
70+
}
71+
72+
public STATE onHeadersReceived(HttpResponseHeaders headers) throws Exception {
73+
return asyncHandler.onHeadersReceived(headers); }
74+
75+
public T onCompleted() throws Exception {
76+
available.release();
77+
return asyncHandler.onCompleted();
78+
}
79+
}
80+
+-----+
81+
82+
In the above, we decorate the original <<<AsyncHandler>>> and use semaphore to throttle requests.
83+
To add <<<RequestFilter>>>, all you need to do is to configure it on the <<<AsyncHttpClientConfig>>>:
84+
85+
+-----+
86+
AsyncHttpClientConfig.Builder b = new AsyncHttpClientConfig.Builder();
87+
b.addRequestFilter(new ThrottleRequestFilter(100));
88+
AsyncHttpClient c = new AsyncHttpClient(b.build());
89+
+-----+
90+
91+
* Response Filter
92+
93+
Like with <<<Request>>>, you can also filter the <<<Response>>>'s bytes before an <<<AsyncHandler>>> gets called.
94+
<<<Response Filters>>> are always invoked before the library executes the logic for authentication, proxy challenging,
95+
redirection etc. That means an application can takes control of those operations at any moment using a <<<Response Filter>>>.
96+
97+
As an example, the following <<<Response Filter>>> redirect request from <<<google.ca>>> to <<<google.com>>> in case
98+
<<<.ca>>> is not responding:
99+
100+
+-----+
101+
AsyncHttpClientConfig.Builder b = new AsyncHttpClientConfig.Builder();
102+
b.addResponseFilter(new ResponseFilter() {
103+
public FilterContext filter(FilterContext ctx) throws FilterException {
104+
if (ctx.getResponseStatus().getStatusCode() == 503) {
105+
return new FilterContext.FilterContextBuilder(ctx)
106+
.request(new RequestBuilder("GET")
107+
.setUrl("http://google.com").build())
108+
.build();
109+
}
110+
}
111+
});
112+
AsyncHttpClient c = new AsyncHttpClient(b.build());
113+
+-----+
114+
115+
* IOException Filter
116+
117+
The AsyncHttpClient library support <<<IOExceptionFilter>>> that can be used to replay a request in case server a
118+
server goes down or unresponsive, a network outage occurs, or nay kind of I/O abnormal situation.
119+
120+
In those cases, the library will catch the <<<IOException>>> and delegate the <<<IOException>>> handling to the <<<Filter>>>.
121+
122+
As an example, the following filter will resume an interrupted download instead of restarting downloading the file
123+
from the beginning:
124+
125+
+-----+
126+
AsyncHttpClient c = new AsyncHttpClient(
127+
new AsyncHttpClientConfig.Builder()
128+
.addIOExceptionFilter(new ResumableIOExceptionFilter()).build());
129+
130+
Response r = c.prepareGet("http://host:port/LargeFile.avi").execute(new AsyncHandler(){...}).get();
131+
+-----+
132+
133+
The <<<IOExceptionFilter>>> is defined as
134+
135+
+-----+
136+
public class ResumableIOExceptionFilter implements IOExceptionFilter {
137+
public FilterContext filter(FilterContext ctx) throws FilterException {
138+
if (ctx.getIOException() != null ) {
139+
Request request = new RequestBuilder(ctx.getRequest()).setRangeOffset(file.length());
140+
return new FilterContext.FilterContextBuilder(ctx)
141+
.request(request)
142+
.replayRequest(true)
143+
.build();
144+
}
145+
return ctx;
146+
}
147+
}
148+
+-----+
149+
150+
In the above we just catch any <<<IOException>>> and replay the request using the <<<Range>>> header to tell the remote
151+
server to restart sending bytes at that position. This way we don't need to re download the entire file.

src/site/apt/oauth.apt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
------
2+
Async Http Client - Using OAuth
3+
------
4+
Jeanfrancois Arcand
5+
------
6+
2012
7+
8+
Using OAuth
9+
10+
You can use the library to pull data from any OAuth site (like Twitter). This is as simple as:
11+
12+
+-----+
13+
private static final String CONSUMER_KEY = "dpf43f3p2l4k3l03";
14+
private static final String CONSUMER_SECRET = "kd94hf93k423k f44";
15+
public static final String TOKEN_KEY = "nnch734d00sl2jdk";
16+
public static final String TOKEN_SECRET = "pfkkdhi9sl3r4s00";
17+
public static final String NONCE = "kllo9940pd9333jh";
18+
final static long TIMESTAMP = 1191242096;
19+
20+
public void oAuth() {
21+
ConsumerKey consumer = new ConsumerKey(CONSUMER_KEY, CONSUMER_SECRET);
22+
RequestToken user = new RequestToken(TOKEN_KEY, TOKEN_SECRET);
23+
OAuthSignatureCalculator calc = new OAuthSignatureCalculator(consumer, user);
24+
AsyncHttpClient client = new AsyncHttpClient();
25+
Response response = client.prepareGet("http://...").setSignatureCalculator(calc).execute().get();
26+
+-----+

0 commit comments

Comments
 (0)