Revision: 3342
          http://vexi.svn.sourceforge.net/vexi/?rev=3342&view=rev
Author:   mkpg2
Date:     2009-01-07 02:10:14 +0000 (Wed, 07 Jan 2009)

Log Message:
-----------
http stuff
  - make error response & its mimetype available for interpretation/display  
  - ability to set content type when posting

Modified Paths:
--------------
    trunk/core/org.ibex.js/src/org/ibex/js/Constants.java
    trunk/core/org.ibex.js/src/org/ibex/js/Fountain.java
    trunk/core/org.ibex.js/src/org/ibex/js/JS.jpp
    trunk/core/org.ibex.js/src/org/ibex/js/JSExn.java
    trunk/core/org.ibex.js/src/org/ibex/js/JSU.jpp
    trunk/core/org.ibex.js/src/org/vexi/js/VexiJS.jpp
    trunk/core/org.ibex.js/src_dev/org/ibex/js/RunJS.java
    trunk/core/org.ibex.js/src_junit/test/js/exec/http/TestHTTP.java
    trunk/core/org.ibex.net/src/org/ibex/net/HTTP.jpp
    trunk/core/org.ibex.net/src_junit/org/ibex/net/TestHTTP.java
    trunk/core/org.ibex.util/src/org/ibex/util/Semaphore.java

Added Paths:
-----------
    trunk/core/org.ibex.js/src_junit/test/js/exec/http/400_withjson.js

Modified: trunk/core/org.ibex.js/src/org/ibex/js/Constants.java
===================================================================
--- trunk/core/org.ibex.js/src/org/ibex/js/Constants.java       2009-01-07 
01:10:59 UTC (rev 3341)
+++ trunk/core/org.ibex.js/src/org/ibex/js/Constants.java       2009-01-07 
02:10:14 UTC (rev 3342)
@@ -6,6 +6,7 @@
     static final JS SC_array = JSU.S("array",true);
        static final JS SC_boolean = JSU.S("boolean",true);
        static final JS SC_callee = JSU.S("callee",true);
+       static final JS SC_code = JSU.S("code",true);
        static final JS SC_date = JSU.S("date",true);
        static final JS SC_error = JSU.S("error",true);
        static final JS SC_eval = JSU.S("eval",true);
@@ -23,6 +24,7 @@
        static final JS SC_lastModified = JSU.S("lastModified",true);
        static final JS SC_length = JSU.S("length",true);
        static final JS SC_message = JSU.S("message",true);
+       static final JS SC_mimetype = JSU.S("mimetype",true);
        static final JS SC_name = JSU.S("name",true);
        static final JS SC_next = JSU.S("next",true);
        static final JS SC_null = JSU.S("null",true);

