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 public class HttpSmartProxyHandler extends AbstractHttpLogicHandler {
41 private final static Logger logger = LoggerFactory
42 .getLogger(HttpSmartProxyHandler.class);
43
44
45
46
47 private boolean requestSent = false;
48
49
50
51
52 private AbstractAuthLogicHandler authHandler;
53
54 public HttpSmartProxyHandler(final ProxyIoSession proxyIoSession) {
55 super(proxyIoSession);
56 }
57
58
59
60
61
62
63 public void doHandshake(final NextFilter nextFilter)
64 throws ProxyAuthException {
65 logger.debug(" doHandshake()");
66
67 if (authHandler != null) {
68 authHandler.doHandshake(nextFilter);
69 } else {
70 if (requestSent) {
71
72 throw new ProxyAuthException(
73 "Authentication request already sent");
74 }
75
76 logger.debug(" sending HTTP request");
77
78
79 HttpProxyRequest req = (HttpProxyRequest) getProxyIoSession()
80 .getRequest();
81 Map<String, List<String>> headers = req.getHeaders() != null ? req
82 .getHeaders() : new HashMap<String, List<String>>();
83
84 AbstractAuthLogicHandler.addKeepAliveHeaders(headers);
85 req.setHeaders(headers);
86
87
88 writeRequest(nextFilter, req);
89 requestSent = true;
90 }
91 }
92
93
94
95
96
97
98
99
100 private void autoSelectAuthHandler(final HttpProxyResponse response)
101 throws ProxyAuthException {
102
103 List<String> values = response.getHeaders().get("Proxy-Authenticate");
104 ProxyIoSession proxyIoSession = getProxyIoSession();
105
106 if (values == null || values.size() == 0) {
107 authHandler = HttpAuthenticationMethods.NO_AUTH
108 .getNewHandler(proxyIoSession);
109
110 } else if (getProxyIoSession().getPreferedOrder() == null) {
111
112 int method = -1;
113
114
115
116 for (String proxyAuthHeader : values) {
117 proxyAuthHeader = proxyAuthHeader.toLowerCase();
118
119 if (proxyAuthHeader.contains("ntlm")) {
120 method = HttpAuthenticationMethods.NTLM.getId();
121 break;
122 } else if (proxyAuthHeader.contains("digest")
123 && method != HttpAuthenticationMethods.NTLM.getId()) {
124 method = HttpAuthenticationMethods.DIGEST.getId();
125 } else if (proxyAuthHeader.contains("basic") && method == -1) {
126 method = HttpAuthenticationMethods.BASIC.getId();
127 }
128 }
129
130 if (method != -1) {
131 try {
132 authHandler = HttpAuthenticationMethods.getNewHandler(
133 method, proxyIoSession);
134 } catch (Exception ex) {
135 logger.debug("Following exception occured:", ex);
136 }
137 }
138
139 if (authHandler == null) {
140 authHandler = HttpAuthenticationMethods.NO_AUTH
141 .getNewHandler(proxyIoSession);
142 }
143
144 } else {
145 for (HttpAuthenticationMethods method : proxyIoSession
146 .getPreferedOrder()) {
147 if (authHandler != null) {
148 break;
149 }
150
151 if (method == HttpAuthenticationMethods.NO_AUTH) {
152 authHandler = HttpAuthenticationMethods.NO_AUTH
153 .getNewHandler(proxyIoSession);
154 break;
155 }
156
157 for (String proxyAuthHeader : values) {
158 proxyAuthHeader = proxyAuthHeader.toLowerCase();
159
160 try {
161
162 if (proxyAuthHeader.contains("basic")
163 && method == HttpAuthenticationMethods.BASIC) {
164 authHandler = HttpAuthenticationMethods.BASIC
165 .getNewHandler(proxyIoSession);
166 break;
167 } else if (proxyAuthHeader.contains("digest")
168 && method == HttpAuthenticationMethods.DIGEST) {
169 authHandler = HttpAuthenticationMethods.DIGEST
170 .getNewHandler(proxyIoSession);
171 break;
172 } else if (proxyAuthHeader.contains("ntlm")
173 && method == HttpAuthenticationMethods.NTLM) {
174 authHandler = HttpAuthenticationMethods.NTLM
175 .getNewHandler(proxyIoSession);
176 break;
177 }
178 } catch (Exception ex) {
179 logger.debug("Following exception occured:", ex);
180 }
181 }
182 }
183
184 }
185
186 if (authHandler == null) {
187 throw new ProxyAuthException(
188 "Unknown authentication mechanism(s): " + values);
189 }
190 }
191
192
193
194
195
196
197 @Override
198 public void handleResponse(final HttpProxyResponse response)
199 throws ProxyAuthException {
200 if (!isHandshakeComplete()
201 && ("close".equalsIgnoreCase(StringUtilities
202 .getSingleValuedHeader(response.getHeaders(),
203 "Proxy-Connection")) || "close"
204 .equalsIgnoreCase(StringUtilities
205 .getSingleValuedHeader(response.getHeaders(),
206 "Connection")))) {
207 getProxyIoSession().setReconnectionNeeded(true);
208 }
209
210 if (response.getStatusCode() == 407) {
211 if (authHandler == null) {
212 autoSelectAuthHandler(response);
213 }
214 authHandler.handleResponse(response);
215 } else {
216 throw new ProxyAuthException("Error: unexpected response code "
217 + response.getStatusLine() + " received from proxy.");
218 }
219 }
220 }