How to remove exception in Yii redis extension if one server down? - yii

I use php (Yii), use this extension: http://www.yiiframework.com/extension/rediscache/ for saving yii cache and session in redis.
I configured it to work with 2 servers.
'cache'=>array(
'class'=>'application.extensions.redis.CRedisCache',
//if you dont set up the servers options it will use the default one
//"host=>'127.0.0.1',port=>6379"
'servers'=>array(
array(
'host'=>'10.1.98.139',
'port'=>6379,
),
array(
'host'=>'10.56.192.5',
'port'=>6379,
)
),
),
How I understand, Yii send cache and session data in both of them.
When one of them down, I need, that all users work in 1 of them, but Yii makes an Exception: 'Predis_CommunicationException' with message 'Connection refused' in /srv/www/protected/extensions/redis/Predis.php:1303
How to fix this, and work only on one of them?
Thanks!

As far I see you need to locate the code in the extension that handles the connection section, and setup two things:
a timeout of 1 second
a try/catch block or other way to handle cannot connect errors.
This should be done by the extension maintainer and you, and it looks like a undocumented behavior of the extension, so make sure you submit a comment/bug ticket to that extension.

Related

Symfony - fallback to another application if Symfonfy app can not handle the request

We have an old Yii application along with new Symfony one.
The basic idea is simple - I need to check if there is a route matching in Symfony application then it is cool, if not then bootstrap Yii application and try to handle the request with it.
The main idea to not instantiate AppKernel (and do not load autoload.php - since there is two different autoload.php for each project) before I am sure there is route matching.
Can I do it somehow?
We've done this before with legacy applications.
There are two approaches you can take.
Wrap your old application inside a symfony project (recommended).
Unfortunately this will indeed load the symfony front-controller and kernel. No way around that. You need to make sure that symfony can't handle the request and to do that the kernel needs to be booted up.
Use sub-directories and apache virtual hosts to load one application vs the other as needed.
Given option 1,
You can either create your own front controller that loads either symfony or yii by reading routes (from static files if using yml or xml, or annotations which will be more complex) OR EventListener (RequestListener) that listens to the HttpKernelInterface::MASTER_REQUEST and ensures that a route can be returned.
Creating your own front controller is the only way that you can make it not load the symfony kernel, but it will require you to write something that understands the routes in both frameworks (or at least symfony's) and hands off the request appropriately.
Event listener example:
public function onkernelRequest(GetResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}
... Code to continue normally, or bootstrap yii and return a custom response... (Can include and ob_start, or make an http request, etc)
}
public function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => ['onKernelRequest']
];
}
As you see, the kernel needs to be booted to ensure symfony can't serve the route. Unless creating your own front controller (as stated above).
A third approach would be to create a fallback controller, which would load up a specified URL if no route was found within symfony. Although this approach is generally used for legacy projects that lack a framework and use page scripts instead of proper routes, and definitely requires the use/help of output buffering.
The EventListener approach gives you the opportunity to create a proper Request to hand off to yii, and using what is returned to create a Response as proper symfony object (can also use ob or other options).
Thank you.
This is an alternative to vpassapera's solution -http://stovepipe.systems/post/migrating-your-project-to-symfony

Laravel 4: when using Config::set to change auth.model then Auth::user() not work

My laravel project has two login system.
1) Using user_name and Password
2) Using secret code
my 1st login system work properly. because auth.model has 'User' model.
so I use 'Config::set' in 'tempSing' method to obtain 2nd login as bellow.
Config::set('auth.model', 'TempUser')
Config::set('auth.table', 'temp_user')
After that code I use bellow code
$user= TempUser::where('secret_code','=',Input::get('code'))->first();
Auth::login($user,true);
if(Auth::check())
return Redirect::route('getTemp');
then that code work properly and redirect to the 'getTemp' and after routing it make 'temp.php'. but their include
if(Auth::check())
so my problem is above logic not become true. that problem is occurred when using 'Config::set' but I Configured 'auth.model' and 'auth.table' manualy in 'auth.php' not happen any error. Please help me.
I would assume Laravel initializes the Auth service once when the application is started, so later edits to configuration don't affect it anymore. A solution would be to initialize an instance yourself, and use that.

Debugging ActiveMerchant; need full request and response. How to?

