Package com.google.opengse.httputil

Source Code of com.google.opengse.httputil.HttpUtil

// Copyright 2007 Google Inc. All Rights Reserved.
//
// 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.

package com.google.opengse.httputil;

import com.google.opengse.util.string.StringUtil;

import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.HashMap;

import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletRequestWrapper;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

/**
* Some util methods for HTTP in servlets.
*
* @author Jeremy Chau
*/
public final class HttpUtil {

  /**
   * Dump the request's HTTP headers into a string, good for logging.
   * Likely to be called from initRequest().
   */
  public static String dumpHeadersToString(HttpServletRequest req) {
    StringBuffer sb = new StringBuffer();
    Enumeration<?> names = req.getHeaderNames();
    while (names.hasMoreElements()) {
      String name = names.nextElement().toString();
      Enumeration<?> values = req.getHeaders(name);
      while (values.hasMoreElements())
        sb.append(name + ": " + values.nextElement() + "\n");
    }

    return sb.toString();
  }

  /**
   * Extract a parameter value from a request.
   *
   * @param request the HttpServletRequest to parse from.
   * @param name the name of the parameter to look for
   * @param defaultValue default value to return.
   * @return String parameter value, or default if not found.
   */
  public static String getDefault (final HttpServletRequest request,
      final String name, final String defaultValue) {
    final String val = request.getParameter(name);
    return null == val ? defaultValue : val;
  }

  /**
   * Returns the value of the parameter as an int, or a default value if the
   * value is unparseable.
   *
   * @param request the HttpServletRequest to parse from.
   * @param name the name of the parameter to look for
   * @param defaultValue default value to return.
   * @return int value from the request parameter, or a default value.
   */
  public static int getIntDefault (final HttpServletRequest request,
     final String name, final int defaultValue) {
    final String val = request.getParameter(name);
    if (null == val) {
      return defaultValue;
    }
    try {
      return Integer.parseInt(val);
    } catch (final NumberFormatException exc) {
      return defaultValue;
    }
  }

  /**
   * Returns the value of the parameter as a long, or a default value if the
   * value is unparseable.
   *
   * @param request the HttpServletRequest to parse from.
   * @param name the name of the parameter to look for
   * @param defaultValue default value to return.
   * @return long value from the request parameter, or a default value.
   */
  public static long getLongDefault (final HttpServletRequest request,
      final String name, final long defaultValue) {
    final String val = request.getParameter(name);
    if (null == val) {
      return defaultValue;
    }
    try {
      return Long.parseLong(val);
    } catch (final NumberFormatException exc) {
      return defaultValue;
    }
  }

  /** Return all headers for this connection in a map
   * Duplicates HttpHeaders.listHeaders()
   **/
  public static Map<String, String[]> getHeaderFields(HttpURLConnection con) {
    int i = 1; // spastic getHeaderFieldKey() uses a 1-based index
    Map<String, String[]> map = new HashMap<String, String[]>();
    String key;
    while (null != (key = con.getHeaderFieldKey(i))) {
      // Add normalized header to the map
      map.put(key.toLowerCase(), new String[] {con.getHeaderField(i)});
      i++;
    }
    return map;
  }

  /**
   * If the specified request was a forwarded or included request, unwrap it
   * and return the original request.
   */
  public static HttpServletRequest unwrap(HttpServletRequest req) {
    if (req instanceof ServletRequestWrapper) {
      ServletRequestWrapper wrapper = (ServletRequestWrapper) req;
      req = (HttpServletRequest) wrapper.getRequest(); // unwrap
    }
    return req;
  }

  /**
   * Returns the request URI of the specified request, including the
   * query string if any. If this request is a forwarded (wrapped)
   * request, the request is first unwrapped. This method is most
   * commonly useful when using request dispatchers to forward from
   * one servlet to another.
   *
   * This method differs from the following <code>getForwardingURL</code>
   * in that only the URI is returned, not the entire URL.
   */
  public static String getForwardingURI(HttpServletRequest req) {
    /*
     * Extract the full request URI from the original request. The
     * query string, if present, is appended to the request URI.
     */
    req = unwrap(req);
    String uri = req.getRequestURI();
    String query = req.getQueryString();
    return (query == null) ? uri : (uri + "?" + query);
  }

  /**
   * Returns the request URL of the specified request, including the
   * query string if any. If this request is a forwarded (wrapped)
   * request, the request is first unwrapped. This method is most
   * commonly useful when using request dispatchers to forward from
   * one servlet to another.
   *
   * This method differs from the preceeding <code>getForwardingURI</code>
   * in that the entire URL is returned, not just the URI.
   */
  public static String getForwardingURL(HttpServletRequest req) {
    /*
     * Extract the full request URI from the original request. The
     * query string, if present, is appended to the request URI.
     */
    req = unwrap(req);
    String url = req.getRequestURL().toString();
    String query = req.getQueryString();
    return (query == null) ? url : (url + "?" + query);
  }

  /**
   * Returns an unmodifiable map from <code>String</code> name to
   * <code>String</code> value for every init parameter in the
   * specified <code>FilterConfig</code>.
   */
  public static Map<String, String> getInitParameters(FilterConfig config) {
    Enumeration<?> e = config.getInitParameterNames();
    if (!e.hasMoreElements()) {
      return Collections.emptyMap();
    }
    Map<String, String> map = new HashMap<String, String>();
    while (e.hasMoreElements()) {
      String name = e.nextElement().toString();
      map.put(name, config.getInitParameter(name));
    }
    return Collections.unmodifiableMap(map);
  }

  /**
   * Returns an unmodifiable map from <code>String</code> name to
   * <code>String</code> value for every init parameter in the
   * specified <code>ServletConfig</code>.
   */
  public static Map<String, String> getInitParameters(ServletConfig config) {
    Enumeration<?> e = config.getInitParameterNames();
    if (!e.hasMoreElements()) {
      return Collections.emptyMap();
    }
    Map<String, String> map = new HashMap<String, String>();
    while (e.hasMoreElements()) {
      String name = e.nextElement().toString();
      map.put(name, config.getInitParameter(name));
    }
    return Collections.unmodifiableMap(map);
  }

  /**
   * Returns an unmodifiable map from <code>String</code> name to
   * {@link Cookie}. If the request has no cookies, this method
   * returns an empty map.
   */
  public static Map<String, Cookie> getCookies(HttpServletRequest req) {
    Cookie[] cookies = req.getCookies();
    if ((cookies == null) || (cookies.length == 0)) {
      return Collections.emptyMap();
    }
    Map<String, Cookie> map = new HashMap<String, Cookie>(cookies.length);
    for (int i = 0; i < cookies.length; i++) {
      Cookie cookie = cookies[i];
      map.put(cookie.getName(), cookie);
    }
    return Collections.unmodifiableMap(map);
  }

  /**
   * Does the reverse of javax.servlet.http.HttpUtils.parseQueryString()
   *
   * @param args        A hashtable mapping keys to arrays of values, such
   *                    as that produced with parseQueryString
   * @param encoding    Build string using this encoding
   * @return String     A single CGI string like "q=test&deb=i..."
   */
  public static String constructQueryString(Map<String, String[]> args,
                                            String encoding)
      throws UnsupportedEncodingException {
    // URL-escape all args (parseQueryString unescapes them)
    Map<String, String[]> safeArgs = new HashMap<String, String[]>();
    for (Map.Entry<String, String[]> e : args.entrySet()) {
      String values[] = e.getValue();
      String safeValues[] = new String[values.length];
      for (int j = 0; j < values.length; j++) {
        safeValues[j] = FastURLEncoder.encode(values[j], encoding);
      }
      safeArgs.put(e.getKey(), safeValues);
    }

    // return CGI string
    return StringUtil.arrayMap2String(safeArgs, "=", "&");
  }

