Prevent output binary data #1884

Open
jumale opened this Issue Apr 29, 2015 · 7 comments

Comments

Projects
None yet
5 participants
@jumale

jumale commented Apr 29, 2015

  • _Known Linux issue:_ terminal is broken after binary data output.
  • _Codeception issue:_ controllers may return binary response which causes the problem in "verbose" or "debug" mode.
  • _How to reproduce:_
    • create a controller which returns binary data, for example ZIP archive
    • create a functional test using REST module and send there a GET request to the controller
    • run the test with -vvv or --debug
  • _Solution:_ if it's possible, it would be nice to check that response contains binary data, and do not output it here (maybe show something like string [Binary Data] instead).

P.S.: I got this issue in REST module, but probably it can happen in some another modules

@DavertMik

This comment has been minimized.

Show comment
Hide comment
@DavertMik

DavertMik Apr 29, 2015

Member

How to do you propose to detect binary data?

Member

DavertMik commented Apr 29, 2015

How to do you propose to detect binary data?

@jumale

This comment has been minimized.

Show comment
Hide comment
@jumale

jumale Apr 30, 2015

@DavertMik ok, I've discovered internet and looks like there is no easy solution to define the binary data.
But I found a way which is enough for me. All is needed from codeception - allow to define a callback to intercept debug messages. Like that:

<?php
namespace Codeception\Util;

class Debug
{
    /**
     * @var callable
     */
    public static $interceptDebug = null;

    public static function debug($message)
    {
        if (!self::$output) {
            return;
        }
        // modified part
        if (is_callable(static::$interceptDebug)) {
            $message = call_user_func(static::$interceptDebug, $message);
        }
        self::$output->debug($message);
    }

    // ...
}

then I can create a helper with the next method:

<?php
public function expectBinaryResponse()
{
    \Codeception\Util\Debug::$interceptDebug = function ($message) {
        if (0 == strpos($message, '[Response]')) {
            $message = '[Response] [Binary Data]';
        }

        return $message;
    };
}

and then in my test:

$I = new Tester($scenario);
$I->expectBinaryResponse();
// ...

I know it looks a bit ugly, but I have no other idea how to hack it :)

jumale commented Apr 30, 2015

@DavertMik ok, I've discovered internet and looks like there is no easy solution to define the binary data.
But I found a way which is enough for me. All is needed from codeception - allow to define a callback to intercept debug messages. Like that:

<?php
namespace Codeception\Util;

class Debug
{
    /**
     * @var callable
     */
    public static $interceptDebug = null;

    public static function debug($message)
    {
        if (!self::$output) {
            return;
        }
        // modified part
        if (is_callable(static::$interceptDebug)) {
            $message = call_user_func(static::$interceptDebug, $message);
        }
        self::$output->debug($message);
    }

    // ...
}

then I can create a helper with the next method:

<?php
public function expectBinaryResponse()
{
    \Codeception\Util\Debug::$interceptDebug = function ($message) {
        if (0 == strpos($message, '[Response]')) {
            $message = '[Response] [Binary Data]';
        }

        return $message;
    };
}

and then in my test:

$I = new Tester($scenario);
$I->expectBinaryResponse();
// ...

I know it looks a bit ugly, but I have no other idea how to hack it :)

@DavertMik

This comment has been minimized.

Show comment
Hide comment
@DavertMik

DavertMik Apr 30, 2015

Member

Thanks, I will try to think on this too

Member

DavertMik commented Apr 30, 2015

Thanks, I will try to think on this too

@codedokode

This comment has been minimized.

Show comment
Hide comment
@codedokode

codedokode May 9, 2015

You could also replace unprintable characters 00-1f with codes like \x00 so the data are still readable.

You could also replace unprintable characters 00-1f with codes like \x00 so the data are still readable.

codemedic added a commit to redmatter/Codeception that referenced this issue Nov 18, 2015

DavertMik added a commit that referenced this issue Nov 25, 2015

Merge pull request #2552 from natterbox/fix-1884-binary-data-from-RES…
…T-module-debug

Fixing issue #1884 in v2.1.x - hides binary request data in debug

@Naktibalda Naktibalda closed this Jun 11, 2016

@spikyjt

This comment has been minimized.

Show comment
Hide comment
@spikyjt

spikyjt Feb 2, 2017

Contributor

The linked PR did not fix this issue, it only fixed an issue where the request data included binary data.

This issue is about the response having binary data.

I fixed this locally in a similar manner to #2552 with the following at the end of Codeception\Module\REST::execute():

        $response = $this->response;
        if (!ctype_print($response) && false === mb_detect_encoding($response, mb_detect_order(), true)) {
            // if the response has non-printable bytes and it is not a valid unicode string, reformat the
            // display string to signify the presence of a binary response
            $response = '[binary-data length:' . strlen($response) . ' md5:' . md5($response) . ']';
        }
        $this->debugSection("Response", $response);

I'll create a PR later if it would be welcomed, but I can't right now as I'm at work!

Contributor

spikyjt commented Feb 2, 2017

The linked PR did not fix this issue, it only fixed an issue where the request data included binary data.

This issue is about the response having binary data.

I fixed this locally in a similar manner to #2552 with the following at the end of Codeception\Module\REST::execute():

        $response = $this->response;
        if (!ctype_print($response) && false === mb_detect_encoding($response, mb_detect_order(), true)) {
            // if the response has non-printable bytes and it is not a valid unicode string, reformat the
            // display string to signify the presence of a binary response
            $response = '[binary-data length:' . strlen($response) . ' md5:' . md5($response) . ']';
        }
        $this->debugSection("Response", $response);

I'll create a PR later if it would be welcomed, but I can't right now as I'm at work!

@Naktibalda

This comment has been minimized.

Show comment
Hide comment
@Naktibalda

Naktibalda Feb 2, 2017

Member

Thanks, please make a PR.

Member

Naktibalda commented Feb 2, 2017

Thanks, please make a PR.

@spikyjt

This comment has been minimized.

Show comment
Hide comment
@spikyjt

spikyjt Feb 2, 2017

Contributor

Done. Sorry for any confusion, I stupidly created a PR on my own fork instead of to the main repo!

Contributor

spikyjt commented Feb 2, 2017

Done. Sorry for any confusion, I stupidly created a PR on my own fork instead of to the main repo!

spikyjt added a commit to spikyjt/Codeception that referenced this issue Feb 3, 2017

DavertMik added a commit that referenced this issue Feb 3, 2017

hide binary response data in debug #1884 (#3985)
* hide binary response data in debug #1884

* rework binary formatting for DRY, variable rename #1884

chris1312 added a commit to chris1312/Codeception that referenced this issue Jun 16, 2017

hide binary response data in debug #1884 (#3985)
* hide binary response data in debug #1884

* rework binary formatting for DRY, variable rename #1884
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment