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

com.squareup.rack.servlet.RackEnvironmentBuilder Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2013 Square, Inc.
 *
 * 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.squareup.rack.servlet;

import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.squareup.rack.RackEnvironment;
import com.squareup.rack.RackErrors;
import com.squareup.rack.RackInput;
import com.squareup.rack.RackLogger;
import com.squareup.rack.io.TempfileBufferedInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.base.Throwables.propagate;
import static com.squareup.rack.RackEnvironment.CONTENT_LENGTH;
import static com.squareup.rack.RackEnvironment.CONTENT_TYPE;
import static com.squareup.rack.RackEnvironment.HTTP_HEADER_PREFIX;
import static com.squareup.rack.RackEnvironment.MINECART_HTTP_SERVLET_REQUEST;
import static com.squareup.rack.RackEnvironment.PATH_INFO;
import static com.squareup.rack.RackEnvironment.QUERY_STRING;
import static com.squareup.rack.RackEnvironment.RACK_ERRORS;
import static com.squareup.rack.RackEnvironment.RACK_HIJACK;
import static com.squareup.rack.RackEnvironment.RACK_INPUT;
import static com.squareup.rack.RackEnvironment.RACK_LOGGER;
import static com.squareup.rack.RackEnvironment.RACK_MULTIPROCESS;
import static com.squareup.rack.RackEnvironment.RACK_MULTITHREAD;
import static com.squareup.rack.RackEnvironment.RACK_RUN_ONCE;
import static com.squareup.rack.RackEnvironment.RACK_URL_SCHEME;
import static com.squareup.rack.RackEnvironment.RACK_VERSION;
import static com.squareup.rack.RackEnvironment.REQUEST_METHOD;
import static com.squareup.rack.RackEnvironment.SCRIPT_NAME;
import static com.squareup.rack.RackEnvironment.SERVER_NAME;
import static com.squareup.rack.RackEnvironment.SERVER_PORT;
import static java.util.Collections.list;

/**
 * 

Transforms an {@link HttpServletRequest} into a {@link RackEnvironment}.

* *

Conforms to version 1.2 of the Rack specification

. * * @see The Rack Specification * @see RFC 3875, section 4.1.18 * @see The Rack * socket hijacking API */ public class RackEnvironmentBuilder { // We conform to version 1.2 of the Rack specification. // Note that this number is completely different than the gem version of rack (lowercase): // for example, the rack-1.5.2 gem ships with handlers that conform to version 1.2 of the Rack // specification. private static final List VERSION_1_2 = ImmutableList.of(1, 2); private static final Logger RACK_ERRORS_LOGGER = LoggerFactory.getLogger(RackErrors.class); private static final Logger RACK_LOGGER_LOGGER = LoggerFactory.getLogger(RackLogger.class); private static final Joiner COMMA = Joiner.on(','); private static final CharMatcher DASH = CharMatcher.is('-'); public RackEnvironment build(HttpServletRequest request) { ImmutableMap.Builder content = ImmutableMap.builder(); content.put(REQUEST_METHOD, request.getMethod()); content.put(SCRIPT_NAME, request.getServletPath()); content.put(PATH_INFO, nullToEmpty(request.getPathInfo())); content.put(QUERY_STRING, nullToEmpty(request.getQueryString())); content.put(SERVER_NAME, request.getServerName()); content.put(SERVER_PORT, String.valueOf(request.getServerPort())); content.put(RACK_VERSION, VERSION_1_2); content.put(RACK_URL_SCHEME, request.getScheme().toLowerCase()); content.put(RACK_INPUT, rackInput(request)); content.put(RACK_ERRORS, new RackErrors(RACK_ERRORS_LOGGER)); content.put(RACK_LOGGER, new RackLogger(RACK_LOGGER_LOGGER)); content.put(RACK_MULTITHREAD, true); content.put(RACK_MULTIPROCESS, true); content.put(RACK_RUN_ONCE, false); content.put(RACK_HIJACK, false); // Extra things we add that aren't in the Rack specification: content.put(MINECART_HTTP_SERVLET_REQUEST, request); // HTTP headers; Multimap acrobatics ensure we normalize capitalization and // punctuation differences early Enumeration headerNames = request.getHeaderNames(); ImmutableListMultimap.Builder headers = ImmutableListMultimap.builder(); while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); headers.putAll(rackHttpHeaderKey(name), list(request.getHeaders(name))); } for (Map.Entry> header : headers.build().asMap().entrySet()) { content.put(header.getKey(), COMMA.join(header.getValue())); } // Request attributes // This will include attributes like javax.servlet.request.X509Certificate Enumeration attributeNames = request.getAttributeNames(); while (attributeNames.hasMoreElements()) { String name = attributeNames.nextElement(); content.put(name, request.getAttribute(name)); } return new RackEnvironment(content.build()); } private RackInput rackInput(HttpServletRequest request) { try { return new RackInput(new TempfileBufferedInputStream(request.getInputStream())); } catch (IOException e) { throw propagate(e); } } private String rackHttpHeaderKey(String headerName) { String transformed = DASH.replaceFrom(headerName.toUpperCase(), "_"); if (transformed.equals(CONTENT_LENGTH) || transformed.equals(CONTENT_TYPE)) { return transformed; } else { return HTTP_HEADER_PREFIX + transformed; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy