http_file_parser 0.1.1

A Rust-based parser for .http files, parsing HTTP request data using Pest and making parsed requests.
Documentation
# HTTP File Parser
- Crate: https://crates.io/crates/http_file_parser
- Grammar Rules Docs: https://docs.rs/http_file_parser/latest/http_file_parser/parser/enum.Rule.html

This project is a Rust-based utility for parsing `.http` files, which are commonly used to store HTTP requests in a structured format. By parsing these files, this tool allows automated processing of HTTP requests, useful in scenarios such as API testing.

### Example of an `.http` File

Here’s an example `.http` file that can be parsed by this tool:
```http request
### POST submit request
POST https://eo7nilf42qb5b5e.m.pipedream.net HTTP/1.1
Authorization: Bearer token123
Content-Type: application/json

{ "name": "Alice", "age": 30 }

### GET profile request
GET https://eo7nilf42qb5b5e.m.pipedream.net HTTP/1.1
Accept: application/json

### DELETE account request
DELETE https://eo7nilf42qb5b5e.m.pipedream.net HTTP/1.1
Authorization: Bearer token123

### PUT profile request
PUT https://eo7nilf42qb5b5e.m.pipedream.net HTTP/1.1
Content-Type: application/json

{ "name": "Alice", "age": 31 }

```

## Technical Description

### Parsing Process
Using the Pest library for Rust, this tool analyzes the structure of `.http` files, extracting key information such as:

- **HTTP Method** (e.g., `GET`, `POST`)
- **Request URL** (e.g., `https://example.com/api/resource`)
- **Headers** (e.g., `Content-Type: application/json`)
- **Request Body**

The `.http` files are parsed line-by-line, following a grammar that identifies sections such as the request line, headers, and body. Pest provides a custom grammar defined in `grammar.pest`, which defines these parsing rules in a concise format.

## Grammar
```pest
http_file = { SOI ~ (delimiter | request)* ~ EOI}

request = {
    request_line ~
    headers? ~
    NEWLINE ~
    body?
}

delimiter = { "###" ~ whitespace* ~ title? ~ NEWLINE+ }
title = { (!NEWLINE ~ ANY)+ }

request_line = _{ method ~ " "+ ~ uri ~ " "+ ~ "HTTP/" ~ version ~ NEWLINE }
uri = { (!whitespace ~ ANY)+ }
method = { ("GET" | "DELETE" | "POST" | "PUT") }
version = { (ASCII_DIGIT | ".")+ }
whitespace = _{ " " | "\t" }

headers = { header+ }
header = { header_name ~ ":" ~ whitespace ~ header_value ~ NEWLINE }
header_name = { (!(NEWLINE | ":") ~ ANY)+ }
header_value = { (!NEWLINE ~ ANY)+ }

body = { (!delimiter ~ ANY)+ }
```

### Let's break down the grammar rule by rule:
- ### Overall Structure
The .http file is represented as an http_file, which can contain multiple request blocks, separated by optional delimiter sections. Each request block contains essential components like request_line, headers, and an optional body.
```pest
http_file = { SOI ~ (delimiter | request)* ~ EOI }
```
- SOI: Start of input.
- EOI: End of input.
- The file can contain multiple request and delimiter sections.

- ### Request
Each HTTP request is structured as follows:
```pest
request = {
    request_line ~
    headers? ~
    NEWLINE ~
    body?
}
```
- request_line: Defines the HTTP method, URI, and version.
- headers: Optional section containing one or more headers.
- NEWLINE: Separates headers from the body.
- body: Optional content, can include any data except the delimiter.

- ### Delimiter
The delimiter rule separates different requests within the file and may include an optional title.
```pest
delimiter = { "###" ~ whitespace* ~ title? ~ NEWLINE+ }
title = { (!NEWLINE ~ ANY)+ }
```
- "###": Indicates a delimiter.
- whitespace: Allows for spaces or tabs after the delimiter.
- title: Optional title text for the delimiter section, placed on the same line.

- ### Request Line
Defines the core structure of an HTTP request.
```pest
request_line = _{ method ~ " "+ ~ uri ~ " "+ ~ "HTTP/" ~ version ~ NEWLINE }
```
- method: The HTTP method (e.g., GET, POST).
- uri: The URL endpoint for the request.
- version: The HTTP version (e.g., 1.1).

- ### Method
The allowed HTTP methods:
```pest
method = { ("GET" | "DELETE" | "POST" | "PUT") }
```

- ### URI and Version
Defines the URI and HTTP version formats:
```pest
uri = { (!whitespace ~ ANY)+ }
version = { (ASCII_DIGIT | ".")+ }
```
- uri: Any non-whitespace characters represent the endpoint.
- version: Consists of digits and periods, like 1.1.

- ### Headers
Optional section containing one or more headers.
```pest
headers = { header+ }
header = { header_name ~ ":" ~ whitespace ~ header_value ~ NEWLINE }
header_name = { (!(NEWLINE | ":") ~ ANY)+ }
header_value = { (!NEWLINE ~ ANY)+ }
```
- header_name: The name of the header (e.g., Content-Type).
- header_value: The value of the header (e.g., application/json).

- ### Body
Optional content for the request:
```pest
body = { (!delimiter ~ ANY)+ }
```

### Parsing Outcome and Usage
Once parsed, the extracted data is structured into an `HttpRequest` object. This object is then used to perform HTTP requests via the `reqwest` library and printing the response.