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/** Represents the contents of an HTTP request that is being serviced by a Cloud Function. */
022public interface HttpRequest extends HttpMessage {
023  /**
024   * The HTTP method of this request, such as {@code "POST"} or {@code "GET"}.
025   *
026   * @return the HTTP method of this request.
027   */
028  String getMethod();
029
030  /**
031   * The full URI of this request as it arrived at the server.
032   *
033   * @return the full URI of this request.
034   */
035  String getUri();
036
037  /**
038   * The path part of the URI for this request, without any query. If the full URI is {@code
039   * http://foo.com/bar/baz?this=that}, then this method will return {@code /bar/baz}.
040   *
041   * @return the path part of the URI for this request.
042   */
043  String getPath();
044
045  /**
046   * The query part of the URI for this request. If the full URI is {@code
047   * http://foo.com/bar/baz?this=that}, then this method will return {@code this=that}. If there is
048   * no query part, the returned {@code Optional} is empty.
049   *
050   * @return the query part of the URI, if any.
051   */
052  Optional<String> getQuery();
053
054  /**
055   * The query parameters of this request. If the full URI is {@code
056   * http://foo.com/bar?thing=thing1&thing=thing2&cat=hat}, then the returned map will map {@code
057   * thing} to the list {@code ["thing1", "thing2"]} and {@code cat} to the list with the single
058   * element {@code "hat"}.
059   *
060   * @return a map where each key is the name of a query parameter and the corresponding {@code
061   *     List} value indicates every value that was associated with that name.
062   */
063  Map<String, List<String>> getQueryParameters();
064
065  /**
066   * The first query parameter with the given name, if any. If the full URI is {@code
067   * http://foo.com/bar?thing=thing1&thing=thing2&cat=hat}, then {@code
068   * getFirstQueryParameter("thing")} will return {@code Optional.of("thing1")} and {@code
069   * getFirstQueryParameter("something")} will return {@code Optional.empty()}. This is a more
070   * convenient alternative to {@link #getQueryParameters}.
071   *
072   * @param name a query parameter name.
073   * @return the first query parameter value with the given name, if any.
074   */
075  default Optional<String> getFirstQueryParameter(String name) {
076    List<String> parameters = getQueryParameters().get(name);
077    if (parameters == null || parameters.isEmpty()) {
078      return Optional.empty();
079    }
080    return Optional.of(parameters.get(0));
081  }
082
083  /**
084   * Represents one part inside a multipart ({@code multipart/form-data}) HTTP request. Each such
085   * part can have its own HTTP headers, which can be retrieved with the methods inherited from
086   * {@link HttpMessage}.
087   */
088  interface HttpPart extends HttpMessage {
089    /**
090     * Returns the filename associated with this part, if any.
091     *
092     * @return the filename associated with this part, if any.
093     */
094    Optional<String> getFileName();
095  }
096
097  /**
098   * Returns the parts inside this multipart ({@code multipart/form-data}) HTTP request. Each entry
099   * in the returned map has the name of the part as its key and the contents as the associated
100   * value.
101   *
102   * @return a map from part names to part contents.
103   * @throws IllegalStateException if the {@link #getContentType() content type} is not {@code
104   *     multipart/form-data}.
105   */
106  Map<String, HttpPart> getParts();
107}