All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javaz.xmlrpc.XmlRpcHttpClient4Transport Maven / Gradle / Ivy

The newest version!
package org.javaz.xmlrpc;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.XmlRpcRequest;
import org.apache.xmlrpc.client.XmlRpcClientException;
import org.apache.xmlrpc.client.XmlRpcHttpClientConfig;
import org.apache.xmlrpc.client.XmlRpcHttpTransport;
import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
import org.apache.xmlrpc.util.HttpUtil;
import org.apache.xmlrpc.util.XmlRpcIOException;
import org.javaz.easyssl.UrlFetcher;
import org.xml.sax.SAXException;

public class XmlRpcHttpClient4Transport extends XmlRpcHttpTransport
{

    private static final int MAX_REDIRECT_ATTEMPTS = 10;
    private HttpClient client;
    private static final String userAgent = USER_AGENT + " (HC 4)";
    private HttpPost method;
    private int contentLength = -1;
    private HttpResponse httpResponse;

    public XmlRpcHttpClient4Transport(XmlRpcHttpClient4TransportFactory pFactory)
    {
        super(pFactory.getClient(), userAgent);
        client = pFactory.getHttpClient();
        if (client == null)
        {
            client = new DefaultHttpClient();
        }
    }

    @Override
    protected void setContentLength(int pLength)
    {
        contentLength = pLength;
    }

    @Override
    protected void initHttpHeaders(XmlRpcRequest pRequest) throws XmlRpcClientException
    {

        XmlRpcHttpClientConfig config = (XmlRpcHttpClientConfig) pRequest.getConfig();
        try
        {
            method = new HttpPost(config.getServerURL().toURI());
        }
        catch (URISyntaxException ex)
        {
            throw new XmlRpcClientException("", ex);
        }
        super.initHttpHeaders(pRequest);
    }

    @Override
    protected void setRequestHeader(String pHeader, String pValue)
    {
        method.setHeader(pHeader, pValue);
    }

    @Override
    protected void close() throws XmlRpcClientException
    {
        method.releaseConnection();
    }

    @Override
    protected boolean isResponseGzipCompressed(XmlRpcStreamRequestConfig pConfig)
    {
        Header[] headers = method.getHeaders("Content-Encoding");
        if (headers == null || headers.length < 1)
        {
            return false;
        }
        else
        {
            Header h = headers[0];
            return HttpUtil.isUsingGzipEncoding(h.getValue());
        }
    }

    @Override
    protected InputStream getInputStream() throws XmlRpcException
    {
        try
        {
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            // All status codes except SC_OK are handled as errors. Perhaps some should require special handling (e.g., SC_UNAUTHORIZED)
            if (statusCode < 200 || statusCode > 299)
            {
                throw new XmlRpcClientException("statusCode : " + statusCode, new Throwable(httpResponse.getStatusLine().getReasonPhrase()));
            }
            return httpResponse.getEntity().getContent();
        }
        catch (ClientProtocolException ex)
        {
            throw new XmlRpcClientException("", ex);
        }
        catch (IOException ex)
        {
            throw new XmlRpcClientException("", ex);
        }
    }

    @Override
    protected void writeRequest(final ReqWriter pWriter) throws XmlRpcException, IOException, SAXException
    {
        BasicHttpEntity entity = new BasicHttpEntity();


        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        pWriter.write(baos);

        BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(baos.toByteArray()));
        entity.setContent(bis);
        entity.setContentLength(contentLength);
        entity.setContentType("text/xml");
        method.setEntity(entity);
        try
        {
            int redirectAttempts = 0;
            for (; ; )
            {
                httpResponse = client.execute(method);
                if (!isRedirectRequired())
                {
                    break;
                }
                if (redirectAttempts++ > MAX_REDIRECT_ATTEMPTS)
                {
                    throw new XmlRpcException("Too many redirects.");
                }
                resetClientForRedirect();
            }
        }
        catch (XmlRpcIOException e)
        {
            Throwable t = e.getLinkedException();
            if (t instanceof XmlRpcException)
            {
                throw (XmlRpcException) t;
            }
            else
            {
                throw new XmlRpcException("Unexpected exception: " + t.getMessage(), t);
            }
        }
        catch (IOException e)
        {
            throw new XmlRpcException("I/O error while communicating with HTTP server: " + e.getMessage(), e);
        }
    }

    protected boolean isRedirectRequired()
    {
        switch (httpResponse.getStatusLine().getStatusCode())
        {
            case HttpStatus.SC_MOVED_TEMPORARILY:
            case HttpStatus.SC_MOVED_PERMANENTLY:
            case HttpStatus.SC_SEE_OTHER:
            case HttpStatus.SC_TEMPORARY_REDIRECT:
                return true;
            default:
                return false;
        }
    }

    protected void resetClientForRedirect() throws XmlRpcException
    {
        //get the location header to find out where to redirect to
        Header locationHeader = httpResponse.getFirstHeader("location");
        if (locationHeader == null)
        {
            throw new XmlRpcException("Invalid redirect: Missing location header");
        }
        String location = locationHeader.getValue();

        URI redirectUri = null;
        try
        {
            redirectUri = new URI(location);
            method.setURI(redirectUri);
        }
        catch (URISyntaxException ex)
        {
            throw new XmlRpcException("", ex);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy