Support mocking HTTP requests out for testing. Essentially you register URLs to mock, and the URL to direct to instead. (Generally this would be a local HTTP server.) It can't be mocked to a file URL because we cast to HttpURLConnection in places, but it can be built to not hit eBay.
- ~
- jbidwatcher
- trunk
- src
- com
- jbidwatcher
- util
- http
- CookieJar.java
| CookieJar.java |
|---|
cyberfox 1 package com.jbidwatcher.util.http; cyberfox 2 /* cyberfox 3 * Copyright (c) 2000-2007, CyberFOX Software, Inc. All Rights Reserved. cyberfox 4 * cyberfox 5 * Developed by mrs (Morgan Schweers) cyberfox 6 */ cyberfox 7 mrs 8 import com.jbidwatcher.util.config.JConfig; cyberfox 9 cyberfox 10 import java.net.*; cyberfox 11 import java.util.*; cyberfox 12 import java.io.IOException; cyberfox 13 cyberfox 14 public class CookieJar { mrs 15 private Map<String, Cookie> mCookies; mrs 16 private boolean mIgnoreRedirectCookies = false; mrs 17 private final static boolean sUberDebug = false; cyberfox 18 cyberfox 19 public CookieJar() { mrs 20 mCookies = new TreeMap<String, Cookie>(); cyberfox 21 } cyberfox 22 cyberfox 23 public Cookie getCookie(String keyName) { mrs 24 return mCookies.get(keyName); cyberfox 25 } cyberfox 26 mrs 27 public String dump() { mrs 28 StringBuffer rval = new StringBuffer(); mrs 29 for(String cookieName : mCookies.keySet()) { mrs 30 Cookie value = mCookies.get(cookieName); mrs 31 rval.append(cookieName).append(": ").append(value.getValue()).append('\n'); mrs 32 } mrs 33 return rval.toString(); cyberfox 34 } cyberfox 35 mrs 36 public static class CookieException extends Exception { mrs 37 public CookieException(String text, Throwable trigger) { mrs 38 super(text, trigger); mrs 39 } cyberfox 40 } cyberfox 41 mrs 42 public static class CookieRedirectException extends RuntimeException { mrs 43 public CookieRedirectException(String text, Throwable trigger) { mrs 44 super(text, trigger); mrs 45 } mrs 46 } mrs 47 cyberfox 48 /** cyberfox 49 * Get all the cookies and the page data itself, using post or get. cyberfox 50 * mrs 51 * @param page - The URL to retrieve. mrs 52 * @param body - The body of the POST to send, if we want to do a POST operation. cyberfox 53 * @param referer - The URL that referred us to this page (can be null). cyberfox 54 * @return - A StringBuffer containing the data at the provided URL, or returned from the POST operation. cyberfox 55 * cyberfox 56 * @throws com.jbidwatcher.util.http.CookieJar.CookieException - If the connection is refused. cyberfox 57 */ mrs 58 public StringBuffer getPage(String page, String body, String referer) throws CookieException { mrs 59 URLConnection uc = connect(page, body, referer, body != null, null); cyberfox 60 if(uc == null) return null; cyberfox 61 cyberfox 62 StringBuffer sb = null; cyberfox 63 cyberfox 64 try { mrs 65 sb = Http.net().receivePage(uc); cyberfox 66 } catch(ConnectException ce) { mrs 67 logException(page, ce); cyberfox 68 if(ce.toString().indexOf("Connection refused") != -1) { cyberfox 69 throw new CookieException("Connection refused", ce); cyberfox 70 } cyberfox 71 } catch(IOException e) { mrs 72 logException(page, e); cyberfox 73 return null; cyberfox 74 } cyberfox 75 cyberfox 76 return sb; cyberfox 77 } cyberfox 78 cyberfox 79 private void logException(String pageName, Exception e) { cyberfox 80 int qLoc = pageName.indexOf('?'); cyberfox 81 mrs 82 String errmsg = "Error loading page: "; cyberfox 83 if(qLoc == -1) { cyberfox 84 errmsg += pageName; cyberfox 85 } else { cyberfox 86 errmsg += pageName.substring(0,qLoc); cyberfox 87 } mrs 88 JConfig.log().handleException(errmsg, e); cyberfox 89 } cyberfox 90 cyberfox 91 /** cyberfox 92 * Retrieve any cookies from the provided page via GET or POST, but only return cyberfox 93 * the URLConnection letting the caller do what they want to with it. cyberfox 94 * mrs 95 * @param page - The page to load. cyberfox 96 * @return - A URLConnection connected to the response from the server for the given request. cyberfox 97 */ mrs 98 public URLConnection connect(String page) { mrs 99 return connect(page, null, null, false, null); cyberfox 100 } cyberfox 101 mrs 102 private Map<String, Integer> mRedirections; mrs 103 mrs 104 public URLConnection connect(String page, String body, String referer, boolean post, List<String> pages) { mrs 105 URLConnection rval; mrs 106 mRedirections = new HashMap<String, Integer>(); mrs 107 rval = internal_connect(page, body, referer, post, pages); mrs 108 mRedirections = null; mrs 109 return rval; mrs 110 } mrs 111 mrs 112 private URLConnection internal_connect(String page, String body, String referer, boolean post, List<String> pages) { mrs 113 if(handleInfiniteRedirection(page)) { mrs 114 // If we're posting, and we hit an infloop, maybe we don't want to re-submit the data... mrs 115 if(post) { mrs 116 post = false; mrs 117 body = null; mrs 118 } else { mrs 119 throw new CookieRedirectException("Looped redirect to " + page, null); mrs 120 } mrs 121 } mrs 122 mrs 123 if(pages != null) pages.add(page); cyberfox 124 mrs 125 HttpURLConnection uc = initiateRequest(post, page, body, referer); cyberfox 126 cyberfox 127 if(uc != null) { mrs 128 String redirect = handleRedirect(uc, page); cyberfox 129 cyberfox 130 if(redirect != null) { mrs 131 if (JConfig.debugging()) { mrs 132 // Don't log passwords in redirection messages. mrs 133 if(!page.contains("pass")) JConfig.log().logMessage("Redirecting from: " + page); mrs 134 if(!page.contains("pass")) JConfig.log().logMessage("Redirecting to: " + redirect); mrs 135 try { mrs 136 if(JConfig.queryConfiguration("debug.urls", "false").equals("true")) { mrs 137 JConfig.log().logMessage("Content: " + Http.net().receivePage(uc)); mrs 138 } mrs 139 } catch (IOException ignored) { mrs 140 // If there's no content or it's an unrecognized type, ignore it. mrs 141 } cyberfox 142 } mrs 143 mrs 144 return internal_connect(redirect, body, referer, post, pages); cyberfox 145 } cyberfox 146 } cyberfox 147 cyberfox 148 return uc; cyberfox 149 } cyberfox 150 mrs 151 private boolean handleInfiniteRedirection(String page) { mrs 152 Integer pageCount = mRedirections.get(page); mrs 153 if(pageCount == null) pageCount = 0; mrs 154 if(pageCount >= 2) return true; mrs 155 mRedirections.put(page, pageCount+1); mrs 156 return false; mrs 157 } mrs 158 cyberfox 159 private String handleRedirect(HttpURLConnection uc, String pageName) { cyberfox 160 int i = 1; cyberfox 161 String redirect = null; cyberfox 162 String nextKey; cyberfox 163 do { cyberfox 164 nextKey = uc.getHeaderFieldKey(i); cyberfox 165 if(nextKey != null) { mrs 166 if(sUberDebug) { mrs 167 JConfig.log().logDebug(nextKey+": " + uc.getHeaderField(i)); cyberfox 168 } cyberfox 169 // If we're redirected, shortcut to loading the new page. cyberfox 170 if(nextKey.startsWith("Location") || cyberfox 171 nextKey.startsWith("location")) { cyberfox 172 redirect = uc.getHeaderField(i); cyberfox 173 redirect = stripQuotedAmpersands(redirect); cyberfox 174 if(!redirect.startsWith("http")) { cyberfox 175 redirect = fixRelativeRedirect(pageName, redirect); cyberfox 176 } cyberfox 177 } cyberfox 178 cyberfox 179 if(nextKey.startsWith("Set-Cookie") || cyberfox 180 nextKey.startsWith("Set-cookie")) { cyberfox 181 Cookie newCookie = new Cookie(uc.getHeaderField(i)); mrs 182 mCookies.put(newCookie.getKey(), newCookie); cyberfox 183 } cyberfox 184 } cyberfox 185 i++; cyberfox 186 } while(nextKey != null); cyberfox 187 return redirect; cyberfox 188 } cyberfox 189 cyberfox 190 private String fixRelativeRedirect(String pageName, String redirect) { cyberfox 191 String slash = ""; cyberfox 192 int serverEnd = pageName.indexOf(".com/"); cyberfox 193 if(!redirect.startsWith("/")) { cyberfox 194 slash = "/"; cyberfox 195 } mrs 196 String prefix; cyberfox 197 if(serverEnd == -1) { cyberfox 198 prefix = pageName; cyberfox 199 } else { cyberfox 200 prefix = pageName.substring(0, serverEnd+4); cyberfox 201 } cyberfox 202 redirect = prefix + slash + redirect; cyberfox 203 return redirect; cyberfox 204 } cyberfox 205 cyberfox 206 private String stripQuotedAmpersands(String redirect) { cyberfox 207 int amploc = redirect.indexOf("&"); cyberfox 208 cyberfox 209 while(amploc != -1) { cyberfox 210 redirect = redirect.substring(0, amploc) + "&" + cyberfox 211 redirect.substring(amploc+5); cyberfox 212 amploc = redirect.indexOf("&"); cyberfox 213 } cyberfox 214 return redirect; cyberfox 215 } cyberfox 216 cyberfox 217 private HttpURLConnection initiateRequest(boolean post, String sendRequest, String cgi, String referer) { mrs 218 URLConnection uc; mrs 219 String cookies = mCookies.isEmpty() ? null : this.toString(); cyberfox 220 mrs 221 if(post) { mrs 222 uc = Http.net().postFormPage(sendRequest, cgi, cookies, referer, mIgnoreRedirectCookies); cyberfox 223 } else { mrs 224 uc = Http.net().getPage(sendRequest, cookies, referer, mIgnoreRedirectCookies); cyberfox 225 } mrs 226 mrs 227 return (HttpURLConnection)uc; cyberfox 228 } cyberfox 229 cyberfox 230 public String toString() { cyberfox 231 boolean firstThrough = true; cyberfox 232 StringBuffer outBuf = null; cyberfox 233 mrs 234 for (Cookie cookie : mCookies.values()) { mrs 235 if (cookie.getValue().length() != 0) { cyberfox 236 if (!firstThrough) { cyberfox 237 outBuf.append("; "); cyberfox 238 } else { cyberfox 239 firstThrough = false; cyberfox 240 outBuf = new StringBuffer(); cyberfox 241 } mrs 242 outBuf.append(cookie.getKey()); cyberfox 243 outBuf.append("="); mrs 244 outBuf.append(cookie.getValue()); cyberfox 245 } cyberfox 246 } cyberfox 247 cyberfox 248 if(outBuf != null) { cyberfox 249 return outBuf.toString(); cyberfox 250 } else { cyberfox 251 return null; cyberfox 252 } cyberfox 253 } cyberfox 254 }
Check out the code: svn co jbidwatcher/trunk/src/com/jbidwatcher/util/http/CookieJar.java
