1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.proxy.handlers.http;
21
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.apache.mina.core.filterchain.IoFilter.NextFilter;
27 import org.apache.mina.proxy.ProxyAuthException;
28 import org.apache.mina.proxy.session.ProxyIoSession;
29 import org.apache.mina.proxy.utils.StringUtilities;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33
34
35
36
37
38
39
40
41 public class HttpSmartProxyHandler extends AbstractHttpLogicHandler {
42 private final static Logger logger = LoggerFactory
43 .getLogger(HttpSmartProxyHandler.class);
44
45
46
47
48 private boolean requestSent = false;
49
50
51
52
53 private AbstractAuthLogicHandler authHandler;
54
55 public HttpSmartProxyHandler(final ProxyIoSession proxyIoSession) {
56 super(proxyIoSession);
57 }
58
59
60
61
62 public void doHandshake(final NextFilter nextFilter)
63 throws ProxyAuthException {
64 logger.debug(" doHandshake()");
65
66 if (authHandler != null) {
67 authHandler.doHandshake(nextFilter);
68 } else {
69 if (requestSent) {
70 throw new ProxyAuthException(
71 "Authentication request already sent");
72 }
73
74 logger.debug(" sending HTTP request");
75
76
77 HttpProxyRequest req = (HttpProxyRequest) getProxyIoSession()
78 .getRequest();
79 Map<String, List<String>> headers = req.getHeaders() != null ? req
80 .getHeaders() : new HashMap<String, List<String>>();
81
82 StringUtilities.addValueToHeader(headers, "Keep-Alive",
83 HttpProxyConstants.DEFAULT_KEEP_ALIVE_TIME, true);
84 StringUtilities.addValueToHeader(headers, "Proxy-Connection",
85 "keep-Alive", true);
86 req.setHeaders(headers);
87
88 writeRequest(nextFilter, req);
89 requestSent = true;
90 }
91 }
92
93
94
95
96
97
98 private void autoSelectAuthHandler(final HttpProxyResponse response)
99 throws ProxyAuthException {
100
101 List<String> values = response.getHeaders().get("Proxy-Authenticate");
102
103 if (values == null || values.size() == 0) {
104 authHandler = HttpAuthenticationMethods.NO_AUTH
105 .getNewHandler(getProxyIoSession());
106
107 } else if (getProxyIoSession().getPreferedOrder() == null) {
108 for (String proxyAuthHeader : values) {
109 proxyAuthHeader = proxyAuthHeader.toLowerCase();
110
111 try {
112
113
114 if (proxyAuthHeader.contains("ntlm")) {
115 authHandler = HttpAuthenticationMethods.NTLM
116 .getNewHandler(getProxyIoSession());
117 break;
118 } else if (proxyAuthHeader.contains("digest")) {
119 authHandler = HttpAuthenticationMethods.DIGEST
120 .getNewHandler(getProxyIoSession());
121 break;
122 } else if (proxyAuthHeader.contains("basic")) {
123 authHandler = HttpAuthenticationMethods.BASIC
124 .getNewHandler(getProxyIoSession());
125 break;
126 }
127 } catch (Exception ex) {
128 logger.debug("Following exception occured:", ex);
129 }
130 }
131
132 if (authHandler == null) {
133 authHandler = HttpAuthenticationMethods.NO_AUTH
134 .getNewHandler(getProxyIoSession());
135 }
136
137 } else {
138 for (HttpAuthenticationMethods method : getProxyIoSession()
139 .getPreferedOrder()) {
140 if (authHandler != null) {
141 break;
142 }
143
144 if (method == HttpAuthenticationMethods.NO_AUTH) {
145 authHandler = HttpAuthenticationMethods.NO_AUTH
146 .getNewHandler(getProxyIoSession());
147 break;
148 }
149
150 for (String proxyAuthHeader : values) {
151 proxyAuthHeader = proxyAuthHeader.toLowerCase();
152
153 try {
154
155 if (proxyAuthHeader.contains("basic")
156 && method == HttpAuthenticationMethods.BASIC) {
157 authHandler = HttpAuthenticationMethods.BASIC
158 .getNewHandler(getProxyIoSession());
159 break;
160 } else if (proxyAuthHeader.contains("digest")
161 && method == HttpAuthenticationMethods.DIGEST) {
162 authHandler = HttpAuthenticationMethods.DIGEST
163 .getNewHandler(getProxyIoSession());
164 break;
165 } else if (proxyAuthHeader.contains("ntlm")
166 && method == HttpAuthenticationMethods.NTLM) {
167 authHandler = HttpAuthenticationMethods.NTLM
168 .getNewHandler(getProxyIoSession());
169 break;
170 }
171 } catch (Exception ex) {
172 logger.debug("Following exception occured:", ex);
173 }
174 }
175 }
176
177 }
178
179 if (authHandler == null) {
180 throw new ProxyAuthException(
181 "Unknown authentication mechanism(s): " + values);
182 }
183 }
184
185
186
187
188
189
190 @Override
191 public void handleResponse(final HttpProxyResponse response)
192 throws ProxyAuthException {
193 if (!isHandshakeComplete()
194 && ("close".equalsIgnoreCase(StringUtilities
195 .getSingleValuedHeader(response.getHeaders(),
196 "Proxy-Connection")) || "close"
197 .equalsIgnoreCase(StringUtilities
198 .getSingleValuedHeader(response.getHeaders(),
199 "Connection")))) {
200 getProxyIoSession().setReconnectionNeeded(true);
201 }
202
203 if (response.getStatusCode() == 407) {
204 if (authHandler == null) {
205 autoSelectAuthHandler(response);
206 }
207 authHandler.handleResponse(response);
208 } else {
209 throw new ProxyAuthException("Received error response code ("
210 + response.getStatusLine() + ").");
211 }
212 }
213 }