diff options
Diffstat (limited to 'debian/vendor-h2o/doc/configure/mruby.html')
-rw-r--r-- | debian/vendor-h2o/doc/configure/mruby.html | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/debian/vendor-h2o/doc/configure/mruby.html b/debian/vendor-h2o/doc/configure/mruby.html new file mode 100644 index 0000000..d424351 --- /dev/null +++ b/debian/vendor-h2o/doc/configure/mruby.html @@ -0,0 +1,281 @@ +<!DOCTYPE html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" /> +<base href="../" /> + +<!-- oktavia --> +<link rel="stylesheet" href="assets/searchstyle.css" type="text/css" /> +<script src="search/jquery-1.9.1.min.js"></script> +<script src="search/oktavia-jquery-ui.js"></script> +<script src="search/oktavia-english-search.js"></script> +<!-- /oktavia --> + +<link rel="stylesheet" href="assets/style.css" type="text/css" /> + +<title>Using Mruby - Configure - H2O - the optimized HTTP/2 server</title> +</head> +<body> +<div id="body"> +<div id="top"> + +<h1> +<a href="index.html">H2O</a> +</h1> +<p class="description">the optimized HTTP/1.x, HTTP/2 server</p> + +<!-- oktavia --> +<form id="searchform"> +<input class="search" type="search" name="search" id="search" results="5" value="" placeholder="Search" /> +<div id="searchresult_box"> +<div id="close_search_box">×</div> +<div id="searchresult_summary"></div> +<div id="searchresult"></div> +<div id="searchresult_nav"></div> +<span class="pr">Powered by <a href="https://github.com/shibukawa/oktavia">Oktavia</a></span> +</div> +</form> +<!-- /oktavia --> + +</div> + +<table id="menu"> +<tr> +<td><a href="index.html">Top</a></td> +<td><a href="install.html">Install</a></td> +<td class="selected">Configure</td> +<td><a href="faq.html">FAQ</a></td> +<td><a href="http://blog.kazuhooku.com/search/label/H2O" target="_blank">Blog</a></td> +<td><a href="http://github.com/h2o/h2o/" target="_blank">Source</a></td> +</tr> +</table> + +<div id="main"> + +<h2> +<a href="configure.html">Configure</a> > +Using Mruby +</h2> + + +<p> +<a href="https://github.com/mruby/mruby">mruby</a> 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. +</p> + +<h3 id="programming-interface">Rack-based Programming Interface</h3> + +<p> +The interface between the mruby program and the H2O server is based on <a href="http://www.rubydoc.info/github/rack/rack/master/file/SPEC">Rack interface specification</a>. +Below is a simple configuration that returns <i>hello world</i>. +</p> + +<div class="example"> +<div class="caption">Example. Hello-world in mruby</div> +<pre><code>paths: + "/": + mruby.handler: | + Proc.new do |env| + [200, {'content-type' => 'text/plain'}, ["Hello world\n"]] + end +</code></pre> +</div> + + +<p> +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: +<ul> +<li>no libraries provided as part of Rack is available (only the interface is compatible) +</ul> +</p> + +<p> +In addition to the Rack interface specification, H2O recognizes status code <code>399</code> which can be used to delegate request to the next handler. +The feature can be used to implement access control and response header modifiers. +</p> + +<h3 id="access-control">Access Control</h3> + +<p> +By using the <code>399</code> status code, it is possible to implement access control using mruby. +The example below restricts access to requests from <code>192.168.</code> private address. +</p> + +<div class="example"> +<div class="caption">Example. Restricting access to 192.168.</div> +<pre><code>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 +</code></pre> +</div> + + +<p> +Support for <a href="configure/basic_auth.html">Basic Authentication</a> is also provided by an mruby script. +</p> + +<h3 id="delegating-request">Delegating the Request</h3> + +<p> +When enabled using the <a href="configure/reproxy_directives.html#reproxy"><code>reproxy</code></a> directive, it is possible to delegate the request from the mruby handler to any other handler. +</p> +<p> +<div class="example"> +<div class="caption">Example. Rewriting URL with delegation</div> +<pre><code>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 +</code></pre> +</div> + + +<h3 id="modifying-response">Modifying the Response</h3> + +<p> +When the mruby handler returns status code <code>399</code>, 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. +</p> +<p> +For example, the following example sets <code>cache-control</code> header for requests against <code>.css</code> and <code>.js</code> files. +</p> + +<div class="example"> +<div class="caption">Example. Setting cache-control header for certain types of files</div> +<pre><code>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 +</code></pre> +</div> + + +<p> +Or in the example below, the handler triggers <a href="configure/http2_directives.html#server-push">HTTP/2 server push</a> with the use of <code>Link: rel=preload</code> headers, and then requests a FastCGI application to process the request. +</p> + +<div class="example"> +<div class="caption">Example. Pushing asset files</div> +<pre><code>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: ... +</code></pre> +</div> + + +<h3 id="http-client">Using the HTTP Client</h3> + +<p> +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. +</p> + +<div class="example"> +<div class="caption">Example. Mruby handler returning the response of http://example.com</div> +<pre><code>paths: + "/": + mruby.handler: | + Proc.new do |env| + req = http_request("http://example.com") + status, headers, body = req.join + [status, headers, body] + end +</code></pre> +</div> + + +<p> +<code>http_request</code> is the method that issues a HTTP request. +</p> +<p> +The method takes two arguments. +First argument is the target URI. +Second argument is an optional hash; <code>method</code> (defaults to <code>GET</code>), <code>header</code>, <code>body</code> attributes are recognized. +</p> +<p> +The method returns a promise object. +When <code>#join</code> 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 <code>#each</code> method to receive the contents, b) call <code>#join</code> to retrieve the body as a string, c) return the object as the response body of the mruby handler. +</p> +<p> +The header and the body object passed to <code>http_request</code> 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 <code>#join</code> method of the promise returned by <code>http_request</code> conforms to the requirements of the Rack specification. +</p> +<p> +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. +</p> +<p> +When HTTPS is used, servers are verified using the properties of <a href="configure/proxy_directives.html#proxy.ssl.cafile"><code>proxy.ssl.cafile</code></a> and <a href="configure/proxy_directives.html#proxy.ssl.verify-peer"><code>proxy.ssl.verify-peer</code></a> specified at the global level. +</p> + +<h3 id="logging-arbitrary-variable">Logging Arbitrary Variable</h3> + +<p> +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 <code>x-fallthru-set-</code> 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. +</p> +<p> +This example shows how to read request data, parse json and then log data from mruby. +</p> + +<div class="example"> +<div class="caption">Example. Logging the content of a POST request via request environment variable</div> +<pre><code>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}' +</code></pre> +</div> + + + + + +</div> +<div id="footer"> +<p> +Copyright © 2015 <a href="http://dena.com/intl/">DeNA Co., Ltd.</a> et al. +</p> +</div> +</body> +</html> |