Package com.noelios.restlet.http

Source Code of com.noelios.restlet.http.HttpServerConverter

/*
* 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.http;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;

import org.restlet.Context;
import org.restlet.data.CookieSetting;
import org.restlet.data.Dimension;
import org.restlet.data.Encoding;
import org.restlet.data.Method;
import org.restlet.data.Parameter;
import org.restlet.data.Status;
import org.restlet.resource.Representation;
import org.restlet.util.DateUtils;
import org.restlet.util.Series;

import com.noelios.restlet.util.CookieUtils;
import com.noelios.restlet.util.SecurityUtils;

/**
* Converter of low-level HTTP server calls into high-level uniform calls.
*
* @author Jerome Louvel (contact@noelios.com)
*/
public class HttpServerConverter extends HttpConverter {
    /**
     * Constructor.
     *
     * @param context
     *            The client context.
     */
    public HttpServerConverter(Context context) {
        super(context);
    }

    /**
     * Converts a low-level HTTP call into a high-level uniform request.
     *
     * @param httpCall
     *            The low-level HTTP call.
     * @return A new high-level uniform request.
     */
    public HttpRequest toRequest(HttpServerCall httpCall) {
        HttpRequest result = new HttpRequest(getContext(), httpCall);
        result.getAttributes().put(HttpConstants.ATTRIBUTE_HEADERS,
                httpCall.getRequestHeaders());

        if (httpCall.getVersion() != null) {
            result.getAttributes().put(HttpConstants.ATTRIBUTE_VERSION,
                    httpCall.getVersion());
        }

        return result;
    }

    /**
     * Commits the changes to a handled uniform call back into the original HTTP
     * call. The default implementation first invokes the "addResponseHeaders"
     * then asks the "htppCall" to send the response back to the client.
     *
     * @param response
     *            The high-level response.
     */
    public void commit(HttpResponse response) {
        try {
            // Add the response headers
            addResponseHeaders(response);

            // Send the response to the client
            response.getHttpCall().sendResponse(response);
        } catch (Exception e) {
            getLogger().log(Level.INFO, "Exception intercepted", e);
            response.getHttpCall().setStatusCode(Status.SERVER_ERROR_INTERNAL.getCode());
            response.getHttpCall().setReasonPhrase(
                    "An unexpected exception occured");
        }
    }

