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