Rails 3.0.10 and activemerchant gem 1.29.3
My app works fine in sandbox, but transactions in production mode are failing with "Security header is not valid", "ErrorCode"=>"10002"
We initiated a support request with paypal, after reviewing all the configuration parameters a million times and they feel we're hitting an incorrect endpoint. They've asked for a full trace for the transaction, including headers, etc, so I'm trying to figure out how to do that. I found this article
which suggested adding this to the config block
ActiveMerchant::Billing::PaypalGateway.wiredump_device = File.new(File.join([Rails.root, "log", "paypal.log"]), "a")
But that just results in an empty log; nothing gets dumped to it.
So, how can I obtain this info from the GATEWAY object, if possible? Here's the production config, the format of which is identical to what's used in staging env.
::GATEWAY = ActiveMerchant::Billing::PaypalGateway(
:login => 'me_api1.blah...',
:password => 'string...',
:signature => 'longer string...'
)
Thanks.
Needed to add the additional line as follows:
ActiveMerchant::Billing::PaypalGateway.wiredump_device.sync = true
Within the same config block in the environment
Somewhere in the class library you're using there should be a function to output this for you (if it's a well built library, that is.)
Even without that, though, you should be able to look in that PaypalGateway function to see where/how it's setting the endpoint. It's either hard-coding the value or it'll be setting different endpoints based on some sandbox option you have configured somewhere else in the class.
It's hard to tell you more than that without getting a look a the actual class library you're using, but I can concur that it must be either incorrect credentials or an incorrect endpoint. I've never once seen that security header error when it wasn't simply invalid credentials, which means either your values are incorrect or you're hitting the wrong endpoint.
If you want to post that whole function (or maybe even the whole library as the endpoint could be getting set from some other function) I can take a look and find the problem for you.

Using java servlet store doesn't work in my Jruby on Rails application running in Tomcat

I'm trying to use the java servlet store instead of the :cookie_store when running in Tomcat. My application runs fine with the :cookie_store, but when using the :java_servlet_store, nothing gets stored no longer...
This seems to work, however, when I store something in the servlet_request.session, later on, I can't seem to get the value again... It seems to be gone...
In my session_store.rb:
require 'action_controller/session/java_servlet_store'
NameApplication::Application.config.session_store :java_servlet_store
In my application_controller.rb:
servlet_request.session.putValue(PROXYBRIDGEKEY, proxy_bridge)
seems to be working
But later on I'm trying to get the value and I'm getting nil...
servlet_request.session.getValue(PROXYBRIDGEKEY)
Any ideas as what could be the problem here?
To be clear, putting the value in the session does work (tested that). With a new html request, getting the value doesn't work anymore. So, there must be a problem with getting the cookie I guess...
One thing that you could try is defining your store as:
require 'action_controller/session/java_servlet_store'
NameApplication::Application.config.session_store :java_servlet_store, :key => "MyKey"
I'm not sure it's relevant, but it was necessary for the :cookie_store. It could make sense that you need to identify your servlet key in the java_servlet_store as well. This key will be the key of the cookie sent to the browser for subsequent requests.
Hope this helps.
If that didn't work for you, also make sure that you set the java_servlet_store key to "JSESSIONID" to use the standard JVM session.
From there in Ruby, all you need to do to read and write session (this will be accessing the JVM session object):
session.id
session[:yoursessionvariable]
Note: If you have not initialized session (assign a session variable value), session will be nil (making session.id undefined) until you do so.

Domain Specific URL include() exemption

I want to allow a URL to be put inside php's include(); but only certain domains - not every one. The other domains are owned by me, and on a separate server. If someone tries to include() any other domain bu these I want them disallowed.
If this is not possible, is there a work around?
My recommendation? Don't do it with includes. Executing code in that fashion is like swallowing a chocolate covered cherry bomb.
You could do it on the web server so you don't even let the domain which is not allowed to parse or get any files. you have to remember any request will go through the web server and server static content or be parsed which all takes time and then add the time for the PHP script to execute.
$allowed_domains = array(
'stackoverflow.com',
'www.stackoverflow.com',
'facebook.com',
'www.facebook.com',
'google.com',
'www.google.com',
);
if(!in_array(parse_url($url, PHP_URL_HOST), $allowed_domains)) {
// throw an error
}