View Javadoc

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 }