Package org.restlet.engine.adapter

Source Code of org.restlet.engine.adapter.HttpRequest

/**
* Copyright 2005-2011 Noelios Technologies.
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL 1.0 (the
* "Licenses"). You can select the license that you prefer but you may not use
* this file except in compliance with one of these Licenses.
*
* You can obtain a copy of the LGPL 3.0 license at
* http://www.opensource.org/licenses/lgpl-3.0.html
*
* You can obtain a copy of the LGPL 2.1 license at
* http://www.opensource.org/licenses/lgpl-2.1.php
*
* You can obtain a copy of the CDDL 1.0 license at
* http://www.opensource.org/licenses/cddl1.php
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://www.noelios.com/products/restlet-engine
*
* Restlet is a registered trademark of Noelios Technologies.
*/

package org.restlet.engine.adapter;

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

import org.restlet.Context;
import org.restlet.Request;
import org.restlet.data.CacheDirective;
import org.restlet.data.ChallengeResponse;
import org.restlet.data.ClientInfo;
import org.restlet.data.Conditions;
import org.restlet.data.Cookie;
import org.restlet.data.Method;
import org.restlet.data.Parameter;
import org.restlet.data.Range;
import org.restlet.data.RecipientInfo;
import org.restlet.data.Reference;
import org.restlet.data.Tag;
import org.restlet.data.Warning;
import org.restlet.engine.header.CacheDirectiveReader;
import org.restlet.engine.header.CookieReader;
import org.restlet.engine.header.ExpectationReader;
import org.restlet.engine.header.HeaderConstants;
import org.restlet.engine.header.HeaderReader;
import org.restlet.engine.header.PreferenceReader;
import org.restlet.engine.header.RangeReader;
import org.restlet.engine.header.RecipientInfoReader;
import org.restlet.engine.header.WarningReader;
import org.restlet.engine.security.AuthenticatorUtils;
import org.restlet.engine.util.DateUtils;
import org.restlet.representation.Representation;
import org.restlet.util.Series;

/**
* Request wrapper for server HTTP calls.
*
* @author Jerome Louvel
*/
public class HttpRequest extends Request {
    /**
     * Adds a new header to the given request.
     *
     * @param request
     *            The request to update.
     * @param headerName
     *            The header name to add.
     * @param headerValue
     *            The header value to add.
     */
    public static void addHeader(Request request, String headerName,
            String headerValue) {
        if (request instanceof HttpRequest) {
            ((HttpRequest) request).getHeaders().add(headerName, headerValue);
        }
    }

    /** Indicates if the cache control data was parsed and added. */
    private volatile boolean cacheDirectivesAdded;

    /** Indicates if the client data was parsed and added. */
    private volatile boolean clientAdded;

    /** Indicates if the conditions were parsed and added. */
    private volatile boolean conditionAdded;

    /** The context of the HTTP server connector that issued the call. */
    private volatile Context context;

    /** Indicates if the cookies were parsed and added. */
    private volatile boolean cookiesAdded;

    /** Indicates if the request entity was added. */
    private volatile boolean entityAdded;

    /** The low-level HTTP call. */
    private volatile ServerCall httpCall;

    /** Indicates if the proxy security data was parsed and added. */
    private volatile boolean proxySecurityAdded;

    /** Indicates if the ranges data was parsed and added. */
    private volatile boolean rangesAdded;

    /** Indicates if the referrer was parsed and added. */
    private volatile boolean referrerAdded;

    /** Indicates if the security data was parsed and added. */
    private volatile boolean securityAdded;

    /** Indicates if the warning data was parsed and added. */
    private volatile boolean warningsAdded;

    /** Indicates if the recipients info was parsed and added. */
    private volatile boolean recipientsInfoAdded;