    /**
     * Adds the response headers for the handled uniform call.
     *
     * @param response
     *            The response returned.
     */
    @SuppressWarnings("unchecked")
    protected void addResponseHeaders(HttpResponse response) {
        try {
            // Add all the necessary response headers
            Series<Parameter> responseHeaders = response.getHttpCall()
                    .getResponseHeaders();

            if (response.getStatus().equals(
                    Status.CLIENT_ERROR_METHOD_NOT_ALLOWED)) {
                // Format the "Allow" header
                StringBuilder sb = new StringBuilder();
                boolean first = true;
                for (Method method : response.getAllowedMethods()) {
                    if (first) {
                        first = false;
                    } else {
                        sb.append(", ");
                    }

                    sb.append(method.getName());
                }

                responseHeaders.add(HttpConstants.HEADER_ALLOW, sb.toString());
            }

            // Add the date
            responseHeaders.add(HttpConstants.HEADER_DATE, DateUtils.format(
                    new Date(), DateUtils.FORMAT_RFC_1123.get(0)));

            // Add the cookie settings
            List<CookieSetting> cookies = response.getCookieSettings();
            for (int i = 0; i < cookies.size(); i++) {
                responseHeaders.add(HttpConstants.HEADER_SET_COOKIE,
                        CookieUtils.format(cookies.get(i)));
            }

            // Set the redirection URI
            if (response.getRedirectRef() != null) {
                responseHeaders.add(HttpConstants.HEADER_LOCATION, response
                        .getRedirectRef().toString());
            }

            // Set the security data
            if (response.getChallengeRequest() != null) {
                responseHeaders.add(HttpConstants.HEADER_WWW_AUTHENTICATE,
                        SecurityUtils.format(response.getChallengeRequest()));
            }

            // Set the server name again
            response.getHttpCall().getResponseHeaders().add(
                    HttpConstants.HEADER_SERVER,
                    response.getServerInfo().getAgent());

            // Set the status code in the response
            if (response.getStatus() != null) {
                response.getHttpCall().setStatusCode(
                        response.getStatus().getCode());
                response.getHttpCall().setReasonPhrase(
                        response.getStatus().getDescription());
            }

            // If an entity was set during the call, copy it to the output
            // stream;
            if (response.getEntity() != null) {
                Representation entity = response.getEntity();

                if (entity.getExpirationDate() != null) {
                    responseHeaders.add(HttpConstants.HEADER_EXPIRES, response
                            .getHttpCall().formatDate(
                                    entity.getExpirationDate(), false));
                }

                if (!entity.getEncodings().isEmpty()) {
                    StringBuilder value = new StringBuilder();
                    for (Encoding encoding : entity.getEncodings()) {
                        if (!encoding.equals(Encoding.IDENTITY)) {
                            if (value.length() > 0)
                                value.append(", ");
                            value.append(encoding.getName());
                        }
                        responseHeaders.add(
                                HttpConstants.HEADER_CONTENT_ENCODING, value
                                        .toString());
                    }
                }

                if (!entity.getLanguages().isEmpty()) {
                    StringBuilder value = new StringBuilder();
                    for (int i = 0; i < entity.getLanguages().size(); i++) {
                        if (i > 0)
                            value.append(", ");
                        value.append(entity.getLanguages().get(i).getName());
                    }
                    responseHeaders.add(HttpConstants.HEADER_CONTENT_LANGUAGE,
                            value.toString());
                }

                if (entity.getMediaType() != null) {
                    StringBuilder contentType = new StringBuilder(entity
                            .getMediaType().getName());

                    if (entity.getCharacterSet() != null) {
                        // Specify the character set parameter
                        contentType.append("; charset=").append(
                                entity.getCharacterSet().getName());
                    }

                    responseHeaders.add(HttpConstants.HEADER_CONTENT_TYPE,
                            contentType.toString());
                }

                if (entity.getModificationDate() != null) {
                    responseHeaders.add(HttpConstants.HEADER_LAST_MODIFIED,
                            response.getHttpCall().formatDate(
                                    entity.getModificationDate(), false));
                }

                if (entity.getTag() != null) {
                    responseHeaders.add(HttpConstants.HEADER_ETAG, entity
                            .getTag().format());
                }

                if (response.getEntity().getSize() != Representation.UNKNOWN_SIZE) {
                    responseHeaders.add(HttpConstants.HEADER_CONTENT_LENGTH,
                            Long.toString(response.getEntity().getSize()));
                }

                if (response.getEntity().getIdentifier() != null) {
                    responseHeaders.add(HttpConstants.HEADER_CONTENT_LOCATION,
                            response.getEntity().getIdentifier().toString());
                }
            }

            // Send the Vary header only to none-MSIE user agents as MSIE seems
            // to support partially and badly this header (cf issue 261).
            if (!(response.getRequest().getClientInfo().getAgent() != null && response
                    .getRequest().getClientInfo().getAgent().contains("MSIE"))) {
                // Add the Vary header if content negotiation was used
                Set<Dimension> dimensions = response.getDimensions();
                if (!dimensions.isEmpty()) {
                    StringBuilder sb = new StringBuilder();
                    boolean first = true;

                    if (dimensions.contains(Dimension.CLIENT_ADDRESS)
                            || dimensions.contains(Dimension.TIME)
                            || dimensions.contains(Dimension.UNSPECIFIED)) {
                        // From an HTTP point of view the representations can
                        // vary in unspecified ways
                        responseHeaders.add(HttpConstants.HEADER_VARY, "*");
                    } else {
                        for (Dimension dim : response.getDimensions()) {
                            if (first) {
                                first = false;
                            } else {
                                sb.append(", ");
                            }

                            if (dim == Dimension.CHARACTER_SET) {
                                sb.append(HttpConstants.HEADER_ACCEPT_CHARSET);
                            } else if (dim == Dimension.CLIENT_AGENT) {
                                sb.append(HttpConstants.HEADER_USER_AGENT);
                            } else if (dim == Dimension.ENCODING) {
                                sb.append(HttpConstants.HEADER_ACCEPT_ENCODING);
                            } else if (dim == Dimension.LANGUAGE) {
                                sb.append(HttpConstants.HEADER_ACCEPT_LANGUAGE);
                            } else if (dim == Dimension.MEDIA_TYPE) {
                                sb.append(HttpConstants.HEADER_ACCEPT);
                            }
                        }

                        responseHeaders.add(HttpConstants.HEADER_VARY, sb
                                .toString());
                    }
                }
            }

            // Add user-defined extension headers
            Series<Parameter> additionalHeaders = (Series<Parameter>) response
                    .getAttributes().get(HttpConstants.ATTRIBUTE_HEADERS);
            addAdditionalHeaders(responseHeaders, additionalHeaders);
        } catch (Exception e) {
            getLogger().log(Level.INFO,
                    "Exception intercepted while adding the response headers",
                    e);
            response.getHttpCall().setStatusCode(
                    Status.SERVER_ERROR_INTERNAL.getCode());
            response.getHttpCall().setReasonPhrase(
                    Status.SERVER_ERROR_INTERNAL.getDescription());
        }
    }
}
TOP

Related Classes of com.noelios.restlet.http.HttpServerConverter

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.