  /**
   * Shortcut for constructQueryString(args, "UTF-8").
   * @see #constructQueryString(Map, String)
   */
  public static String constructQueryString(Map<String, String[]> args) {
    try {
      return constructQueryString(args, "UTF-8");
    } catch (UnsupportedEncodingException ue) {
      // This cannot happen with UTF-8
      throw new AssertionError("Could not construct query in UTF-8");
    }
  }

  /**
   * Given a request, reconstruct the first line as sent by the client.
   * This looks something like:
   *  GET /images?q=johnson+street&svnum=10&hl=en&ie=UTF8&oe=UTF8&sa=N HTTP/1.1
   *
   * @param req The request object. Must not be null
   * @return The first line of the request
   */
  public static String reconstructRequestFirstLine(HttpServletRequest req) {
    if (req == null) {
      throw new IllegalArgumentException();
    }
    return constructRequestFirstLine(req.getMethod(),
                                     req.getRequestURI(),
                                     req.getQueryString(),
                                     req.getProtocol());
  }

  /**
   * Constructs the first line of an HTTP(S) request.
   *
   * @param method HTTP method. See {@link HttpServletRequest#getMethod()}.
   * @param path URL path. See {@link HttpServletRequest#getRequestURI()}. Note
   * that this must be the raw (still escaped) path.
   * @param queryString URL query string, or null. See {@link
   * HttpServletRequest#getQueryString()}.
   * @param protocol request protocol. See {@link
   * HttpServletRequest#getProtocol()}.
   * @return The first line of the request.
   */
  public static String constructRequestFirstLine(
      String method, String path, String queryString, String protocol) {
    StringBuffer b = new StringBuffer();
    b.append(method);
    b.append(" ");
    b.append(path);
    if (queryString != null) {
      b.append("?");
      b.append(queryString);
    }
    b.append(" ");
    b.append(protocol);
    return b.toString();
  }

  /**
   * Resolves the provided cookie domain argument based on the supplied host
   * argument. This makes it possible for applications to define the cookie
   * domain in form of ".example." and have it expanded acoording to the Host
   * header of the HTTP request at run time.
   * <p>
   * If the cookie domain does not end with a ".", then the cookie domain is
   * returned verbatim, unless the host is non-{@code null} and conflicts with
   * the cookie domain, in which case {@code null} is returned.
   * <p>
   * Otherwise, if the cookie domain ends with a ".", the substring of the host
   * starting at the cookie domain is returned, unless the host {@code null} or
   * the host conflicts with the cookie domain, in which case {@code null} is
   * returned.
   * <p>
   * For example, if the cookie domain is set to ".example.":
   * <pre>
   * HTTP/1.1 Host      Session cookie domain
   * www.example.co.uk   .example.co.uk
   * www.example.ca      .example.ca
   * foo.example.com     .example.com
   * bar.example.com    .example.com
   * </pre>

   * @param cookieDomain the domain for which the HTTP cookie is valid. If the
   * cookie domain ends with a ".", the substring of the host starting at the
   * cookie domain used instead. Otherwise, the cookie domain is used verbatim.
   * Must not be null.
   * @param host the HTTP/1.1 Host header value.
   * @return the resolved cookie domain, which may be {@code null}
   * @throws NullPointerException if {@code cookieDomain} is {@code null}
   */
  public static String resolveCookieDomain(String cookieDomain,
      String host) {

    if (cookieDomain.endsWith(".")) {
      if (host == null) {
        return null;
      }

      // Take the suffix from the user-supplied Host header
      int index = host.indexOf(cookieDomain);
      if (index == -1) {
        return null;
      } else {
        int colonIndex = host.indexOf(':', index);
        if (colonIndex == -1) {
          return host.substring(index);
        } else {
          return host.substring(index, colonIndex);
        }
      }
    } else {
      if (host != null && !host.endsWith(cookieDomain)) {
        // don't return a domain restriction that conflicts with the
        // host the browser is asking for
        return null;
      } else {
        return cookieDomain;
      }
    }
  }

  private HttpUtil() {}
}
TOP

Related Classes of com.google.opengse.httputil.HttpUtil

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.