From 041a9844d9b03818ca67f033d76efec6011b0c72 Mon Sep 17 00:00:00 2001 From: Yessiest Date: Sat, 9 Sep 2023 01:08:21 +0400 Subject: [PATCH] More examples, +fixes to response not resetting +fixes to missing request body --- README.md | 115 ++++++++++++++++++-------------------- examples/buckets.ru | 22 ++++++++ examples/helloworld.ru | 13 +++++ examples/lib | 1 + examples/logging.ru | 25 +++++++++ examples/stack.ru | 20 +++++++ examples/staticfiles.ru | 12 ++++ lib/hyde/probe/handler.rb | 1 + lib/hyde/request.rb | 5 +- 9 files changed, 152 insertions(+), 62 deletions(-) create mode 100644 examples/buckets.ru create mode 100644 examples/helloworld.ru create mode 120000 examples/lib create mode 100644 examples/logging.ru create mode 100644 examples/stack.ru create mode 100644 examples/staticfiles.ru diff --git a/README.md b/README.md index 6d70c1a..20768a7 100644 --- a/README.md +++ b/README.md @@ -8,38 +8,38 @@ Hyde was made mostly for fun. Ideally it will become something more, but as of y A simple "Hello, World!" HTTP API using Hyde ```ruby -require 'Hyde' +require 'hyde' -server = Hyde::Server.new Port: 8000 do - get "/hello" do |ctx| - ctx.response.body = "Hello, World!" - ctx.response['Content-Type'] = "text/plain" - end +app = Hyde::Server.new do + get "/hello" do + header "content-type", "text/plain" + "Hello world!" + end end -server.start +run app ``` A push/pull stack as an HTTP API -```ruby +```ruby require 'hyde' -Stack = [] +stack = [] -server = Hyde::Server.new Port: 8000 do - get "pull" do |ctx| - ctx.response.body = "#{Stack.pop}" - ctx.response["Content-Type"] = "text/plain" - end - post "push" do |ctx| - Stack.push ctx.request.body - ctx.response.body = "#{ctx.request.body}" - ctx.response["Content-Type"] = "text/plain" - end +app = Hyde::Server.new do + get "/pop" do + header 'content-type', 'text/plain' + stack.pop.to_s + end + post "/push" do + header 'content-type', 'text/plain' + stack.push(request.body) + request.body + end end -server.start +run app ``` Several push/pull buckets @@ -47,25 +47,23 @@ Several push/pull buckets ```ruby require 'hyde' -Stack = {"bucket_1" => [], "bucket_2" => [], "bucket_3" => []} +stack = { "1" => [], "2" => [], "3" => [] } -server = Hyde::Server.new Port: 8000 do - path ["bucket_1","bucket_2","bucket_3"] do - get "pull" do |ctx| - bucket_name = (ctx.filepath.match /bucket_[^\/]*/)[0] - ctx.response.body = "#{Stack[bucket_name].pop}" - ctx.response["Content-Type"] = "text/plain" - end - post "push" do |ctx| - bucket_name = (ctx.filepath.match /bucket_[^\/]*/)[0] - Stack[bucket_name].push ctx.request.body - ctx.response.body = "#{ctx.request.body}" - ctx.response["Content-Type"] = "text/plain" - end +app = Hyde::Server.new do + path "bucket_(1|2|3)" do + get "pop" do |bucket| + header "content-type", "text/plain" + stack[bucket].pop.to_s end + post "push" do |bucket| + header "content-type", "text/plain" + stack[bucket].push(request.body) + request.body + end + end end -server.start +run app ``` Static file serving @@ -74,16 +72,13 @@ Static file serving ```ruby require 'hyde' -server = Hyde::Server.new Port:8000 do - path "static" do - root "/var/www" - index ["index.html","index.htm"] - serve "*/*.html" safe_regexp: false - serve "*.html" - end +app = Hyde::Server.new do + root "/var/www" + index ["index.html","index.htm"] + serve "**/*.(html|htm)" end -server.start +run app ``` Logging on a particular path @@ -91,29 +86,29 @@ Logging on a particular path ```ruby require 'hyde' -server = Hyde::Server.new Port:8000 do - path "unimportant" do - get "version" do |ctx| - ctx.response.body = '{"version": "the good one"}' - ctx.response['Content-Type'] = "application/json" - end +app = Hyde::Server.new do + path "unimportant" do + get "version" do + header "content-type", "text/plain" + "1337 (the best one)" end - path "important" do - preprocess do |ctx| - # Implement logging logic here - puts "Client at #{ctx.request.remote_ip} wanted to access something /important!" - end - get "answer" do |ctx| - ctx.response.body = '{"answer":42}' - ctx.response['Content-Type'] = "application/json" - end + end + path "important" do + preprocess do |req| + # Implement logging logic here + puts "Client at #{req.headers['REMOTE_ADDR']} wanted to access something /important!" end + get "answer" do + header "content-type", "application/json" + '{"answer":42, "desc":"something important!"}' + end + end end -server.start +run app ``` -And a lot more to come (hopefully) +And a lot more to be found in /examples in this repo. # Documentation diff --git a/examples/buckets.ru b/examples/buckets.ru new file mode 100644 index 0000000..39acb85 --- /dev/null +++ b/examples/buckets.ru @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib") +require 'hyde' + +stack = { "1" => [], "2" => [], "3" => [] } + +app = Hyde::Server.new do + path "bucket_(1|2|3)" do + get "pop" do |bucket| + header "content-type", "text/plain" + stack[bucket].pop.to_s + end + post "push" do |bucket| + header "content-type", "text/plain" + stack[bucket].push(request.body) + request.body + end + end +end + +run app diff --git a/examples/helloworld.ru b/examples/helloworld.ru new file mode 100644 index 0000000..31205e9 --- /dev/null +++ b/examples/helloworld.ru @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib") +require 'hyde' + +app = Hyde::Server.new do + get "/hello" do + header "content-type", "text/plain" + "Hello World!" + end +end + +run app diff --git a/examples/lib b/examples/lib new file mode 120000 index 0000000..dc598c5 --- /dev/null +++ b/examples/lib @@ -0,0 +1 @@ +../lib \ No newline at end of file diff --git a/examples/logging.ru b/examples/logging.ru new file mode 100644 index 0000000..42e2cc7 --- /dev/null +++ b/examples/logging.ru @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib") +require 'hyde' + +app = Hyde::Server.new do + path "unimportant" do + get "version" do + header "content-type", "text/plain" + "1337 (the best one)" + end + end + path "important" do + preprocess do |req| + # Implement logging logic here + puts "Client at #{req.headers['REMOTE_ADDR']} wanted to access something /important!" + end + get "answer" do + header "content-type", "application/json" + '{"answer":42, "desc":"something important!"}' + end + end +end + +run app diff --git a/examples/stack.ru b/examples/stack.ru new file mode 100644 index 0000000..f07af22 --- /dev/null +++ b/examples/stack.ru @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib") +require 'hyde' + +stack = [] + +app = Hyde::Server.new do + get "/pop" do + header 'content-type', 'text/plain' + stack.pop.to_s + end + post "/push" do + header 'content-type', 'text/plain' + stack.push(request.body) + request.body + end +end + +run app diff --git a/examples/staticfiles.ru b/examples/staticfiles.ru new file mode 100644 index 0000000..11ec180 --- /dev/null +++ b/examples/staticfiles.ru @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib") +require 'hyde' + +app = Hyde::Server.new do + root "/var/www" + index ["index.html", "index.htm"] + serve "**/*.(html|htm)" +end + +run app diff --git a/lib/hyde/probe/handler.rb b/lib/hyde/probe/handler.rb index 7df15c1..58142ee 100644 --- a/lib/hyde/probe/handler.rb +++ b/lib/hyde/probe/handler.rb @@ -34,6 +34,7 @@ module Hyde # @return [Boolean] true if further navigation is possible # @raise [UncaughtThrowError] may raise if die() is called. def process(request) + @response = nil return reject(request) unless request.path.match?(/^\/?$/) @request = request diff --git a/lib/hyde/request.rb b/lib/hyde/request.rb index 6b28e32..6681294 100644 --- a/lib/hyde/request.rb +++ b/lib/hyde/request.rb @@ -37,7 +37,7 @@ module Hyde # Returns request body (if POST data exists) # @return [nil, String] def body - @rack.input&.gets + @body ||= @rack.input&.gets end # Push current navigation state (path, splat, param) onto state stack @@ -112,7 +112,8 @@ module Hyde [name.delete_prefix("HTTP_"), value] if name.start_with?("HTTP_") end.to_h headers.merge!({ "CONTENT_TYPE" => env["CONTENT_TYPE"], - "CONTENT_LENGTH" => env["CONTENT_LENGTH"] }) + "CONTENT_LENGTH" => env["CONTENT_LENGTH"], + "REMOTE_ADDR" => env["REMOTE_ADDR"] }) headers.freeze end end