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