Grammar::HTTP
Grammar::HTTP
Grammars for parsing HTTP headers, message bodies, and URIs
Synopsis
use Grammar::HTTP;
my $request = "GET / HTTP/1.1\r\nHost: www.raku.org\r\n\r\n";
my $match = Grammar::HTTP.parse($request);
say $match;
# ļ½¢GET / HTTP/1.1
# Host: www.raku.org
#
#ļ½£
# HTTP-message => ļ½¢GET / HTTP/1.1
# Host: www.raku.org
#
#ļ½£
# start-line => ļ½¢GET / HTTP/1.1
#ļ½£
# request-line => ļ½¢GET / HTTP/1.1
#ļ½£
# method => ļ½¢GETļ½£
# request-target => ļ½¢/ļ½£
# HTTP-version => ļ½¢HTTP/1.1ļ½£
# HTTP-name => ļ½¢HTTPļ½£
# major => ļ½¢1ļ½£
# minor => ļ½¢1ļ½£
# header-field => ļ½¢Host: www.raku.orgļ½£
# name => ļ½¢Hostļ½£
# value => ļ½¢www.raku.orgļ½£
# host => ļ½¢www.raku.orgļ½£
# message-body => ļ½¢ļ½£
Rules
token HTTP-start
token HTTP-headers
token HTTP-header
token HTTP-body
token HTTP-message
Parsing individual parts of the HTTP message can also be done by using a different rule. The default
Grammar::HTTP.parse($str)
is really the same as Grammar::HTTP.parse($str, :rule('HTTP-message')
.
So to parse just the start line you could do:
my $string = "GET /http.html HTTP/1.1\r\n";
say Grammar::HTTP.parse($string, :rule<HTTP-start>)'
# ļ½¢GET /http.html HTTP/1.1
# ļ½£
# start-line => ļ½¢GET /http.html HTTP/1.1
# ļ½£
# request-line => ļ½¢GET /http.html HTTP/1.1
# ļ½£
# method => ļ½¢GETļ½£
# request-target => ļ½¢/http.htmlļ½£
# HTTP-version => ļ½¢HTTP/1.1ļ½£
# HTTP-name => ļ½¢HTTPļ½£
# major => ļ½¢1ļ½£
# minor => ļ½¢1ļ½£
Actions
Grammar::HTTP::Actions
can be used to generate a structured hash from a HTTP response message
use Grammar::HTTP::Actions;
use Grammar::HTTP;
my $response = "HTTP/1.1 200 OK\r\n"
~ "Allow: GET, HEAD, PUT\r\n"
~ "Content-Type: text/html; charset=utf-8\r\n"
~ "Transfer-Encoding: chunked, gzip\r\n\r\n";
my $parsed = Grammar::HTTP.parse($response, :actions(Grammar::HTTP::Actions.new));
my %header = $parsed.<HTTP-message>.<header-field>>>.made;
dd %header;
# Hash %header = {
# :Allow($("GET", "HEAD", "PUT")),
# :Content-Type($[
# :type("text"),
# :subtype("html"),
# :parameters([ :charset("utf-8") ])
# ]),
# :Transfer-Encoding($("chunked", "gzip"))}
RFCs
RFC1035 Domain Names - Implementation and Specification
RFC3066 Tags for the Identification of Languages
RFC4234 Augmented BNF for Syntax Specifications: ABNF
RFC5234 Augmented BNF for Syntax Specifications: ABNF (replaces 4234)
RFC7405 Case-Sensitive String Support in ABNF
RFC4647 Matching of Language Tags
RFC5322 Internet Message Format
RFC5646 Tags for Identifying Languages
RFC7230 Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing
RFC7231 Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
RFC7232 Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests
RFC7233 Hypertext Transfer Protocol (HTTP/1.1): Range Requests
RFC7234 Hypertext Transfer Protocol (HTTP/1.1): Caching
RFC7235 Hypertext Transfer Protocol (HTTP/1.1): Authentication