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.io.BufferedWriter;
018import java.io.IOException;
019import java.io.OutputStream;
020import java.util.List;
021import java.util.Map;
022import java.util.Optional;
023
024/**
025 * Represents the contents of an HTTP response that is being sent by a Cloud Function in response
026 * to an HTTP request.
027 */
028public interface HttpResponse {
029  /**
030   * Sets the numeric HTTP
031   * <a href="https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml">status
032   * code</a> to use in the response. Most often this will be 200, which is the OK status.
033   */
034  void setStatusCode(int code);
035
036  /**
037   * Sets the numeric HTTP
038   * <a href="https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml">status
039   * code</a> and reason message to use in the response. For example<br>
040   * {@code setStatusCode(400, "Something went wrong")}.
041   */
042  void setStatusCode(int code, String message);
043
044  /**
045   * Sets the value to use for the {@code Content-Type} header in the response. This may include
046   * a character encoding, for example {@code setContentType("text/plain; charset=utf-8")}.
047   */
048  void setContentType(String contentType);
049
050  /**
051   * Returns the {@code Content-Type} that was previously set by {@link #setContentType}, or by
052   * {@link #appendHeader} with a header name of {@code Content-Type}. If no {@code Content-Type}
053   * has been set, returns {@code Optional.empty()}.
054   */
055  Optional<String> getContentType();
056
057  /**
058   * Includes the given header name with the given value in the response. This method may be called
059   * several times for the same header, in which case the response will contain the header the same
060   * number of times.
061   */
062  void appendHeader(String header, String value);
063
064  /**
065   * Returns the headers that have been defined for the response so far. This will contain at least
066   * the headers that have been set via {@link #appendHeader} or {@link #setContentType}, and may
067   * contain additional headers such as {@code Date}.
068   */
069  Map<String, List<String>> getHeaders();
070
071  /**
072   * Returns an {@link OutputStream} that can be used to write the body of the response.
073   * This method is typically used to write binary data. If the body is text, the
074   * {@link #getWriter()} method is more appropriate.
075   *
076   * @throws IOException if a valid {@link OutputStream} cannot be returned for some reason.
077   * @throws IllegalStateException if {@link #getWriter} has already been called on this instance.
078   */
079  OutputStream getOutputStream() throws IOException;
080
081  /**
082   * Returns a {@link BufferedWriter} that can be used to write the text body of the response.
083   * If the written text will not be US-ASCII, you should specify a character encoding by calling
084   * {@link #setContentType setContentType("text/foo; charset=bar")} or
085   * {@link #appendHeader appendHeader("Content-Type", "text/foo; charset=bar")}
086   * before calling this method.
087   *
088   * @throws IOException if a valid {@link BufferedWriter} cannot be returned for some reason.
089   * @throws IllegalStateException if {@link #getOutputStream} has already been called on this
090   *     instance.
091   */
092  BufferedWriter getWriter() throws IOException;
093}