1 package org.influxdb.impl;
2
3 import java.io.IOException;
4 import java.util.concurrent.atomic.AtomicBoolean;
5 import java.util.regex.Pattern;
6
7 import okhttp3.Interceptor;
8 import okhttp3.MediaType;
9 import okhttp3.Request;
10 import okhttp3.RequestBody;
11 import okhttp3.Response;
12 import okio.BufferedSink;
13 import okio.GzipSink;
14 import okio.Okio;
15
16 /**
17  * Implementation of a intercepter to compress http's body using GZIP.
18  *
19  * @author fujian1115 [at] gmail.com
20  */

21 final class GzipRequestInterceptor implements Interceptor {
22
23     private static final Pattern WRITE_PATTERN = Pattern.compile(".*/write", Pattern.CASE_INSENSITIVE);
24
25     private AtomicBoolean enabled = new AtomicBoolean(false);
26
27     GzipRequestInterceptor() {
28     }
29
30     public void enable() {
31         enabled.set(true);
32     }
33
34     public boolean isEnabled() {
35         return enabled.get();
36     }
37
38     public void disable() {
39         enabled.set(false);
40     }
41
42     @Override
43     public Response intercept(final Interceptor.Chain chain) throws IOException {
44         if (!enabled.get()) {
45             return chain.proceed(chain.request());
46         }
47
48         Request originalRequest = chain.request();
49         RequestBody body = originalRequest.body();
50         if (body == null || originalRequest.header("Content-Encoding") != null) {
51             return chain.proceed(originalRequest);
52         }
53
54         if (!WRITE_PATTERN.matcher(originalRequest.url().encodedPath()).matches()) {
55             return chain.proceed(originalRequest);
56         }
57
58         Request compressedRequest = originalRequest.newBuilder().header("Content-Encoding""gzip")
59                 .method(originalRequest.method(), gzip(body)).build();
60         return chain.proceed(compressedRequest);
61     }
62
63     private RequestBody gzip(final RequestBody body) {
64         return new RequestBody() {
65             @Override
66             public MediaType contentType() {
67                 return body.contentType();
68             }
69
70             @Override
71             public long contentLength() {
72                 return -1; // We don't know the compressed length in advance!
73             }
74
75             @Override
76             public void writeTo(final BufferedSink sink) throws IOException {
77                 BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
78                 body.writeTo(gzipSink);
79                 gzipSink.close();
80             }
81         };
82     }
83 }
84