HTTP client¶
omni_httpc provides an efficient HTTP/1, HTTP/2 and HTTP/3 (experimental) client functionality.
Standard mode¶
The basic mode for omni_httpc use is through the use of functions provided by the extension.
Preparing a request¶
In order to prepare a request, one can use omni_httpc.http_request() function, with the following
parameters:
| Parameter | Type | Description | Default |
|---|---|---|---|
| url | text | URL | None 1 |
| method | omni_http.http_method | HTTP method 2 | GET |
| headers | omni_http.http_headers | An array of HTTP headers | None |
| body | bytea | Request body | NULL |
The function returns a prepared request. No request is executed at this point.
Null values in headers
If header name is null, it won't create any header. If header value is
null, it'll be serialized as an empty string.
Executing requests¶
Requests can be executed using omni_httpc.http_execute functions which takes a variadic array
of requests (which means you can execute more than one request at a time):
select
version >> 8 as http_version, status, headers,
convert_from(body, 'utf-8')
from
omni_httpc.http_execute(
omni_httpc.http_request('https://example.com'),
omni_httpc.http_request('https://example.org'))
Produces
-[ RECORD 1 ]+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
http_version | 1
status | 200
headers | {"(age,500113)","(cache-control,max-age=604800)","(content-type,\"text/html; charset=UTF-8\")","(date,\"Mon, 29 May 2023 23:45:47 GMT\")","(etag,\"\"\"3147526947+ident\"\"\")","(expires,\"Mon, 05 Jun 2023 23:45:47 GMT\")","(last-modified,\"Thu, 17 Oct 2019 07:18:26 GMT\")","(server,\"ECS (sec/96ED)\")","(vary,Accept-Encoding)","(x-cache,HIT)","(content-length,1256)"}
convert_from | <!doctype html> +
| <html> +
| <head> +
| <title>Example Domain</title> +
| +
| <meta charset="utf-8" /> +
| <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> +
| <meta name="viewport" content="width=device-width, initial-scale=1" /> +
| <style type="text/css"> +
| body { +
| background-color: #f0f0f2; +
| margin: 0; +
| padding: 0; +
| font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +
| +
| } +
| div { +
| width: 600px; +
| margin: 5em auto; +
| padding: 2em; +
| background-color: #fdfdff; +
| border-radius: 0.5em; +
| box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); +
| } +
| a:link, a:visited { +
| color: #38488f; +
| text-decoration: none; +
| } +
| @media (max-width: 700px) { +
| div { +
| margin: 0 auto; +
| width: auto; +
| } +
| } +
| </style> +
| </head> +
| +
| <body> +
| <div> +
| <h1>Example Domain</h1> +
| <p>This domain is for use in illustrative examples in documents. You may use this +
| domain in literature without prior coordination or asking for permission.</p> +
| <p><a href="https://www.iana.org/domains/example">More information...</a></p> +
| </div> +
| </body> +
| </html> +
|
-[ RECORD 2 ]+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
http_version | 1
status | 200
headers | {"(age,21859)","(cache-control,max-age=604800)","(content-type,\"text/html; charset=UTF-8\")","(date,\"Mon, 29 May 2023 23:45:47 GMT\")","(etag,\"\"\"3147526947+ident\"\"\")","(expires,\"Mon, 05 Jun 2023 23:45:47 GMT\")","(last-modified,\"Thu, 17 Oct 2019 07:18:26 GMT\")","(server,\"ECS (sec/96EE)\")","(vary,Accept-Encoding)","(x-cache,HIT)","(content-length,1256)"}
convert_from | <!doctype html> +
| <html> +
| <head> +
| <title>Example Domain</title> +
| +
| <meta charset="utf-8" /> +
| <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> +
| <meta name="viewport" content="width=device-width, initial-scale=1" /> +
| <style type="text/css"> +
| body { +
| background-color: #f0f0f2; +
| margin: 0; +
| padding: 0; +
| font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; +
| +
| } +
| div { +
| width: 600px; +
| margin: 5em auto; +
| padding: 2em; +
| background-color: #fdfdff; +
| border-radius: 0.5em; +
| box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02); +
| } +
| a:link, a:visited { +
| color: #38488f; +
| text-decoration: none; +
| } +
| @media (max-width: 700px) { +
| div { +
| margin: 0 auto; +
| width: auto; +
| } +
| } +
| </style> +
| </head> +
| +
| <body> +
| <div> +
| <h1>Example Domain</h1> +
| <p>This domain is for use in illustrative examples in documents. You may use this +
| domain in literature without prior coordination or asking for permission.</p> +
| <p><a href="https://www.iana.org/domains/example">More information...</a></p> +
| </div> +
| </body> +
| </html> +
|
Response columns¶
| Column | Type | Description |
|---|---|---|
| version | smallint | http_major << 8 + http_minor 3 |
| status | smallint | HTTP response status (200, 404, etc.) |
| headers | omni_http.http_headers | Response headers |
| body | bytea | Response body |
| error | text | If not NULL, an error occurred during request |
Configuring request execution¶
It is also possible to configure certain parameters of request execution.
In this example, we're making omni_httpc switch to HTTP/2:
select
version >> 8 as http_version, status, headers
from
omni_httpc.http_execute_with_options(omni_httpc.http_execute_options(http2_ratio => 100),
omni_httpc.http_request('https://example.com'),
omni_httpc.http_request('https://example.org'))
You can now see that http_version is set to 2:
-[ RECORD 1 ]+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
http_version | 2
status | 200
headers | {"(age,592467)","(cache-control,max-age=604800)","(content-type,\"text/html; charset=UTF-8\")","(date,\"Mon, 29 May 2023 23:49:05 GMT\")","(etag,\"\"\"3147526947+ident\"\"\")","(expires,\"Mon, 05 Jun 2023 23:49:05 GMT\")","(last-modified,\"Thu, 17 Oct 2019 07:18:26 GMT\")","(server,\"ECS (sec/976A)\")","(vary,Accept-Encoding)","(x-cache,HIT)","(content-length,1256)"}
-[ RECORD 2 ]+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
http_version | 2
status | 200
headers | {"(age,500311)","(cache-control,max-age=604800)","(content-type,\"text/html; charset=UTF-8\")","(date,\"Mon, 29 May 2023 23:49:05 GMT\")","(etag,\"\"\"3147526947+ident\"\"\")","(expires,\"Mon, 05 Jun 2023 23:49:05 GMT\")","(last-modified,\"Thu, 17 Oct 2019 07:18:26 GMT\")","(server,\"ECS (sec/96ED)\")","(vary,Accept-Encoding)","(x-cache,HIT)","(content-length,1256)"}
Options¶
| Option | Type | Description | Default |
|---|---|---|---|
| http2_ratio | smallint | Percentage of requests to be attempted with HTTP/2 (0..100) 4 |
0 |
| http3_ratio | smallint | Percentage of requests to be attempted with HTTP/3 (0..100) 4 |
0 |
| force_cleartext_http2 | bool | Allow HTTP/2 to be used without SSL | false |
| first_byte_timeout | int | Timeout before first bytes received in milliseconds. | 5000 |
| timeout | int | General timeout | 5000 |
| follow_redirects | bool | Whether to follow HTTP redirects | true |
| cacerts | text[] | CA certificates to install (PEM-encoded) | null |
| clientcert | client_certificate | Client certificate (private_key and certificate encoded as PEM) |
null |
More options will be added in the near future
Connection Pool¶
In every Postgres process, omni_httpc maintains a connection pool shared across function calls. You can inspect it by calling
omni_httpc.http_connections:
Sample output:
Background mode¶
Not yet supported
There's a plan to add a capability for processing HTTP requests in background, executing SQL queries upon request completion.
However, this work has not been done yet. You're welcome to contribute