1 /*
2 * Copyright 1999-2002,2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.commons.latka.http;
18
19 import java.net.URL;
20 import java.util.LinkedList;
21
22 import org.apache.commons.httpclient.HttpState;
23 import org.apache.commons.httpclient.Cookie;
24
25 /**
26 * An implementation of a Latka Session interface based on the Apache Commons
27 * HttpClient package.
28 *
29 * @todo accept proxy details on create request
30 * @todo fix interface to match proxy details
31 * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
32 * @author <a href="mailto:mdelagra@us.britannica.com">Morgan Delagrange</a>
33 * @author dIon Gillard
34 * @version $Id: SessionImpl.java 561366 2007-07-31 15:58:29Z rahul $
35 */
36 public class SessionImpl implements Session {
37
38 /**
39 * tracks URLs treated by this session
40 * Session will automatically set the referer
41 * header for a request to the URL of the
42 * previous request
43 */
44 protected LinkedList _urls = new LinkedList();
45
46 /**
47 * this state object 'belongs' to HttpClient
48 * we maintain a reference in SessionImpl for
49 * simplicity
50 */
51 protected HttpState _state = new HttpState();
52
53 ///////////////////////////////
54 // Session Interface Methods //
55 ///////////////////////////////
56
57 /**
58 * Creates a request object with the specified URL, HTTP Method,
59 * and version.
60 *
61 * @param url The URL to request of the HTTP server.
62 * @param httpMethod An integer representing the HTTP method (e.g. GET, PUT)
63 * used to communicate with server.
64 * @param version A String representing the version of the HTTP request, i.e.
65 * 1.0 or 1.1.
66 * @return a new <code>Request</code> object representing the <code>url</code>
67 * and <code>httpMethod</code>
68 * @see org.apache.commons.latka.http.Request#HTTP_METHOD_GET
69 * @see org.apache.commons.latka.http.Request#HTTP_METHOD_POST
70 */
71 public Request createRequest(URL url, int httpMethod, String version) {
72 // default label to null, follow redirects to true and proxy to null
73 return createRequest(null, url, httpMethod, version, true, null);
74 }
75
76 /**
77 * Creates a labeled request object with the specified URL, HTTP Method,
78 * version, and redirect handling behavior.
79 *
80 * Note: in the current implementation, old request objects will not be resued.
81 *
82 * @param label Name of the request
83 * @param url The URL to request of the HTTP server.
84 * @param httpMethod An integer representing the HTTP method (e.g. GET, PUT)
85 * used to communicate with server.
86 * @param version A String representing the version of the HTTP request, i.e.
87 * 1.0 or 1.1.
88 * @param followRedirects whether HTTP redirects should be processed
89 * @return a new <code>Request</code> object representing the <code>url</code>
90 * and <code>httpMethod</code>
91 * @see org.apache.commons.latka.http.Request#HTTP_METHOD_GET
92 * @see org.apache.commons.latka.http.Request#HTTP_METHOD_POST
93 */
94 public Request createRequest(String label, URL url, int httpMethod,
95 String version, boolean followRedirects) {
96 // default proxy to null
97 return createRequest(label, url, httpMethod, version, followRedirects, null);
98 }
99
100 /**
101 * Creates a request object with the specified URL, HTTP Method, and
102 * version to be accessed via the provided proxy.
103 *
104 * @param url The URL to request of the HTTP server.
105 * @param httpMethod An integer representing the HTTP method (e.g. GET, PUT)
106 * used to communicate with server.
107 * @param version A String representing the version of the HTTP request, i.e.
108 * 1.0 or 1.1.
109 * @return a new {@link Request} object representing the <code>url</code>
110 * and <code>httpMethod</code>
111 * @param proxy a proxy to use during the request
112 * @see org.apache.commons.latka.http.Request#HTTP_METHOD_GET
113 * @see org.apache.commons.latka.http.Request#HTTP_METHOD_POST
114 * @see org.apache.commons.latka.http.Proxy
115 */
116 public Request createRequest(URL url, int httpMethod, Proxy proxy, String version) {
117 // default label to null, and follow redirects to true
118 return createRequest(null, url, httpMethod, version, true, proxy);
119 }
120
121 /**
122 * Create a labeled request , with the specified URL, HTTP method, version, and
123 * redirect handling behavior, using the given proxy for communications.
124 *
125 * @param label a name used to identify the request
126 * @param url The URL to request of the HTTP server.
127 * @param httpMethod An integer representing the HTTP method (e.g. GET, PUT)
128 * used to communicate with server.
129 * @param version A String representing the version of the HTTP request, i.e.
130 * 1.0 or 1.1.
131 * @param followRedirects whether to follow HTTP redirection responses
132 * @param proxy a proxy to use during the request
133 * @return a new {@link Request} object representing the <code>url</code>
134 * and <code>httpMethod</code>.
135 * @see org.apache.commons.latka.http.Request#HTTP_METHOD_GET
136 * @see org.apache.commons.latka.http.Request#HTTP_METHOD_POST
137 * @see org.apache.commons.latka.http.Proxy
138 */
139 public Request createRequest(String label, URL url, int httpMethod,
140 String version, boolean followRedirects, Proxy proxy) {
141
142 RequestImpl request = new RequestImpl(label, url, httpMethod, _state,
143 this, followRedirects);
144 request.setProxy(proxy);
145 request.setVersion(version);
146
147 URL referer = getReferer();
148
149 if (referer != null) {
150 request.addHeader("Referer", referer.toString());
151 }
152
153 return request;
154
155 }
156
157 /**
158 * Called inside the request.execute() method, setting the
159 * referer for the next request.
160 *
161 * @param url URL of the last executed request.
162 */
163 protected void setReferer(URL url) {
164 _urls.add(url);
165 }
166
167 /**
168 * The URL of the last request that was executed. This
169 * will be the _actual_ url accessed in the result of
170 * a 301 or 302 redirect (the page that returned
171 * a 200 status code).
172 *
173 * @return Referer of the last request, or null if there have
174 * been no successful requests.
175 */
176 protected URL getReferer() {
177 if (_urls.size() > 0) {
178 return (URL) _urls.getLast();
179 }
180
181 return null;
182 }
183
184 /**
185 * Adds a cookie to all HTTP requests whose domain and path match (according
186 * to RFC2109).
187 *
188 * @param domain the domain to which the cookie should apply
189 * @param path the path to which the cookie should apply
190 * @param name the name of the cookie
191 * @param value the value of the cookie
192 */
193 public void addCookie(String domain, String path,
194 String name, String value) {
195
196 Cookie cookie = new Cookie(domain, name, value);
197 cookie.setPath(path);
198
199 _state.addCookie(cookie);
200 }
201
202 /**
203 * Returns the value of cookie <code>name</code>.
204 *
205 * @param name the name of the cookie
206 *
207 * @return the value of the cookie, or null if the cookie isn't set
208 */
209 public String getCookieValue(String name) {
210 String value = null;
211 boolean done = false;
212
213 Cookie[] cookies = _state.getCookies();
214
215 for (int i = 0; i < cookies.length && !done; i++) {
216 if (cookies[i].getName().equals(name)) {
217 value = cookies[i].getValue();
218 done = true;
219 }
220 }
221
222 return value;
223 }
224
225 }