From 0937042e07c2cccc800e2e96d1cce8ddbd984f86 Mon Sep 17 00:00:00 2001 From: Pekka Laiho Date: Sat, 20 Jun 2020 10:33:15 +0700 Subject: [PATCH] added function for http requests --- README.md | 10 ++++++- src/Lib/Http.php | 72 +++++++++++++++++++++++++++++++++++++++++++++ src/LispFactory.php | 1 + 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/Lib/Http.php diff --git a/README.md b/README.md index e9520be..0e6d2a4 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ Name | Example | Example result | Description ### Database functions -This is just a simple wrapper for [PDO](https://www.php.net/manual/en/book.pdo.php). +This is a simple wrapper for [PDO](https://www.php.net/manual/en/book.pdo.php). Name | Example | Example result | Description ----------- | ------- | -------------- | ----------- @@ -207,6 +207,14 @@ db-trans | `(db-trans d)` | `true` | Start a transaction. db-commit | `(db-commit d)` | `true` | Commit a transaction. db-rollback | `(db-rollback d)` | `true` | Roll back a transaction. +### Http functions + +This is a simple wrapper for [cURL](https://www.php.net/manual/en/book.curl.php). + +Name | Example | Example result | Description +----------- | ------- | -------------- | ----------- +http | `(http "POST" "http://example.com/" (to-json {"key":"value"}) {"Content-Type":"application/json"})` | `{"status":200 "body":"" "headers":{}}` | Perform a HTTP request. First argument is the HTTP method, second is URL, third is request body and fourth is headers as a hash-map. The function returns a hash-map which contains keys `status`, `body` and `headers`. + ### IO functions Name | Example | Example result | Description diff --git a/src/Lib/Http.php b/src/Lib/Http.php new file mode 100644 index 0000000..78631f0 --- /dev/null +++ b/src/Lib/Http.php @@ -0,0 +1,72 @@ +set('http', new CoreFunc('http', 'Perform a HTTP request.', 2, 4, + function (string $method, string $url, ?string $requestBody = null, ?Hash $requestHeaders = null) { + $ch = curl_init($url); + + $method = strtoupper($method); + if ($method == 'HEAD') { + curl_setopt($ch, CURLOPT_NOBODY, true); + } elseif ($method != 'GET') { + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); + } + + if ($requestBody !== null) { + curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody); + curl_setopt($ch, CURLOPT_POSTREDIR, 3); + } + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + + if ($requestHeaders !== null) { + $h = []; + foreach ($requestHeaders->getData() as $key => $val) { + $h[] = "$key: $val"; + } + curl_setopt($ch, CURLOPT_HTTPHEADER, $h); + } + + // for debugging + // curl_setopt($ch, CURLOPT_VERBOSE, true); + + $responseHeaders = []; + curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$responseHeaders) { + $parts = explode(':', $header); + if (count($parts) == 2) { + $key = trim($parts[0]); + $val = trim($parts[1]); + $responseHeaders[$key] = $val; + } + return strlen($header); + }); + + $responseBody = @curl_exec($ch); + + if (curl_errno($ch) !== 0) { + throw new MadLispException('HTTP error: ' . curl_error($ch)); + } + + $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + curl_close($ch); + + return new Hash([ + 'status' => $status, + 'body' => $responseBody, + 'headers' => new Hash($responseHeaders) + ]); + } + )); + } +} diff --git a/src/LispFactory.php b/src/LispFactory.php index 687054d..2027d01 100644 --- a/src/LispFactory.php +++ b/src/LispFactory.php @@ -45,6 +45,7 @@ class LispFactory (new Lib\Collections())->register($env); (new Lib\Compare())->register($env); (new Lib\Database())->register($env); + (new Lib\Http())->register($env); (new Lib\IO())->register($env); (new Lib\Json())->register($env); (new Lib\Math())->register($env);