    /**
     * Constructor.
     *
     * @param context
     *            The context of the HTTP server connector that issued the call.
     * @param httpCall
     *            The low-level HTTP server call.
     */
    public HttpRequest(Context context, ServerCall httpCall) {
        this.context = context;
        this.clientAdded = false;
        this.conditionAdded = false;
        this.cookiesAdded = false;
        this.entityAdded = false;
        this.referrerAdded = false;
        this.securityAdded = false;
        this.proxySecurityAdded = false;
        this.recipientsInfoAdded = false;
        this.warningsAdded = false;
        this.httpCall = httpCall;

        // Set the properties
        setMethod(Method.valueOf(httpCall.getMethod()));

        // Set the host reference
        StringBuilder sb = new StringBuilder();
        sb.append(httpCall.getProtocol().getSchemeName()).append("://");
        sb.append(httpCall.getHostDomain());
        if ((httpCall.getHostPort() != -1)
                && (httpCall.getHostPort() != httpCall.getProtocol()
                        .getDefaultPort())) {
            sb.append(':').append(httpCall.getHostPort());
        }
        setHostRef(sb.toString());

        // Set the resource reference
        if (httpCall.getRequestUri() != null) {
            setResourceRef(new Reference(getHostRef(), httpCall.getRequestUri()));

            if (getResourceRef().isRelative()) {
                // Take care of the "/" between the host part and the segments.
                if (!httpCall.getRequestUri().startsWith("/")) {
                    setResourceRef(new Reference(getHostRef().toString() + "/"
                            + httpCall.getRequestUri()));
                } else {
                    setResourceRef(new Reference(getHostRef().toString()
                            + httpCall.getRequestUri()));
                }
            }

            setOriginalRef(getResourceRef().getTargetRef());
        }

        // Set the request date
        String dateHeader = httpCall.getRequestHeaders().getFirstValue(
                HeaderConstants.HEADER_DATE);
        Date date = null;
        if (dateHeader != null) {
            date = DateUtils.parse(dateHeader);
        }

        if (date == null) {
            date = new Date();
        }

        setDate(date);
    }

    @Override
    public boolean abort() {
        return getHttpCall().abort();
    }

    @Override
    public List<CacheDirective> getCacheDirectives() {
        List<CacheDirective> result = super.getCacheDirectives();

        if (!cacheDirectivesAdded) {
            for (Parameter header : getHttpCall().getRequestHeaders().subList(
                    HeaderConstants.HEADER_CACHE_CONTROL)) {
                CacheDirectiveReader.addValues(header, result);
            }

            cacheDirectivesAdded = true;
        }

        return result;
    }

    @Override
    public ChallengeResponse getChallengeResponse() {
        ChallengeResponse result = super.getChallengeResponse();

        if (!this.securityAdded) {
            // Extract the header value
            String authorization = getHttpCall().getRequestHeaders().getValues(
                    HeaderConstants.HEADER_AUTHORIZATION);

            // Set the challenge response
            result = AuthenticatorUtils.parseResponse(this, authorization,
                    getHttpCall().getRequestHeaders());
            setChallengeResponse(result);
            this.securityAdded = true;
        }

        return result;
    }

    /**
     * Returns the client-specific information.
     *
     * @return The client-specific information.
     */
    @Override
    public ClientInfo getClientInfo() {
        final ClientInfo result = super.getClientInfo();

        if (!this.clientAdded) {
            // Extract the header values
            String acceptMediaType = getHttpCall().getRequestHeaders()
                    .getValues(HeaderConstants.HEADER_ACCEPT);
            String acceptCharset = getHttpCall().getRequestHeaders().getValues(
                    HeaderConstants.HEADER_ACCEPT_CHARSET);
            String acceptEncoding = getHttpCall().getRequestHeaders()
                    .getValues(HeaderConstants.HEADER_ACCEPT_ENCODING);
            String acceptLanguage = getHttpCall().getRequestHeaders()
                    .getValues(HeaderConstants.HEADER_ACCEPT_LANGUAGE);
            String expect = getHttpCall().getRequestHeaders().getValues(
                    HeaderConstants.HEADER_EXPECT);

            // Parse the headers and update the call preferences

            // Parse the Accept* headers. If an error occurs during the parsing
            // of each header, the error is traced and we keep on with the other
            // headers.
            try {
                PreferenceReader.addCharacterSets(acceptCharset, result);
            } catch (Exception e) {
                this.context.getLogger().log(Level.INFO, e.getMessage());
            }

            try {
                PreferenceReader.addEncodings(acceptEncoding, result);
            } catch (Exception e) {
                this.context.getLogger().log(Level.INFO, e.getMessage());
            }

            try {
                PreferenceReader.addLanguages(acceptLanguage, result);
            } catch (Exception e) {
                this.context.getLogger().log(Level.INFO, e.getMessage());
            }

            try {
                PreferenceReader.addMediaTypes(acceptMediaType, result);
            } catch (Exception e) {
                this.context.getLogger().log(Level.INFO, e.getMessage());
            }

            try {
                ExpectationReader.addValues(expect, result);
            } catch (Exception e) {
                this.context.getLogger().log(Level.INFO, e.getMessage());
            }

            // Set other properties
            result.setAgent(getHttpCall().getRequestHeaders().getValues(
                    HeaderConstants.HEADER_USER_AGENT));
            result.setFrom(getHttpCall().getRequestHeaders().getFirstValue(
                    HeaderConstants.HEADER_FROM));
            result.setAddress(getHttpCall().getClientAddress());
            result.setPort(getHttpCall().getClientPort());

            if (getHttpCall().getUserPrincipal() != null) {
                result.getPrincipals().add(getHttpCall().getUserPrincipal());
            }

            if (this.context != null) {
                // Special handling for the non standard but common
                // "X-Forwarded-For" header.
                final boolean useForwardedForHeader = Boolean
                        .parseBoolean(this.context.getParameters()
                                .getFirstValue("useForwardedForHeader", false));
                if (useForwardedForHeader) {
                    // Lookup the "X-Forwarded-For" header supported by popular
                    // proxies and caches.
                    final String header = getHttpCall().getRequestHeaders()
                            .getValues(HeaderConstants.HEADER_X_FORWARDED_FOR);
                    if (header != null) {
                        final String[] addresses = header.split(",");
                        for (int i = 0; i < addresses.length; i++) {
                            String address = addresses[i].trim();
                            result.getForwardedAddresses().add(address);
                        }
                    }
                }
            }

            this.clientAdded = true;
        }

        return result;
    }

