1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package de.bea.domingo.http;
24
25 import java.io.IOException;
26 import java.io.Serializable;
27 import java.net.MalformedURLException;
28 import java.net.URL;
29
30 import org.apache.commons.httpclient.Cookie;
31 import org.apache.commons.httpclient.Credentials;
32 import org.apache.commons.httpclient.HostConfiguration;
33 import org.apache.commons.httpclient.HttpClient;
34 import org.apache.commons.httpclient.HttpMethod;
35 import org.apache.commons.httpclient.HttpState;
36 import org.apache.commons.httpclient.HttpStatus;
37 import org.apache.commons.httpclient.URIException;
38 import org.apache.commons.httpclient.UsernamePasswordCredentials;
39 import org.apache.commons.httpclient.auth.AuthScope;
40 import org.apache.commons.httpclient.methods.GetMethod;
41 import org.apache.commons.httpclient.methods.PostMethod;
42
43 import de.bea.domingo.DNotesMonitor;
44 import de.bea.domingo.monitor.AbstractMonitorEnabled;
45
46 /***
47 * An Http client for communication with Lotus Domino.
48 *
49 * @author <a href=mailto:kriede@users.sourceforge.net>Kurt Riede</a>
50 */
51 public final class DominoHttpClient extends AbstractMonitorEnabled implements Serializable {
52
53 /*** serial version ID for serialization. */
54 private static final long serialVersionUID = 1071222474842080977L;
55
56 /*** Default port of Http protocol. */
57 private static final int DEFAULT_HTTP_PORT = 80;
58
59 private Credentials fCredentials;
60
61 private String fProtocol = "http:";
62
63 private String fHost;
64
65 private int fPort = DEFAULT_HTTP_PORT;
66
67 private String fUsername;
68
69 private String fPassword;
70
71 /*** List of {@link org.apache.commons.httpclient.Cookie}s. */
72
73
74 private HttpClient fHttpClient;
75
76 /***
77 * Constructor.
78 *
79 * @param monitor the monitor
80 * @param host the host for the session to connect
81 * @param username the username for login
82 * @param password the password for login
83 * @throws MalformedURLException if the host is not valid
84 */
85 public DominoHttpClient(final DNotesMonitor monitor, final String host, final String username, final String password)
86 throws MalformedURLException {
87 super(monitor);
88 final String urlStr = (host.indexOf(':') < 0) ? "http://" + host : host;
89 final URL url = new URL(urlStr);
90 fProtocol = url.getProtocol();
91 if (!"http".equals(fProtocol) && !"https".equals(fProtocol)) {
92 throw new NotesHttpRuntimeException("protocol not supported: " + fProtocol);
93 }
94 fHost = url.getHost();
95 fPort = url.getPort();
96 fPort = fPort == -1 ? DEFAULT_HTTP_PORT : fPort;
97 fUsername = username;
98 fPassword = password;
99 fHttpClient = new HttpClient();
100 DominoPreferences prefs = new DominoPreferences(fHost);
101 fHttpClient.getState().addCookie(prefs.getTimeZoneCookie());
102 fHttpClient.getState().addCookie(prefs.getRegionalCookie());
103 }
104
105 /***
106 * Login to the Lotus Domino server.
107 *
108 * @throws IOException if the login fails
109 */
110 public void login() throws IOException {
111 loginBasicAuthentication();
112 loginSessionAuthentication();
113 }
114
115 private void loginBasicAuthentication() throws IOException {
116 fCredentials = new UsernamePasswordCredentials(fUsername, fPassword);
117 fHttpClient.getState().setCredentials(new AuthScope(fHost, fPort, AuthScope.ANY_REALM), fCredentials);
118
119
120
121
122
123
124
125
126
127
128
129
130 }
131
132 private void loginSessionAuthentication() throws IOException {
133 final String url = fProtocol + "://" + fHost + ":" + fPort + "/" + "names.nsf?Login";
134 final PostMethod method = new PostMethod(url);
135 method.addParameter("%%ModDate", "0000000000000000");
136 method.addParameter("Username", fUsername);
137 method.addParameter("Password", fPassword);
138 method.addParameter("RedirectTo", "/names.nsf");
139 try {
140 getMonitor().debug("Session authentication with " + url);
141 final int statusCode = fHttpClient.executeMethod(method);
142 if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_MOVED_TEMPORARILY) {
143 getMonitor().error("Http request failed: " + method.getStatusLine());
144 }
145
146
147 logCookies();
148 } catch (IOException e) {
149 getMonitor().error(e.getLocalizedMessage(), e);
150 throw e;
151 } finally {
152 method.releaseConnection();
153 }
154 }
155
156 /***
157 * Returns the protocol for the connection, either <tt>http</tt> or
158 * <tt>https</tt>.
159 *
160 * @return protocol
161 */
162 public String getProtocol() {
163 return fProtocol;
164 }
165
166 /***
167 * Returns the host name of the server.
168 *
169 * @return host name
170 */
171 public String getHost() {
172 return fHost;
173 }
174
175 /***
176 * Returns the port of the server.
177 *
178 * @return port
179 */
180 public int getPort() {
181 return fPort;
182 }
183
184 /***
185 * Returns the current user name.
186 *
187 * @return username
188 */
189 public String getUserName() {
190 return fUsername;
191 }
192
193 /***
194 * Returns the name of the current user in the common format.
195 *
196 * @return username in common format
197 */
198 public String getCommonUserName() {
199
200 return fUsername;
201 }
202
203 /***
204 * Returns the name of the current user in the canonical format.
205 *
206 * @return username in canonical format
207 */
208 public String getCanonicalUserName() {
209
210 return fUsername;
211 }
212
213 /***
214 * Executes the given {@link HttpMethod HTTP method} using the given custom
215 * {@link HostConfiguration host configuration} with the given custom
216 * {@link HttpState HTTP state}.
217 *
218 * @param hostConfiguration The {@link HostConfiguration host configuration}
219 * to use. If <code>null</code>, the host configuration
220 * returned by {@link HttpClient#getHostConfiguration()} will be used
221 * @param method the {@link HttpMethod HTTP method} to execute.
222 * @param state the {@link HttpState HTTP state} to use when executing the
223 * method. If <code>null</code>, the state returned by
224 * {@link HttpClient#getState()} will be used.
225 * @return the method's response code
226 *
227 * @throws IOException If an I/O (transport) error occurs. Some transport
228 * exceptions can be recovered from.
229 */
230 public int executeMethod(final HostConfiguration hostConfiguration, final HttpMethod method, final HttpState state)
231 throws IOException {
232 logMethod(method);
233 return fHttpClient.executeMethod(hostConfiguration, method, state);
234 }
235
236 /***
237 * Executes the given {@link HttpMethod HTTP method} using custom
238 * {@link HostConfiguration host configuration}.
239 *
240 * @param hostConfiguration The {@link HostConfiguration host configuration}
241 * to use. If <code>null</code>, the host configuration
242 * returned by {@link HttpClient#getHostConfiguration()} will be used
243 * @param method the {@link HttpMethod HTTP method} to execute
244 * @return the method's response code
245 *
246 * @throws IOException If an I/O (transport) error occurs. Some transport
247 * exceptions can be recovered from.
248 */
249 public int executeMethod(final HostConfiguration hostConfiguration, final HttpMethod method) throws IOException {
250 logMethod(method);
251 return fHttpClient.executeMethod(hostConfiguration, method);
252 }
253
254 /***
255 * Executes the given {@link HttpMethod HTTP method}.
256 *
257 * @param method the {@link HttpMethod HTTP method} to execute
258 * @return the method's response code
259 *
260 * @throws IOException If an I/O (transport) error occurs. Some transport
261 * exceptions can be recovered from.
262 */
263 public int executeMethod(final DominoHttpMethod method) throws IOException {
264 logMethod(method);
265 return fHttpClient.executeMethod(method);
266 }
267
268
269
270
271
272
273
274
275
276
277
278
279
280 private void logMethod(final HttpMethod method) throws URIException {
281 if (method instanceof GetMethod) {
282 getMonitor().debug("HTTP GET " + method.getURI());
283 } else if (method instanceof GetMethod) {
284 getMonitor().debug("HTTP POST " + method.getURI());
285 }
286 logCookies();
287 }
288
289 private void logCookies() {
290 if (getMonitor().isDebugEnabled()) {
291 Cookie[] cookies = fHttpClient.getState().getCookies();
292 for (int i = 0; i < cookies.length; i++) {
293 Cookie cookie = (Cookie) cookies[i];
294 getMonitor().debug(cookie.getName() + ": " + cookie.getValue());
295 }
296 }
297 }
298
299 /***
300 * Creates and returns a new Http POST method.
301 *
302 * @param pathInfo the path on the server
303 * @return new POST method
304 */
305 public DominoPostMethod createPost(final String pathInfo) {
306 final String url = fProtocol + "://" + fHost + ":" + fPort + "/" + pathInfo;
307 return DominoPostMethod.getInstance(url);
308 }
309
310 /***
311 * Creates and returns a new Http GET method.
312 *
313 * @param pathInfo the path on the server
314 * @return new GET method
315 */
316 public DominoGetMethod createGetMethod(final String pathInfo) {
317 final String url = fProtocol + "://" + fHost + ":" + fPort + "/" + pathInfo;
318 return DominoGetMethod.getInstance(url);
319 }
320 }