Skip to content

Commit

Permalink
feat: allow URLContentHandler to accept request body params and enhan…
Browse files Browse the repository at this point in the history
…ce type inference #504
  • Loading branch information
jaredhendrickson13 committed Jul 10, 2024
1 parent 9e60bf1 commit 89c509d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 19 deletions.
13 changes: 10 additions & 3 deletions docs/CONTENT_AND_ACCEPT_TYPES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,18 @@ Content types are used to specify the format of the data being sent in your requ

### application/x-www-form-urlencoded
- MIME Type: `application/x-www-form-urlencoded`
- Description: Use this content type to send form data in the URL of the request. The data is sent as key-value pairs separated by an ampersand `&`.
- Example: ```https://pfsense.example.com?key=value&key2=value2```
- Description: Use this content type to send form data in the URL query string or body of the request. The data is sent as key-value pairs separated by an ampersand `&`.
- Examples:
- URL query string: ```https://pfsense.example.com?key=value&key2=value2```
- Request body: ```key=value&key2=value2```

!!! Note
In the case that both the URL query string and request body contain form data, the data in the URL query string will take precedence.

!!! Warning
The `application/x-www-form-urlencoded` content-type is not fully suitable for requests other than `GET` and `DELETE` requests. It is recommended to use `application/json` for all other request types.
The `application/x-www-form-urlencoded` content-type can only infer the type of the data submitted, and therefor
may not be fully suitable for requests other than `GET` and `DELETE` requests. It is recommended to use
`application/json` for requests that require full control over the data type being sent.

## Accept Types

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ class URLContentHandler extends ContentHandler {
public string $mime_type = 'application/x-www-form-urlencoded';

/**
* Obtains the client's request data from PHP's $_GET superglobal.
*
* @return array The request data parsed from the query string.
* Obtains the raw query string data from the request if present, otherwise obtains the raw request body.
* @note In the event that both the request body and query string contain data, the query string data will take precedence.
* @return string|null The request data parsed from the query string.
*/
public function get_content(): array {
return $_GET;
public function get_content(): ?string {
return $_SERVER['QUERY_STRING'] ?: file_get_contents('php://input');
}

/**
Expand All @@ -26,21 +26,48 @@ class URLContentHandler extends ContentHandler {
* @return mixed The decode content.
*/
protected function _decode(mixed $content = null): mixed {
# Parse the request data into an array
parse_str($content, $content);

# Loop through each query string item and check for expected data types
foreach ($content as $key => $value) {
# Check for boolean type query strings
if ($value === 'true') {
$content[$key] = true;
} elseif ($value === 'false') {
$content[$key] = false;
}

# Check for integer type query strings
if (is_numeric($value)) {
$content[$key] = intval($value);
}
# Infer the data type of the value
$content[$key] = $this->infer_type($value);
}

return $content;
}

/**
* Infers the data type of given string values.
* @param string $value The value to infer the data type of.
* @return mixed The inferred value converted to the appropriate data type.
*/
public function infer_type(mixed $value): mixed
{
# If value is an array, recursively infer the type of each element
if (is_array($value)) {
return array_map([$this, 'infer_type'], $value);
}

# Convert primitive data types
if ($value === 'true') {
return true;
}
elseif ($value === 'false') {
return false;
}
elseif ($value === 'null') {
return null;
}
elseif (ctype_digit($value)) {
return intval($value);
}
elseif (is_numeric($value) and str_contains($value, '.')) {
return floatval($value);
}

# If a data type could not be inferred, return the original string value
return $value;
}
}

0 comments on commit 89c509d

Please sign in to comment.