    /**
     * Returns the condition data applying to this call.
     *
     * @return The condition data applying to this call.
     */
    @Override
    public Conditions getConditions() {
        final Conditions result = super.getConditions();

        if (!this.conditionAdded) {
            // Extract the header values
            String ifMatchHeader = getHttpCall().getRequestHeaders().getValues(
                    HeaderConstants.HEADER_IF_MATCH);
            String ifNoneMatchHeader = getHttpCall().getRequestHeaders()
                    .getValues(HeaderConstants.HEADER_IF_NONE_MATCH);
            Date ifModifiedSince = null;
            Date ifUnmodifiedSince = null;
            String ifRangeHeader = getHttpCall().getRequestHeaders()
                    .getFirstValue(HeaderConstants.HEADER_IF_RANGE);

            for (Parameter header : getHttpCall().getRequestHeaders()) {
                if (header.getName().equalsIgnoreCase(
                        HeaderConstants.HEADER_IF_MODIFIED_SINCE)) {
                    ifModifiedSince = HeaderReader.readDate(header.getValue(),
                            false);
                } else if (header.getName().equalsIgnoreCase(
                        HeaderConstants.HEADER_IF_UNMODIFIED_SINCE)) {
                    ifUnmodifiedSince = HeaderReader.readDate(
                            header.getValue(), false);
                }
            }

            // Set the If-Modified-Since date
            if ((ifModifiedSince != null) && (ifModifiedSince.getTime() != -1)) {
                result.setModifiedSince(ifModifiedSince);
            }

            // Set the If-Unmodified-Since date
            if ((ifUnmodifiedSince != null)
                    && (ifUnmodifiedSince.getTime() != -1)) {
                result.setUnmodifiedSince(ifUnmodifiedSince);
            }

            // Set the If-Match tags
            List<Tag> match = null;
            Tag current = null;
            if (ifMatchHeader != null) {
                try {
                    HeaderReader<Object> hr = new HeaderReader<Object>(
                            ifMatchHeader);
                    String value = hr.readRawValue();

                    while (value != null) {
                        current = Tag.parse(value);

                        // Is it the first tag?
                        if (match == null) {
                            match = new ArrayList<Tag>();
                            result.setMatch(match);
                        }

                        // Add the new tag
                        match.add(current);

                        // Read the next token
                        value = hr.readRawValue();
                    }
                } catch (Exception e) {
                    this.context.getLogger().log(
                            Level.INFO,
                            "Unable to process the if-match header: "
                                    + ifMatchHeader);
                }
            }

            // Set the If-None-Match tags
            List<Tag> noneMatch = null;
            if (ifNoneMatchHeader != null) {
                try {
                    HeaderReader<Object> hr = new HeaderReader<Object>(
                            ifNoneMatchHeader);
                    String value = hr.readRawValue();

                    while (value != null) {
                        current = Tag.parse(value);

                        // Is it the first tag?
                        if (noneMatch == null) {
                            noneMatch = new ArrayList<Tag>();
                            result.setNoneMatch(noneMatch);
                        }

                        noneMatch.add(current);

                        // Read the next token
                        value = hr.readRawValue();
                    }
                } catch (Exception e) {
                    this.context.getLogger().log(
                            Level.INFO,
                            "Unable to process the if-none-match header: "
                                    + ifNoneMatchHeader);
                }
            }

            if (ifRangeHeader != null && ifRangeHeader.length() > 0) {
                Tag tag = Tag.parse(ifRangeHeader);

                if (tag != null) {
                    result.setRangeTag(tag);
                } else {
                    Date date = HeaderReader.readDate(ifRangeHeader, false);
                    result.setRangeDate(date);
                }
            }

            this.conditionAdded = true;
        }

        return result;
    }

