- private static final JSFunction isPlainHostName = new JSFunction() {
- public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
- return (args[0].toString().indexOf('.') == -1) ? Boolean.TRUE : Boolean.FALSE;
- }
- };
-
- private static final JSFunction dnsDomainIs = new JSFunction() {
- public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
- return (args[0].toString().endsWith(args[1].toString())) ? Boolean.TRUE : Boolean.FALSE;
- }
- };
-
- private static final JSFunction localHostOrDomainIs = new JSFunction() {
- public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
- return (args[0].toString().equals(args[1].toString()) ||
- (args[0].toString().indexOf('.') == -1 && args[1].toString().startsWith(args[0].toString()))) ?
- Boolean.TRUE : Boolean.FALSE;
- }
- };
-
- private static final JSFunction isResolvable = new JSFunction() {
- public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
- try {
- return (InetAddress.getByName(args[0].toString()) != null) ? Boolean.TRUE : Boolean.FALSE;
- } catch (UnknownHostException e) {
- return Boolean.FALSE;
- }
- }
- };
-
- private static final JSFunction isInNet = new JSFunction() {
- public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
- if (args.length != 3) return Boolean.FALSE;
- try {
- byte[] host = InetAddress.getByName(args[0].toString()).getAddress();
- byte[] net = InetAddress.getByName(args[1].toString()).getAddress();
- byte[] mask = InetAddress.getByName(args[2].toString()).getAddress();
- return ((host[0] & mask[0]) == net[0] &&
- (host[1] & mask[1]) == net[1] &&
- (host[2] & mask[2]) == net[2] &&
- (host[3] & mask[3]) == net[3]) ?
- Boolean.TRUE : Boolean.FALSE;
- } catch (Exception e) {
- throw new JavaScriptException("exception in isInNet(): " + e);
- }
- }
- };
-
- private static final JSFunction dnsResolve = new JSFunction() {
- public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
- try {
- return InetAddress.getByName(args[0].toString()).getHostAddress();
- } catch (UnknownHostException e) {
- return null;
- }
- }
- };
-
- private static final JSFunction myIpAddress = new JSFunction() {
- public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
- try {
- return InetAddress.getLocalHost().getHostAddress();
- } catch (UnknownHostException e) {
- if (Log.on) Log.log(this, "strange... host does not know its own address");
- return null;
- }
- }
- };
-
- private static final JSFunction dnsDomainLevels = new JSFunction() {
- public Object call(Context cx, Scriptable thisObj, Scriptable ctorObj, Object[] args) throws JavaScriptException {
- String s = args[0].toString();
- int i = 0;
- while((i = s.indexOf('.', i)) != -1) i++;
- return new Integer(i);
- }
- };
-
- // FIXME: test this!
- private static boolean match(String[] arr, String s, int index) {
- if (index == arr.length) return true;
- for(int i=0; i<s.length(); i++) {
- String s2 = s.substring(i);
- if (s2.startsWith(arr[index]) && match(arr, s.substring(arr[index].length()), index + 1)) return true;
- }
- return false;
+ /** reads a set of HTTP headers off of the input stream, returning null if the stream is already at its end */
+ private Hashtable parseHeaders(InputStream in) throws IOException {
+ Hashtable ret = new Hashtable();
+
+ // we can't use a BufferedReader directly on the input stream, since it will buffer past the end of the headers
+ byte[] buf = new byte[4096];
+ int buflen = 0;
+ while(true) {
+ int read = in.read();
+ if (read == -1 && buflen == 0) return null;
+ if (read == -1) throw new HTTPException("stream closed while reading headers");
+ buf[buflen++] = (byte)read;
+ if (buflen >= 4 && buf[buflen - 4] == '\r' && buf[buflen - 3] == '\n' && buf[buflen - 2] == '\r' && buf[buflen - 1] == '\n') break;
+ if (buflen == buf.length) {
+ byte[] newbuf = new byte[buf.length * 2];
+ System.arraycopy(buf, 0, newbuf, 0, buflen);
+ buf = newbuf;