Package foo.domaintest.http

Source Code of foo.domaintest.http.HttpApiModule

/**
* Copyright 2014 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 foo.domaintest.http;

import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.collect.Iterables.getFirst;
import static foo.domaintest.util.QueryStringHelper.parseQuery;
import static java.util.UUID.randomUUID;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import com.google.common.collect.Table;
import com.google.common.io.CharStreams;
import foo.domaintest.action.Action;
import foo.domaintest.action.RequestModule;
import foo.domaintest.action.annotation.RequestData;
import foo.domaintest.config.ConfigModule.EasterEggs;
import foo.domaintest.metrics.Metrics;
import foo.domaintest.metrics.impl.MetricsModule;

import dagger.Lazy;
import dagger.Module;
import dagger.Provides;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.annotation.Documented;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.inject.Qualifier;
import javax.inject.Singleton;
import javax.servlet.http.HttpServletResponse;

/** Dagger module for creating the HTTP API actions. */
@Module(
    addsTo = RequestModule.class,
    includes = MetricsModule.class,
    injects = {
        EchoAction.class,
        StashAction.class,
        TempAction.class,
        TokenAction.class })
public class HttpApiModule {

  /** Binding annotation for a random token for memcache. */
  @Qualifier
  @Documented
  @interface RandomToken {}

  /** Binding annotation for request parameters. */
  @Qualifier
  @Documented
  @interface Param {
    String value();
  }

  public static final Set<Class<? extends Action>> ACTIONS =
      ImmutableSet.<Class<? extends Action>>of(
          EchoAction.class,
          StashAction.class,
          TempAction.class,
          TokenAction.class);

  @Provides
  @Singleton
  Multimap<String, String> provideParameterMap(
      @RequestData("queryString") String queryString,
      @RequestData("postBody") Lazy<String> lazyPostBody,
      @RequestData("charset") String requestCharset,
      FileItemIterator multipartIterator) {
    // Calling request.getParameter() or request.getParameterMap() etc. consumes the POST body. If
    // we got the "postpayload" param we don't want to parse the body, so use only the query params.
    // Note that specifying both "payload" and "postpayload" will result in the "payload" param
    // being honored and the POST body being completely ignored.
    ImmutableMultimap.Builder<String, String> params = new ImmutableMultimap.Builder<>();
    Multimap<String, String> getParams = parseQuery(queryString);
    params.putAll(getParams);
    if (getParams.containsKey("postpayload")) {
      // Treat the POST body as if it was the "payload" param.
      return params.put("payload", nullToEmpty(lazyPostBody.get())).build();
    }
    // No "postpayload" so it's safe to consume the POST body and look for params there.
    if (multipartIterator == null) {  // Handle GETs and form-urlencoded POST requests.
      params.putAll(parseQuery(nullToEmpty(lazyPostBody.get())));
    } else // Handle multipart/form-data requests.
      try {
        while (multipartIterator != null && multipartIterator.hasNext()) {
          FileItemStream item = multipartIterator.next();
          try (InputStream stream = item.openStream()) {
            params.put(
                item.isFormField() ? item.getFieldName() : item.getName(),
                CharStreams.toString(new InputStreamReader(stream, requestCharset)));
          }
        }
      } catch (FileUploadException | IOException e) {
        // Ignore the failure and fall through to return whatever params we managed to parse.
      }
    }
    return params.build();
  }

  @Provides
  @Singleton
  @EasterEggs
  String provideEasterEggUrl(
      Multimap<String, String> params, @EasterEggs Table<String, String, String> easterEggs) {
    for (Entry<String, String> param : params.entries()) {
      String easterEggUrl = easterEggs.get(param.getKey(), param.getValue());
      if (easterEggUrl != null) {
        return easterEggUrl;
      }
    }
    return null;
  }

  @Provides
  @Param("status")
  Integer provideStatus(Multimap<String, String> params, @EasterEggs String easterEggUrl) {
    if (easterEggUrl == null) {
      String statusString = getFirst(params.get("status"), null);
      return statusString == null ? null : parseInt(statusString);
    }
    return HttpServletResponse.SC_FOUND;
  }

  @Provides
  @Param("sleep")
  Integer provideSleep(Multimap<String, String> params) {
    String sleepString = getFirst(params.get("sleep"), null);
    return sleepString == null ? null : parseInt(sleepString);
  }

  @Provides
  @Param("mime")
  String provideMime(Multimap<String, String> params) {
    return getFirst(params.get("mime"), null);
  }

  @Provides
  @Param("payload")
  String providePayload(Multimap<String, String> params, @EasterEggs String easterEggUrl) {
    return easterEggUrl == null ? getFirst(params.get("payload"), null) : easterEggUrl;
  }

  @Provides
  @Param("token")
  String provideToken(Multimap<String, String> params) {
    return getFirst(params.get("token"), null);
  }

  @Provides
  @Param("delcookie")
  List<String> provideDelCookie(Multimap<String, String> params) {
    return ImmutableList.copyOf(params.get("delcookie"));
  }

  @Provides
  @Param("addcookie")
  Map<String, String> provideAddCookie(Multimap<String, String> params) {
    return parseMap(params.get("addcookie"));
  }

  @Provides
  @Param("header")
  Map<String, String> provideHeader(Multimap<String, String> params) {
    return parseMap(params.get("header"));
  }

  @Provides
  @RandomToken
  String provideRandomToken(Metrics metrics) {
    metrics.addActivity("random_token");
    return randomUUID().toString();
  }

  private Integer parseInt(String value) {
    try {
      return Integer.parseInt(value);
    } catch (NumberFormatException e) {
      return null;
    }
  }

  private Map<String, String> parseMap(Collection<String> values) {
    ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
    for (String value : values) {
      List<String> parts = Splitter.on('=').limit(2).splitToList(value);
      // Note that this puts "" in the map if there's no '=' in the value.
      builder.put(parts.get(0), Iterables.get(parts, 1, ""));
    }
    return builder.build();
  }
}
TOP

Related Classes of foo.domaintest.http.HttpApiModule

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.