Package com.noelios.restlet.ext.net

Source Code of com.noelios.restlet.ext.net.HttpUrlConnectionCall

/*
* Copyright 2005-2007 Noelios Consulting.
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License (the "License"). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* http://www.opensource.org/licenses/cddl1.txt See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each file and
* include the License file at http://www.opensource.org/licenses/cddl1.txt If
* applicable, add the following below this CDDL HEADER, with the fields
* enclosed by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*/

package com.noelios.restlet.ext.net;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.logging.Level;

import javax.net.ssl.HttpsURLConnection;

import org.restlet.data.Parameter;
import org.restlet.data.Request;
import org.restlet.data.Status;
import org.restlet.resource.Representation;
import org.restlet.util.Series;

import com.noelios.restlet.Engine;
import com.noelios.restlet.http.HttpClientCall;

/**
* HTTP client connector call based on JDK's java.net.HttpURLConnection class.
*
* @author Jerome Louvel (contact@noelios.com)
*/
public class HttpUrlConnectionCall extends HttpClientCall {
    /** The wrapped HTTP URL connection. */
    private HttpURLConnection connection;

    /** Indicates if the response headers were added. */
    private boolean responseHeadersAdded;

    /**
     * Constructor.
     *
     * @param helper
     *            The parent HTTP client helper.
     * @param method
     *            The method name.
     * @param requestUri
     *            The request URI.
     * @param hasEntity
     *            Indicates if the call will have an entity to send to the
     *            server.
     * @throws IOException
     */
    public HttpUrlConnectionCall(HttpClientHelper helper, String method,
            String requestUri, boolean hasEntity) throws IOException {
        super(helper, method, requestUri);

        if (requestUri.startsWith("http")) {
            URL url = new URL(requestUri);
            this.connection = (HttpURLConnection) url.openConnection();

            // These properties can only be used with Java 1.5 and upper
            // releases
            int majorVersionNumber = Engine.getJavaMajorVersion();
            int minorVersionNumber = Engine.getJavaMinorVersion();
            if ((majorVersionNumber > 1)
                    || (majorVersionNumber == 1 && minorVersionNumber >= 5)) {
                this.connection.setConnectTimeout(getHelper()
                        .getConnectTimeout());
                this.connection.setReadTimeout(getHelper().getReadTimeout());
            }

            this.connection.setAllowUserInteraction(getHelper()
                    .isAllowUserInteraction());
            this.connection.setDoOutput(hasEntity);
            this.connection.setInstanceFollowRedirects(getHelper()
                    .isFollowRedirects());
            this.connection.setUseCaches(getHelper().isUseCaches());
            this.responseHeadersAdded = false;
            setConfidential(this.connection instanceof HttpsURLConnection);
        } else {
            throw new IllegalArgumentException(
                    "Only HTTP or HTTPS resource URIs are allowed here");
        }
    }

    /**
     * Returns the HTTP client helper.
     *
     * @return The HTTP client helper.
     */
    public HttpClientHelper getHelper() {
        return (HttpClientHelper) super.getHelper();
    }

    /**
     * Returns the connection.
     *
     * @return The connection.
     */
    public HttpURLConnection getConnection() {
        return this.connection;
    }

