Serving static directory in Rails - ruby-on-rails-3

I have a simple rails app deployed to Heroku, and I'm trying to serve a static directory (containing an index.html) from the public/demos folder but running into a weird issue. I have config.serve_static_assets = true enabled in production, and if I go to mysite.com/demos/folder/, I can access the static page fine. But if I go to mysite.com/demos/folder (lacking a trailing slash), the index page loads but fails to load a bunch of linked css/js stuff located in the same directory. Is there any way around this or a better way to do it? I'm not sure what the best way is to serve static content with Rails, but this feels like a poor solution.

Related

Can I change where root requests resolve to in an express app?

I've created a small Express app that essentially serves as a file browser for our department's work. Users can drag their files and folders onto a network drive, and the app presents this folder structure as a browsable web directory for my colleagues to view various simple static files such as html files, images, css and javascript.
This is extremely business critical, and has worked flawlessly for over a year now, but there is one feature that I'd like to add. Occasionally the work contained in a subdirectory is a slightly more complex project, and there would be a huge architecture/complexity benefit from it being able to reference files from its own root path. I'll try and explain with a small example:
/app
/projects
/project1
/project2
/index.html
/styles.css
/finished
/project3
It would be great if there was a simple way I could declare the base url of project 2 to be /app/projects/project2 so that I could reference the css file from the html with href="/styles.css".
I've read that I could do this by creating a second express app for project2, and then route requests to /app/projects/project2 to that app, but this requirement crops up quite regularly and the thought of configuring/managing a multitude of sub apps without breaking the main viewer doesn't seem like fun!
Is there a simpler way? I'm thinking of a special designation in the subdirectory name e.g. "wwwproject2" that could get the app to adjust where it maps root requests to.
I'm sorry if this all sounds insane to those with more knowledge than me!
I don't think there is a way to do that.
But you could simply reference it by using the relative path to it -> href="./styles.css"

AWS EBS - Rails5 / nginx - robots.txt not found error (404)

I deployed a pretty standard Rails 5 app with AWS EBS.
My /robots.txt is not reacheable and requests to it's URL return a 404 error.
I put it in the /public folder along with 404.html, 422.html and 500.html pages, which are correctly served by nginx.
Any clue about what might be wrong? What shall I check?
EB CLI 3.14.6 (Python 2.7.1)
Ruby 2.4.3 / Rails 5.1.4 / Puma (gem) 3.7
Looks like a very similar question have been asked 4 years ago on the official AWS forum: https://forums.aws.amazon.com/thread.jspa?threadID=150904
Only 4 years later a brave guy from AWS stepped in with a reply! Here below the quoted reply:
Hello hello! I'm Chris, the new Ruby platforms person at Elastic
Beanstalk. Visiting this thread today, it looks like there's been a
lot of pain (and also confusion!) from Beanstalk's Ruby+Puma's
handling of static files.
Quick summary: When this thread was created (in 2014), Beanstalk was
essentially using the default Nginx that comes with Amazon Linux, with
only some logging modifications to support the health monitoring. That
spawned this thread, as static files are generally expected to be
served the the web server when one is present.
So, the folks here went and fixed the /assets folder. Great!
Unfortunately, there was a misunderstanding with the request to fix
serving the /public folder - Beanstalk's Puma platform instead serves
things in '/public' from '/pubilc', not from '/'. This is definitely
an issue, so here's some workarounds:
Workaround 1: Turning on serve static assets. Yes, this wastes some
application threads here or there, but if your use case is only
robots.txt and favicon.ico, you're only robbing a couple of appserver
threads. I'd pick this one unless I was running my application servers
hot.
Workaround 2: Write an .ebextension to modify the Nginx configuration
to serve /public at /. I'm in the process of writing one, so I'll tack
it as a reply to this when I've given it the thought it deserves. Some
of the current ones may serve your app's code, so double check the
configuration if you've already done this workaround.
I've created a tracking issue for the team with this level of detail,
so we'll work to get this corrected. Thank you all for your feedback -
we'd love to serve you and your apps better.
Since then, no further replies; if anybody knows the "aws-approved-way" to edit nginx config with .ebextensions let's post it here please! :)
In AWS EB with PUMA, static files under the public folder are served under the /public/ url. Webcrawlers expect the file available at /robots.txt
I've struggled to try and implement routing to these files and settled instead on a more 'Rails' way of implementing this.
1) config/routes.rb
get "/robots.txt", to: "robots#show"
2) app/controllers/robots_controller.rb
class RobotsController < ApplicationController
def show
render "show", layout: false, content_type: "text/plain"
end
end
3) app/views/robots_txts/show.erb
User-agent: *
Disallow: /
The above link to AWS forums is erroring with a 400 right now, so here's how I fixed this issue. Ruby 2.7 running on AWS2 platform:
Static Files in sub-directory of /public:
Create a file under the .ebextensions folder called static-files.conf. Content should look similar to:
option_settings:
aws:elasticbeanstalk:environment:proxy:staticfiles:
/w3c: public/w3c
/images: public/images
This will ensure that all requests to domain.com/images and domain.com/w3c are served from the appropriate /public sub-directory.
Static Files in top level of /public directory:
For top-level files like robots.txt or sitemap.xml add appropriate entry to routes.rb to serve the static content directly:
get '/robots.txt', to: proc {|env| [200, {}, [File.open(Rails.root.join('public', 'robots.txt')).read]] }
get '/sitemap.xml', to: proc {|env| [200, {}, [File.open(Rails.root.join('public', 'sitemap.xml')).read]] }
Ensure production.rb has static files config set properly:
config.serve_static_files = false
This last part is most-important.

