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.
###
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.
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)*
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)+
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
whitespace:
SP, also known as "space"
HT, also known as "horizontal tab"
FF, also known as "form feed"
optional-whitespace:
(whitespace)*
required-whitespace:
(whitespace)+
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.
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
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.
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.
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.
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.
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.
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.
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.
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
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.
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--
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.
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.
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.
TODO: describe request execution process: preprocessing (decoding and encoding, whitespace trimming), variable substitution, execution, response handler (update global variables, perform assertions).
TODO: specify how non-ASCII symbols in host should be handled. RFC3986
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.
Request body should be encoded according to the ‘Content-Type’ header field. If it’s not specified, the ‘UTF-8’ encoding should be used.
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 ”.
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”.
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--
TODO: how to define environment, how value is inserted
Response handler script should be written in JavaScript ECMAScript 5.1 specification
TODO: describe API available in response handler script