    /**
     * Sends the request to the client. Commits the request line, headers and
     * optional entity and send them over the network.
     *
     * @param request
     *            The high-level request.
     * @return The result status.
     */
    public Status sendRequest(Request request) {
        Status result = null;

        try {
            if (request.isEntityAvailable()) {
                Representation entity = request.getEntity();

                // These properties can only be used with Java 1.5 and upper
                // releases
                int majorVersionNumber = Engine.getJavaMajorVersion();
                int minorVersionNumber = Engine.getJavaMinorVersion();
                if ((majorVersionNumber > 1)
                        || (majorVersionNumber == 1 && minorVersionNumber >= 5)) {
                    // Adjust the streaming mode
                    if (entity.getSize() > 0) {
                        // The size of the entity is known in advance
                        getConnection().setFixedLengthStreamingMode(
                                (int) entity.getSize());
                    } else {
                        // The size of the entity is not known in advance
                        if (getHelper().getChunkLength() >= 0) {
                            // Use chunked encoding
                            getConnection().setChunkedStreamingMode(
                                    getHelper().getChunkLength());
                        } else {
                            // Use entity buffering to determine the content
                            // length
                        }
                    }
                }
            }

            // Set the request method
            getConnection().setRequestMethod(getMethod());

            // Set the request headers
            for (Parameter header : getRequestHeaders()) {
                getConnection().addRequestProperty(header.getName(),
                        header.getValue());
            }

            // Ensure that the connections is active
            getConnection().connect();

            // Send the optional entity
            result = super.sendRequest(request);
        } catch (ConnectException ce) {
            getHelper()
                    .getLogger()
                    .log(
                            Level.FINE,
                            "An error occurred during the connection to the remote HTTP server.",
                            ce);
            result = new Status(Status.CONNECTOR_ERROR_CONNECTION,
                    "Unable to connect to the remote server. "
                            + ce.getMessage());
        } catch (SocketTimeoutException ste) {
            getHelper()
                    .getLogger()
                    .log(
                            Level.FINE,
                            "An timeout error occurred during the communication with the remote HTTP server.",
                            ste);
            result = new Status(Status.CONNECTOR_ERROR_COMMUNICATION,
                    "Unable to complete the HTTP call due to a communication timeout error. "
                            + ste.getMessage());
        } catch (FileNotFoundException fnfe) {
            getHelper()
                    .getLogger()
                    .log(
                            Level.FINE,
                            "An unexpected error occurred during the sending of the HTTP request.",
                            fnfe);
            result = new Status(Status.CONNECTOR_ERROR_INTERNAL,
                    "Unable to find a local file for sending. "
                            + fnfe.getMessage());
        } catch (IOException ioe) {
            getHelper()
                    .getLogger()
                    .log(
                            Level.FINE,
                            "An error occurred during the communication with the remote HTTP server.",
                            ioe);
            result = new Status(
                    Status.CONNECTOR_ERROR_COMMUNICATION,
                    "Unable to complete the HTTP call due to a communication error with the remote server. "
                            + ioe.getMessage());
        } catch (Exception e) {
            getHelper()
                    .getLogger()
                    .log(
                            Level.FINE,
                            "An unexpected error occurred during the sending of the HTTP request.",
                            e);
            result = new Status(Status.CONNECTOR_ERROR_INTERNAL,
                    "Unable to send the HTTP request. " + e.getMessage());
        }

        return result;
    }

    /**
     * Returns the request entity stream if it exists.
     *
     * @return The request entity stream if it exists.
     */
    public OutputStream getRequestStream() {
        try {
            return getConnection().getOutputStream();
        } catch (IOException ioe) {
            return null;
        }
    }

    /**
     * Returns the response address.<br/> Corresponds to the IP address of the
     * responding server.
     *
     * @return The response address.
     */
    public String getServerAddress() {
        return getConnection().getURL().getHost();
    }

    /**
     * Returns the modifiable list of response headers.
     *
     * @return The modifiable list of response headers.
     */
    public Series<Parameter> getResponseHeaders() {
        Series<Parameter> result = super.getResponseHeaders();

        if (!this.responseHeadersAdded) {
            // Read the response headers
            int i = 1;
            String headerName = getConnection().getHeaderFieldKey(i);
            String headerValue = getConnection().getHeaderField(i);
            while (headerName != null) {
                result.add(headerName, headerValue);
                i++;
                headerName = getConnection().getHeaderFieldKey(i);
                headerValue = getConnection().getHeaderField(i);
            }

            this.responseHeadersAdded = true;
        }

        return result;
    }

    /**
     * Returns the response status code.
     *
     * @return The response status code.
     * @throws IOException
     */
    public int getStatusCode() throws IOException {
        return getConnection().getResponseCode();
    }

    /**
     * Returns the response reason phrase.
     *
     * @return The response reason phrase.
     */
    public String getReasonPhrase() {
        try {
            return getConnection().getResponseMessage();
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * Returns the response stream if it exists.
     *
     * @return The response stream if it exists.
     */
    public InputStream getResponseStream() {
        InputStream result = null;

        try {
            result = getConnection().getInputStream();
        } catch (IOException ioe) {
            result = getConnection().getErrorStream();
        }

        if (result == null) {
            // Maybe an error stream is available instead
            result = getConnection().getErrorStream();
        }

        return result;
    }
}
TOP

Related Classes of com.noelios.restlet.ext.net.HttpUrlConnectionCall

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.