openapi: 3.0.0
info:
  title: webfakes::httpbin_app() API
  version: 1.0.0
  contact:
    email: csardi.gabor@gmail.com
  license:
    name: The MIT License
    url: 'https://opensource.org/licenses/MIT'
  description: |
    This is a webfakes web app for HTTP testing in R packages.
    It implements the https://httpbin.org API

paths:
  /get:
    get:
      tags:
      - HTTP methods
      summary: GET request
      description: |
        An endpoint to make a GET request agains. It returns the request's
        parameters and the request headers, in JSON.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/get'
  /delete:
    delete:
      tags:
      - HTTP methods
      summary: DELETE request
      description: |
        Endpoint to make DELETE requests againts.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'
  /patch:
    patch:
      tags:
      - HTTP methods
      summary: PATCH request
      description: |
        Endpoint to make PATCH requests against.
      responses:
        '200':
          description:  Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'
  /post:
    post:
      tags:
      - HTTP methods
      summary: POST request
      description: |
        Endpoints to make a POST request against.
      responses:
        '200':
          description:  Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'
  /put:
    put:
      tags:
      - HTTP methods
      summary: PUT request
      description: |
        Endpoints to make a PUT request against.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'

  '/basic-auth/:user/:password':
    parameters:
    - name: user
      in: path
      required: true
      description: User name.
      schema:
        type: string
    - name: password
      in: path
      required: true
      description: Password.
      schema:
        type: string
    - name: Authorization
      in: header
      schema:
        type: string
      description: |
        Base64 encoded user name and password. See <https://en.wikipedia.org/wiki/Basic_access_authentication#Client_side> for the protocol.
    get:
      tags:
      - Auth
      summary: Basic authentication.
      description: |
        Basic authentication with specified user and password
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  authenticated:
                    type: boolean
                  user:
                    type: string
                    example: "Aladdin"
        '401':
          description: Failed authentication.
          headers:
            WWW-Authenticate:
              description: Contains the authentication realm.
              schema:
                type: string
                pattern: '^Basic realm=".*"'

  '/hidden-basic-auth/:user/:password':
    parameters:
    - name: user
      in: path
      required: true
      description: User name.
      schema:
        type: string
    - name: password
      in: path
      required: true
      description: Password.
      schema:
        type: string
    - name: Authorization
      in: header
      schema:
        type: string
      description: |
        Base64 encoded user name and password.
        See <https://en.wikipedia.org/wiki/Basic_access_authentication#Client_side>
        for the protocol.
    get:
      tags:
      - Auth
      summary: Hidden basic authentication.
      description: |
        Basic authentication with specified user and password. This is the same
        as `/basic-auth`, but it returns a 404 if no authentication is supplied or
        the authentication fails.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  authenticated:
                    type: boolean
                  user:
                    type: string
                    example: "Aladdin"
        '404':
          description: Failed authentication.

  '/digest-auth/:qop/:user/:passwd':
    parameters:
    - name: qop
      in: path
      required: true
      description: Quality of protection, possible values are `auth` and `auth-int`.
      schema:
        type: string
    - name: user
      in: path
      required: true
      description: User name.
      schema:
        type: string
    - name: passwd
      in: path
      required: true
      description: Password.
      schema:
        type: string
    - name: require_cookie
      in: query
      required: false
      description: |
        Whether to require cookie handling for a successful authentication.
        Set to `1`, 't` or `true` to require cookies.
      scheme:
        type: string
    - name: Authorization
      in: header
      schema:
        type: string
      description: |
        Digest authentication header. See
        https://en.wikipedia.org/wiki/Digest_access_authentication for the details.
    get:
      tags:
      - Auth
      summary: Digest authentication.
      description: |
        Digest authentication with specified user and password
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  authenticated:
                    type: boolean
                  user:
                    type: string
                    example: "Aladdin"
        '401':
          description: Failed authentication.

  '/digest-auth/:qop/:user/:passwd/:algorithm':
    parameters:
    - name: qop
      in: path
      required: true
      description: Quality of protection, possible values are `auth` and `auth-int`.
      schema:
        type: string
    - name: user
      in: path
      required: true
      description: User name.
      schema:
        type: string
    - name: passwd
      in: path
      required: true
      description: Password.
      schema:
        type: string
    - name: algorithm
      in: path
      required: true
      description: |
        Hashing algorithm to use: `MD5`, `SHA-256` or `SHA-512`.
      schema:
        type: string
      default: MD5
    - name: require_cookie
      in: query
      required: false
      description: |
        Whether to require cookie handling for a successful authentication.
        Set to `1`, 't` or `true` to require cookies.
      scheme:
        type: string
    - name: Authorization
      in: header
      schema:
        type: string
      description: |
        Digest authentication header. See
        https://en.wikipedia.org/wiki/Digest_access_authentication for the details.
    get:
      tags:
      - Auth
      summary: Digest authentication algorithms.
      description: |
        Digest authentication with specified user and password, and algorithm.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  authenticated:
                    type: boolean
                  user:
                    type: string
                    example: "Aladdin"
        '401':
          description: Failed authentication.

  '/digest-auth/:qop/:user/:passwd/:algorithm/:stale_after':
    parameters:
    - name: qop
      in: path
      required: true
      description: Quality of protection, possible values are `auth` and `auth-int`.
      schema:
        type: string
    - name: user
      in: path
      required: true
      description: User name.
      schema:
        type: string
    - name: passwd
      in: path
      required: true
      description: Password.
      schema:
        type: string
    - name: algorithm
      in: path
      required: true
      description: |
        Hashing algorithm to use: `MD5`, `SHA-256` or `SHA-512`.
      schema:
        type: string
      default: MD5
    - name: stale_after
      in: path
      required: true
      description: |
        How many requests are allowed. This is stored in a cookie.
      schema:
        type: string
      default: 'never'
    - name: require_cookie
      in: query
      required: false
      description: |
        Whether to require cookie handling for a successful authentication.
        Set to `1`, 't` or `true` to require cookies.
      scheme:
        type: string
    - name: Authorization
      in: header
      schema:
        type: string
      description: |
        Digest authentication header. See
        https://en.wikipedia.org/wiki/Digest_access_authentication for the details.
    get:
      tags:
      - Auth
      summary: Digest authentication, stale after.
      description: |
        Digest authentication with specified user, password and algorithm,
        with a stale_after value.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  authenticated:
                    type: boolean
                  user:
                    type: string
                    example: "Aladdin"
        '401':
          description: Failed authentication.

  '/bearer':
    parameters:
    - name: Authorization
      in: header
      schema:
        type: string
        pattern: '^Bearer '
    get:
      tags:
      - Auth
      summary: Bearer authentication.
      description: |
        Checks is that a token is supplied in the `Authorization` header.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  authenticated:
                    type: boolean
                  token:
                    type: string
        '401':
          description: Failed authentication.
          headers:
            WWW-Authenticate:
              description: Contains the authentication realm.
              schema:
                type: string
                pattern: '^bearer$'

  '/status/:status':
    parameters:
    - $ref: '#/components/parameters/status'
    delete:
      tags:
      - Status codes
      summary: Return the specified HTTP status code, works for all HTTP verbs.
      description: |
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`. See
        <https://en.wikipedia.org/wiki/List_of_HTTP_status_codes> for more
        about status codes.
      responses:
        '100':
          description: Informational responses.
        '200':
          description: Success.
        '300':
          description: Redirection.
        '400':
          description: Client errors.
        '500':
          description: Server errors.
    get:
      tags:
      - Status codes
      summary: Return the specified HTTP status code, works for all HTTP verbs.
      description: |
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`. See
        <https://en.wikipedia.org/wiki/List_of_HTTP_status_codes> for more
        about status codes.
      responses:
        '100':
          description: Informational responses.
        '200':
          description: Success.
        '300':
          description: Redirection.
        '400':
          description: Client errors.
        '500':
          description: Server errors.
    patch:
      tags:
      - Status codes
      summary: Return the specified HTTP status code, works for all HTTP verbs.
      description: |
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`. See
        <https://en.wikipedia.org/wiki/List_of_HTTP_status_codes> for more
        about status codes.
      responses:
        '100':
          description: Informational responses.
        '200':
          description: Success.
        '300':
          description: Redirection.
        '400':
          description: Client errors.
        '500':
          description: Server errors.
    post:
      tags:
      - Status codes
      summary: Return the specified HTTP status code, works for all HTTP verbs.
      description: |
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`. See
        <https://en.wikipedia.org/wiki/List_of_HTTP_status_codes> for more
        about status codes.
      responses:
        '100':
          description: Informational responses.
        '200':
          description: Success.
        '300':
          description: Redirection.
        '400':
          description: Client errors.
        '500':
          description: Server errors.
    put:
      tags:
      - Status codes
      summary: Return the specified HTTP status code, works for all HTTP verbs.
      description: |
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`. See
        <https://en.wikipedia.org/wiki/List_of_HTTP_status_codes> for more
        about status codes.
      responses:
        '100':
          description: Informational responses.
        '200':
          description: Success.
        '300':
          description: Redirection.
        '400':
          description: Client errors.
        '500':
          description: Server errors.

  '/headers':
    get:
      tags:
      - Request inspection
      summary: HTTP request headers.
      responses:
        '200':
          description: The requests's HTTP headers.
          content:
            application/json:
              schema:
                type: object
                properties:
                  headers:
                    type: object

  '/ip':
    get:
      tags:
      - Request inspection
      summary: IP address of the client.
      responses:
        '200':
          description: |
            The IP address of the client, usually `127.0.0.1`, as the webfakes
            server runs on the localhost.
          content:
            application/json:
              schema:
                type: object
                properties:
                  origin:
                    type: string

  '/user-agent':
    get:
      tags:
      - Request inspection
      summary: The client's user agent.
      responses:
        '200':
          description: The content of the `User-Agent` HTTP request header.
          content:
            application/json:
              schema:
                type: object
                properties:
                  'user-agent':
                    type: string

  '/cache':
    parameters:
    - name: If-Modified-Since
      in: header
    - name: If-None-Match
      in: header
    get:
      tags:
      - Response inspection
      summary: Caching
      description: |
        Returns a 304 if an `If-Modified-Since` header or `If-None-Match` is present.
        Returns the same as a GET otherwise.
      responses:
        '200':
          description: Cached response.
          content:
            application/json:
                $ref: '#/components/schemas/get'
        '304':
          description: Modified.


  '/cache/:value':
    parameters:
    - name: value
      in: path
      schema:
        type: integer
    get:
      tags:
      - Response inspection
      summary: Cache control.
      description: |
        Sets a `Cache-Control` header for n seconds.
      responses:
        '200':
          description: Cache control set.
          content:
            application/json:
                $ref: '#/components/schemas/get'

  '/etag/:etag':
    parameters:
    - name: etag
      in: path
      required: true
      description: Assumed ETag value.
      schema:
        type: string
    get:
      tags:
      - Response inspection
      summary: Work with ETags.
      description: |
        Assumes the specified `etag` parameter as the `ETag` header.
        * If a matching tag is supplied in the `If-None-Match` header, then
          it returns with HTTP status code 304.
        * If a non-matching `If-Match` header is supplied, then it return with
          HTTP status code 412.
        * Otherwise it returns with a JSON body and status 200.

        See <https://en.wikipedia.org/wiki/HTTP_ETag> for more about `ETag`
        headers.
      responses:
        '200':
          description: |
            Non-matching `If-Non-Match` or matching `If-Match`, or no
            such headers at all.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/get'
          headers:
            ETag:
              description: The supplied `etag` value.
              schema:
                type: string
        '304':
          description: |
            Matching `If-Non-Match` header.
        '412':
          description: |
            Non-matchinf `If-Match` header.

  '/response-headers':
    parameters:
    - in: query
      name: params
      schema:
        type: object
        additionalProperties:
          type: string
    get:
      tags:
      - Response inspection
      summary: Set response headers.
      description: |
        Set response headers from the passed query parameters. The same
        parameter migth be specified multiple times to create the same HTTP
        header multiple times.
      responses:
        '200':
          description: |
            The passed query parameters are also returned as a JSON response.
          content:
            application/json:
              schema:
                type: object
    post:
      tags:
      - Response inspection
      summary: Set response headers.
      description: |
        Set response headers from the passed query parameters. The same
        parameter migth be specified multiple times to create the same HTTP
        header multiple times.
      responses:
        '200':
          description: |
            The passed query parameters are also returned as a JSON response.
          content:
            application/json:
              schema:
                type: object


  '/deny':
    get:
      tags:
      - Response formats
      summary: A simple page that is denied for robots.
      description: |
        This exists in conjunction with `/robots.txt` which disallows this page.
      responses:
        '200':
          description: A simple page.
          content:
            text/plain:
              schema:
                type:
                  string
                example:
                  'Example content.'

  '/gzip':
    get:
      tags:
      - Response formats
      summary: Send gzip encoded data.
      responses:
        '200':
          description: Some gzipped JSON.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'
          headers:
            'Content-Encoding':
              description: Set to `gzip`.
              schema:
                type: string
                pattern: '^gzip$'

  '/deflate':
    get:
      tags:
      - Response formats
      summary: Deflated data.
      description: |
        Returns Deflate-encoded data. This needs the zip R package.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/common'
          headers:
            'Content-Encoding':
              description: Set to `deflate`.
              schema:
                type: string
                pattern: '^deflate$'

  '/brotli':
    get:
      tags:
      - Response formats
      summary: brotli compression
      description: |
        Returns brotli-encoded data. This needs the brotli R package.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/common'
          headers:
            'Content-Encoding':
              description: Set to `brotli`.
              schema:
                type: string
                pattern: '^brotli'

  '/encoding/utf8':
    get:
      tags:
      - Response formats
      summary: Send UTF-8 enconded data.
      responses:
        '200':
          description: HTML with a lot of UTF-8.
          content:
            text/html:
              schema:
                type: string
          headers:
            'Content-Type':
              description: Set to `text/html; charset=utf-8`.
              schema:
                type: string

  '/html':
    get:
      tags:
      - Response formats
      summary: Send an HTML page.
      responses:
        '200':
          description: An example HTML page.
          content:
            text/html:
              schema:
                type: string

  '/json':
    get:
      tags:
      - Response formats
      summary: Send a JSON document.
      responses:
        '200':
          description: An example JSON document.
          content:
            application/json:
              schema:
                type: object

  '/robots.txt':
    get:
      tags:
      - Response formats
      summary: Send example `robots.txt` rules.
      description: It will not allow the `/deny` endpoint.
      responses:
        '200':
          description: An example `robots.txt` file.
          content:
            text/plain:
              schema:
                type: string

  '/xml':
    get:
      tags:
      - Response formats
      summary: Send an XML document.
      responses:
        '200':
          description: An example XML document.
          content:
            application/xml:
              schema:
                type: string

  '/base64/:value':
    parameters:
    - name: value
      in: path
      required: true
      description: Assumed ETag value.
      schema:
        type: string
    get:
      tags:
      - Dynamic data
      summary: Base64 decoder
      description: Base64 decode the supplied value and echo it back.
      responses:
        '200':
          description: Decoded base64.
          content:
            application/octet-stream:
              schema:
                type: string

  '/bytes/:n':
    parameters:
    - name: n
      in: path
      required: true
      description: Number of bytes, maximum 10000.
      schema:
        type: integer
    get:
      tags:
      - Dynamic data
      summary: Random bytes.
      responses:
        '200':
          description: Random bytes.
          content:
            application/octest-stream:
              schema:
                type:
                  string

  '/delay/:secs':
    parameters:
    - name: secs
      in: path
      required: true
      description: Number of seconds, fractions are supported.
      schema:
        type: number
    get:
      tags:
      - Dynamic data
      summary: Delayed response.
      description: |
        Wait for the specified number of seconds before sending the response.
      responses:
        '200':
          description: JSON response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'

  '/drip':
    parameters:
    - name: duration
      in: query
      description: Number of seconds for the whole response.
      schema:
        type: number
        default: 2
    - name: numbytes
      in: query
      description: Number of bytes to return.
      schema:
        type: integer
        default: 10
    - name: code
      in: query
      description: HTTP status code to return with.
      schema:
        type: integer
        default: 200
    - name: delay
      in: query
      description: Initial delay, in seconds. Zero means no delay.
      schema:
        type: number
        default: 0
    get:
      tags:
      - Dynamic data
      summary: Drip bytes
      description: |
        Drip the specified number of bytes over the specified number of seconds,
        potentially after some initial delay.
      responses:
        '200':
          description: |
            Data of the specified length. The status code is not neccesarily
            200, but the one specified in the `code` query parameter.
          content:
            application/octet-stream:
              schema:
                type: string

  '/links/:n/:offset':
    parameters:
    - name: n
      in: path
      required: true
      description: Number of links.
      schema:
        type: integer
    - name: offset
      in: path
      required: false
      description: Id of the page to return, out of `n`.
      schema:
        type: integer
    get:
      tags:
      - Dynamic data
      summary: Links
      description: |
        Generate a page containing n links to other pages which do the same.
      responses:
        '200':
          description: |
            HTML links.
          content:
            text/html

  '/stream/:n':
    parameters:
    - name: n
      in: path
      required: true
      description: Number of JSON chunks to send.
      schema:
        type: integer
    get:
      tags:
      - Dynamic data
      summary: Stream JSON chunks.
      description: |
        Stream `n` JSON responses, each terminated by a newline character.
      responses:
        '200':
          description: |
            Streamed JSON responses. Each JSON chunk contains an `id` field, from
            zero, up to `n-1`.
          content:
            application/json

  '/stream-bytes/:n':
    parameters:
    - name: n
      in: path
      required: true
      description: Number of bytes, maximum 102400.
      schema:
        type: integer
    - name: seed
      in: query
      description: Random seed.
      schema:
        type: number
        default: 42
    - name: chunk-size
      in: query
      description: |
        Size of a chunked for the chunked encoding. The last chunk migh be
        shorter than his.
      schema:
        type: integer
        default: 10240
    get:
      tags:
      - Dynamic data
      summary: Stream in chunks.
      description: |
        Streams n random bytes generated with given seed, at given chunk
        size per packet.
      responses:
        '200':
          description: Random bytes.
          content:
            application/octest-stream:
              schema:
                type:
                  string

  '/range/:n':
    parameters:
    - name: n
      in: path
      required: true
      description: Number of bytes, maximum 102400.
      schema:
        type: integer
    - name: chunk_size
      in: query
      required: false
      description: Chunk size, if `duration` is not 0.
      schema:
        type: number
        default: 10240
    - name: duration
      in: query
      required: false
      description: |
        Duration for the total response. It applies to the full response size
        without ranges.
      schema:
        type: number
        default: 0
    get:
      tags:
      - Dynamic data
      summary: Range requests.
      description: |
        Send only part of the response, after a `Range` header.
      responses:
        '200':
          description: |
            Full response, if there was no `Range` header, or the `Range` header
            was invalid.
          content:
            text/plain
        '206':
          description: |
            Partial response, containing the requested range.
    head:
      tags:
      - Dynamic data
      summary: Range requests..
      desciption: |
        HEAD request to an endpoint that supports ranges.
      responses:
        '200':
          description: |
            Response with an `Accept-Ranges: bytes` header.

  '/uuid':
    get:
      tags:
      - Dynamic data
      summary: Random UUID.
      description: It is pseudo-random, and not secure.
      responses:
        '200':
          description: Random UUID v4 in JSON.
          content:
            application/json:
              schema:
                type: object
                properties:
                  uuid:
                    type: string
                    example: "ee4610df-3b7b-4624-8ce9-da6975b3e9f1"

  '/cookies':
    get:
      tags:
      - Cookies
      summary: Cookie data.
      description: Returns cookie data.
      responses:
        '200':
          description: Set cookies.
          content:
            application/json:
              schema:
                type: object
                properties:
                  cookies:
                    type: object

  '/cookies/delete':
    parameters:
    - name: freeform
      in: query
      style: "form"
    get:
      tags:
      - Cookies
      summary: Delete cookies.
      description: |
        Deletes cookie(s) as provided by the query string and redirects
        to cookie list.
      responses:
        '302':
          description: Redirect to the cookie list.

  '/cookies/set':
    parameters:
    - name: freeform
      in: query
      style: "form"
    get:
      tags:
      - Cookies
      summary: Set cookies.
      description: |
        Sets cookie(s) as provided by the query string and redirects
        to cookie list.
      responses:
        '302':
          description: Redirect to the cookie list.

  '/cookies/set/:name/:value':
    parameters:
    - name: name
      in: path
      description: Cookie name.
      schema:
        type: string
    - name: value
      in: path
      description: Cookie value.
      schema:
        type: string
    get:
      tags:
      - Cookies
      summary: Set one cookie.
      description: |
        Sets a cookie and redirects to cookie list.
      responses:
        '302':
          description: Redirect to the cookie list.

  '/image':
    parameters:
    - name: Accept
      in: header
      description: Accepted image content type.
      schema:
        type: string
    get:
      tags:
      - Images
      summary: Return an image.
      description: |
        It selects the format according to the `Accept` request header.
        Supported formats: `image/jpeg`, `image/png`, `image/svg+xml`,
        `image/webp`, `image/*`.
      responses:
        '200':
          description: Image file.
          content:
            image/jpeg:
              schema:
                type: string
                format: binary
            image/png:
              schema:
                type: string
                format: binary
            image/svg+xml:
              schema:
                type: string
                format: binary
            image/webp:
              schema:
                type: string
                format: binary
        '406':
          description: The client did not request a supported media type.
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: "Client did not request a supported media type."
                  accept:
                    type: array
                    items:
                      type: string
                    example:
                    - "image/jpeg"
                    - "image/png"
                    - "image/svg+xml"
                    - "image/webp"

  '/image/:format':
    parameters:
    - name: format
      description: Image format. May be `jpeg`, `png`, `svg` or `webp`.
      in: path
      schema:
        type: string
      required: true
    get:
      tags:
      - Images
      summary: Return an image of the specified format.
      responses:
        '200':
          description: Image file.
          content:
            image/jpeg:
              schema:
                type: string
                format: binary
            image/png:
              schema:
                type: string
                format: binary
            image/svg+xml:
              schema:
                type: string
                format: binary
            image/webp:
              schema:
                type: string
                format: binary

  '/absolute-redirect/:n':
    parameters:
    - name: n
      in: path
      required: true
      description: Number of times to redirect. Maximum is five.
      schema:
        type: integer
    get:
      tags:
      - Redirects
      summary: Redirect to an absolute URL, n times.
      responses:
        '302':
          description: Redirect.

  '/relative-redirect/:n':
    parameters:
    - name: n
      in: path
      description: Number of times to redirect. Maximum is five.
      schema:
        type: integer
      required: true
    get:
      tags:
      - Redirects
      summary: Redirect to a relative URL, n times.
      responses:
        '302':
          description: Redirect.

  '/redirect-to':
    parameters:
    - name: url
      in: query
      description: URL to redirect to.
      schema:
        type: string
    - name: status_code
      in: query
      description: HTTP status code to use for the redirection.
      schema:
        type: integer
        default: 302
    delete:
      tags:
      - Redirects
      summary: Redirect to an URL.
      description: |
        See <https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection>
        for details.
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`.
      responses:
        '300':
          description: Multiple Choices.
        '301':
          description: Moved Permanently.
        '302':
          description: Found (Previously "Moved temporarily")
        '303':
          description: See Other (since HTTP/1.1)
        '304':
          description: Not Modified (RFC 7232)
        '305':
          description: Use Proxy (since HTTP/1.1)
        '306':
          description: Switch Proxy
        '307':
          description: Temporary Redirect (since HTTP/1.1)
        '308':
          description: Permanent Redirect (RFC 7538)
    get:
      tags:
      - Redirects
      summary: Redirect to an URL.
      description: |
        See <https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection>
        for details.
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`.
      responses:
        '300':
          description: Multiple Choices.
        '301':
          description: Moved Permanently.
        '302':
          description: Found (Previously "Moved temporarily")
        '303':
          description: See Other (since HTTP/1.1)
        '304':
          description: Not Modified (RFC 7232)
        '305':
          description: Use Proxy (since HTTP/1.1)
        '306':
          description: Switch Proxy
        '307':
          description: Temporary Redirect (since HTTP/1.1)
        '308':
          description: Permanent Redirect (RFC 7538)
    patch:
      tags:
      - Redirects
      summary: Redirect to an URL.
      description: |
        See <https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection>
        for details.
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`.
      responses:
        '300':
          description: Multiple Choices.
        '301':
          description: Moved Permanently.
        '302':
          description: Found (Previously "Moved temporarily")
        '303':
          description: See Other (since HTTP/1.1)
        '304':
          description: Not Modified (RFC 7232)
        '305':
          description: Use Proxy (since HTTP/1.1)
        '306':
          description: Switch Proxy
        '307':
          description: Temporary Redirect (since HTTP/1.1)
        '308':
          description: Permanent Redirect (RFC 7538)
    post:
      tags:
      - Redirects
      summary: Redirect to an URL.
      description: |
        See <https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection>
        for details.
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`.
      responses:
        '300':
          description: Multiple Choices.
        '301':
          description: Moved Permanently.
        '302':
          description: Found (Previously "Moved temporarily")
        '303':
          description: See Other (since HTTP/1.1)
        '304':
          description: Not Modified (RFC 7232)
        '305':
          description: Use Proxy (since HTTP/1.1)
        '306':
          description: Switch Proxy
        '307':
          description: Temporary Redirect (since HTTP/1.1)
        '308':
          description: Permanent Redirect (RFC 7538)
    put:
      tags:
      - Redirects
      summary: Redirect to an URL.
      description: |
        See <https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection>
        for details.
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`.
      responses:
        '300':
          description: Multiple Choices.
        '301':
          description: Moved Permanently.
        '302':
          description: Found (Previously "Moved temporarily")
        '303':
          description: See Other (since HTTP/1.1)
        '304':
          description: Not Modified (RFC 7232)
        '305':
          description: Use Proxy (since HTTP/1.1)
        '306':
          description: Switch Proxy
        '307':
          description: Temporary Redirect (since HTTP/1.1)
        '308':
          description: Permanent Redirect (RFC 7538)

  '/anything':
    delete:
      tags:
      - Anything
      summary: Returns anything passed in request data.
      description: |
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`.
      responses:
        '200':
          description: The request data.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'
    get:
      tags:
      - Anything
      summary: Returns anything passed in request data.
      description: |
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`.
      responses:
        '200':
          description: The request data.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'
    patch:
      tags:
      - Anything
      summary: Returns anything passed in request data.
      description: |
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`.
      responses:
        '200':
          description: The request data.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'
    post:
      tags:
      - Anything
      summary: Returns anything passed in request data.
      description: |
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`.
      responses:
        '200':
          description: The request data.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'
    put:
      tags:
      - Anything
      summary: Returns anything passed in request data.
      description: |
        This endpoint works for these other HTTP verbs as well, the same
        way as for `GET`: `CONNECT`, `DELETE`, `HEAD`, `MKCOL`, `OPTIONS`,
        `PATCH`, `POST`, `PROPFIND`, `PUT`, `REPORT`.
      responses:
        '200':
          description: The request data.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/common'

components:
  parameters:
    status:
      name: status
      in: path
      required: true
      description: Status code.
      schema:
        type: integer
  schemas:
    get:
      properties:
        args:
          type: object
        headers:
          type: object
        origin:
          type: string
        path:
          type: string
        url:
          type: string
      required:
        - args
        - headers
        - origin
        - path
        - url

    common:
      properties:
        args:
          type: object
        data:
          type: object
        files:
          type: object
        form:
          type: object
        headers:
          type: object
        json:
          type: object
        method:
          type: string
        path:
          type: string
        origin:
          type: string
        url:
          type: string
