Sinatra App Routes Not Working As Anticipated - ruby

I've been doing a Ruby course on Skillcrush (still very much an amateur) and have come across a part of the course where my code just doesn't work.
The app uses Sinatra, and is supposed to show the views/people/index.erb when going to localhost:9292/people, but instead it goes to the error page which it should when the wrong extension is given after localhost:9292/ (normally a date format, but if anything else is entered it should bring an error).
I had to switch computers half way through the course, so have a feeling it may be to do with my setup. I've used the code that they've supplied and have checked for discrepancies using diff --brief -r dir1/ dir2/ and can only see some in my Gemfile.lock file. I'm using Ruby 2.4 due to issues with gems on pre-2.0 Ruby and wondered if this might be the case?
My code can be seen here.
Can anyone see any glaring issues?

I believe what is happening is that Sinatra is pattern matching your url localhost:9292/people to the first route of your index controller get '/:birthdate' instead of get '/people'. Sinatra takes the request and then checks each of the routes in order, the first one to match then handles the request.
To test this:
try changing get '/:birthdate' to get '/birthdate/:birthdate' (if it works you would then have to change any links to birthdate appropriately).
or
comment out the birthdate route
or
move all the routes into the same file and change the order they are arranged in to get a feel for how the pattern matching is occurring.

Related

View routes in Sinatra

The following code snippet is how I am handling routes in my Sinatra application. All of my views are contained in my views/pages directory. These are just haml files that represent static html, with some javascript. Are there any negative implications to loading views in this manner? If the page does not exist, it throws a file not found error. I am worried this is somehow an attack vector.
error RuntimeError do
status 500
"A RuntimeError occured"
end
get '/:page' do
begin
haml "pages/#{params['page']}".to_sym
rescue Errno::ENOENT
status 404
"404"
end
end
I'm not sure if this is a security concern here (I'm not that into all the details of Sinatra) but I tend to be paranoid when using user specified data like for example params['page'] in your example. As said I'm not sure if Sinatra sanitizes the content and would make this example impossible, but imagine it said something like ../db_connection.yml. So Sinatra would be told to load the haml file pages/../db_connection.yml which might actually exist and display it to the user showing them your database configuration.
If you don't have any weird symlinks in your pages directory it would probably be enough to replace all double occurences of a dot with something like .gsub(/\.+/, ".") of the passed string (or replace all dots if you don't need them in the name to be even more paranoid). I'm not sure if there are any multi-byte insecurities where someone could do something ugly with encodings though and it might be useless to do the replacing at all because the exploit would work nevertheless.
Edit: Short reading into the Sinatra manual yielded that
By the way, unless you disable the path traversal attack protection (see below), the request path might be modified before matching against your routes.
So it seams that it should be secure to just use the params value without any special filtering, you may however like to look into the documentation some more (especially the security sections). However I don't think it's too much of a security issue if it's possible to figure out if a file in your pages directory exists or not.
Are there any negative implications to loading views in this manner?
Time would be one, it takes a lot longer to generate a page than to serve a static one. Resource use would be another for the same reason. Added complexity another. Reinventing the wheel would be another.
Why not just put static pages in the public directory? Or why not use a static site generator?
Pick the tool that fits your needs, and don't reinvent the wheel (especially when the framework has already provided you with that wheel!)

Magento code changes in local don't work

I'm trying to fix the Magento search issue where 'OR' is used for comparison of multiple search terms instead of 'AND'.
I've seen quite a number of suggestions on the web regarding how to fix this, and the general idea is as follows:
Copy
app/code/core/Mage/CatalogSearch/Model/resource/Fulltext.php to
app/code/local/Mage/CatalogSearch/Model/resource/Fulltext.php and in the copy, change the instances of 'OR' to 'AND', where the SQL queries are built.
However, my changes don't seem to work as expected and what is even more confusing is that the prepareResult() method (which is where the SQL changes above are made) doesn't even seem to run at all when searches are done. I've tested this by putting some debugging code in the function.
I've used the same debug code to verify that the file gets loaded. But the debug code doesn't run when inserted at the prepareResult() function. (The debug code basically writes to a file on disk).
What am I missing here?
Kindly note that this is not so much about the right way to accomplish the end goal of fixing Magento search. I'm aware it's best done via an extension. I'd just like to figure out why prepareResult() isn't being called as expected.

URL rewriting all pages into one page?

I'm trying to get all URLs except for a few to rewrite to _main.php?url=/url/path/here (the exceptions being a System, Frameworks, _Assets, or Administrator folder). I have a RegEx that does this matching for me: (^|\n)(?!/?(?:_Assets|Administrator|Frameworks|System)).+ but I am not really understanding how to do this properly in IIS8. What it currently does is give me the correct data when I load the page, but it doesn't rewrite the URL, as seen in this image:
My rule looks like this (with no conditions or variables):
I was also trying to follow this guide, but it seemed like the exact opposite of what I wanted to achieve, and I don't know how to do the reverse.
I managed to solve this by changing the regexp to be (^|\n)(?!_main.php\\?)(?!/?(?:_Assets|Administrator|Frameworks|System)).+ (ignoring _main.php) and then changing the rule to be a redirect instead of a rewrite, which achieved the desired effect.

How to debug Octopress markdown source files?

I use Octopress for blogging. Generally it works well except one occassion -- after typing rake generate, I got depressing output which says something like:
psych.rb:203:in `parse': (<unknown>): mapping values are not allowed in this context at line 3 column 6 (Psych::SyntaxError)
I can't remember how many times I've encounterd this situation. Every time I google the key words above, but got nothing help.
What I can do is to exclude all the source files (*.mkd) from _posts, and add them one by one to check which one goes wrong. I keep checking, and finally it turns out that a minor grammer mistake makes octopress angry.
Life should NOT be that hard. So is it possible to debug a octopress source file to show which line of file is incorrect in grammer? The outputs from rake generate don't make sense at all.
The reason could be wrong JAML in the top part of the post (e.g. ':' in the title), see https://github.com/jekyll/jekyll/issues/549 for more info.
I've seen a similar error ("mapping values are not allowed in this context") when I try to convert markdown files, using Pandoc. Perhaps your error message is coming from pandoc somehow?
Don't bother to debug Octopress. Please migrate to Pelican -- a Python-powered static site generator. It is full-featured, easy to use, and no doubt, generating useful debug information.

Adding Bootstrap Less to Sinatra

I have a Modular Sinatra app and I'm trying to add the Bootstrap less to the application.
get '/bootstrap/application.css' do
less :"bootstrap/bootstrap"
end
I have all less files in views/bootstrap, including bootstrap.less.
I get this error:
Less::ParseError at /bootstrap/application.css 'reset.less' wasn't found.
The first real line of Bootstrap.less is:
// CSS Reset
#import "reset.less";
I've tried all different path formats, but it never finds the files it's looking to import. Any idea how to make this work?
Have you tried passing the :paths config option?
get '/bootstrap/application.css' do
less :"bootstrap/bootstrap", :paths => ["views/bootstrap"]
end
I've had problems with this option in the past but it may work for you.
I found a solution that worked for me here: Parsing LESS options in a Sinatra app
Since this question was the one I found first on Google, I thought I'd leave the link here so that others can find it.

Resources