1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.services.webpage;
18
19
20 import java.io.IOException;
21 import java.io.FileOutputStream;
22 import java.io.InputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.DataOutputStream;
25
26
27 import java.util.Iterator;
28 import java.util.Enumeration;
29 import java.util.HashMap;
30
31
32 import javax.servlet.http.*;
33
34
35 import java.net.URL;
36 import java.net.URLConnection;
37 import java.net.HttpURLConnection;
38 import java.net.URLEncoder;
39
40 import org.apache.log4j.Logger;
41
42
43
44
45
46
47
48 public abstract class AbstractSiteSession implements SiteSession
49 {
50
51
52 protected String targetBase;
53
54
55 protected String proxyBase;
56
57
58 protected HashMap cookies = new HashMap();
59
60
61 protected int hitCount = 0;
62 protected int cacheCount = 0;
63
64
65 static Logger log = Logger.getLogger(AbstractSiteSession.class);
66
67 /***
68 * Create a NetElementSession, which maintains sessions with one network element.
69 *
70 * @param targetBase the target host's base URL
71 * @param proxyBase the proxy server host URL base address.
72 */
73 public AbstractSiteSession(String targetBase, String proxyBase)
74 {
75 this.proxyBase = proxyBase;
76 this.targetBase = targetBase;
77 }
78
79 /***
80 * Given a URL, returns the content from that URL in a string.
81 * All HTTP hyperlinks(HREFs) are rewritten as proxied-referenced hyperlinks.
82 * All relative references to web resources (images, stylesheets, ...) are
83 * rewritten as absolute references, but are not proxied.
84 * Determines if we are logged on to the target site. If not,
85 * calls logon(), which is a implementation specific 'POST' exchange
86 *
87 * @see logon(String, HttpServletRequest, HttpServletResponse)
88 *
89 * @param url the proxied resource address.
90 * @param data the rundata
91 *
92 * @exception IOException a servlet exception.
93 */
94
95 public void dispatch(String url, ProxyRunData data)
96 throws IOException
97 {
98 try
99 {
100 Configuration config = Configuration.getInstance();
101
102 log.debug("=== Dispatching =" + url);
103
104
105
106 URL u = new URL(null, url, new sun.net.www.protocol.http.Handler() );
107 HttpURLConnection con = (HttpURLConnection)u.openConnection();
108
109
110 con.setDoInput(true);
111 con.setDoOutput(true);
112 con.setAllowUserInteraction(false);
113 con.setFollowRedirects(false);
114
115 if (data.getPosting()) {
116 con.setRequestMethod("POST");
117 }
118
119
120 if (cookies.isEmpty())
121 {
122
123 log.debug("... no session id provided. Logging on...");
124
125 if (false == logon(data))
126 return;
127
128 }
129
130
131 Iterator it = cookies.values().iterator();
132 Cookie cookie;
133 while (it.hasNext()) {
134 cookie = (Cookie)it.next();
135 String sessionID = WebPageHelper.buildCookieString(cookie);
136 con.setRequestProperty("Cookie", sessionID);
137 log.debug("... Sending Session ID: " + sessionID );
138 }
139
140
141
142
143
144 if (data.getPosting()) {
145
146
147 StringBuffer postParams = new StringBuffer();
148 int count = 0;
149 Enumeration e = data.getRequest().getParameterNames();
150 while (e.hasMoreElements())
151 {
152
153 String name = (String) e.nextElement();
154 if (name.equals(config.getSID()) ||
155 name.equals(config.getURL())) {
156 continue;
157 }
158
159 String values[] = data.getRequest().getParameterValues(name);
160 if (values != null)
161 {
162 for (int i = 0; i < values.length; i++) {
163 if (count > 0) {
164 postParams.append("&");
165 }
166 postParams.append(name);
167 postParams.append("=");
168 postParams.append(URLEncoder.encode(values[i]));
169 count++;
170 }
171 }
172 }
173 String postString = postParams.toString();
174 con.setRequestProperty("Content-length", String.valueOf(postString.length()) );
175
176 DataOutputStream dos = new DataOutputStream(con.getOutputStream());
177
178 log.debug("... POST: " + postString);
179 dos.writeBytes(postString);
180 dos.close();
181 }
182
183 int rc = con.getResponseCode();
184
185
186 int contentType = WebPageHelper.getContentType(con.getHeaderField("content-type"), u.toString());
187 String location = con.getHeaderField("Location");
188
189 if ((rc == con.HTTP_MOVED_PERM || rc == con.HTTP_MOVED_TEMP) && null != location)
190 {
191 log.debug("+++ REDIRECT = " + location);
192 location = WebPageHelper.concatURLs(targetBase, location);
193 dispatch(location , data);
194 return;
195 }
196
197
198 String cookieString = con.getHeaderField("Set-Cookie");
199 if (null != cookieString)
200 {
201 log.debug("... new SessionID found: " + cookieString);
202 WebPageHelper.parseCookies(cookieString, this);
203 }
204
205 if (contentType == WebPageHelper.CT_IMAGE ||
206 contentType == WebPageHelper.CT_BINARY ||
207 contentType == WebPageHelper.CT_APPLICATION) {
208
209 getBinaryContent(con, data.getResponse());
210 return;
211 }
212
213 rewriteContent(data, con, contentType, url);
214
215 }
216 catch (IOException ex)
217 {
218 log.error("*** PROXY DISPATCH EXCEPTION = " + ex);
219 throw ex;
220 }
221
222 }
223
224 /***
225 * Gets the HTML content from the URL Connection stream and returns it
226 * in a string
227 *
228 * @param con The URLConnection to read from.
229 * @param resource The full URL of the resource.
230 * @return The HTML Content from the stream.
231 *
232 * @exception IOException a servlet exception.
233 */
234 public String getHTMLContent(URLConnection con,
235 ProxyRunData data,
236 String resource) throws IOException
237 {
238
239 int CAPACITY = 4096;
240
241 InputStream is = con.getInputStream();
242 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
243
244 Configuration config = Configuration.getInstance();
245 FileOutputStream fos = null;
246 boolean logging = config.getEnableContentLog();
247 if (logging)
248 {
249 if (data != null)
250 {
251 String fileName = data.getServlet().getServletContext().getRealPath(
252 config.getLogLocation() );
253 fos = new FileOutputStream(fileName, true);
254 WebPageHelper.writeHeader(fos, resource);
255 }
256 }
257
258
259
260 byte[] bytes = new byte[CAPACITY];
261
262 int readCount = 0;
263 int total = 0;
264
265 while( ( readCount = is.read( bytes )) > 0 )
266 {
267 buffer.write( bytes, 0, readCount);
268 if (logging)
269 {
270 fos.write( bytes, 0, readCount);
271 }
272 total += readCount;
273 }
274 if (logging)
275 {
276 fos.close();
277 }
278 is.close();
279
280 return buffer.toString();
281 }
282
283 /***
284 * Gets the HTML content from the URL Connection stream and writes it to respones
285 *
286 * @param con The URLConnection to read from.
287 *
288 * @exception IOException a servlet exception.
289 */
290 public void getBinaryContent(URLConnection con,
291 HttpServletResponse response) throws IOException
292 {
293
294 int CAPACITY = 4096;
295
296
297 InputStream is = con.getInputStream();
298
299
300
301
302
303 byte[] bytes = new byte[CAPACITY];
304
305 int readCount = 0;
306 while( ( readCount = is.read( bytes )) > 0 ) {
307
308 response.getOutputStream().write(bytes, 0, readCount);
309
310 }
311
312
313 is.close();
314
315 }
316
317 /***
318 * Given a cookie, it first checks to see if that cookie is already
319 * managed in this session. If it is, it means that the session has
320 * timed out and that the network element has now created a new session.
321 * In that case, replace the cookie, and re-establish the session (logon)
322 * If its a new cookie, we will still need to logon, and and the cookie to
323 * the managed cookies collection for this session.
324 *
325 * @param cookie new cookie returned from target server.
326 * @return true when a new cookie added, false when updated.
327 *
328 */
329 public boolean addCookieToSession(Cookie cookie)
330 {
331 boolean added = (null == cookies.get(cookie.getName()));
332 cookies.put(cookie.getName(), cookie);
333 return added;
334 }
335
336
337
338
339
340
341 public int getHitCount()
342 {
343 return hitCount;
344 }
345
346
347
348
349
350 public void incHitCount()
351 {
352 hitCount++;
353 }
354
355
356
357
358
359
360 public int getCacheCount()
361 {
362 return cacheCount;
363 }
364
365
366
367
368
369 public void incCacheCount()
370 {
371 cacheCount++;
372 }
373
374
375 }
376