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

org.wisdom.api.http.RequestHeader Maven / Gradle / Ivy

There is a newer version: 0.10.0
Show newest version
/*
 * #%L
 * Wisdom-Framework
 * %%
 * Copyright (C) 2013 - 2014 Wisdom Framework
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package org.wisdom.api.http;

import com.google.common.net.MediaType;
import org.wisdom.api.cookies.Cookie;
import org.wisdom.api.cookies.Cookies;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * This class allows manipulating the HTTP Request headers.
 */
public abstract class RequestHeader {
    /**
     * Regex to parse a segment of the ACCEPT-LANGUAGE header.
     * The group #1 contains the locale tag, while the group #5 contains the `q` value.
     */
    private static final Pattern LANGUAGE_SEGMENT_PATTERN = Pattern.compile("([a-zA-Z]+(-[a-zA-Z]+)?(-[a-zA-Z]+)?)(;q=(.*))?");

    /**
     * @return the complete request URI, containing both path and query string.
     */
    public abstract String uri();

    /**
     * The client IP address.
     * 

* If the X-Forwarded-For header is present, then this method will return the value in that header * if either the local address is 127.0.0.1, or if trustxforwarded is configured to be true in the * application configuration file. * * @return the client IP address */ public abstract String remoteAddress(); /** * @return The request host. */ public abstract String host(); /** * @return The URI path (without the query). */ public abstract String path(); /** * @return The preferred media type in the request {@literal Accept header}. */ public abstract MediaType mediaType(); /** * @return The set of media types from the request Accept header, sorted by preference (preferred first). If the * Accept header is not set, it must return the singleton list [text/*]. */ public abstract Collection mediaTypes(); /** * Checks if this request accepts a given media type. * * @param mimeType the mime type to check. * @return true if {@code mimeType} is in the {@literal Accept} header, otherwise false */ public abstract boolean accepts(String mimeType); /** * @return the request cookies */ public abstract Cookies cookies(); /** * Gets the cookie having the given name. * * @param name the cookie to retrieve * @return the cookie, if found, otherwise null. */ public Cookie cookie(String name) { return cookies().get(name); } /** * Retrieves all headers. * * @return headers */ public abstract java.util.Map> headers(); /** * Retrieves a single header. * * @param headerName the header name * @return the value of the header. If the header has multiple value, * the first one is returned. If the header has no value (is not specified in the request), * {@literal null} is returned. */ public String getHeader(String headerName) { List headers = null; for (String h : headers().keySet()) { if (headerName.equalsIgnoreCase(h)) { headers = headers().get(h); break; } } if (headers == null || headers.isEmpty()) { return null; } return headers.get(0); } /** * Get the encoding that is acceptable for the client. E.g. Accept-Encoding: * compress, gzip *

* The Accept-Encoding request-header field is similar to Accept, but * restricts the content-codings that are acceptable in the response. * * @return the encoding that is acceptable for the client * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html */ public abstract String encoding(); /** * Get the language that is acceptable for the client. E.g. Accept-Language: * da, en-gb;q=0.8, en;q=0.7 *

* The Accept-Language request-header field is similar to Accept, but * restricts the set of natural languages that are preferred as a response * to the request. * * @return the language that is acceptable for the client * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html */ public abstract String language(); /** * Get the locale that are acceptable for the client. E.g. Accept-Language: * da, en-gb;q=0.8, en;q=0.7 *

* The Accept-Language request-header field is similar to Accept, but * restricts the set of natural languages that are preferred as a response * to the request. *

* This method builds an ordered list of locale (favorite first). * * @return the set of locale that are acceptable for the client in the preference order. * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html */ public Locale[] languages() { return getLocaleList(getHeader(HeaderNames.ACCEPT_LANGUAGE)); } /** * Get the charset that is acceptable for the client. E.g. Accept-Charset: * iso-8859-5, unicode-1-1;q=0.8 *

* The Accept-Charset request-header field can be used to indicate what * character sets are acceptable for the response. This field allows clients * capable of understanding more comprehensive or special- purpose character * sets to signal that capability to a server which is capable of * representing documents in those character sets. * * @return the charset that is acceptable for the client * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html */ public abstract String charset(); /** * Builds the list of locale in the preference order accepted by the client. For reminder, * the ACCEPT-LANGUAGE header follows this convention: * *

     *         Accept-Language = "Accept-Language" ":"
     *         1#( language-range [ ";" "q" "=" qvalue ] )
     *         language-range  = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
     *     
* * * @param accept the ACCEPT-LANGUAGE header value * @return the list of locale, empty if the header is {@literal null} or non-parseable * @see RequestHeader#languages() */ public static Locale[] getLocaleList(String accept) { if (accept == null || accept.length() == 0) { return new Locale[0]; } Map> locales = new TreeMap<>(new Comparator() { @Override public int compare(Float o1, Float o2) { return o2.compareTo(o1); } }); String[] segments = accept.split(","); for (String segment : segments) { Matcher matcher = LANGUAGE_SEGMENT_PATTERN.matcher(segment.trim()); if (!matcher.matches()) { continue; } float q = 1; if (matcher.group(5) != null) { q = Float.valueOf(matcher.group(5)); } List l = locales.get(q); if (l == null) { l = new ArrayList<>(); locales.put(q, l); } l.add(Locale.forLanguageTag(matcher.group(1))); } // Now iterates from highest q to lowest. List list = new ArrayList<>(); for (Map.Entry> entry : locales.entrySet()) { list.addAll(entry.getValue()); } return list.toArray(new Locale[list.size()]); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy