Skip to content

Latest commit

 

History

History
533 lines (398 loc) · 19.3 KB

spec.md

File metadata and controls

533 lines (398 loc) · 19.3 KB

1. Introduction

1.1. General

The document describes the HTTP Request in Editor format designed to provide a simple way to create, execute, and store information about HTTP requests. The specification mostly repeats RFC 7230 with several extensions intended for easier requests composing and editing.

The differences between RFC 7230 and the HTTP Request in Editor format are highlighted using a smaller font size, e.g.:
This text highlights the differences between the base HTTP message protocol and the HTTP Request in Editor format.

The document is intended to serve as a complete and self-consistent specification. All readers are invited to report any errors, typos and inconsistencies.

1.2. Example Request

###
POST http://example.com/api/add
Content-Type: application/json

{
  “name”: “entity”,
  “value”: “content”
}

The above fragment will execute a POST request to http://example.com/api/add with the JSON message body.

1.3. Notation

The format is described using context-free grammar and semantics written in natural language. Context-free grammar provides a formal definition, while format semantics explains the purpose and possible use cases for the statements.

Context-free grammar is represented as a set of production rules.

The base token can be replaced with the child token enclosed in parentheses.

base:
      ‘(’ child ‘)’

The base token can be replaced with either child-1 or child-2.

base:
      child-1
      child-2

The base token can be replaced with either child or optional-child followed by child.

base:
      [optional-child] child

The base token can be replaced with child taken one or multiple times.

base:
      (child)+

The base token can be replaced with either nothing or child taken one or multiple times.

base:
      (child)*

2. Lexical structure

2.1. Base symbols

input-character:
      any Unicode character except new-line

Unlike the HTTP message format described in RFC 7230, HTTP Request in Editor supports unicode characters as part of request target, path or query.

alpha:
      ASCII Latin letters A-Z (\u0041- \u005a) or a-z (\u0061-\u007a)

digit:
      0-9 (\u0030-\u0039)

identifier-character:
      alpha
      digit
      ‘-’
      ‘_’

identifier:
      (ident_ifier-character)+

2.2. Line Terminators

new-line:
      LF, also known as "newline"
      CR, also known as "return"
      CR LF, “return” followed by “newline”

new-line-with-indent:
      new-line required-whitespace

line-tail:
      (input-character)* new-line

2.3. Whitespaces

whitespace:
      SP, also known as "space"
      HT, also known as "horizontal tab"
      FF, also known as "form feed"

optional-whitespace:
      (whitespace)*

required-whitespace:
      (whitespace)+

2.4. Comments

Line comments are supported in HTTP Requests. Comments can be used before or after a request, inside the header section, or within the request body. Comments used within the request body must start from the beginning of the line with or without indent.

line-comment:
      ‘#’ line-tail
      ‘//’ line-tail

Example:

# request comment
// request comment

The HTTP message protocol supports comments only as part of specialized header fields; HTTP Request in Editor supports general line comments.

2.5. Request Separators

Multiple requests defined in a single file must be separated from each other with a request separator symbol. A separator may contain comments.

request-separator:
      ‘###’ line-tail

Example:

###

or

### request comment

3. Grammar structure

3.1. Requests file

An HTTP Requests file is a list of HTTP requests separated by a request separator. A file may start or end with multiple request separators.

requests-file:
      (request-separator)* request (request-with-separator)* (request-separator)*

request-with-separator:
      (request-separator)+ request

Example:

###
GET http://example.com
###
GET http://example.com
###

One of the most important extensions HTTP Request in Editor provides is the support of multiple requests within a single file. This capability was introduced to make the format more flexible.

3.2. Request

An HTTP request starts with a request line followed by optional header fields, message body, response handler, and previous response references. Message body must be separated from the request line or header fields with an empty line.

request:
      request-line new-line headers new-line [message-body] [response-handler] [response-ref]

Example:

POST http://example.com/auth
Content-Type: application/json

< input.json 
> {% client.global.set("auth", response.body.token); %} 
<> previous-response.200.json

Compared with the HTTP message format, two new request sections were introduced: response-ref and response-handler.

3.2.1 Request line

A request line consists of a request method, target and the HTTP protocol version. If the request method is omitted, ‘GET’ will be used as a default. The HTTP protocol version can be also omitted.

request-line:
      [method required-whitespace] request-target [required-whitespace http-version]

method:
      ‘GET’
      ‘HEAD’
      ‘POST’
      ‘PUT’
      ‘DELETE’
      ‘CONNECT’
      ‘PATCH’
      ‘OPTIONS’
      ‘TRACE’

http-version:
      ‘HTTP/’ (digit)+ ‘.’ (digit)+

Example:

http://example.com

or

GET http://example.com HTTP/1.1

There are two important differences in request-line between the HTTP message and the HTTP Request in Editor formats:
   1) The HTTP Request in Editor format pre-defines the list of supported methods; The HTTP message defines the method as any token;
   2) The request method and the protocol version are optional in the HTTP Request in Editor format but are required in the HTTP message.

3.2.1.1 Request target

A request target can be an absolute path on the server, a full path to the server resources including the request scheme, host, port, and the path on the server, and asterisk path, which is intended for performing server-wide requests.

If the first request target type is used, the host must be defined in the ‘Host’ header field; otherwise, the request can’t be executed.

request-target:
      origin-form
      absolute-form
      asterisk-form

origin-form:
      absolute-path [‘?’ query] [‘#’ fragment]

Example:

GET /api/get
Host: example.com

If the request target is a full path, it’s necessary to specify the target authority and optionally the request scheme and path on the server. ‘http’ will be used as a default value if scheme is not specified.

absolute-form:
      [scheme ‘://’] hier-part [‘?’ query] [‘#’ fragment]

scheme:
      ‘http’
      ‘https’

hier-part:
      authority [absolute-path]

Example:

GET http://example.com/api/get

The asterisk form can be used for a server-wide OPTIONS request.

asterisk-form:
      ‘*’

Example:

OPTIONS * HTTP/1.1
Host: http://example.com:8080

Absolute-form and authority-form from the HTTP message format were combined into a simplified absolute-form version.

3.2.1.2. Authority

Authority is a target host and port. A host can be represented by the IPv4 or IPv6 address, or by a host name.

authority:
      host [‘:’ port]
port:
      (digit)+

host:
      ‘[‘ ipv6-address ‘]’
      ipv4-or-reg-name

ipv6-address:
      (any input-character except ‘/’ and ‘]’)+
ipv4-or-reg-name:
      (any input-character except ‘/’, ‘:’, ‘?’ and ‘#’)+

Example:

http://[::1]
http://127.0.0.1:8080
http://example.com

HTTP Request in Editor supports unicode characters as part of request authority.

3.2.1.3. Resource path

The resources path on the server is represented by a number of segments separated by ‘/’ or line separators. A path segment may contain any unicode symbol except line separator, ‘/‘, ‘?’ and ‘#’. A path ends after a new line without indent or after the ‘?’ or the ‘#’ symbols.

absolute-path:
      ‘/’
      (path-separator segment)+

path-separator:
      ‘/’
      new-line-with-indent

segment:
      (any input-character except ‘/’, ‘?’ and ‘#’)*

HTTP Request in Editor supports unicode characters as part of a resources path. A resources path can be split into several lines for better request readability. Line separators won’t be sent as part of the request during execution.

3.2.1.4. Query and Fragment

A request query may contain any unicode characters except line separators and the ‘#’ symbol.

query:
      (any input-character except ‘#’)* [new-line-with-indent query]

Example:

http://example.com/api/get?id=42

A request fragment may contain any unicode characters except line separators and the ‘?’ symbol. The fragment part of a URL is used only on a client side; therefore, it won’t be sent as part of the request.

fragment:
      (any input-character except ‘?’)* [new-line-with-indent fragment]

Example:

http://example.com/api/get#q=hello+world

All non-ASCII symbols in path and query are encoded before sending; the already encoded symbols must not be encoded twice. For example, ‘%20’ must be inserted as ‘%2520’ to be sent as part of the path.

HTTP Request in Editor supports unicode characters as part of the request query and fragment.

3.2.2. Headers

Each header field consists of a case-insensitive field name followed by a colon (‘:’), optional leading whitespace, the field value, and optional trailing whitespace.

Header fields are send as is without encoding.

headers:
      (header-field new-line)*

header-field:
      field-name ‘:’ optional-whitespace field-value optional-whitespace

field-name:
      (any input-character except ‘:’)+

field-value:
      line-tail [new-line-with-indent field-value]

Example:

GET http://example.com/api/get?id=15
From: user@example.com

3.2.3. Message body

The message body can be represented as a simple message or a mixed type message (multipart-form-data). A request message can be inserted in-place or from a file.

message-body:
      messages
      multipart-form-data

messages:
      message-line [ new-line message-line ]

message-line:
      (any input-character except ‘< ’, ’<> ’ and ‘###’) line-tail
      input-file-ref

input-file-ref:
      ‘<’ required-whitespace file-path

file-path:
      line-tail

Example:

POST http://example.com/api/add
Content-Type: application/json

{ “key”: “value” }

Or

POST http://example.com/api/add
Content-Type: application/json

< ./input.json

Unlike the HTTP message format, the HTTP Request in Editor format supports sending the message body from a separate file.

3.2.3.1. Multipart-form-data

Multipart form data is a mixed message body consisting of several multipart fields separated by a boundary. A multipart field consists of optional header fields and a simple request message. Message body type and multipart boundary should be defined in the ‘Content-Type’ request header field.

multipart-form-data:
      multipart-field [multipart-form-data] boundary

multipart-field:
      boundary (header-field new-line)* new-line [messages]

Example:

POST http://example.com/api/upload
Content-Type: multipart/form-data; boundary=abcd

--abcd
Content-Disposition: form-data; name="text"

Text
--abcd
Content-Disposition: form-data; name="file_to_send"; filename="input.txt"

< ./input.txt
--abcd--

3.2.4. Response handler

A custom response handler script can be specified at the end of the request to capture and save information from the response to a global variable, or to perform assertions. A script can be inserted in-place or by referencing a separate file. An in-place script can’t contain ‘%}’ or request separator (‘###’).

response-handler:
      ‘>’ required-whitespace ‘{%’ handler-script ‘%}’
      ‘>’ required-whitespace file-path

Example:

GET http://example.com/auth

> {% client.global.set("auth", response.body.token);%}

The response handler section is not defined in the HTTP message format; it was introduced in HTTP Request in Editor.

3.2.5. Response reference

A reference to a previously received response is represented with the ‘<> ’ symbol and the path to a file. References are used to provide easy access to the requests execution history. The section may be useful for comparing different responses.

response-ref:
      ‘<>’ required-whitespace file-path

Example:

GET http://example.com

<> previous-response.200.json

The response reference section is not defined in the HTTP message format; it was introduced in HTTP Request in Editor.

3.2.6. Environment variables

Environment variables are used for avoiding unnecessary data duplication in requests or for providing an easy way of switching between the development and production environments. They can be used inside request target, header fields and message body. Each environment variable is represented by a case-sensitive identifier surrounded by double curly braces.

env-variable:
      ‘{{’ optional-whitespace identifier optional-whitespace ‘}}’

Example:

GET http://{{host}}/api/get?id={{ element-id }}

Environment variables are not defined in the HTTP message format; they were introduced in HTTP Request in Editor.

4. Execution

TODO: describe request execution process: preprocessing (decoding and encoding, whitespace trimming), variable substitution, execution, response handler (update global variables, perform assertions).

4.1. Encoding

4.1.1. Host

TODO: specify how non-ASCII symbols in host should be handled. RFC3986

4.1.2. Resource path and query

All non-ASCII symbols in path and query are encoded before sending; the already encoded symbols must not be encoded twice. For example, ‘%20’ must be inserted as ‘%2520’ to be sent as part of the path.

4.1.3. Request body

Request body should be encoded according to the ‘Content-Type’ header field. If it’s not specified, the ‘UTF-8’ encoding should be used.

4.2. Whitespaces

4.2.1. Resource path and query

Whitespaces around each line of the request path and the query will be trimmed. To send leading or trailing whitespaces, use the encoded version.

Example:

http://example.com/
    api
    /get

The request will be sent as “http://example.com/api/get”.

Example:

http://example.com/
    %20api%20
    +/get+

The request will be sent as “http://example.com/ api / get ”.

4.2.2. Request body

If the request body is configured in-place, whitespaces around it will be trimmed. To send leading or trailing whitespaces as part of the request body, send it from a separate file.

Example:

###
POST http://example.com/add


message-body

###

Only “message-body” will be send as the request body.

Example:

###
POST http://example.com/add

< input.txt
###

input.txt:


message-body

The whole content of the ‘input.txt’ will be send as request body, i.e. “\nmessage-body\n”.

4.3. Multipart/form-data

Multipart form body part can be sent either as a file or as a plain string body. Which one to use is regulated by the ‘filename’ option in the body part header.

Example:
The first body part will be sent as a string and the second one – as a file.

POST http://example.com/api/upload
Content-Type: multipart/form-data; boundary=abcd

--abcd
Content-Disposition: form-data; name="text"

Text
--abcd
Content-Disposition: form-data; name="file_to_send"; filename="input.txt"

< ./input.txt
--abcd--

4.4 Environment variables

TODO: how to define environment, how value is inserted

4.5 Response handler script

Response handler script should be written in JavaScript ECMAScript 5.1 specification

TODO: describe API available in response handler script