Home | History | Annotate | Download | only in transport
      1 /**
      2  *  Copyright (c) 2003,2004, Stefan Haustein, Oberhausen, Rhld., Germany
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a copy
      5  * of this software and associated documentation files (the "Software"), to deal
      6  * in the Software without restriction, including without limitation the rights
      7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or
      8  * sell copies of the Software, and to permit persons to whom the Software is
      9  * furnished to do so, subject to the following conditions:
     10  *
     11  * The  above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     20  * IN THE SOFTWARE.
     21  *
     22  * Contributor(s): John D. Beatty, Dave Dash, F. Hunter, Alexander Krebs,
     23  *                 Lars Mehrmann, Sean McDaniel, Thomas Strang, Renaud Tognelli
     24  * */
     25 
     26 package org.ksoap2.transport;
     27 
     28 import java.util.List;
     29 import java.util.zip.GZIPInputStream;
     30 import java.io.*;
     31 import java.net.MalformedURLException;
     32 import java.net.Proxy;
     33 import java.net.URL;
     34 
     35 import org.ksoap2.*;
     36 import org.ksoap2.serialization.SoapSerializationEnvelope;
     37 import org.xmlpull.v1.*;
     38 
     39 /**
     40  * A J2SE based HttpTransport layer.
     41  */
     42 public class HttpTransportSE extends Transport {
     43 
     44     private ServiceConnection serviceConnection;
     45 
     46     /**
     47      * Creates instance of HttpTransportSE with set url
     48      *
     49      * @param url
     50      *            the destination to POST SOAP data
     51      */
     52     public HttpTransportSE(String url) {
     53         super(null, url);
     54     }
     55 
     56     /**
     57      * Creates instance of HttpTransportSE with set url and defines a
     58      * proxy server to use to access it
     59      *
     60      * @param proxy
     61      * Proxy information or <code>null</code> for direct access
     62      * @param url
     63      * The destination to POST SOAP data
     64      */
     65     public HttpTransportSE(Proxy proxy, String url) {
     66         super(proxy, url);
     67     }
     68 
     69     /**
     70      * Creates instance of HttpTransportSE with set url
     71      *
     72      * @param url
     73      *            the destination to POST SOAP data
     74      * @param timeout
     75      *   timeout for connection and Read Timeouts (milliseconds)
     76      */
     77     public HttpTransportSE(String url, int timeout) {
     78         super(url, timeout);
     79     }
     80 
     81     public HttpTransportSE(Proxy proxy, String url, int timeout) {
     82         super(proxy, url, timeout);
     83     }
     84 
     85     /**
     86      * Creates instance of HttpTransportSE with set url
     87      *
     88      * @param url
     89      *            the destination to POST SOAP data
     90      * @param timeout
     91      *   timeout for connection and Read Timeouts (milliseconds)
     92      * @param contentLength
     93      *   Content Lenght in bytes if known in advance
     94      */
     95     public HttpTransportSE(String url, int timeout, int contentLength) {
     96         super(url, timeout);
     97     }
     98 
     99     public HttpTransportSE(Proxy proxy, String url, int timeout, int contentLength) {
    100         super(proxy, url, timeout);
    101     }
    102 
    103     /**
    104      * set the desired soapAction header field
    105      *
    106      * @param soapAction
    107      *            the desired soapAction
    108      * @param envelope
    109      *            the envelope containing the information for the soap call.
    110      * @throws IOException
    111      * @throws XmlPullParserException
    112      */
    113     public void call(String soapAction, SoapEnvelope envelope) throws IOException,
    114             XmlPullParserException {
    115 
    116         call(soapAction, envelope, null);
    117     }
    118 
    119     /**
    120      *
    121      * set the desired soapAction header field
    122      *
    123      * @param soapAction
    124      *            the desired soapAction
    125      * @param envelope
    126      *            the envelope containing the information for the soap call.
    127      * @param headers
    128      *              a list of HeaderProperties to be http header properties when establishing the connection
    129      *
    130      * @return <code>CookieJar</code> with any cookies sent by the server
    131      * @throws IOException
    132      * @throws XmlPullParserException
    133      */
    134     public List call(String soapAction, SoapEnvelope envelope, List headers)
    135             throws IOException, XmlPullParserException {
    136 
    137         if (soapAction == null) {
    138             soapAction = "\"\"";
    139         }
    140 
    141         System.out.println("call action:" + soapAction);
    142         byte[] requestData = createRequestData(envelope, "UTF-8");
    143 
    144         if (requestData != null) {
    145             requestDump = debug ? new String(requestData) : null;
    146         }
    147         else {
    148             requestDump = null;
    149         }
    150         responseDump = null;
    151 
    152         System.out.println("requestDump:" + requestDump);
    153         ServiceConnection connection = getServiceConnection();
    154         System.out.println("connection:" + connection);
    155 
    156         connection.setRequestProperty("User-Agent", USER_AGENT);
    157         // SOAPAction is not a valid header for VER12 so do not add
    158         // it
    159         // @see "http://code.google.com/p/ksoap2-android/issues/detail?id=67
    160         System.out.println("envelope:" + envelope);
    161         if (envelope != null) {
    162             if (envelope.version != SoapSerializationEnvelope.VER12) {
    163                 connection.setRequestProperty("SOAPAction", soapAction);
    164             }
    165 
    166             if (envelope.version == SoapSerializationEnvelope.VER12) {
    167                 connection.setRequestProperty("Content-Type", CONTENT_TYPE_SOAP_XML_CHARSET_UTF_8);
    168             } else {
    169                 connection.setRequestProperty("Content-Type", CONTENT_TYPE_XML_CHARSET_UTF_8);
    170             }
    171 
    172             connection.setRequestProperty("Connection", "close");
    173             connection.setRequestProperty("Accept-Encoding", "gzip");
    174             connection.setRequestProperty("Content-Length", "" + requestData.length);
    175 
    176             //M: Retry for HTTP Authentication
    177             //connection.setFixedLengthStreamingMode(requestData.length);
    178 
    179             // Pass the headers provided by the user along with the call
    180             if (headers != null) {
    181                 for (int i = 0; i < headers.size(); i++) {
    182                     HeaderProperty hp = (HeaderProperty) headers.get(i);
    183                     connection.setRequestProperty(hp.getKey(), hp.getValue());
    184                 }
    185             }
    186 
    187             connection.setRequestMethod("POST");
    188 
    189         }
    190         else {
    191             connection.setRequestProperty("Connection", "close");
    192             connection.setRequestProperty("Accept-Encoding", "gzip");
    193             connection.setRequestMethod("GET");
    194         }
    195 
    196         if (requestData != null) {
    197             OutputStream os = connection.openOutputStream();
    198 
    199             os.write(requestData, 0, requestData.length);
    200             os.flush();
    201             os.close();
    202             requestData = null;
    203         }
    204         InputStream is;
    205         List retHeaders = null;
    206         boolean gZippedContent = false;
    207         boolean bcaCert = false;
    208 
    209         try {
    210             retHeaders = connection.getResponseProperties();
    211             System.out.println("[HttpTransportSE] retHeaders = " + retHeaders);
    212             for (int i = 0; i < retHeaders.size(); i++) {
    213                 HeaderProperty hp = (HeaderProperty) retHeaders.get(i);
    214                 // HTTP response code has null key
    215                 if (null == hp.getKey()) {
    216                     continue;
    217                 }
    218                 // ignoring case since users found that all smaller case is used on some server
    219                 // and even if it is wrong according to spec, we rather have it work..
    220                 if (hp.getKey().equalsIgnoreCase("Content-Encoding")
    221                         && hp.getValue().equalsIgnoreCase("gzip")) {
    222                     gZippedContent = true;
    223                 }
    224             }
    225             if (gZippedContent) {
    226                 is = getUnZippedInputStream(connection.openInputStream());
    227             } else {
    228                 is = connection.openInputStream();
    229             }
    230         } catch (IOException e) {
    231             if (gZippedContent) {
    232                 is = getUnZippedInputStream(connection.getErrorStream());
    233             } else {
    234                 is = connection.getErrorStream();
    235             }
    236 
    237             if (is == null) {
    238                 connection.disconnect();
    239                 throw (e);
    240             }
    241         }
    242 
    243         if (debug) {
    244             ByteArrayOutputStream bos = new ByteArrayOutputStream();
    245             byte[] buf = new byte[8192];
    246 
    247             while (true) {
    248                 int rd = is.read(buf, 0, 8192);
    249                 if (rd == -1) {
    250                     break;
    251                 }
    252                 bos.write(buf, 0, rd);
    253             }
    254 
    255             bos.flush();
    256             buf = bos.toByteArray();
    257 
    258             responseDump = new String(buf);
    259 
    260             System.out.println("responseDump:" + responseDump);
    261             is.close();
    262             is = new ByteArrayInputStream(buf);
    263         }
    264 
    265         if (envelope != null) {
    266             parseResponse(envelope, is);
    267         }
    268 
    269         return retHeaders;
    270     }
    271 
    272     private InputStream getUnZippedInputStream(InputStream inputStream) throws IOException {
    273         /* workaround for Android 2.3
    274            (see http://stackoverflow.com/questions/5131016/)
    275         */
    276         try {
    277             return (GZIPInputStream) inputStream;
    278         } catch (ClassCastException e) {
    279             return new GZIPInputStream(inputStream);
    280         }
    281     }
    282 
    283     public ServiceConnection getServiceConnection() throws IOException {
    284         if (serviceConnection == null) {
    285             System.out.println("new ServiceConnectionSE:" + proxy + " " + url + " " + timeout);
    286             serviceConnection = new ServiceConnectionSE(proxy, url, timeout);
    287         }
    288         return serviceConnection;
    289     }
    290 
    291     public String getHost() {
    292 
    293         String retVal = null;
    294 
    295         try {
    296             retVal = new URL(url).getHost();
    297         } catch (MalformedURLException e) {
    298             e.printStackTrace();
    299         }
    300 
    301         return retVal;
    302     }
    303 
    304     public int getPort() {
    305 
    306         int retVal = -1;
    307 
    308         try {
    309             retVal = new URL(url).getPort();
    310         } catch (MalformedURLException e) {
    311             e.printStackTrace();
    312         }
    313 
    314         return retVal;
    315     }
    316 
    317     public String getPath() {
    318 
    319         String retVal = null;
    320 
    321         try {
    322             retVal = new URL(url).getPath();
    323         } catch (MalformedURLException e) {
    324             e.printStackTrace();
    325         }
    326 
    327         return retVal;
    328     }
    329 
    330     public String getQuery() {
    331 
    332         String retVal = null;
    333 
    334         try {
    335             retVal = new URL(url).getQuery();
    336         } catch (MalformedURLException e) {
    337             e.printStackTrace();
    338         }
    339 
    340         return retVal;
    341     }
    342 
    343     /**
    344      * @hide
    345      */
    346     public byte[] getRequestData(SoapEnvelope envelope, String encoding) {
    347         try {
    348             return createRequestData(envelope, encoding);
    349         } catch (Exception e) {
    350             e.printStackTrace();
    351         }
    352 
    353         return null;
    354     }
    355 }
    356