> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gcore.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Request and response properties

FastEdge CDN applications read and modify request and response data through the `get_property` and `set_property` host functions. The table below lists all properties accessible through this API. HTTP headers are read and written through dedicated header methods (`get_http_request_header`, `set_http_response_header`, etc.) and are not included here.

## Available properties

| Property path          | Type    | Access     | Available in                                        | Description                                                                                                                  |
| ---------------------- | ------- | ---------- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `request.url`          | String  | Read-write | `on_http_request_headers`                           | Original URL path before modifications                                                                                       |
| `request.host`         | String  | Read-write | `on_http_request_headers`                           | Host header value                                                                                                            |
| `request.path`         | String  | Read-write | `on_http_request_headers`                           | Request URL path                                                                                                             |
| `request.scheme`       | String  | Read-only  | `on_http_request_headers`                           | Protocol scheme (`http` or `https`)                                                                                          |
| `request.method`       | String  | Read-only  | `on_http_request_headers`                           | HTTP method                                                                                                                  |
| `request.extension`    | String  | Read-only  | `on_http_request_headers`                           | File extension from the request path                                                                                         |
| `request.query`        | String  | Read-write | `on_http_request_headers`                           | Query string                                                                                                                 |
| `request.country`      | String  | Read-only  | `on_http_request_headers`                           | Two-letter country code, derived from client IP                                                                              |
| `request.city`         | String  | Read-only  | `on_http_request_headers`                           | City name, derived from client IP                                                                                            |
| `request.asn`          | String  | Read-only  | `on_http_request_headers`                           | ASN of the network associated with the client IP                                                                             |
| `request.geo.lat`      | String  | Read-only  | `on_http_request_headers`                           | Latitude, derived from client IP                                                                                             |
| `request.geo.long`     | String  | Read-only  | `on_http_request_headers`                           | Longitude, derived from client IP                                                                                            |
| `request.region`       | String  | Read-only  | `on_http_request_headers`                           | Region, derived from client IP                                                                                               |
| `request.continent`    | String  | Read-only  | `on_http_request_headers`                           | Continent, derived from client IP                                                                                            |
| `request.country.name` | String  | Read-only  | `on_http_request_headers`                           | Country name, derived from client IP                                                                                         |
| `nginx.log_field1`     | String  | Write-only | `on_http_request_headers`                           | Appends a value to the CDN access log. Requires [Log Uploader](/cdn/logs/raw-logs-export-cdn-resource-logs-to-your-storage). |
| `response.status`      | Integer | Read-only  | `on_http_response_headers`, `on_http_response_body` | HTTP response status code                                                                                                    |

Property paths are case-sensitive.

The following example reads the client country and conditionally sets the log field:

```rust theme={null}
fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
    if let Some(country) = self.get_property(vec!["request.country"]) {
        let code = String::from_utf8_lossy(&country);
        self.set_property(vec!["nginx.log_field1"], Some(code.as_bytes()));
    }
    Action::Continue
}
```

## Custom properties

Applications can define custom properties to pass state between related hooks. For example, a property set in `on_http_response_headers` is readable in `on_http_response_body`.

<Warning>
  Custom properties created in `on_http_request_headers` are not available in later hooks.
</Warning>

The following example marks a response as Markdown in `on_http_response_headers` and reads that flag in `on_http_response_body`:

```rust theme={null}
fn on_http_response_headers(&mut self, _: usize, _: bool) -> Action {
    if let Some(content_type) = self.get_http_response_header("Content-Type") {
        if content_type.starts_with("text/plain") || content_type.starts_with("text/markdown") {
            self.set_http_response_header("Content-Length", None);
            self.set_http_response_header("Transfer-Encoding", Some("chunked"));
            self.set_http_response_header("Content-Type", Some("text/html"));
            self.set_property(vec!["response.markdown"], Some(b"true"));
        }
    }
    Action::Continue
}

fn on_http_response_body(&mut self, _: usize, _: bool) -> Action {
    if self.get_property(vec!["response.markdown"]).is_none() {
        return Action::Continue;
    }
    // convert body to HTML here
    Action::Continue
}
```
