package com.jcomeau.blackberry; import java.io.*; import java.util.Hashtable; import javax.microedition.io.*; // for Connection and HttpConnection import net.rim.device.api.io.FilterBaseInterface; public class TestHttpFilter extends UselessHttpFilter { public static String[][] htmlheaders = { {"content-type", "text/html"}, {null, null} }; public static String[][] pngheaders = { {"content-type", "image/x-png"}, {null, null} }; public static String[][] gzipheaders = { {"content-type", "text/html"}, {"content-encoding", "gzip"}, {null, null} }; public static Class baseClass = null; public String[][] outheaders = htmlheaders; public String url = "http:"; public static boolean autoRedirect = false; // see function below public static boolean tryGzipped = false; // see function below public Hashtable parsedUrl = null; public int mode = 0; public boolean timesOut = true; public int responseCode = 200; public InputStream fileStream = null; public Connection openFilter(String url, int mode, boolean timesOut) { if (baseClass == null) baseClass = this.getClass(); // to get resources this.url = "http:" + url; this.mode = mode; this.timesOut = timesOut; Common.debugprintln(baseClass.getName() + ": new connection object for " + this.url + ", " + mode + ", " + timesOut); parsedUrl = UrlParser.parseUrl(url); String filename = (String)parsedUrl.get("path"); if (filename.endsWith("/")) parsedUrl.put("path", filename += "index.html"); if (filename.endsWith(".png")) outheaders = pngheaders; if (!((String)parsedUrl.get("host")).equals("localhost")) { Common.debugprintln("tryGzipped = " + tryGzipped); if (!tryGzipped || (fileStream = trySendingGzipped(filename)) == null) { if ((fileStream = findResourceAsStream(filename, "")) == null) { responseCode = 404; // "File not found" if (autoRedirect) attemptRedirect(); } } else outheaders = gzipheaders; } return this; } public InputStream findResourceAsStream(String filename, String extension) { InputStream stream = null; for (int i = 0; i < Common.HTMLFILES.length; i++) { String tryPath = Common.HTMLFILES[i] + filename + extension; Common.debugprintln("Attempting to open stream to " + tryPath); try { if ((stream = baseClass.getResourceAsStream(tryPath)) == null) throw new IOException("nonesuch: " + tryPath); else break; } catch (Exception whatever) { Common.debugprintln("Could not open stream to file " + filename + ": " + whatever); } } return stream; } /* the BB browser on the v4.0 JDE 7290 simulator doesn't send the * "accept-encoding: gzip" header, but let's see if it accepts it anyway... */ public InputStream trySendingGzipped(String filename) { return findResourceAsStream(filename, ".gz"); } /* since RIM severely limits the amount of data you can have in a .cod * file (though apparently not as severely as they say -- we've gotten * 500k of data to work in a single .cod, about 8 times what they say * is the max), it may become necessary to split your files into groups * and have a separate Protocol.class handle each group. So to avoid * having to fully-specify URLs with http://my.other.fake.host/file.html, * use a subdirectory like part1/file.html and set autoRedirect to true, * and this routine will change it to * http://part1.my.fake.host/file.html and issue a 301 redirect */ public void attemptRedirect() { String[][] redirectHeaders = { {"location", null}, {null, null} }; String[] path = UrlParser.splitPath((String)parsedUrl.get("path")); if (path.length >= 1 && path[0].indexOf('.') < 0) { redirectHeaders[0][1] = "http://" + path[0] + "." + (String)parsedUrl.get("host") + "/" + UrlParser.joinPath(path, 1); outheaders = redirectHeaders; responseCode = 301; // "Moved permanently" } } public String getHeaderField(int index) { return outheaders[index][1]; } public String getHeaderFieldKey(int index) { return outheaders[index][0]; } public InputStream openInputStream() throws IOException { if (((String)parsedUrl.get("host")).equals("localhost")) fileStream = new ByteArrayInputStream(("http://localhost/ -- success!").getBytes()); else if (fileStream == null) fileStream = new ByteArrayInputStream(("Not found: " + url).getBytes()); return fileStream; } public int getResponseCode() { return responseCode; } }