XmlRpcCommonsTransport.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.BufferedOutputStream;
00022 import java.io.FilterOutputStream;
00023 import java.io.IOException;
00024 import java.io.InputStream;
00025 import java.io.OutputStream;
00026 
00027 import org.apache.commons.httpclient.Credentials;
00028 import org.apache.commons.httpclient.Header;
00029 import org.apache.commons.httpclient.HttpClient;
00030 import org.apache.commons.httpclient.HttpException;
00031 import org.apache.commons.httpclient.HttpMethod;
00032 import org.apache.commons.httpclient.HttpStatus;
00033 import org.apache.commons.httpclient.HttpVersion;
00034 import org.apache.commons.httpclient.URI;
00035 import org.apache.commons.httpclient.URIException;
00036 import org.apache.commons.httpclient.UsernamePasswordCredentials;
00037 import org.apache.commons.httpclient.auth.AuthScope;
00038 import org.apache.commons.httpclient.methods.PostMethod;
00039 import org.apache.commons.httpclient.methods.RequestEntity;
00040 import org.apache.commons.httpclient.params.HttpMethodParams;
00041 import org.apache.xmlrpc.XmlRpcException;
00042 import org.apache.xmlrpc.XmlRpcRequest;
00043 import org.apache.xmlrpc.common.XmlRpcStreamConfig;
00044 import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
00045 import org.apache.xmlrpc.util.HttpUtil;
00046 import org.apache.xmlrpc.util.XmlRpcIOException;
00047 import org.xml.sax.SAXException;
00048 
00049 
00053 public class XmlRpcCommonsTransport extends XmlRpcHttpTransport {
00057     private static final int MAX_REDIRECT_ATTEMPTS = 100;
00058 
00059     protected final HttpClient client;
00060         private static final String userAgent = USER_AGENT + " (Jakarta Commons httpclient Transport)";
00061         protected PostMethod method;
00062         private int contentLength = -1;
00063         private XmlRpcHttpClientConfig config;      
00064 
00068         public XmlRpcCommonsTransport(XmlRpcCommonsTransportFactory pFactory) {
00069                 super(pFactory.getClient(), userAgent);
00070         HttpClient httpClient = pFactory.getHttpClient();
00071         if (httpClient == null) {
00072             httpClient = newHttpClient();
00073         }
00074         client = httpClient;
00075      }
00076 
00077         protected void setContentLength(int pLength) {
00078                 contentLength = pLength;
00079         }
00080 
00081     protected HttpClient newHttpClient() {
00082         return new HttpClient();
00083     }
00084 
00085     protected void initHttpHeaders(XmlRpcRequest pRequest) throws XmlRpcClientException {
00086         config = (XmlRpcHttpClientConfig) pRequest.getConfig();
00087         method = newPostMethod(config);
00088         super.initHttpHeaders(pRequest);
00089         
00090         if (config.getConnectionTimeout() != 0)
00091             client.getHttpConnectionManager().getParams().setConnectionTimeout(config.getConnectionTimeout());
00092         
00093         if (config.getReplyTimeout() != 0)
00094             client.getHttpConnectionManager().getParams().setSoTimeout(config.getReplyTimeout());
00095         
00096         method.getParams().setVersion(HttpVersion.HTTP_1_1);
00097     }
00098 
00099     protected PostMethod newPostMethod(XmlRpcHttpClientConfig pConfig) {
00100         return new PostMethod(pConfig.getServerURL().toString());
00101     }
00102 
00103         protected void setRequestHeader(String pHeader, String pValue) {
00104                 method.setRequestHeader(new Header(pHeader, pValue));
00105         }
00106 
00107         protected boolean isResponseGzipCompressed() {
00108                 Header h = method.getResponseHeader( "Content-Encoding" );
00109                 if (h == null) {
00110                         return false;
00111                 } else {
00112                         return HttpUtil.isUsingGzipEncoding(h.getValue());
00113                 }
00114         }
00115 
00116         protected InputStream getInputStream() throws XmlRpcException {
00117         try {
00118             checkStatus(method);
00119             return method.getResponseBodyAsStream();
00120                 } catch (HttpException e) {
00121                         throw new XmlRpcClientException("Error in HTTP transport: " + e.getMessage(), e);
00122                 } catch (IOException e) {
00123                         throw new XmlRpcClientException("I/O error in server communication: " + e.getMessage(), e);
00124                 }
00125         }
00126 
00127         protected void setCredentials(XmlRpcHttpClientConfig pConfig) throws XmlRpcClientException {
00128                 String userName = pConfig.getBasicUserName();
00129                 if (userName != null) {
00130             String enc = pConfig.getBasicEncoding();
00131             if (enc == null) {
00132                 enc = XmlRpcStreamConfig.UTF8_ENCODING;
00133             }
00134             client.getParams().setParameter(HttpMethodParams.CREDENTIAL_CHARSET, enc);
00135                         Credentials creds = new UsernamePasswordCredentials(userName, pConfig.getBasicPassword());
00136                         AuthScope scope = new AuthScope(null, AuthScope.ANY_PORT, null, AuthScope.ANY_SCHEME);
00137                         client.getState().setCredentials(scope, creds);
00138             client.getParams().setAuthenticationPreemptive(true);
00139         }
00140         }
00141 
00142         protected void close() throws XmlRpcClientException {
00143                 method.releaseConnection();
00144         }
00145 
00146         protected boolean isResponseGzipCompressed(XmlRpcStreamRequestConfig pConfig) {
00147                 Header h = method.getResponseHeader( "Content-Encoding" );
00148                 if (h == null) {
00149                         return false;
00150                 } else {
00151                         return HttpUtil.isUsingGzipEncoding(h.getValue());
00152                 }
00153         }
00154 
00155         protected boolean isRedirectRequired() {
00156             switch (method.getStatusCode()) {
00157                 case HttpStatus.SC_MOVED_TEMPORARILY:
00158                 case HttpStatus.SC_MOVED_PERMANENTLY:
00159                 case HttpStatus.SC_SEE_OTHER:
00160                 case HttpStatus.SC_TEMPORARY_REDIRECT:
00161                     return true;
00162                 default:
00163                     return false;
00164             }
00165         }
00166 
00167         protected void resetClientForRedirect()
00168             throws XmlRpcException {
00169             //get the location header to find out where to redirect to
00170             Header locationHeader = method.getResponseHeader("location");
00171             if (locationHeader == null) {
00172             throw new XmlRpcException("Invalid redirect: Missing location header");
00173             }
00174             String location = locationHeader.getValue();
00175 
00176             URI redirectUri = null;
00177             URI currentUri = null;
00178             try {
00179                 currentUri = method.getURI();
00180                 String charset = currentUri.getProtocolCharset();
00181                 redirectUri = new URI(location, true, charset);
00182                 method.setURI(redirectUri);
00183             } catch (URIException ex) {
00184             throw new XmlRpcException(ex.getMessage(), ex);
00185             }
00186 
00187             //And finally invalidate the actual authentication scheme
00188             method.getHostAuthState().invalidate();
00189     }
00190 
00191     protected void writeRequest(final ReqWriter pWriter) throws XmlRpcException {
00192                 method.setRequestEntity(new RequestEntity(){
00193                         public boolean isRepeatable() { return true; }
00194                         public void writeRequest(OutputStream pOut) throws IOException {
00195                                 try {
00196                     /* Make sure, that the socket is not closed by replacing it with our
00197                      * own BufferedOutputStream.
00198                      */
00199                     OutputStream ostream;
00200                     if (isUsingByteArrayOutput(config)) {
00201                         // No need to buffer the output.
00202                         ostream = new FilterOutputStream(pOut){
00203                             public void close() throws IOException {
00204                                 flush();
00205                             }
00206                         };
00207                     } else {
00208                         ostream = new BufferedOutputStream(pOut){
00209                             public void close() throws IOException {
00210                                 flush();
00211                             }
00212                         };
00213                     }
00214                                         pWriter.write(ostream);
00215                                 } catch (XmlRpcException e) {
00216                                         throw new XmlRpcIOException(e);
00217                                 } catch (SAXException e) {
00218                     throw new XmlRpcIOException(e);
00219                 }
00220                         }
00221                         public long getContentLength() { return contentLength; }
00222                         public String getContentType() { return "text/xml"; }
00223                 });
00224                 try {
00225             int redirectAttempts = 0;
00226             for (;;) {
00227                         client.executeMethod(method);
00228                 if (!isRedirectRequired()) {
00229                     break;
00230                 }
00231                 if (redirectAttempts++ > MAX_REDIRECT_ATTEMPTS) {
00232                     throw new XmlRpcException("Too many redirects.");
00233                 }
00234                 resetClientForRedirect();
00235             }
00236                 } catch (XmlRpcIOException e) {
00237                         Throwable t = e.getLinkedException();
00238                         if (t instanceof XmlRpcException) {
00239                                 throw (XmlRpcException) t;
00240                         } else {
00241                                 throw new XmlRpcException("Unexpected exception: " + t.getMessage(), t);
00242                         }
00243                 } catch (IOException e) {
00244                         throw new XmlRpcException("I/O error while communicating with HTTP server: " + e.getMessage(), e);
00245                 }
00246         }
00247     
00254     private void checkStatus(HttpMethod pMethod) throws XmlRpcHttpTransportException {
00255         final int status = pMethod.getStatusCode();
00256         
00257         // All status codes except SC_OK are handled as errors. Perhaps some should require special handling (e.g., SC_UNAUTHORIZED)
00258         if (status < 200  ||  status > 299) {
00259             throw new XmlRpcHttpTransportException(status, pMethod.getStatusText());
00260         }
00261     }
00262 }


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