0

If I have a page written in Ruby that contains a form (it's an ERB file running in Rack/Puma). The page is processed using ERB.new(File.read('index.html')).result.

How can I detect a POST request and check the request params without Rails or other similar frameworks. Gems would be okay! But the file must be kept as a single file as it's called using ERB directly (the reasons for this are out of scope for this question).

In PHP I could do this with:

// if a post request if($_SERVER['REQUEST_METHOD'] == "POST") { // if post request contains a password and matches the string if($_POST['password'] == 'qwe123') { // do something } else { // do something else } } 

How can I do the same in Ruby?

1
  • @JordanRunning I've updated the question to allow gems but not use Rails or other frameworks. I need to be able to do it in a single file inline so gems would be okay to pull in certain methods etc. But I don't want to run it within a framework. Commented Jan 4, 2018 at 22:40

4 Answers 4

5

Please see the documentation for the rack request object which appears to do what you want.

http://www.rubydoc.info/gems/rack/Rack/Request

Try reading http://hawkins.io/2012/07/rack_from_the_beginning/ and using the code there. It might look something like this:

class HelloWorldApp def self.call(env) request = Rack::Request.new env # request.params -- contains the union of GET and POST params # request.post? -- requested with POST # require.body -- the incoming request IO stream if request.post? and request.params['password'] == 'my_password' [200, {}, "Damn, you know me!"] else [200, {}, "Incorrect!!! I don't know you stranger!"] end end end 
Sign up to request clarification or add additional context in comments.

5 Comments

Is it possible to access the Rack Request without the class or method? As the file gets processed directly by ERB so I won't have methods that process the requests outside of the file.
Yes, it's possible. Rack just want a "thing" that has a valid call method. The easiest way is just to give Rack a lambda (which has a call). -> (env) { ... }, where ... is the method body in the answer.
@Aetherus Sorry mate I'm not following that last comment. Could you add a full example to your answer? Thanks.
@Cameron answer added.
Ah okies. Sorry what I meant was that the code has to be inside the actual ERB file itself. I already have a rack up file that uses Rack Jekyll to run the website but I have modified it to run ERB files as well. So I can only code inside the ERB file itself. Is that possible to access the request purely from within the file (like you can in PHP)?
4

You might want to take a look at rack-server-pages. I haven't used it, but it seems like it does what you're looking for:

Rack middleware and application for serving dynamic pages in very simple way. There are no controllers or models, just only views like a jsp, asp and php!

It exposes the Rack::Request object to the template as request, so you ought to be able to do something like this:

<% if request.post? %> <% if request['password'] == 'qwe123' %> Do something <% else %> Do something else <% end %> <% end %> 

Comments

0

Create a file named config.ru with the following content

run -> (env) { request = Rack::Request.new env # request.params -- contains the union of GET and POST params # request.post? -- requested with POST # require.body -- the incoming request IO stream if request.post? and request.params['password'] == 'my_password' [200, {}, "Damn, you know me!"] else [200, {}, "Incorrect!!! I don't know you stranger!"] end } 

Then in terminal, run rackup, that's all.

Comments

-2

Ruby and PHP are not the same thing. Ruby is a general purpose computer language that can be used to process http requests, among other things. PHP has evolved into a more general purpose language, but in its roots it's made to easily process http requests out of the box.

What that means is that the PHP language processor has everything built in to interact with the Apache server (or nginx, lighttpd, etc.) and run a script when a URL is requested on the server. That script will inherit an environment that includes get variables (the "query" part of the url), post variables (passed in as the body of the request), and various information about the http request, the web server, etc. All of that is presented to your script without you having to do anything else. On the other side, your script just needs to "print" and the information will make it out to the web browser on the other end.

Ruby is a very different beast. It's a general purpose language that wasn't built specifically for use on a web server, so to get this same functionality you have to use some sort of framework - even if it's just a gem - to get information from the server that you'll need as well as to put together an outbound response to the web browser on the other end.

The easiest way to get that functionality is to use Sinatra.

http://sinatrarb.com/

As you can see on the home page, you create a really simple script like this:

require 'sinatra' get '/frank-says' do 'Put this in your pipe & smoke it!' end 

Then, in the browser you go to http://whatever.com/frank-says and it'll show "Put this in your pipe & smoke it!".

You still need something to connect Apache and your Sinatra application if you're using Apache, and it'll probably be Passenger or something like it. Alternately you can use a Ruby web server such as Puma.

Edit:

Here's a good article discussing Rails::API vs. Sinatra vs. Grape:

http://blog.scoutapp.com/articles/2017/02/20/rails-api-vs-sinatra-vs-grape-which-ruby-microframework-is-right-for-you

Definitely worth a read, also.

4 Comments

Thanks for the info. However I need it to remain as a single file that then gets processed via ERB.new. So can't use Sinatra etc.
Sinatra apps can be a single file, and can process ERB.
Yeah, if you'd bother to follow the link you would find single file examples that include erb templates.
No what I mean is that the processing is done by something else (Jekyll Rack) that has been modified to run ERB files. So therefore I can't pull in another framework.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.