001// Copyright 2019 Google LLC
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//      http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package com.google.cloud.functions;
016
017import java.util.List;
018import java.util.Map;
019import java.util.Optional;
020
021/**
022 * Represents the contents of an HTTP request that is being serviced by a Cloud Function.
023 */
024public interface HttpRequest extends HttpMessage {
025  /** The HTTP method of this request, such as {@code "POST"} or {@code "GET"}. */
026  String getMethod();
027
028  /** The full URI of this request as it arrived at the server. */
029  String getUri();
030
031  /**
032   * The path part of the URI for this request, without any query. If the full URI is
033   * {@code http://foo.com/bar/baz?this=that}, then this method will return {@code /bar/baz}.
034   */
035  String getPath();
036
037  /**
038   * The query part of the URI for this request. If the full URI is
039   * {@code http://foo.com/bar/baz?this=that}, then this method will return {@code this=that}.
040   * If there is no query part, the returned {@code Optional} is empty.
041   */
042  Optional<String> getQuery();
043
044  /**
045   * The query parameters of this request. If the full URI is
046   * {@code http://foo.com/bar?thing=thing1&thing=thing2&cat=hat}, then the returned map will map
047   * {@code thing} to the list {@code "thing1", "thing2"} and {@code cat} to the list with the
048   * single element {@code "hat"}.
049   */
050  Map<String, List<String>> getQueryParameters();
051
052  /**
053   * The first query parameter with the given name, if any. If the full URI is
054   * {@code http://foo.com/bar?thing=thing1&thing=thing2&cat=hat}, then
055   * {@code getFirstQueryParameter("thing")} will return {@code Optional.of("thing1")} and
056   * {@code getFirstQueryParameter("something")} will return {@code Optional.empty()}. This is a
057   * more convenient alternative to {@link #getQueryParameters}.
058   */
059  default Optional<String> getFirstQueryParameter(String name) {
060    List<String> parameters = getQueryParameters().get(name);
061    if (parameters == null || parameters.isEmpty()) {
062      return Optional.empty();
063    }
064    return Optional.of(parameters.get(0));
065  }
066
067  /**
068   * Represents one part inside a multipart ({@code multipart/form-data}) HTTP request. Each such
069   * part can have its own HTTP headers, which can be retrieved with the methods inherited from
070   * {@link HttpMessage}.
071   */
072  interface HttpPart extends HttpMessage {
073    /** Returns the filename associated with this part, if any. */
074    Optional<String> getFileName();
075  }
076
077  /**
078   * Returns the parts inside this multipart ({@code multipart/form-data}) HTTP request. Each entry
079   * in the returned map has the name of the part as its key and the contents as the associated
080   * value.
081   *
082   * @throws IllegalStateException if the {@link #getContentType() content type} is not
083   *     {@code multipart/form-data}.
084   */
085  Map<String, HttpPart> getParts();
086}