1 /**
2 * .
3 * Copyright � 1999 Erich P G.
4 *
5 */
6
7 package autohit.transport;
8
9 import HTTPClient.HTTPConnection;
10 import HTTPClient.HTTPResponse;
11 import HTTPClient.CookiePolicyHandler;
12 import HTTPClient.CookieModule;
13 import HTTPClient.Cookie;
14 import HTTPClient.RoRequest;
15 import HTTPClient.RoResponse;
16
17 /**
18 * A HTTP transport. It uses the HTTPClient library. for http implementation specifics,
19 * see the library documentation.
20 * <p>
21 * I'm thinking that HTTPClient will have to get replaced. It will be slow. It
22 * works for multi-client simulation, but it isn't designed for it. I'm worried
23 * that Objects and cookies will ghost and build up.
24 * <p>
25 * @author Erich P. Gatejen
26 * @version 1.0
27 * <i>Version History</i>
28 * <code>EPG - Initial - 18Jan99</code>
29 *
30 */
31 public class HTTPTransport implements Transport, CookiePolicyHandler {
32
33 // --- FINAL FIELDS ------------------------------------------------------
34
35 // --- FIELDS ------------------------------------------------------------
36
37 /**
38 * Address.
39 */
40 private String addr;
41
42 /**
43 * Port.
44 */
45 private int port;
46
47 /**
48 * HTTP Connection.
49 */
50 private HTTPConnection con;
51
52 /*
53 * Allow cookies?
54 */
55 private boolean cookies = true;
56
57
58 // --- PUBLIC METHODS ----------------------------------------------------
59
60 /**
61 * Default constructor.
62 */
63 public HTTPTransport() {
64
65 con = null;
66 }
67
68 /**
69 * Prepare to connect to a web server. If this method is subsiquently
70 * called BEFORE the connection is disconnect()'ed, it will throw a TransportException.
71 *
72 * The port can be specified in the address--such as "my.domain.com:8080"
73 *
74 * @param address Address specification. This should only be the DOMAIN portion
75 * of a URL.
76 *
77 * @throws autohit.transport.TransportException
78 */
79 public void connect(String address) throws TransportException {
80
81 if (con != null) throw new TransportException("Already connected.");
82
83 try {
84 // is there a port or not?
85 int c = address.indexOf(":");
86 if (c >= 0) {
87 addr = address.substring(0, c-1);
88 String portText = address.substring(c+1, address.length()-1 );
89 port = Integer.parseInt(portText);
90
91 } else {
92 addr = address;
93 port = 80;
94 }
95
96 } catch (Exception e) { throw new TransportException("Bad address string."); }
97
98 con = new HTTPConnection(addr, port);
99 con.setContext(this); // We want to be autonomous.
100 CookieModule.setCookiePolicyHandler(this); // move this?
101 }
102
103 /**
104 * Push a query and <b>wait</b> for a response.
105 * <p>
106 * <pre>
107 * The Query should be formed as the following:
108 * Query.headers = any non-default headers. Be careful that they they
109 * don't break how HTTPClient works.
110 * Query.qs = The URI query string including URL encoded variables.
111 * It should include the "/" after the domain in URI--such
112 * as "/cgi-bin/goats.pl" rather than "cgi-bin/goats.pl"
113 * Query.body = Any body elements. If this is null, then the http GET method
114 * will be used. Otherwise, http POST is used and this body will
115 * be the form data.
116 * </pre>
117 * <p>
118 * WARNING! For now, headers are not given in the Response. Reponse.header
119 * will be null.
120 * <p>
121 * If it is not connected or there is an underlying transport error, it will
122 * throw a TransportException.
123 *
124 * @param q A queury specification.
125 * @return A response object.
126 * @throws autohit.transport.TransportException
127 * @see autohit.transport.Query
128 * @see autohit.transport.Response
129 */
130 public Response push(Query q) throws TransportException {
131
132 if (addr == null) throw new TransportException("Not connected.");
133
134 HTTPResponse rep;
135 Response r;
136
137 try {
138
139 if (q.body == null) {
140
141 // USE GET
142 rep = con.Get(q.qs, "", q.headers);
143
144 } else {
145
146 // USE POST
147 rep = con.Post(q.qs, q.body, q.headers);
148
149 }
150 } catch (Exception e) {
151 throw new TransportException("Failed Query [" + addr + ":" + port + q.qs + "] with JAVA Exception: " + e.getMessage() );
152 }
153
154 try {
155 r = new Response();
156 r.headers = null;
157 r.code = rep.getStatusCode();
158 r.content = rep.getData();
159 r.cLength = r.content.length;
160 } catch (Exception e) {
161 throw new TransportException("Failed Response [" + addr + ":" + port + q.qs + "] with JAVA Exception: " + e.getMessage() );
162 }
163
164 return r;
165 }
166
167 /**
168 * Set an environment variable for this transport.
169 * <p><pre>
170 * The following as defined for this transport. (Defaults shown in paren.)
171 *
172 * - Accept cookies? "cookies" == "true" or "false" (true)
173 * - Allow redirects? "redir" == "true" or "false" (true)
174 * WARNING! For now, redirects will ALWAYS be allowed.
175 * I'll have to hack the HTTPClient to change this....
176 * </pre><p>
177 * Names and boolean values are NOT case sensitive.
178 *
179 * @param name variable name.
180 * @param value variable value.
181 */
182 public void environment(String name, String value) {
183
184 if (name.compareToIgnoreCase("cookies") == 0) {
185
186 if (value.compareToIgnoreCase("true") == 0) cookies = true;
187 else cookies = false;
188
189 } //else if (name.compareToIgnoreCase("redir") == 0) {
190
191 //}
192 }
193
194 /**
195 * Disconnect transport.
196 * <p>
197 * If it isn't currently connected, nothing bad will happen.
198 */
199 public void disconnect() {
200
201 // Null this reference. Hopefully GC will get to it soon. :D
202 // ... erk, I also hope the cookies all go away when there are no
203 // more active HTTPConnection's.
204 con = null;
205 }
206
207 // --- COOKIE INTERFACE ---------------------------------------------------
208
209 /**
210 * Just don't use these... We will use the environemnt var to decide whether
211 * to allow cookies....
212 */
213 public boolean acceptCookie(Cookie cookie,
214 RoRequest req,
215 RoResponse resp) {
216 return cookies;
217
218 }
219 public boolean sendCookie(Cookie cookie, RoRequest req) {
220
221 return cookies;
222 }
223
224
225
226 // --- PRIVATE METHODS ---------------------------------------------------
227 }
|