Class HttpStream

  • All Implemented Interfaces:
    java.io.Closeable, java.lang.AutoCloseable
    Direct Known Subclasses:
    XmlReadableSocket

    public class HttpStream
    extends Stream
    A HttpStream HAS-A totalcross.net.Socket and takes care of exchange protocol. It starts reading (in a buffer) at the message-body. If you are having read problems, try to increase the timeout with Options.readtimeout.

    Here is an example showing a rest consumer class managing data from an restful webservice:

     import totalcross.io.IOException;
     import totalcross.net.HttpStream;
     import totalcross.net.URI;
     import totalcross.net.UnknownHostException;
     import totalcross.net.ssl.SSLSocketFactory;
     import totalcross.sys.Vm;
     
     public class RestConsumerApplication {
            
            public static final String CONTENT_TYPE_JSON = "application/json";
            
            public static void printResponse (HttpStream hs) {
                    byte[] buf = new byte[hs.contentLength];
         try {
                            hs.readBytes(buf, 0, hs.contentLength);
                            Vm.debug("status:" + hs.getStatus());
                            Vm.debug("response:" + new String(buf));
                    } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                    }
            }
            
            public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
     
                    String getString = "https://jsonplaceholder.typicode.com/posts/1";
                    String postString = "https://jsonplaceholder.typicode.com/posts";
                    String putString = "https://jsonplaceholder.typicode.com/posts/1";
                    String deleteString = "https://jsonplaceholder.typicode.com/posts/1";
                    String patchString = "https://jsonplaceholder.typicode.com/posts/1";
                    
                    HttpStream httpStream           ;
                    HttpStream.Options options = new HttpStream.Options();
                    options.socketFactory = new SSLSocketFactory(); // In case https protocol is required   
                            
                    Vm.debug("=============  GET  ==============");
                    
                    options.httpType = HttpStream.GET;
                    httpStream = new HttpStream(new URI(getString), options);
                    printResponse(httpStream);
                    
                    Vm.debug("=============  POST  ==============");
                    
                    options.httpType = HttpStream.POST;
                    options.setContentType(CONTENT_TYPE_JSON);      
                    options.data = "{\"title\": \"foo\", \"body\": \"bar\", \"userId\": 1}";
                    
                    httpStream = new HttpStream(new URI(postString), options);
                    printResponse(httpStream);
                    
                    Vm.debug("=============  PUT  ==============");
                    
                    options.httpType = HttpStream.PUT;
                    options.data = "{\"id\": 1, \"title\": \"new title\", \"body\": \"bar\", \"userId\": 1}";
                    httpStream = new HttpStream(new URI(putString), options);
                    printResponse(httpStream);
                    
                    Vm.debug("=============  PATCH  ==============");
                                    
                    options.httpType = HttpStream.PATCH;
                    options.data = "{\"title\": \"new title 2\"}";
                    httpStream = new HttpStream(new URI(patchString), options);
                    printResponse(httpStream);
                    
                    Vm.debug("=============  DELETE  ==============");
                    
                    options.httpType = HttpStream.DELETE;
                    httpStream = new HttpStream(new URI(deleteString), options);
                    printResponse(httpStream);      
            }       
     } 
     
    See also the HttpConn wrapper and the enumeration of common HTTP methods. HttpConn abstracts dozens of stuff and is totally free to use and modify.
    • Field Detail

      • debugHeader

        public static boolean debugHeader
        Set to true to print the header to the debug console.
      • responseCode

        public int responseCode
        READ-ONLY should be one of the 20x. Used in the response.
      • contentEncoding

        public java.lang.String contentEncoding
        READ-ONLY encoding. Used in the response.
      • contentLength

        public int contentLength
        READ-ONLY the size of the returned data (-1 if unknown). Used in the response.
      • contentRead

        public int contentRead
        READ-ONLY number of bytes read from the response's content. Initialized with 0 and incremented whenever the readBytes method is executed.
      • contentType

        public byte contentType
        READ-ONLY see the xxx_TYPE enum below. Used in the response.
      • version

        public ByteString version
        READ-ONLY HTTP Version. Used in the response.
      • connection

        public java.lang.String connection
        READ-ONLY connection status. Used in the response.
      • location

        public URI location
        READ-ONLY location. Used in the response.
      • cookies

        public Hashtable cookies
        READ-ONLY cookies. Null if response returned no cookies. You can get all returned cookies by iterating in the keys returned by cookies.getKeys(). If you want to persist a session, just store the cookies sent by the server and then send them back in each request you make, like this:
         public class SessionTest extends MainWindow
         {
            String url = "http://localhost:8080/servlet/sessionTest";
            Button btnGO;
            Hashtable cookies;
            ...
            if (event.target == btnGO)
            {
               HttpStream.Options options = new HttpStream.Options();
        
               // set cookies if they already exist
               if (cookies != null)
                  options.setCookies(cookies);
        
               HttpStream st = new HttpStream(new URI(url),options);
        
               // Save cookies sent by server
               if (st.cookies != null)
                  cookies = st.cookies;
            }
            ...
         }
         
        Note that its important that you call Socket.disconnect() before exiting your application.
        See Also:
        HttpStream.Options.setCookies(Hashtable)
      • headers

        public Hashtable headers
        This Hashtable contains all headers that came in the response that don't belong to the public fields.
        Since:
        TotalCross 1.62
      • UNKNOWN_TYPE

        public static final byte UNKNOWN_TYPE
        Used in the contentType property.
        See Also:
        Constant Field Values
      • TEXT_HTML_TYPE

        public static final byte TEXT_HTML_TYPE
        Used in the contentType property.
        See Also:
        Constant Field Values
      • IMAGE_TYPE

        public static final byte IMAGE_TYPE
        Used in the contentType property.
        See Also:
        Constant Field Values
      • MULTIPART_TYPE

        public static final byte MULTIPART_TYPE
        Used in the contentType property.
        See Also:
        Constant Field Values
      • sendSleep

        public int sendSleep
        This makes a sleep during the send of a file. Important: when using softick, you must set this to 500(ms) or more, or softick will starve to death.
      • readTokensDelimiter

        public char readTokensDelimiter
        The delimiter used when reading data using readTokens. Once the readTokens method is called, changing the delimiter field will be useless.
        Since:
        TotalCross 1.25
        See Also:
        readTokens()
      • readTokensDoTrim

        public boolean readTokensDoTrim
        This value is passed to the TokenReader created when readTokens is called.
        Since:
        TotalCross 1.25
        See Also:
        LineReader.doTrim, readTokens()
      • socket

        protected Socket socket
      • ofsStart

        protected int ofsStart
      • ofsEnd

        protected int ofsEnd
      • buffer

        protected byte[] buffer
      • readPos

        protected int readPos
      • badResponseCode

        public boolean badResponseCode
        Returns true if the response code represents an error.
    • Method Detail

      • readBytes

        public int readBytes​(byte[] buf,
                             int start,
                             int count)
                      throws IOException
        Description copied from class: Stream
        Reads bytes from the stream. Returns the number of bytes actually read or -1 if the end of the stream was reached. (if applicable to the stream)
        Specified by:
        readBytes in class Stream
        Parameters:
        buf - the byte array to read data into
        start - the start position in the array
        count - the number of bytes to read
        Throws:
        IOException
      • writeBytes

        public int writeBytes​(byte[] buf,
                              int start,
                              int count)
                       throws IOException
        Description copied from class: Stream
        Writes bytes to the stream. Returns the number of bytes actually written or throws an IOException if an error prevented the write operation from occurring.
        Specified by:
        writeBytes in class Stream
        Parameters:
        buf - the byte array to write data from
        start - the start position in the byte array
        count - the number of bytes to write
        Returns:
        the number of bytes actually written
        Throws:
        IOException
      • close

        public void close()
                   throws IOException
        Closes this I/O connection, releasing any associated resources. Once closed a connection is no longer valid.
        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface java.io.Closeable
        Throws:
        IOException - If an I/O error occurs.
      • isOk

        public boolean isOk()
        Tell if this HttpStream is functioning properly.
        Returns:
        true, if this HttpStream is functionning properly and the socket is open; false otherwise.
      • getStatus

        public java.lang.String getStatus()
        Get a human readable text to describe the current status of this HttpStream
      • refill

        public final boolean refill()
                             throws IOException
        Refill the buffer, assuming that ofsCur is at ofsEnd.
        Throws:
        IOException
      • skipToNextMimePart

        protected boolean skipToNextMimePart()
                                      throws IOException
        Skip to the next mime part.
        • ofsCur points after the '\n' ending the content-type parameter
        • multipartSep can be null if no mime separator (boundary) was found
        Returns:
        true if we were able to position the stream on the '\n' that ends the mime-separator signaling the beginning of the mime part.
        Throws:
        IOException - Actually, we only handle the first mime part This code might later be extended for other parts.
      • readLine

        public java.lang.String readLine()
                                  throws IOException
        Reads a line of text comming from the socket attached to this HttpStream. This method correctly handles newlines with \\n or \\r\\n. If you're reading tokens, use the readTokens method. Note that both readLine and readTokens cannot be used at the same time.
        Returns:
        the read line or null if nothing was read.
        Throws:
        IOException
        Since:
        SuperWaba 5.7
        See Also:
        readTokens()
      • readTokens

        public java.lang.String[] readTokens()
                                      throws IOException
        Reads a line of text comming from the socket attached to this HttpStream. This method correctly handles newlines with \\n or \\r\\n. If you're reading lines, use the readLines method. Note that both readLine and readTokens cannot be used at the same time. The delimiter must be set using the delimiter field, prior to using this method.
        Returns:
        the read line or null if nothing was read.
        Throws:
        IOException
        Since:
        TotalCross 1.25
        See Also:
        readTokensDelimiter, readTokensDoTrim, readLine()