Rails 4 images in public folder are not loading on Apache development

I am new to rails. I am working on a sample application for social networking. I have managed to upload the profile picture of users manually (By copying the image uploaded to /tmp/image to the public folder- public/images/tmp/image) and saved the path to db as avatar_url.
In the profile view I used
<%= image_tag(#userinfo.avatar_url, :alt=>"Avatar image")%>
and getting the picture when running on the rails server.
But after that I have deployed the app in apache with passenger in the development environment by setting RailsEnv development. After that the images are not loading. I tried to go to myip:80/public/images/tmp/image, and it gives Routing Error.
After searching on the web, I found that adding config.serve_static_assets = true in production.rb will solve the problem in production. But no use for me because it also stated that the static files will serve in development by default. For confirming the problem again, I started the rails server and opened localhost:3000/profile, image is there and not getting the image in myip:80/profile.
So do I need to add any other config. Or am I not supposed to do that in this way.
Finally, I got the solution for my problem. Just sharing here.
The problem was actually because of permission issues. The picture will be created in a root temp directory on the form submission. Then I copied the image form the temp folder to the public folder. Hence it has only read permissions. After I deployed it, the image gets returns 403 forbidden error.
I used,
FileUtils.chmod 775, target
to set the permission. After that it worked well.
The option config.serve_static_assets = true tells rails to serve the static assets for your application, but that job should really be left to Apache.
Your issue sounds more related to your Apache configuration than rails.
I would take a look at a tutorial on how to configure Apache and Passenger to make sure your environment is setup correctly.
Anything in the public folder should be served by the web server. However myip:80/public/images/tmp/image is not a valid path. You would need to also have a filename at the end with an extension.

get apache to serve a static file named index.html?parameter=1

I am working on a website on a low memory server. I edit/update the website in a CMS and then do a nighly wget to an other folder/vhost that serves fast static pages to the users.
It works great and fast, but now I found out that I have some pages that don't work.
Wget downloads index.php?id=10 and creates the file index.html?id=10.html
One specific folder of my website has the files index.html, index.html?id=1, index.html?id=2, index.html?id=3 etc
When i open www.mysite.com/myfolder/index.html?id=1.html in my browser i get index.html, even if the file index.html?id=1.html exists.
Does anybody have any solution for how to fix this? maybe an htaccess solution or something else?
I am looking forward to any ideas,

Routing to a Location on the Server

I have several custom routes in my rails 3.0 app, the simplest one of which is.
match "*user", "profile#index", :via => :get
Because of that route physical locations on the server are killed. As an example.
/images/rails.png
tries to route to the images user.
I also have to be able to setup where people access
/<username>/archive.zip
So
/buddy/archive.zip
Where the archive.zip is a physical file on the server that has been generated and put there. How can I achieve this in my routing.
For the later I have an actual folder structure in a root folder for /<username>/archive.zip so I was thinking somem sort of symlink would be easy, but without being able to hit physical locations on the server. I am kind of stuck/confused.
Any help is appreciated.
You probably want to have any static assets get handled by your web server before hitting your rails stack. This is generally done by setting the document root in your webserver to the public/ directory within your rails app to serve your static images/css/js.
This is greatly preferred over allowing Rails to serve static assets because web servers are much faster at handling these sorts of requests, and your not tying up your rails processes for these requests, which are often limited to less than a handful.