    /**
     * Returns the cookies provided by the client.
     *
     * @return The cookies provided by the client.
     */
    @Override
    public Series<Cookie> getCookies() {
        final Series<Cookie> result = super.getCookies();

        if (!this.cookiesAdded) {
            String cookieValues = getHttpCall().getRequestHeaders().getValues(
                    HeaderConstants.HEADER_COOKIE);

            if (cookieValues != null) {
                new CookieReader(cookieValues).addValues(result);
            }

            this.cookiesAdded = true;
        }

        return result;
    }

    /**
     * Returns the representation provided by the client.
     *
     * @return The representation provided by the client.
     */
    @Override
    public Representation getEntity() {
        if (!this.entityAdded) {
            setEntity(((ServerCall) getHttpCall()).getRequestEntity());
            this.entityAdded = true;
        }

        return super.getEntity();
    }

    /**
     * Returns the HTTP headers.
     *
     * @return The HTTP headers.
     */
    @SuppressWarnings("unchecked")
    public Series<Parameter> getHeaders() {
        return (Series<Parameter>) getAttributes().get(
                HeaderConstants.ATTRIBUTE_HEADERS);
    }

    /**
     * Returns the low-level HTTP call.
     *
     * @return The low-level HTTP call.
     */
    public ServerCall getHttpCall() {
        return this.httpCall;
    }

    @Override
    public ChallengeResponse getProxyChallengeResponse() {
        ChallengeResponse result = super.getProxyChallengeResponse();

        if (!this.proxySecurityAdded) {
            // Extract the header value
            final String authorization = getHttpCall().getRequestHeaders()
                    .getValues(HeaderConstants.HEADER_PROXY_AUTHORIZATION);

            // Set the challenge response
            result = AuthenticatorUtils.parseResponse(this, authorization,
                    getHttpCall().getRequestHeaders());
            setProxyChallengeResponse(result);
            this.proxySecurityAdded = true;
        }

        return result;
    }

    @Override
    public List<Range> getRanges() {
        final List<Range> result = super.getRanges();

        if (!this.rangesAdded) {
            // Extract the header value
            final String ranges = getHttpCall().getRequestHeaders().getValues(
                    HeaderConstants.HEADER_RANGE);
            result.addAll(RangeReader.read(ranges));

            this.rangesAdded = true;
        }

        return result;
    }

    @Override
    public List<RecipientInfo> getRecipientsInfo() {
        List<RecipientInfo> result = super.getRecipientsInfo();
        if (!recipientsInfoAdded) {
            for (String header : getHttpCall().getRequestHeaders()
                    .getValuesArray(HeaderConstants.HEADER_VIA)) {
                new RecipientInfoReader(header).addValues(result);
            }
            recipientsInfoAdded = true;
        }
        return result;
    }

    /**
     * Returns the referrer reference if available.
     *
     * @return The referrer reference.
     */
    @Override
    public Reference getReferrerRef() {
        if (!this.referrerAdded) {
            final String referrerValue = getHttpCall().getRequestHeaders()
                    .getValues(HeaderConstants.HEADER_REFERRER);
            if (referrerValue != null) {
                setReferrerRef(new Reference(referrerValue));
            }

            this.referrerAdded = true;
        }

        return super.getReferrerRef();
    }

    @Override
    public List<Warning> getWarnings() {
        List<Warning> result = super.getWarnings();
        if (!warningsAdded) {
            for (String header : getHttpCall().getRequestHeaders()
                    .getValuesArray(HeaderConstants.HEADER_WARNING)) {
                new WarningReader(header).addValues(result);
            }
            warningsAdded = true;
        }
        return result;
    }

    @Override
    public void setChallengeResponse(ChallengeResponse response) {
        super.setChallengeResponse(response);
        this.securityAdded = true;
    }

    @Override
    public void setEntity(Representation entity) {
        super.setEntity(entity);
        this.entityAdded = true;
    }

    @Override
    public void setProxyChallengeResponse(ChallengeResponse response) {
        super.setProxyChallengeResponse(response);
        this.proxySecurityAdded = true;
    }

    @Override
    public void setRecipientsInfo(List<RecipientInfo> recipientsInfo) {
        super.setRecipientsInfo(recipientsInfo);
        this.recipientsInfoAdded = true;
    }

    @Override
    public void setWarnings(List<Warning> warnings) {
        super.setWarnings(warnings);
        this.warningsAdded = true;
    }

}
TOP

Related Classes of org.restlet.engine.adapter.HttpRequest

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.