|
| 1 | +--- |
| 2 | +title: HTTP – Knowledge Base – kdb+ and q documentation |
| 3 | +description: How to work with HTTP in q |
| 4 | +keywords: browser, http, https, kdb+, q, web |
| 5 | +--- |
| 6 | +# :fontawesome-solid-handshake: HTTP |
| 7 | + |
| 8 | +## HTTP client |
| 9 | + |
| 10 | +### Creating HTTP requests |
| 11 | + |
| 12 | +kdb+ has helper methods that provide functionality as described in the linked reference material: |
| 13 | + |
| 14 | +* [.Q.hg](../ref/dotq.md#hg-http-get) for performing a HTTP GET, where a query string can be sent in the URL |
| 15 | +* [.Q.hp](../ref/dotq.md#hp-http-post) for performing a HTTP POST, where data transmitted is sent in the request body |
| 16 | + |
| 17 | +e.g. |
| 18 | +```q |
| 19 | +q)/ perform http post |
| 20 | +q).Q.hp["http://httpbin.org/post";.h.ty`txt]"my data" |
| 21 | +"{\n \"args\": {}, \n \"data\": \"my data\", \n \"files\": {}, \n \"form\": {}, \n \"headers\": {\n \"Accept-Encoding\": \"gzip\", \n \"Content-Length\": \"7\", \n \"Content-Type\": \"text/plain\", \n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-665711e1-19e62fef6b6e4d192a9a7096\"\n }, \n \"json\": null, \n \"origin\": \"78.147.173.108\", \n \"url\": \"http://httpbin.org/post\"\n}\n" |
| 22 | +q)/ request gzipped data, which is unzipped & returned in json and formatted appropriately |
| 23 | +q).j.k .Q.hg "http://httpbin.org/gzip" |
| 24 | +gzipped| 1b |
| 25 | +headers| `Accept-Encoding`Host`X-Amzn-Trace-Id!("gzip";"httpbin.org";"Root=1-665710aa-50bd49d724b532913348a62a") |
| 26 | +method | "GET" |
| 27 | +origin | "78.147.173.108" |
| 28 | +``` |
| 29 | + |
| 30 | +In addition, kdb+ provides a low level HTTP request mechanism: |
| 31 | + |
| 32 | +```q |
| 33 | +`:http://host:port "string to send as HTTP request" |
| 34 | +``` |
| 35 | + |
| 36 | +which returns the HTTP response as a string. |
| 37 | + |
| 38 | +An HTTP request generally consists of: |
| 39 | + |
| 40 | +* a request line (URL, method, protocol version), terminated by a carriage return and line feed, |
| 41 | +* zero or more header fields (field name, colon, field value), terminated by a carriage return and line feed |
| 42 | +* an empty line (consisting of a carriage return and a line feed) |
| 43 | +* an optional message body |
| 44 | + |
| 45 | +e.g. |
| 46 | + |
| 47 | +```q |
| 48 | +q)/ perform HTTP DELETE |
| 49 | +q)`:http://httpbin.org "DELETE /anything HTTP/1.1\r\nConnection: close\r\nHost: httpbin.org\r\n\r\n" |
| 50 | +"HTTP/1.1 200 OK\r\ndate: Wed, 29 May 2024 12:23:54 GMT\r\ncontent-type: application/json\r\ncontent-length: 290\r\nconnection: close\r\nserver: gunicorn/19.9.0\r\naccess-control-allow-origin: *\r\naccess-control-allow-credentials: true\r\n\r\n{\n \"args\": {},... |
| 51 | +q)postdata:"hello" |
| 52 | +q)/ perform HTTP POST (inc Content-length to denote the payload size) |
| 53 | +q)`:http://httpbin.org "POST /anything HTTP/1.1\r\nConnection: close\r\nHost: httpbin.org\r\nContent-length: ",(string count postdata),"\r\n\r\n",postdata |
| 54 | +"HTTP/1.1 200 OK\r\ndate: Wed, 29 May 2024 13:08:41 GMT\r\ncontent-type: application/json\r\ncontent-length: 321\r\nconnection: close\r\nserver: gunicorn/19.9.0\r\naccess-control-allow-origin: *\r\naccess-control-allow-credentials: true\r\n\r\n{\n \"args\": {}, \n \"data\": \"hello\"... |
| 55 | +``` |
| 56 | + |
| 57 | +An HTTP response typically consists of: |
| 58 | + |
| 59 | +* a status line (protocol version, status code, reason), terminated by a carriage return and line feed |
| 60 | +* zero or more header fields (field name, colon, field value), terminated by a carriage return and line feed |
| 61 | +* an empty line (consisting of a carriage return and a line feed) |
| 62 | +* an optional message body |
| 63 | + |
| 64 | +e.g. |
| 65 | + |
| 66 | +```q |
| 67 | +q)/ x will be complete HTTP response |
| 68 | +q)x:`:http://httpbin.org "DELETE /delete HTTP/1.1\r\nConnection: close\r\nHost: httpbin.org\r\n\r\n" |
| 69 | +q)/ seperate body from headers, get body |
| 70 | +q)@["\r\n\r\n" vs x;1] |
| 71 | +"{\n \"args\": {}, \n \"data\": \"\", \n \"files\": {}, \n \"form\": {}, \n \"headers\": {\n \"Host\": \"httpbin.org\", \n \"X-Amzn-Trace-Id\": \"Root=1-66572924-7396cee34f268fcd406e94d5\"\n }, \n \"json\": null, \n \"origin\": \"78.147.173.108\", \n \"url\": \"http://httpbin.org/delete\"\n}\n" |
| 72 | +``` |
| 73 | + |
| 74 | +!!! note "If a server uses chunked transfer encoding, the response is constructed from the chunks prior to returning (since V3.3 2014.07.31)." |
| 75 | + |
| 76 | +:fontawesome-regular-map: |
| 77 | +[HTTP](https://en.wikipedia.org/wiki/HTTP) |
| 78 | + |
| 79 | + |
| 80 | +### SSL/TLS |
| 81 | + |
| 82 | +To use SSL/TLS, kdb+ should first be [configured to use SSL/TLS](ssl.md). For any request requiring SSL/TLS, replace `http` with `https`. |
| 83 | + |
| 84 | +## HTTP server |
| 85 | + |
| 86 | +kdb+ has an in-built service capable of handling HTTP/HTTPS requests. |
| 87 | + |
| 88 | +### Listening port |
| 89 | + |
| 90 | +When kdb+ is [configured](../basics/listening-port.md) to listen on a port, it uses the same port as that serving kdb+ IPC and websocket connections. |
| 91 | + |
| 92 | +### SSL/TLS |
| 93 | + |
| 94 | +HTTPS can be handled once kdb+ has been [configured to use SSL/TLS](ssl.md). |
| 95 | + |
| 96 | +### Authentication / Authorization |
| 97 | + |
| 98 | +Client requests can be authenticated/authorized using [.z.ac](../ref/dotz.md#zac-http-auth). |
| 99 | +This allows kdb+ to be customized with a variety of mechanisms for securing HTTP requests e.g. LDAP, OAuth2, OpenID Connect, etc. |
| 100 | + |
| 101 | +### Request handling |
| 102 | + |
| 103 | +HTTP request handling is customized by using the following callbacks: |
| 104 | + |
| 105 | +* [.z.ph](../ref/dotz.md#zph-http-get) for HTTP GET |
| 106 | +* [.z.pp](../ref/dotz.md##zpp-http-post) for HTTP POST |
| 107 | +* [.z.pm](../ref/dotz.md##zpp-http-post) for HTTP OPTIONS/PATCH/PUT/DELETE |
| 108 | + |
| 109 | +#### Default .z.ph handling |
| 110 | + |
| 111 | +The default implementation of .z.ph displays all variables and views. For example, starting kdb+ listening on port (`q -p 8080`) and visiting `http://localhost:8080` from a web browser on the same machine, displays all created variables/views). |
| 112 | + |
| 113 | +Providing q code as a GET param causes it to be evaluated eg. `http://localhost:8080?1+1` returns `2`. |
| 114 | + |
| 115 | +[.h.HOME](../ref/doth.md#hhome-webserver-root) can be set to be the webserver root in order to serve files contained in the directory e.g. |
| 116 | +creating an HTML file index.html in directory `/webserver/` and setting `.h.HOME="/webserver"` allows the file to be viewed via `http://localhost:8080/index.html'. |
| 117 | + |
| 118 | +:fontawesome-regular-map: |
| 119 | +[Restricting HTTP queries](../wp/permissions/index.md#restricting-http-queries) |
| 120 | +<br> |
| 121 | +:fontawesome-regular-map: |
| 122 | +[Custom web server](custom-web.md) |
| 123 | + |
| 124 | +### Keep-alive |
| 125 | + |
| 126 | +Persistent connections to supported clients can be enabled via [.h.ka](../ref/doth.md#hka-http-keepalive) |
| 127 | + |
| 128 | +### Compression |
| 129 | + |
| 130 | +HTTP server supports gzip compression via `Content-Encoding: gzip` for responses to `form?…`-style requests. |
| 131 | +The response payload must be 2,000+ chars and the client must indicate support via `Accept-Encoding: gzip` in the HTTP header. |
| 132 | +(Since V4.0 2020.03.17.) |
| 133 | + |
| 134 | +## HTTP markup |
| 135 | + |
| 136 | +The [.h namespace](../ref/doth.md) provides a range of markup and HTTP protocol formatting tools. |
| 137 | + |
| 138 | +---- |
| 139 | +:fontawesome-solid-street-view: |
| 140 | +_Q for Mortals_ |
| 141 | +[§11.7.1 HTTP Connections](/q4m3/q4m3/11_IO/#1171-http-connections) |
0 commit comments