Modified: trunk/core/org.ibex.js/src/org/ibex/js/Fountain.java
===================================================================
--- trunk/core/org.ibex.js/src/org/ibex/js/Fountain.java        2009-01-07 
01:10:59 UTC (rev 3341)
+++ trunk/core/org.ibex.js/src/org/ibex/js/Fountain.java        2009-01-07 
02:10:14 UTC (rev 3342)
@@ -181,43 +181,45 @@
     /** HTTP or HTTPS resource */
     public static class HTTP extends Fountain{
         private String url;
-        private HTTPInputStream lastResponse;
-        private JS lastInfo;
-        private org.ibex.net.HTTP http(){ return new org.ibex.net.HTTP(url);}
-        public String canonical() { return url; }
+        // request
+        public String mimetype = "";
+        // response
+        private HTTPInputStream responseStream;
+        private JS responseInfo;
+        
         public HTTP(String url) { 
                while (url.endsWith("/")) url = url.substring(0, url.length() - 
1);
                this.url = url;
         }
+        private org.ibex.net.HTTP http(){ return new org.ibex.net.HTTP(url);}
+        public String canonical() { return url; }
+        
+        
         public JS _get(JS key) throws JSExn { return new HTTP(url + "/" + 
JSU.toString(key)); }
         private JS readInfo(HTTPInputStream is){
                JS.Obj r = new JS.Obj();
-               try {
-                       r.put(SC_lastModified, JSU.S(is.getLastModified()));
-                       r.put(SC_length, JSU.N(is.getLength()));
-                       r.put(SC_name, JSU.S(url));
-               }catch(JSExn e){
-                       // should not be possible
-                       throw new Error(e);
-               }
+               r.putSafe(SC_lastModified, JSU.S(is.info.lastModified));
+               r.putSafe(SC_length, JSU.N(is.info.contentLength));
+               r.putSafe(SC_mimetype, JSU.S(is.info.contentType));
+               r.putSafe(SC_name, JSU.S(url));
                return r;
         }
         
         public JS getInfo() throws IOException {
-               if(lastInfo==null){
-                       lastResponse = (HTTPInputStream) http().GET(null, null);
-                       lastInfo = readInfo(lastResponse);
+               if(responseInfo==null){
+                       responseStream = (HTTPInputStream) http().GET(null, 
null);
+                       responseInfo = readInfo(responseStream);
                }
-               return lastInfo;
+               return responseInfo;
         }
         //public String getCacheKey(Vec path) throws NotCacheableException { 
return url; }
         public InputStream _getInputStream() throws IOException { 
-               if(lastResponse==null){
-                       lastResponse = (HTTPInputStream) http().GET(null, null);
-                       lastInfo = readInfo(lastResponse);
+               if(responseStream==null){
+                       responseStream = (HTTPInputStream) http().GET(null, 
null);
+                       responseInfo = readInfo(responseStream);
                }
-               InputStream r = lastResponse;
-               lastResponse = null;
+               InputStream r = responseStream;
+               responseStream = null;
                return r;
         }
         /*public InputStream getHeadInputStream() throws IOException { 
@@ -231,13 +233,25 @@
                // from the http post
                ByteArrayOutputStream r = new ByteArrayOutputStream(){
                        public void close() throws IOException {
-                               // HACK - hardcode mime type
-                               lastResponse= (HTTPInputStream) 
http().POST("test/xml", toByteArray(), null, null);
-                               lastInfo = readInfo(lastResponse);
+                               responseStream= (HTTPInputStream) 
http().POST(mimetype, toByteArray(), null, null);
+                               responseInfo = readInfo(responseStream);
                        }
                };
                return r;
         }
+        
+        public JS getResponseInfo(){ return responseInfo; }
+        
+               public void setRequestInfo(JS info) throws JSExn {
+                       Enumeration en = info.keys().iterator();
+                       while(en.hasNext()){
+                               String key = JSU.toString(en.next());
+                               if(!"mimetype".equals(key)){
+                                       throw new JSExn("'"+key+"' not 
supported, only mimetype currently supported in request info"); 
+                               }
+                               mimetype = JSU.toString(info.get(SC_mimetype));
+                       }
+               }
     }
 
     /** byte arrays */

Modified: trunk/core/org.ibex.js/src/org/ibex/js/JS.jpp
===================================================================
--- trunk/core/org.ibex.js/src/org/ibex/js/JS.jpp       2009-01-07 01:10:59 UTC 
(rev 3341)
+++ trunk/core/org.ibex.js/src/org/ibex/js/JS.jpp       2009-01-07 02:10:14 UTC 
(rev 3342)
@@ -4,7 +4,6 @@
 
 package org.ibex.js; 
 
-import org.ibex.util.*; 
 import java.util.*;
 
 /** The minimum set of functionality required for objects which are 
manipulated by JavaScript */
@@ -195,13 +194,15 @@
         public JS type() { return SC_object; }
         
         /** Fetches any value stored against the given key. */
-        public JS get(JS key) throws JSExn { 
+        public JS get(JS key) throws JSExn { return getSafe(key); }
+        final public JS getSafe(JS key)  {  // workaround, avoid JSExn in 
signature
             if (props==null) return null;
             return (JS)props.get(key);
         }
 
         /** Store a value against a key on the object. */ 
-        public void put(JS key, JS value) throws JSExn { 
+        public void put(JS key, JS value) throws JSExn { putSafe(key,value); }
+        public void putSafe(JS key, JS value) {  // workaround, avoid JSExn in 
signature
             if (props==null) props = new HashMap(4);
             props.put(key, value);
         }

Modified: trunk/core/org.ibex.js/src/org/ibex/js/JSExn.java
===================================================================
--- trunk/core/org.ibex.js/src/org/ibex/js/JSExn.java   2009-01-07 01:10:59 UTC 
(rev 3341)
+++ trunk/core/org.ibex.js/src/org/ibex/js/JSExn.java   2009-01-07 02:10:14 UTC 
(rev 3342)
@@ -83,18 +83,14 @@
         }
     }
 
-    public JS getObject() { return js; } 
+    public JS.Obj getObject() { return js; } 
     
     // JSExn JS interface (as !JSExn instanceof JS)
     // Provides access to the stack trace from JSExn.
     public class ExnJSObj extends JS.Obj{
        public ExnJSObj(JS msg, JS type) {
-               try{
-                       put(SC_message,msg);
-                       put(SC_type,type);
-               }catch(JSExn e){
-                       // Shouldn't happen
-               }
+                       putSafe(SC_message,msg);
+                       putSafe(SC_type,type);
                }
 
        public JS get(JS key) throws JSExn {

Modified: trunk/core/org.ibex.js/src/org/ibex/js/JSU.jpp
===================================================================
--- trunk/core/org.ibex.js/src/org/ibex/js/JSU.jpp      2009-01-07 01:10:59 UTC 
(rev 3341)
+++ trunk/core/org.ibex.js/src/org/ibex/js/JSU.jpp      2009-01-07 02:10:14 UTC 
(rev 3342)
@@ -2,6 +2,7 @@
 
 import java.io.*;
 
+import org.ibex.net.HTTP.*;
 import org.ibex.util.*;
 
 public class JSU implements Constants{
@@ -28,12 +29,18 @@
        return j;
     }
     
-    public static Fountain getFountain(JS j) {
+    static public Fountain getFountain(JS j) {
         while(j != null && j instanceof JS.Clone) j = j.unclone();
         if (j != null && j instanceof Fountain) return ((Fountain)j);
         return null;
     }
     
+    static public Fountain.HTTP getHTTPFountain(JS j) throws JSExn {
+       Fountain r = getFountain(j);
+       if(!(r instanceof Fountain.HTTP)) throw new JSExn("Expected http, got 
"+r);
+       return (Fountain.HTTP)r;
+    }
+    
     static public InputStream getInputStream(JS js) throws IOException {
        Fountain f = getFountain(js);
        return (f!=null)?f.getInputStream():null;
@@ -48,7 +55,20 @@
     // on everywhere that handles IOExceptions from fountains to
     // call this...
     static public JSExn handleFountainExn(IOException e) {
-       if(e instanceof org.ibex.net.HTTP.HTTPException) return new 
JSExn(JSU.S(e.getMessage()),SC_http);
+       if(e instanceof HTTPErrorResponse) {
+               HTTPErrorResponse he = (HTTPErrorResponse)e;
+               JSExn je = new JSExn(JSU.S(e.getMessage()),SC_http);
+               Fountain.ByteArray stream = new Fountain.ByteArray(he.bytes);
+               JS.Obj jeObj = je.getObject();
+               jeObj.putSafe(SC_code,JSU.S(he.code));
+               jeObj.putSafe(SC_stream,stream);
+               String mimetype = he.info.contentType;
+               // remove ; charset ... (TODO - verify we have already taken 
this into account)
+               if(mimetype.indexOf(";")!=-1)
+                       mimetype = mimetype.substring(0,mimetype.indexOf(";"));
+               jeObj.putSafe(SC_mimetype, JSU.S(mimetype));
+               return je;
+       }
        return new JSExn(e.getMessage());
     }
     

Modified: trunk/core/org.ibex.js/src/org/vexi/js/VexiJS.jpp
===================================================================
--- trunk/core/org.ibex.js/src/org/vexi/js/VexiJS.jpp   2009-01-07 01:10:59 UTC 
(rev 3341)
+++ trunk/core/org.ibex.js/src/org/vexi/js/VexiJS.jpp   2009-01-07 02:10:14 UTC 
(rev 3342)
@@ -193,28 +193,31 @@
     static public final JS http = new JS.Immutable() {
         public JS get(JS key) throws JSExn {
             //#switch(JSU.toString(key))
-               case "post": return METHOD;
+               case "getResponseInfo": return METHOD;
+               case "setRequestInfo": return METHOD;
                case "stream": return METHOD;
             //#end
             return super.get(key);
         }
         public JS call(JS method, JS[] args) throws JSExn {
-               //#switch(JSU.toString(method))
-               case "post":
-                       throw new RuntimeException("TODO/REMOVE");
-                       /*JSU.checkArgs(args, ARGTYPES_post);
-                       String url = JSU.toString(args[0]);
-                       Fountain in = JSU.getFountain(args[1]);
-                       return new 
Fountain.ByteArray(args.length>0?args[0]:null);*/
-               //#end
-               
                switch(args.length) {
             case 1: {
                //#switch(JSU.toString(method))
+               case "getResponseInfo":
+                       Fountain.HTTP http = JSU.getHTTPFountain(args[0]);
+               return http.getResponseInfo();
                    case "stream": return fountainForURL(JSU.toString(args[0]));
                    //#end
             }
+            case 2: {
+               //#switch(JSU.toString(method))
+               case "setRequestInfo":
+                       Fountain.HTTP http = JSU.getHTTPFountain(args[0]);
+               http.setRequestInfo(args[1]);
+               return null;
+               //#end
                }
+               }
             return super.call(method, args);
         }
     };

Modified: trunk/core/org.ibex.js/src_dev/org/ibex/js/RunJS.java
===================================================================
--- trunk/core/org.ibex.js/src_dev/org/ibex/js/RunJS.java       2009-01-07 
01:10:59 UTC (rev 3341)
+++ trunk/core/org.ibex.js/src_dev/org/ibex/js/RunJS.java       2009-01-07 
02:10:14 UTC (rev 3342)
@@ -276,6 +276,13 @@
                                        if(!JSU.isString(arg)) return null;
                                        String key = JSU.toString(arg);
                                // TEST SPECIFIC
+                                       if("trace".equals(key)) return METHOD;
+                                       if("log".equals(key)) return 
getSub(arg);
+                               if("log.debug".equals(key)) return METHOD;
+                               if("log.info".equals(key)) return METHOD;
+                               if("log.warn".equals(key)) return METHOD;
+                               if("log.error".equals(key)) return METHOD;
+                                       
                                        if("res".equals(key)) return resObj;
                                        if("date".equals(key)) return METHOD;
                                        if("firethis".equals(key)) return 
METHOD;
@@ -299,18 +306,15 @@
                                        if("string".equals(key)) return 
VexiJS.string;
                                        if("http".equals(key)) return 
VexiJS.http;
                                        
-                                       if("log".equals(key)) return 
getSub(arg);
-                               if("log.debug".equals(key)) return METHOD;
-                               if("log.info".equals(key)) return METHOD;
-                               if("log.warn".equals(key)) return METHOD;
-                               if("log.error".equals(key)) return METHOD;
+
                                        
                                if("js".equals(key)) return getSub(arg);
                                if("js.stringify".equals(key)) return METHOD;
+                               if("js.eval".equals(key)) return METHOD;
                                
-                               
                                        
                                        
+                                       
                                        /*
                                        if("bgget".equals(key)) {
                                                action = "bgget";
@@ -346,6 +350,8 @@
                                        
                                        if(!JSU.isString(method)) return null;
                                        String methName = JSU.toString(method);
+
+                                       if("trace".equals(methName)) { 
JSU.warn(JSON.marshal(args[0])); return null; } 
                                        if("log.debug".equals(methName)) {    
if(args.length<1) JSU.debug(null); else JSU.debug(args[0]); return null;}
                                        if("log.info".equals(methName)) {     
if(args.length<1) JSU.info(null); else JSU.info(args[0]); return null;}
                                        if("log.warn".equals(methName)) {     
if(args.length<1) JSU.warn(null); else JSU.warn(args[0]); return null;}
@@ -393,6 +399,9 @@
                            if("js.stringify".equals(methName)){
                                return JSON.marshal(args[0]);
                            }
+                           if("js.eval".equals(methName)){
+                               return Methods.eval(args);
+                           }
                                        return null;
                                }
                        }

Added: trunk/core/org.ibex.js/src_junit/test/js/exec/http/400_withjson.js
===================================================================
--- trunk/core/org.ibex.js/src_junit/test/js/exec/http/400_withjson.js          
                (rev 0)
+++ trunk/core/org.ibex.js/src_junit/test/js/exec/http/400_withjson.js  
2009-01-07 02:10:14 UTC (rev 3342)
@@ -0,0 +1,25 @@
+       
+       
+       var ss = sys.http.stream("http://localhost:9999/400_withjson";);
+          
+       var doIt = function(f,args){
+       if(args==null) args = [];
+       try{
+                   f.apply(args);
+                       throw "Expected exn";
+               }catch(e){
+                   if(e["type"]!="http") throw e;
+                   sys.trace(e);
+                   assert(e["code"]=="400");
+                   assert(e["mimetype"]=="text/json");
+                   var json = sys.stream.utf8reader(e["stream"]).all;
+                   var obj = sys.js.eval("return "+json+";");
+                   assert(obj["type"]=="arbitrary");
+               }
+       }
+
+    doIt( function(){ sys.stream.utf8reader(ss).line; });
+    doIt( function(){ sys.stream.utf8writer(ss).write("abc"); });
+       
+
+

Modified: trunk/core/org.ibex.js/src_junit/test/js/exec/http/TestHTTP.java
===================================================================
--- trunk/core/org.ibex.js/src_junit/test/js/exec/http/TestHTTP.java    
2009-01-07 01:10:59 UTC (rev 3341)
+++ trunk/core/org.ibex.js/src_junit/test/js/exec/http/TestHTTP.java    
2009-01-07 02:10:14 UTC (rev 3342)
@@ -42,9 +42,11 @@
     }
     
     static public void main(String[] args) throws Throwable {
+       //String test = "404.js";
+       String test = "400_withjson.js";
        before();
        JSTestSuite jts = new TestHTTP();
-       TestCase t = jts.createTestCase(jts.getResourceDirs(), "post3.js");
+       TestCase t = jts.createTestCase(jts.getResourceDirs(), test);
        t.run();
        after();
        }

Modified: trunk/core/org.ibex.net/src/org/ibex/net/HTTP.jpp
===================================================================
--- trunk/core/org.ibex.net/src/org/ibex/net/HTTP.jpp   2009-01-07 01:10:59 UTC 
(rev 3341)
+++ trunk/core/org.ibex.net/src/org/ibex/net/HTTP.jpp   2009-01-07 02:10:14 UTC 
(rev 3342)
@@ -109,17 +109,28 @@
     
     
     /** Performs an HTTP GET request */
-    public InputStream GET(String referer, Cookie.Jar cookies) throws 
IOException {
+    public HTTPInputStream GET(String referer, Cookie.Jar cookies) throws 
IOException {
         return makeRequest("GET", null, referer, cookies); }
     
-    public InputStream HEAD(String referer, Cookie.Jar cookies) throws 
IOException {
+    public HTTPInputStream HEAD(String referer, Cookie.Jar cookies) throws 
IOException {
         return makeRequest("HEAD", null, referer, cookies); }
     
     /** Performs an HTTP POST request; content is additional headers, blank 
line, and body */
-    public InputStream POST(String contentType, byte[] content, String 
referer, Cookie.Jar cookies) throws IOException {
+    public HTTPInputStream POST(String contentType, byte[] content, String 
referer, Cookie.Jar cookies) throws IOException {
         return makeRequest(contentType, content, referer, cookies); }
 
     public static class HTTPException extends IOException { public 
HTTPException(String s) { super(s); } }
+    public static class HTTPErrorResponse extends HTTPException { 
+       final public String code;
+       final public byte[] bytes;
+       final public EntityInfo info;
+       public HTTPErrorResponse(String s, byte[] bytes, EntityInfo info) { 
+               super("HTTP Error: " + s); 
+               this.code = s.substring(0,3);
+               this.bytes = bytes;
+               this.info = info;
+       } 
+    }
 
     public static HTTP stdio = new HTTP("stdio:");
 
@@ -155,7 +166,7 @@
      *  This method isn't synchronized; however, only one thread can be in the 
inner synchronized block at a time, and the rest of
      *  the method is protected by in-order one-at-a-time semaphore lock-steps
      */
-    private InputStream makeRequest(String contentType, byte[] content, String 
referer, Cookie.Jar cookies) throws IOException {
+    private HTTPInputStream makeRequest(String contentType, byte[] content, 
String referer, Cookie.Jar cookies) throws IOException {
 
         // Step 1: send the request and establish a semaphore to stop any 
requests that pipeline after us
         Semaphore blockOn = null;
@@ -203,8 +214,7 @@
                     Log.info(this, "proxy returned an HTTP/1.0 reply with no 
content-length...");
                     reset();
                 } else {
-                    int cl = h.get("content-length") == null ? -1 : 
Integer.parseInt(h.get("content-length").toString());
-                    new HTTPInputStream(in, cl, releaseMe,null).close();
+                    newHTTPInputStream(in, h, releaseMe).close();
                 }
                 releaseMe.release();
                 return makeRequest(contentType, content, referer, cookies);
@@ -221,15 +231,19 @@
             } else if (reply.startsWith("2")) {
                 if (h.get("HTTP").equals("1.0") && h.get("content-length") == 
null)
                     throw new HTTPException("Vexi does not support HTTP/1.0 
servers which fail to return the Content-Length header");
-                int cl = h.get("content-length") == null ? -1 : 
Integer.parseInt(h.get("content-length").toString());
-                String timestamp = (String) h.get("last-modified");
-                               InputStream ret = new HTTPInputStream(in, cl, 
releaseMe, timestamp);
-                if ("gzip".equals(h.get("content-encoding"))) ret = new 
java.util.zip.GZIPInputStream(ret);
+                HTTPInputStream ret = newHTTPInputStream(in, h, releaseMe);
                 doRelease = false;
                 return ret;
-                
             } else {
-                throw new HTTPException("HTTP Error: " + reply);
+               HTTPInputStream his = newHTTPInputStream(in, h, releaseMe);
+               // read into stream, so that we can release and are not obliged 
to handle
+               // the response (close the inputstream) - mike (assumes this is 
necessary)
+               ByteArrayOutputStream baos  = new 
ByteArrayOutputStream(his.info.contentLength>0?his.info.contentLength:1024);
+               IOUtil.pipe(his, baos);
+               byte[] bytes = baos.toByteArray();
+               //byte[] bytes = "{}".getBytes();
+               his.close();
+               throw new HTTPErrorResponse(reply, bytes, his.info);
             }
             
         } catch (IOException e) { reset(); throw e;
@@ -470,38 +484,43 @@
 
 
     // HTTPInputStream 
///////////////////////////////////////////////////////////////////////////////////
+    public class EntityInfo{
+       final public int contentLength;       ///< the length of the entire 
content body; -1 if chunked
+       final public String contentType;
+        final public String lastModified;
+        EntityInfo(int contentLength, String lastModified, String contentType){
+               this.contentLength = contentLength;
+               this.lastModified = lastModified;
+               this.contentType = contentType;
+        }
 
+    }
+    
     /** An input stream that represents a subset of a longer input stream. 
Supports HTTP chunking as well */
     public class HTTPInputStream extends FilterInputStream{
 
-        private int length = 0;              ///< if chunking, numbytes left 
in this subset; else the remainder of the chunk
+
+               final public EntityInfo info;
+               
+               private int length = 0;              ///< if chunking, numbytes 
left in this subset; else the remainder of the chunk
         private Semaphore releaseMe = null;  ///< this semaphore will be 
released when the stream is closed
-        boolean chunkedDone = false;         ///< indicates that we have 
encountered the zero-length terminator chunk
-        boolean firstChunk = true;           ///< if we're on the first chunk, 
we don't pre-read a CRLF
-        private int contentLength = 0;       ///< the length of the entire 
content body; -1 if chunked
-               /** the last time the content was modified */
-               private String lastModified = "";
+        private boolean chunkedDone = false;         ///< indicates that we 
have encountered the zero-length terminator chunk
+        private boolean firstChunk = true;           ///< if we're on the 
first chunk, we don't pre-read a CRLF
         
-        HTTPInputStream(InputStream in, int length, Semaphore releaseMe, 
String lastModified) throws IOException {
+               
+        HTTPInputStream(InputStream in, Semaphore releaseMe, EntityInfo info) 
throws IOException {
             super(in);
+            this.info = info;
             this.releaseMe = releaseMe;
-            this.contentLength = length;
-            this.length = length == -1 ? 0 : length;
-            this.lastModified = lastModified == null ? "" : lastModified;
+            this.length = info.contentLength == -1 ? 0 : info.contentLength;
         }
-
-        public int getLength() { return contentLength; }
         public boolean markSupported() { return false; }
         public int read(byte[] b) throws IOException { return read(b, 0, 
b.length); }
         public long skip(long n) throws IOException { return read(null, -1, 
(int)n); }
         public int available() throws IOException {
-            if (contentLength == -1) return 
java.lang.Math.min(super.available(), length);
+            if (info.contentLength == -1) return 
java.lang.Math.min(super.available(), length);
             return super.available();
         }
-
-               public String getLastModified() {
-                       return lastModified;
-               }
         
         public int read() throws IOException {
             byte[] b = new byte[1];
@@ -533,7 +552,7 @@
         public int read(byte[] b, int off, int len) throws IOException {
             boolean good = false;
             try {
-                if (length == 0 && contentLength == -1) {
+                if (length == 0 && info.contentLength == -1) {
                     readChunk();
                     if (chunkedDone) { good = true; return -1; }
                 } else {
@@ -552,7 +571,7 @@
         }
 
         public void close() throws IOException {
-            if (contentLength == -1) {
+            if (info.contentLength == -1) {
                 while(!chunkedDone) {
                     if (length != 0) skip(length);
                     readChunk();
@@ -567,7 +586,23 @@
             }
             if (releaseMe != null) releaseMe.release();
         }
+
     }
+    
+    private EntityInfo newEntityInfo(Hashtable h){
+       int cl = h.get("content-length") == null ? -1 : 
Integer.parseInt(h.get("content-length").toString());
+        String timestamp = (String) h.get("last-modified");
+        if(timestamp==null) timestamp="";
+        String contentType = (String) h.get("content-type");
+        if(contentType==null) contentType = "";
+        return new EntityInfo (cl, timestamp, contentType);
+    }
+    
+    private HTTPInputStream newHTTPInputStream(InputStream in, Hashtable h, 
Semaphore releaseMe) throws IOException{
+       EntityInfo info = newEntityInfo(h);
+        if ("gzip".equals(h.get("content-encoding"))) in = new 
java.util.zip.GZIPInputStream(in);
+        return new HTTPInputStream(in, releaseMe, info);
+    }
 
     void reset() {
         firstRequest = true;

Modified: trunk/core/org.ibex.net/src_junit/org/ibex/net/TestHTTP.java
===================================================================
--- trunk/core/org.ibex.net/src_junit/org/ibex/net/TestHTTP.java        
2009-01-07 01:10:59 UTC (rev 3341)
+++ trunk/core/org.ibex.net/src_junit/org/ibex/net/TestHTTP.java        
2009-01-07 02:10:14 UTC (rev 3342)
@@ -32,7 +32,7 @@
 
                
handler.addServletWithMapping(CapitalizeServlet.class.getName(), "/capitalize");
                handler.addServletWithMapping(ReorderServlet.class.getName(), 
"/reorder");
-
+               handler.addServletWithMapping(ExceptionServlet.class.getName(), 
"/400_withjson");
                server.start();
        }
 
@@ -40,6 +40,19 @@
                server.stop();
        }
        static  private byte[] workspace = new byte[16 * 1024];
+       
+       
+       static public class ExceptionServlet extends HttpServlet
+    {
+               protected void service(HttpServletRequest request, 
HttpServletResponse response)
+                               throws ServletException, IOException {
+               response.setContentType("text/json");
+               response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+               
response.getWriter().print("{\"type\":\"arbitrary\",\"reason\":\"why not\"}");
+               response.getWriter().close();
+               }
+    }
+       
        static public class CapitalizeServlet extends HttpServlet
     {
        protected void doPost(HttpServletRequest request, HttpServletResponse 
response) throws ServletException, IOException

Modified: trunk/core/org.ibex.util/src/org/ibex/util/Semaphore.java
===================================================================
--- trunk/core/org.ibex.util/src/org/ibex/util/Semaphore.java   2009-01-07 
01:10:59 UTC (rev 3341)
+++ trunk/core/org.ibex.util/src/org/ibex/util/Semaphore.java   2009-01-07 
02:10:14 UTC (rev 3342)
@@ -20,8 +20,8 @@
                 wait();
             } catch (InterruptedException e) {
             } catch (Throwable e) {
-                Log.info(this, "Exception in Semaphore.block(); this should 
never happen");
-                Log.info(this, e);
+                Log.error(this, "Exception in Semaphore.block(); this should 
never happen");
+                Log.error(this, e);
             }
         }
         val--;


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It is the best place to buy or sell services for
just about anything Open Source.
http://p.sf.net/sfu/Xq1LFB
_______________________________________________
Vexi-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to