1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.esigate.http;
17
18 import java.io.IOException;
19 import java.util.Properties;
20
21 import org.apache.http.HttpException;
22 import org.apache.http.HttpStatus;
23 import org.apache.http.client.methods.CloseableHttpResponse;
24 import org.apache.http.client.methods.HttpExecutionAware;
25 import org.apache.http.client.methods.HttpRequestWrapper;
26 import org.apache.http.client.protocol.HttpClientContext;
27 import org.apache.http.conn.routing.HttpRoute;
28 import org.apache.http.impl.client.cache.CachingHttpClientBuilder;
29 import org.apache.http.impl.execchain.ClientExecChain;
30 import org.esigate.HttpErrorPage;
31 import org.esigate.cache.CacheAdapter;
32 import org.esigate.events.EventManager;
33 import org.esigate.events.impl.FetchEvent;
34
35 public class ProxyingHttpClientBuilder extends CachingHttpClientBuilder {
36 private Properties properties;
37 private EventManager eventManager;
38 private boolean useCache = true;
39
40 @Override
41 protected ClientExecChain decorateMainExec(ClientExecChain mainExec) {
42 ClientExecChain result = mainExec;
43 result = addFetchEvent(result);
44 if (useCache) {
45 CacheAdapter cacheAdapter = new CacheAdapter();
46 cacheAdapter.init(properties);
47 result = cacheAdapter.wrapBackendHttpClient(result);
48 result = super.decorateMainExec(result);
49 result = cacheAdapter.wrapCachingHttpClient(result);
50 }
51 return result;
52 }
53
54 public void setUseCache(boolean useCache) {
55 this.useCache = useCache;
56 }
57
58 public void setEventManager(EventManager eventManager) {
59 this.eventManager = eventManager;
60 }
61
62 public Properties getProperties() {
63 return properties;
64 }
65
66 public void setProperties(Properties properties) {
67 this.properties = properties;
68 }
69
70 public EventManager getEventManager() {
71 return eventManager;
72 }
73
74 public boolean isUseCache() {
75 return useCache;
76 }
77
78
79
80
81
82
83
84 private ClientExecChain addFetchEvent(final ClientExecChain wrapped) {
85 return new ClientExecChain() {
86
87 @Override
88 public CloseableHttpResponse execute(HttpRoute route, HttpRequestWrapper request,
89 HttpClientContext httpClientContext, HttpExecutionAware execAware) {
90 OutgoingRequestContext context = OutgoingRequestContext.adapt(httpClientContext);
91
92 FetchEvent fetchEvent = new FetchEvent(context, request);
93
94 eventManager.fire(EventManager.EVENT_FETCH_PRE, fetchEvent);
95
96 if (fetchEvent.isExit()) {
97 if (fetchEvent.getHttpResponse() == null) {
98
99 fetchEvent.setHttpResponse(HttpErrorPage.generateHttpResponse(
100 HttpStatus.SC_INTERNAL_SERVER_ERROR,
101 "An extension stopped the processing of the request without providing a response"));
102 }
103 } else {
104 try {
105 fetchEvent.setHttpResponse(wrapped.execute(route, request, context, execAware));
106 } catch (IOException | HttpException e) {
107 fetchEvent.setHttpResponse(HttpErrorPage.generateHttpResponse(e));
108 }
109 }
110
111
112 eventManager.fire(EventManager.EVENT_FETCH_POST, fetchEvent);
113
114 return fetchEvent.getHttpResponse();
115 }
116 };
117
118 }
119 }