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