// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.net.http;

using fuchsia.mem;
using fuchsia.url;
using zx;

using Method = string:1024;

/// An error occurred during the HTTP transaction.
enum Error {
    /// Some other problem occurred that cannot be classified using one of the
    /// more specific statuses. Retry is optional.
    INTERNAL = 1;

    /// An HTTP parse error.
    UNABLE_TO_PARSE = 2;

    /// Indicates a channel (client or body sender) is closed.
    CHANNEL_CLOSED = 3;

    /// Error occurred while connecting.
    CONNECT = 4;

    /// The deadline specified in Request has passed
    DEADLINE_EXCEEDED = 5;
};

/// An HTTP header field.
struct Header {
    /// The name of the header field.
    bytes name;

    /// The value of the header field.
    bytes value;
};

/// The body of an HTTP request.
union Body {
    /// A buffer that will contain the complete request or response body.
    1: fuchsia.mem.Buffer buffer;

    /// A socket that will contain the streaming request or response body.
    2: handle<socket> stream;
};

/// An HTTP request.
table Request {
    /// The HTTP method if applicable.
    ///
    /// Defaults to "GET".
    1: Method method;

    /// The URL to load.
    ///
    /// Required.
    2: fuchsia.url.Url url;

    /// Additional HTTP request headers.
    3: vector<Header>:MAX headers;

    /// The payload for the request body. For HTTP requests, the method must be
    /// set to "POST" or "PUT". If a buffer is used for the body, a
    /// Content-Length header will automatically be added.
    4: Body body;

    /// Determines when to give up on waiting for a response from the server. If no deadline is
    /// provided, the implementation will provide a reasonable default.
    5: zx.time deadline;
};

/// A description of the redirect the server requested.
///
/// The semantics of an HTTP redirect vary according to the status code use to
/// generate the redirect. This structure ensures that the loader and its client
/// agree on the interpretation of the redirect response from the server.
table RedirectTarget {
    /// The HTTP method the server suggested for the redirect.
    1: Method method;

    /// The URL the server suggested for the redirect.
    2: fuchsia.url.Url url;

    /// The referrer the server suggested for the redirect.
    3: fuchsia.url.Url referrer;
};

/// A response to an HTTP request.
table Response {
    /// If the response resulted in a network level error, this field will be
    /// set.
    1: Error error;

    /// The response body.
    2: handle<socket> body;

    /// The final URL of the response, after redirects have been followed.
    3: fuchsia.url.Url final_url;

    /// The HTTP status code.
    4: uint32 status_code;

    /// The HTTP status line.
    5: bytes status_line;

    /// The HTTP response headers.
    6: vector<Header>:MAX headers;

    /// A description of the redirect the server requested, if any.
    7: RedirectTarget redirect;
};

/// An HTTP loader.
///
/// The loader can service many HTTP requests concurrently. The loader tracks
/// all the outstanding requests and will cancel them all if the client closes
/// the loader interface.
[Discoverable]
protocol Loader {
    /// Initiate the given HTTP request, follow redirects, and return the final
    /// response.
    ///
    /// The loader will follow redirects (up to an implementation-defined limit)
    /// and return the final response as a reply to this message. To cancel the
    /// request, either close the loader interface or close the peer to the
    /// `event` included in the `request`.
    Fetch(Request request) -> (Response response);

    /// Initiate the given HTTP request and return all intermediate responses to
    /// the given client.
    ///
    /// Unlike `Fetch`, `Start` does not automatically follow all redirects.
    /// Instead, each individual response along the redirect chain is delivered
    /// to the `LoaderClient`.
    Start(Request request, LoaderClient client);
};

/// A client interface used with `Loader.Start`.
///
/// Closing the underlying channel will cancel the associated HTTP transaction.
protocol LoaderClient {
    /// Called by the loader when the loader receives an HTTP response.
    ///
    /// If the server has requested a redirect, then `redirect` in `response`
    /// table will describe the target the server requested. To follow the
    /// redirect, reply to this message. To not follow the redirect, close the
    /// underlying channel.
    OnResponse(Response response) -> ();
};
