In Sinatra, is there a way to forward a request to another app? - sinatra

I'm trying to do something like this:
class Dispatcher < Sinatra::Base
def initialize
#foo = Foo.new
end
get '/foo/*' do
#foo.call(params[:splat])
end
end
So that URL /foo/abc/def?xxx=yyy would be like calling the Foo app with /abc/def?xxx=yyy.
This seems like it should be easy, but I haven't seen any example of it.

I ended up doing this in a Rack config.ru file:
map "/abc" do
run Foo.new('abc')
end
map "/def" do
run Foo.new('def')
end
Not exactly what I wanted, but saves me from modifying the underlying app.

I'm not sure why you would use Sinatra for that. If I understand you right, and you use Apache with Proxy-Rewrite rules you just do:
The .htaccess file
RewriteEngine On
RewriteRule ^foo/(.*) http://localhost:61000/$1 [P]
So all your domain.tdl/foo get redirected to your local running app athttp://localhost:61000/ with all Post and Get Parameters.

Related

How to silence DataMapper in Sinatra

So, a simple little question. Every time I perform some transaction with DataMapper inside one of my "get" or "post" blocks, I get output looking something like this...
core.local - - [19/Sep/2012:09:04:54 CEST] "GET /eval_workpiece/state?id=24 HTTP/1.1" 200 4
- -> /eval_workpiece/state?id=24
It's a little too verbose for my liking. Can I turn this feedback off?
This isn’t Datamapper logging, this is the logging done by the WEBrick server, which logs all requests using these two formats by default.
(Note this isn’t Rack logging either, although the Rack::CommonLogger uses the same (or at least very similar) format).
The simplest way to stop this would be to switch to another server that doesn’t add its own logging, such as Thin.
If you want to continue using WEBrick, you’ll need to find a way to pass options to it from your Sinatra app. The current released Sinatra gem (1.3.3) doesn’t allow an easy way to do this, but the current master allows you to set the :server_options setting which Sinatra will then pass on. So in the future you should be able to do this:
set :server_settings, {:AccessLog => []}
in order to silence WEBrick.
For the time being you can add something like this to the end of your app file (I’m assuming you’re launching your app with something like ruby my_app_file.rb):
disable :run
Sinatra::Application.run! do |server|
server.config[:AccessLog] = []
end
To cut off all logging:
DataMapper.logger = nil
To change verbosity:
DataMapper.logger.set_log(logger, :warn) # where logger is Sinatra's logging object
Other levels are :fatal => 7, :error => 6, :warn => 4, :info => 3, :debug => 0 (http://rubydoc.info/gems/dm-core/1.1.0/DataMapper/Logger)
If you're running with ActiveSupport, you can use the Kernel extension:
quietly { perform_a_noisy_task }
This temporarily binds STDOUT and SDTERR to /dev/null for the duration of the block. Since you may not want to suppress all output, theoretically you can do:
with_warnings(:warn) { # or :fatal or :error or :info or :debug
perform_a_noisy_task
}
and appropriate messages will be suppressed. (NB: I say 'theoretically' because using with_warnings gave me a seemingly unrelated error in my Padrino/DataMapper environment. YMMV.)

Difference between uri_for and uri_for_action

What is the difference between $c->uri_for and $c->uri_for_action methods of Catalyst.
Which one to use? And why?
#Devendra I think your examples could be somehow misleading if someone reads them.
uri_for expects path (and not action). It return an absolute URI object, so for example it's useful for linking to static content or in case you don't expect your paths to change.
So for example, let say you've deployed your application on domain example.com and subdir abc (example.com/abc/): $c->uri_for('/static/images/catalyst.png') would return example.com/abc/static/images/catalyst.pn, or for example: $c->uri_for('/contact-us-today') would return example.com/abc/contact-us-today. If you decide later to deploy your application under another subdirectory or at / you'll still end up with correct links.
Let say that your contact-us action looks like: sub contact :Path('/contact-us-today') :Args(0) {...} and you decide later that /contact-us-today should become just /contact-us. If you've used uri_for('/contact-us-today') you'll need to find and change all lines which points to this url. However you can use $c->uri_for_action('/controller/action_name') which will return the correct url.
dpetrov_ in #catalyst says:
If the paths are likely to change, uri_for_action is better idea.
I found below difference between $c->uri_for and $c->uri_for_action
Consider
Othercontroller.pm
__PACKAGE__->config(namespace => 'Hello');
.
.
.
sub bar: Local{
$c->res->redirect($c->uri_for('yourcontroller/method_name'));
$c->res->redirect($c->uri_for_action('yourcontroller/method_name'));
}
Yourcontroller.pm
sub method_name: Local{
print "In Yourcontroller:: method_name"
}
In case of $c->uri_for the url changes to
http://localhost:3000/Hello/yourcontroller/method_name
However for $c->uri_for_action the url changes to
http://localhost:3000/yourcontroller/method_name
So the namespace gets added in case of uri_for.

Testing view helpers

I'm currently working on a Rails plugin used for generating iPhone specific HTML meta-tags. I'm trying to use ActionView::TestCase for unit tests but keep getting the same error. See file contents and error below. Any ideas or help would be much appreciated.
test_helper.rb
require 'rubygems'
require 'test/unit'
require 'active_support'
require 'action_view'
require File.join(File.dirname(__FILE__), '..', 'lib', 'iphone_helper')
iphone_test_helper.rb
require 'test_helper'
class IphoneHelperTest < ActionView::TestCase
test 'br' do
tag = tag('br')
assert_tag_in tag, '<br />'
end
end
error
RuntimeError: In order to use #url_for, you must include routing helpers explicitly. For instance, `include Rails.application.routes.url_helpers
Awful and hacky workaround that worked for me (since I am working on a gem and not in a full rails environment):
require 'ostruct'
module ActionController::UrlFor
def _routes
helpers = OpenStruct.new
helpers.url_helpers = Module.new
helpers
end
end
Did you try to include the respective Module in an old-fashioned way?:
include ActionDispatch::Routing::RouteSet
If a NameError is raised telling you that ActionDispatch is unknown you might have to require 'action_dispatch'.
Maybe a stupid question, but is the fact that the class name and the file name don't match possibly a problem (IphoneHelperTest vs. iphone_test_helper.rb)? Sometimes that leads to classes not being loaded.

Configuring form_path in Catalyst::Controller::Formbuilder

Using the Catalyst::Controller::FormBuilder module to handle forms in a Catalyst application.
The documentation says you can set the form_path like this:
form_path => File::Spec->catfile( $c->config->{home}, 'root', 'forms' ),
But the call to config() in my application is at the top level of the base module. Therefore, $c is undefined. So I can't call $c->config->{home}.
What is the proper way to configure form_path please?
You should be able to access configuration values that have already been set from your application's main module using the __PACKAGE__->config hash. Example: __PACKAGE__->config->{home} or __PACKAGE__->config->{'Controller::FormBuilder'}->{form_path}.
If you're trying to set the FormBuilder configuration in your applications main module, you should be able to use the code provided in the documentation and just replace $c->config->{home} with __PACKAGE__->config->{home}. I think they might have even made a mistake by not doing it this way, but I'm not sure.

Zend framework: how to migrate a site

I'm trying to copy a site built on ZF from production to a localhost environment. All files and db contents were copied but I just get a blank screen. No errors, nothing
Changes made in config.ini I added an entry for development:production
general.host = "localhost:8888"
db.adapter = PDO_MYSQL
db.params.host = localhost:8888
db.params.username = bla
db.params.password = bla
db.params.dbname = db_name
bootstrap.php
$frontController->registerPlugin(new Initializer('development'));
.htaccess contains a few basic directives but if I put some random stuff at the top I don't get Internal server errors so I don't think it even reaches the .htaccess stage.
Did I miss some kind of configuration somewhere?
EDIT:
I have code below in my bootstrap but still get a blank page. Very quickly, it barely loads at all
$frontController->registerPlugin(new Initializer('development'));
$frontController->throwExceptions(true);
// Dispatch the request using the front controller.
try {
$frontController->dispatch();
}
catch (Exception $exception)
{
exit($exception->getMessage());
}
Try adding this line before running dispatch() on front controller object.
$frontController->throwExceptions(true);
On production systems throwing exceptions is almost always disabled, enabling it on dev could tell you more about the nature of the problem.
Yes, you probably missed some configuration.
Try setting display_errors=On in php.ini. You should be able to see what is going on.
Also, like suggested - try putting $frontController->throwExceptions(true) before calling dispatch().
Regarding the .htaccess file - you need to put the AllowOverride All (or anything valid, other than None) in your apache.conf/vhosts config.