XmlRpcLiteHttpTransport.java
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one
00003  * or more contributor license agreements.  See the NOTICE file
00004  * distributed with this work for additional information
00005  * regarding copyright ownership.  The ASF licenses this file
00006  * to you under the Apache License, Version 2.0 (the
00007  * "License"); you may not use this file except in compliance
00008  * with the License.  You may obtain a copy of the License at
00009  *
00010  *   http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing,
00013  * software distributed under the License is distributed on an
00014  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
00015  * KIND, either express or implied.  See the License for the
00016  * specific language governing permissions and limitations
00017  * under the License.    
00018  */
00019 package org.apache.xmlrpc.client;
00020 
00021 import java.io.BufferedInputStream;
00022 import java.io.BufferedOutputStream;
00023 import java.io.IOException;
00024 import java.io.InputStream;
00025 import java.io.OutputStream;
00026 import java.io.UnsupportedEncodingException;
00027 import java.net.ConnectException;
00028 import java.net.Socket;
00029 import java.net.URL;
00030 import java.net.UnknownHostException;
00031 import java.util.ArrayList;
00032 import java.util.HashMap;
00033 import java.util.Iterator;
00034 import java.util.List;
00035 import java.util.Map;
00036 import java.util.StringTokenizer;
00037 
00038 import org.apache.xmlrpc.XmlRpcException;
00039 import org.apache.xmlrpc.XmlRpcRequest;
00040 import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
00041 import org.apache.xmlrpc.util.HttpUtil;
00042 import org.apache.xmlrpc.util.LimitedInputStream;
00043 import org.xml.sax.SAXException;
00044 
00045 
00049 public class XmlRpcLiteHttpTransport extends XmlRpcHttpTransport {
00050         private static final String userAgent = USER_AGENT + " (Lite HTTP Transport)";
00051         private boolean ssl;
00052         private String hostname;
00053         private String host;
00054         private int port;
00055         private String uri;
00056         private Socket socket;
00057         private OutputStream output;
00058         private InputStream input;
00059         private final Map headers = new HashMap();
00060         private boolean responseGzipCompressed = false;
00061         private XmlRpcHttpClientConfig config;
00062 
00067         public XmlRpcLiteHttpTransport(XmlRpcClient pClient) {
00068                 super(pClient, userAgent);
00069         }
00070 
00071         public Object sendRequest(XmlRpcRequest pRequest) throws XmlRpcException {
00072                 config = (XmlRpcHttpClientConfig) pRequest.getConfig();
00073                 URL url = config.getServerURL();
00074                 ssl = "https".equals(url.getProtocol());
00075                 hostname = url.getHost();
00076         int p = url.getPort();
00077                 port = p < 1 ? 80 : p;
00078                 String u = url.getFile();
00079                 uri = (u == null  ||  "".equals(u)) ? "/" : u;
00080                 host = port == 80 ? hostname : hostname + ":" + port;
00081                 headers.put("Host", host);
00082                 return super.sendRequest(pRequest);
00083         }
00084 
00085         protected void setRequestHeader(String pHeader, String pValue) {
00086                 Object value = headers.get(pHeader);
00087                 if (value == null) {
00088                         headers.put(pHeader, pValue);
00089                 } else {
00090                         List list;
00091                         if (value instanceof String) {
00092                                 list = new ArrayList();
00093                                 list.add(value);
00094                                 headers.put(pHeader, list);
00095                         } else {
00096                                 list = (List) value;
00097                         }
00098                         list.add(pValue);
00099                 }
00100         }
00101 
00102         protected void close() throws XmlRpcClientException {
00103                 IOException e = null;
00104                 if (input != null) {
00105                         try {
00106                                 input.close();
00107                         } catch (IOException ex) {
00108                                 e = ex;
00109                         }
00110                 }
00111                 if (output != null) {
00112                         try {
00113                                 output.close();
00114                         } catch (IOException ex) {
00115                                 if (e != null) {
00116                                         e = ex;
00117                                 }
00118                         }
00119                 }
00120                 if (socket != null) {
00121                         try {
00122                                 socket.close();
00123                         } catch (IOException ex) {
00124                                 if (e != null) {
00125                                         e = ex;
00126                                 }
00127                         }
00128                 }
00129                 if (e != null) {
00130                         throw new XmlRpcClientException("Failed to close connection: " + e.getMessage(), e);
00131                 }
00132         }
00133 
00134         private OutputStream getOutputStream() throws XmlRpcException {
00135                 try {
00136                         final int retries = 3;
00137                 final int delayMillis = 100;
00138         
00139                         for (int tries = 0;  ;  tries++) {
00140                                 try {
00141                                         socket = newSocket(ssl, hostname, port);
00142                                         output = new BufferedOutputStream(socket.getOutputStream()){
00148                                                 public void close() throws IOException {
00149                                                         flush();
00150                                                         socket.shutdownOutput();
00151                                                 }
00152                                         };
00153                                         break;
00154                                 } catch (ConnectException e) {
00155                                         if (tries >= retries) {
00156                                                 throw new XmlRpcException("Failed to connect to "
00157                                                                 + hostname + ":" + port + ": " + e.getMessage(), e);
00158                                         } else {
00159                             try {
00160                                 Thread.sleep(delayMillis);
00161                             } catch (InterruptedException ignore) {
00162                             }
00163                                         }
00164                                 }
00165                         }
00166                         sendRequestHeaders(output);
00167                         return output;
00168                 } catch (IOException e) {
00169                         throw new XmlRpcException("Failed to open connection to "
00170                                         + hostname + ":" + port + ": " + e.getMessage(), e);
00171                 }
00172         }
00173 
00174     protected Socket newSocket(boolean pSSL, String pHostName, int pPort) throws UnknownHostException, IOException {
00175         if (pSSL) {
00176             throw new IOException("Unable to create SSL connections, use the XmlRpcLite14HttpTransportFactory.");
00177         }
00178         return new Socket(pHostName, pPort);
00179     }
00180 
00181         private byte[] toHTTPBytes(String pValue) throws UnsupportedEncodingException {
00182                 return pValue.getBytes("US-ASCII");
00183         }
00184 
00185         private void sendHeader(OutputStream pOut, String pKey, String pValue) throws IOException {
00186                 pOut.write(toHTTPBytes(pKey + ": " + pValue + "\r\n"));
00187         }
00188 
00189         private void sendRequestHeaders(OutputStream pOut) throws IOException {
00190                 pOut.write(("POST " + uri + " HTTP/1.0\r\n").getBytes("US-ASCII"));
00191                 for (Iterator iter = headers.entrySet().iterator();  iter.hasNext();  ) {
00192                         Map.Entry entry = (Map.Entry) iter.next();
00193                         String key = (String) entry.getKey();
00194                         Object value = entry.getValue();
00195                         if (value instanceof String) {
00196                                 sendHeader(pOut, key, (String) value);
00197                         } else {
00198                                 List list = (List) value;
00199                                 for (int i = 0;  i < list.size();  i++) {
00200                                         sendHeader(pOut, key, (String) list.get(i));
00201                                 }
00202                         }
00203                 }
00204                 pOut.write(toHTTPBytes("\r\n"));
00205         }
00206 
00207         protected boolean isResponseGzipCompressed(XmlRpcStreamRequestConfig pConfig) {
00208                 return responseGzipCompressed;
00209         }
00210 
00211         protected InputStream getInputStream() throws XmlRpcException {
00212                 final byte[] buffer = new byte[2048];
00213                 try {
00214             // If reply timeout specified, set the socket timeout accordingly
00215             if (config.getReplyTimeout() != 0)
00216                 socket.setSoTimeout(config.getReplyTimeout());
00217             input = new BufferedInputStream(socket.getInputStream());
00218                         // start reading  server response headers
00219                         String line = HttpUtil.readLine(input, buffer);
00220                         StringTokenizer tokens = new StringTokenizer(line);
00221                         tokens.nextToken(); // Skip HTTP version
00222                         String statusCode = tokens.nextToken();
00223                         String statusMsg = tokens.nextToken("\n\r");
00224                         final int code;
00225                         try {
00226                             code = Integer.parseInt(statusCode);
00227                         } catch (NumberFormatException e) {
00228                 throw new XmlRpcClientException("Server returned invalid status code: "
00229                         + statusCode + " " + statusMsg, null);
00230                         }
00231                         if (code < 200  ||  code > 299) {
00232                         throw new XmlRpcHttpTransportException(code, statusMsg);
00233                     }
00234                         int contentLength = -1;
00235                         for (;;) {
00236                                 line = HttpUtil.readLine(input, buffer);
00237                                 if (line == null  ||  "".equals(line)) {
00238                                         break;
00239                                 }
00240                                 line = line.toLowerCase();
00241                                 if (line.startsWith("content-length:")) {
00242                                         contentLength = Integer.parseInt(line.substring("content-length:".length()).trim());
00243                                 } else if (line.startsWith("content-encoding:")) {
00244                                         responseGzipCompressed = HttpUtil.isUsingGzipEncoding(line.substring("content-encoding:".length()));
00245                                 }
00246                         }
00247                         InputStream result;
00248                         if (contentLength == -1) {
00249                                 result = input;
00250                         } else {
00251                                 result = new LimitedInputStream(input, contentLength);
00252                         }
00253                         return result;
00254                 } catch (IOException e) {
00255                         throw new XmlRpcClientException("Failed to read server response: " + e.getMessage(), e);
00256                 }
00257         }
00258 
00259         protected boolean isUsingByteArrayOutput(XmlRpcHttpClientConfig pConfig) {
00260             boolean result = super.isUsingByteArrayOutput(pConfig);
00261         if (!result) {
00262             throw new IllegalStateException("The Content-Length header is required with HTTP/1.0, and HTTP/1.1 is unsupported by the Lite HTTP Transport.");
00263         }
00264         return result;
00265     }
00266 
00267     protected void writeRequest(ReqWriter pWriter) throws XmlRpcException, IOException, SAXException {
00268         pWriter.write(getOutputStream());
00269         }
00270 }


rosjava_core
Author(s):
autogenerated on Wed Aug 26 2015 16:06:49