项目作者: vladfaust

项目描述 :
Mount multiple web applications 🚦
高级语言: Crystal
项目地址: git://github.com/vladfaust/http-multiserver.cr.git
创建时间: 2017-09-09T17:34:24Z
项目社区:https://github.com/vladfaust/http-multiserver.cr

开源协议:MIT License

下载


HTTP::Multiserver

Built with Crystal
Build status
API Docs
Releases
Awesome
vladfaust.com
Patrons count
Gitter chat

The requests dispatcher shard for Crystal.

Supporters

Thanks to all my patrons, I can continue working on beautiful Open Source Software! 🙏

Lauri Jutila, Alexander Maslov, Dainel Vera

You can become a patron too in exchange of prioritized support and other perks

Become Patron

About

HTTP::Multiserver dispatches a server request to another vanilla HTTP::Server depending on its path similar to Ruby’s Rack::URLMap.

Installation

Add this to your application’s shard.yml:

  1. dependencies:
  2. http-multiserver:
  3. github: vladfaust/http-multiserver.cr
  4. version: ~> 0.2.0

This shard follows Semantic Versioning 2.0.0, so see releases and change the version accordingly.

Usage

Basic example

  1. require "http-multiserver"
  2. simple_server = HTTP::Server.new([HTTP::LogHandler.new]) do |context|
  3. context.response.print("Hello from Simple Server!")
  4. end
  5. # For example purposes
  6. resque = Resque::Server.new
  7. multiserver = HTTP::Multiserver.new({
  8. "/resque" => resque,
  9. "/" => simple_server,
  10. }, [HTTP::ErrorHandler.new(true)]) do |context|
  11. # This is an optional custom fallback handler; by default returns "404 Not Found"
  12. context.response.status_code = 418
  13. context.response.print("☕ #{context.request.path} not found")
  14. end
  15. multiserver.bind_tcp(5000)
  16. multiserver.listen

HTTP::Multiserver extends from a regular HTTP::Server, so it CAN have its own handlers. Same for underlying servers, they obviously CAN have their own handlers too.

Mapping

Mapping relies on either String or Regex keys; when using String as a key, a slash is automatically appended to it.

Assuming that this map is passed to HTTP::Multiserver initializer:

  1. map = {
  2. "/foo" => foo_server,
  3. %r{/bar} => bar_server,
  4. "/" => fallback_server
  5. }
  6. multiserver = HTTP::Multiserver.new(port, map)

This is how the request is dispatched under the hood (simplified):

  1. internal_map = {
  2. %r{^/foo/} => foo_server,
  3. %r{/bar} => bar_server,
  4. %r{^/} => fallback_server
  5. }
  6. path = request.path.append_slash # "/foo/abc" turns into "foo/abc/"
  7. server = internal_map.find { |regex, _| regex.match(path) }
  8. server ? server.call(context) : not_found

Please see specs for dispatching specifications.

Performance

As mentioned above, HTTP::Multiserver is just a regular HTTP::Server which dispatches the handling to underlying servers based on super-fast Regex.match. A very tiny impact on the performance is expected if any.

Contributing

  1. Fork it ( https://github.com/vladfaust/http-multiserver.cr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am ‘Add some feature’)
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors