From c21c3b0befeb46a51b6bf3758ffa30813bea0ff0 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 9 Mar 2024 14:19:22 +0100 Subject: Adding upstream version 1.44.3. Signed-off-by: Daniel Baumann --- web/server/h2o/libh2o/doc/configure/mruby.html | 281 +++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 web/server/h2o/libh2o/doc/configure/mruby.html (limited to 'web/server/h2o/libh2o/doc/configure/mruby.html') diff --git a/web/server/h2o/libh2o/doc/configure/mruby.html b/web/server/h2o/libh2o/doc/configure/mruby.html new file mode 100644 index 000000000..d424351d8 --- /dev/null +++ b/web/server/h2o/libh2o/doc/configure/mruby.html @@ -0,0 +1,281 @@ + + + + + + + + + + + + + + + + +Using Mruby - Configure - H2O - the optimized HTTP/2 server + + +
+
+ +

+H2O +

+

the optimized HTTP/1.x, HTTP/2 server

+ + +
+ +
+ +
+
+
+Powered by Oktavia +
+
+ + +
+ + + + + + + + + + + + +
+ +

+Configure > +Using Mruby +

+ + +

+mruby is a lightweight implementation of the Ruby programming language. +With H2O, users can implement their own request handling logic using mruby, either to generate responses or to fix-up the request / response. +

+ +

Rack-based Programming Interface

+ +

+The interface between the mruby program and the H2O server is based on Rack interface specification. +Below is a simple configuration that returns hello world. +

+ +
+
Example. Hello-world in mruby
+
paths:
+  "/":
+    mruby.handler: |
+      Proc.new do |env|
+        [200, {'content-type' => 'text/plain'}, ["Hello world\n"]]
+      end
+
+
+ + +

+It should be noted that as of H2O version 1.7.0, there are limitations when compared to ordinary web application server with support for Rack such as Unicorn: +

    +
  • no libraries provided as part of Rack is available (only the interface is compatible) +
+

+ +

+In addition to the Rack interface specification, H2O recognizes status code 399 which can be used to delegate request to the next handler. +The feature can be used to implement access control and response header modifiers. +

+ +

Access Control

+ +

+By using the 399 status code, it is possible to implement access control using mruby. +The example below restricts access to requests from 192.168. private address. +

+ +
+
Example. Restricting access to 192.168.
+
paths:
+  "/":
+    mruby.handler: |
+      lambda do |env|
+        if /\A192\.168\./.match(env["REMOTE_ADDR"])
+          return [399, {}, []]
+        end
+        [403, {'content-type' => 'text/plain'}, ["access forbidden\n"]]
+      end
+
+
+ + +

+Support for Basic Authentication is also provided by an mruby script. +

+ +

Delegating the Request

+ +

+When enabled using the reproxy directive, it is possible to delegate the request from the mruby handler to any other handler. +

+

+

+
Example. Rewriting URL with delegation
+
paths:
+  "/":
+    mruby.handler: |
+      lambda do |env|
+        if /\/user\/([^\/]+)/.match(env["PATH_INFO"])
+          return [307, {"x-reproxy-url" => "/user.php?user=#{$1}"}, []]
+        end
+        return [399, {}, []]
+      end
+
+
+ + +

Modifying the Response

+ +

+When the mruby handler returns status code 399, H2O delegates the request to the next handler while preserving the headers emitted by the handler. +The feature can be used to add extra headers to the response. +

+

+For example, the following example sets cache-control header for requests against .css and .js files. +

+ +
+
Example. Setting cache-control header for certain types of files
+
paths:
+  "/":
+    mruby.handler: |
+      Proc.new do |env|
+        headers = {}
+        if /\.(css|js)\z/.match(env["PATH_INFO"])
+          headers["cache-control"] = "max-age=86400"
+        end
+        [399, headers, []]
+      end
+    file.dir: /path/to/doc-root
+
+
+ + +

+Or in the example below, the handler triggers HTTP/2 server push with the use of Link: rel=preload headers, and then requests a FastCGI application to process the request. +

+ +
+
Example. Pushing asset files
+
paths:
+  "/":
+    mruby.handler: |
+      Proc.new do |env|
+        push_paths = []
+        # push css and js when request is to dir root or HTML
+        if /(\/|\.html)\z/.match(env["PATH_INFO"])
+          push_paths << ["/css/style.css", "style"]
+          push_paths << ["/js/app.js", "script"]
+        end
+        [399, push_paths.empty? ? {} : {"link" => push_paths.map{|p| "<#{p[0]}>; rel=preload; as=#{p[1]}"}.join("\n")}, []]
+      end
+    fastcgi.connect: ...
+
+
+ + +

Using the HTTP Client

+ +

+Starting from version 1.7, a HTTP client API is provided. +HTTP requests issued through the API will be handled asynchronously; the client does not block the event loop of the HTTP server. +

+ +
+
Example. Mruby handler returning the response of http://example.com
+
paths:
+  "/":
+    mruby.handler: |
+      Proc.new do |env|
+        req = http_request("http://example.com")
+        status, headers, body = req.join
+        [status, headers, body]
+      end
+
+
+ + +

+http_request is the method that issues a HTTP request. +

+

+The method takes two arguments. +First argument is the target URI. +Second argument is an optional hash; method (defaults to GET), header, body attributes are recognized. +

+

+The method returns a promise object. +When #join method of the promise is invoked, a three-argument array containing the status code, response headers, and the body is returned. +The response body is also a promise. +Applications can choose from three ways when dealing with the body: a) call #each method to receive the contents, b) call #join to retrieve the body as a string, c) return the object as the response body of the mruby handler. +

+

+The header and the body object passed to http_request should conform to the requirements laid out by the Rack specification for request header and request body. +The response header and the response body object returned by the #join method of the promise returned by http_request conforms to the requirements of the Rack specification. +

+

+Since the API provides an asynchronous HTTP client, it is possible to effectively issue multiple HTTP requests concurrently and merge them into a single response. +

+

+When HTTPS is used, servers are verified using the properties of proxy.ssl.cafile and proxy.ssl.verify-peer specified at the global level. +

+ +

Logging Arbitrary Variable

+ +

+In version 2.3, it is possible from mruby to set and log an arbitrary-named variable that is associated to a HTTP request. +A HTTP response header that starts with x-fallthru-set- is handled specially by the H2O server. Instead of sending the header downstream, the server accepts the value as a request environment variable, taking the suffix of the header name as the name of the variable. +

+

+This example shows how to read request data, parse json and then log data from mruby. +

+ +
+
Example. Logging the content of a POST request via request environment variable
+
paths:
+  "/":
+    mruby.handler: |
+      Proc.new do |env|
+        input = env["rack.input"] ? env["rack.input"].read : '{"default": "true"}'
+        parsed_json = JSON.parse(input)
+        parsed_json["time"] = Time.now.to_i
+        logdata = parsed_json.to_s
+        [204, {"x-fallthru-set-POSTDATA" => logdata}, []]
+      end
+    access-log:
+      path: /path/to/access-log.json
+      escape: json
+      format: '{"POST": %{POSTDATA}e}'
+
+
+ + + + + +
+ + + -- cgit v1.2.3