3

I use Redis as session storage in my website (Laravel 4.2). Sometimes I get following errors. I guess ">" char broke the setex commands.

production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '>'' in 

production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command 'tml>''

production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '</div>''

These errors occurs rarely on production server and I can't reproduce them. Do you have any idea why these errors occurs and how can I prevent them?

key: laravel:xxxxxxxxxxxxxxx

value: s:217:"a:4:{s:6:"_token";s:40:"xxxxxxxxxxx";s:4:"lang";s:2:"fr";s:9:"_sf2_meta";a:3:{s:1:"u";i:1461777248;s:1:"c";i:1461777248;s:1:"l";s:1:"0";}s:5:"flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}";

exception 'Predis\ServerException' with message 'ERR unknown command 'ml>'' in vendor/predis/predis/lib/Predis/Client.php:282

Update

Code example where I am using redis.

    public function view($username = null)
    {
        $username = mb_strtolower($username);
        $redis = $this->getRedis();
        try{
            $view = $redis->get(User::getCacheKeyByUsername($username));
        }catch (\Exception $exception){
            $view = null;
        }
        if($view === null || Session::has("admin")){
            $user = User::where('username', '=', $username)->where("status", 1)->first();
            if (empty($user)) {
                return Redirect::to(Session::get("lang") . '/all');
            }
            $view = View::make("view", array("user" => $user));
            if(!Session::has("admin")){
                try{
                    $redis->setex(User::getCacheKeyByUsername($username), 3600, $view);
                }catch (\Exception $exception){
                    Log::error($exception->getMessage());
                }
            }
        }
        return $view;
    }
Farid Movsumov
  • 12,350
  • 8
  • 71
  • 97

2 Answers2

1

Ok, so basically what can I say from Your error log: redis doesn't like special characters like < and >, so You have to encode them.

Use htmlspecialchars to encode and htmlspecialchars_decode to decode data when retrieving.

Giedrius Kiršys
  • 5,154
  • 2
  • 20
  • 28
0

something is wrong with your redis client. You can not reproduce it, because the error does not happen in your code, but in TCP communication between client and redis server.

i would suggest to update the question and mention what redis client module are you using. Is it predis?

If you are on unix, try compile and install phpredis. it is php module and I never had any problems with it.


Reproduction with telnet

Do telnet host port and follow instructions:

Normal request GET a would look like this:

*2
$3
get
$1
a
$-1

Now consider this - ask for gem a:

*2
$3
gem
$1
a
-ERR unknown command 'gem'

Protocol is valid, but command "gem" is invalid.

Now consider this:

*1
$3
ml>
-ERR unknown command 'ml>'

Here is your error. Valid protocol, invalid command.

Alternatively consider this:

*2
$3
get
$1
<html>
$-1
-ERR unknown command 'ml>'

Here is your error again. Invalid strlen("<html>");

Why this is redis client error and not user error:

Many redis clients uses PHP magic methods.

This means if you call $redis->bla(), they extract "bla" part and it parameters and forward them to the redis server.

However you can not do $redis->ml>(). This will be syntax error. So this is error from redis client, not from your code.

It also looks like part of HTML. It looks like you are storing HTML data in redis. I only can guess that the client does not compute strlen() or count() and send wrong information "down the telnet line".

Community
  • 1
  • 1
Nick
  • 9,962
  • 4
  • 42
  • 80
  • thanks for -1. Once again - something is wrong with redis library. I will edit how you can reproduce the error with telnet. – Nick May 11 '16 at 09:23
  • Thanks for your answer @Nick but how can I solve this problem? – Farid Movsumov May 11 '16 at 11:27
  • I will search this error inside predis client. I will let you know result. – Farid Movsumov May 11 '16 at 11:29
  • install phpredis at least to check, link is https://github.com/phpredis/phpredis - this is 100% supported in Laravel, because is de-facto standard for redis connectivity. – Nick May 11 '16 at 11:38