Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite... again, sorry! #740

Open
utrenkner opened this issue Feb 4, 2016 · 3 comments
Open

Rewrite... again, sorry! #740

utrenkner opened this issue Feb 4, 2016 · 3 comments

Comments

@utrenkner
Copy link
Contributor

It seems there are quite a few users who are looking for how to rewrite URLs in h2o. mruby makes it possible, but is not clear how. I quickly explain my latest challenge:

On our server, we have to map query strings to actual files on the server; and these may include blank spaces (or %20 when URL-encoded). For example:
example.com/search?item=something%20and%somethingelse should get the file
example.com/search/something_and_somethingelse

I read the mruby examples for h2o and the Rack specs, but I do not quite understand what I need to write to tell h2o to use a different path. I can read the PATH_INFO and QUERY_STRING environment variables, but how do I communicate the new values back to the h2o server ("look here instead of there")?

On a related note, I found a seemingly well-known gem called "rack-rewrite". And I was wondering, if this might help me with my rewrite rules, and how such a gem could be combined with my h2o server. Do you have an example somewhere?

@kazuho
Copy link
Member

kazuho commented Feb 5, 2016

I can read the PATH_INFO and QUERY_STRING environment variables, but how do I communicate the new values back to the h2o server ("look here instead of there")?

You should set reproxy: on in your configuration file and return a response with an x-reproxy-url header set. That instructs the reproxy handler to return the contents of the URL specified with the header.
see also: https://h2o.examp1e.net/configure/mruby_directives.html#delegating-request

On a related note, I found a seemingly well-known gem called "rack-rewrite". And I was wondering, if this might help me with my rewrite rules, and how such a gem could be combined with my h2o server. Do you have an example somewhere?

Rack-rewrite depends on the libraries provided by Rack, and I am afraid you cannot use it as is from mruby (though IMO porting it to mruby would not be hard).

I do understand there is a need for a more declarative way of specifying redirects rather than writing the rules down using mruby; it would be great if somebody could come up with a port of rack-rewrite or something similar.

@utrenkner
Copy link
Contributor Author

Thank you so much! Now I got it.

For the record - and everyone looking for something similar: The following part of h2o.conf replaces a single empty space with an underscore in all URLs under /test/

E.g. https://www.example.com/test/something%20and%20somethingelse is rewritten to
https://www.example.com/test/something_and_somethingelse

Should h2o not find the rewritten file, it internally redirects to a PHP script which - in my case - makes a lookup from a database to fetch the desired content.

      "/test":
        reproxy: ON
        mruby.handler: |
          lambda do |env|
            if /^\/([^ ]+[ ][^ ]+)/.match(env["PATH_INFO"]) # All URLs with at least one empty space NOT in the beginning or end
              str = "#{$1}"
              str = str.gsub( %r{[ ]}, '_') # replace every single empty space with an underscore
              return [307, {"x-reproxy-url" => "https://www.example.com/test/#{str}"}, []] # reproxy to rewritten URL
            end
            return [399, {}, []]
          end
        file.dir: "/usr/local/www/apache22/data/test/json"   # serve static files if found
        redirect:           # if not found, internally redirect to /test/index.php/<path>
          url: /test/index.php/
          internal: YES
          status: 307

@basbebe
Copy link

basbebe commented Feb 9, 2016

I have to chime in saying that using mruby for this seems very tedious and complicated for someone coming from NGINX.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants