skip to Main Content

I have a PHP/MariaDB application that has some images stored as BLOBs. I recently moved the app to a cloud hosted service and the behaviour of viewing images is broken. PHP serving a GET request for an image is this:

    require(__DIR__.'/../include/db/MyDatabase.php');
    
    try {
        $data = (new MyDatabase())->getImage(htmlspecialchars($date));
        header('Content-Type:'.$data['mime']);
        header('Content-Length:'.strlen($data['image']));
        echo $data['image'];
    }catch(Exception $e){
        header('Content-Type:application/json; charset=UTF-8');
        echo json_encode([ 'errors' => [ $e->getMessage() ]]);
    }

$data is an associative array with the image’s mime type, binary, and a date that the image is for. When I was hosting the app on my server, this works fine. That’s Ubuntu 22.04 with PHP 8.1 and MySQL PDO driver mysqlnd 8.1.2-1ubuntu2.14.

On the cloud hosting service, they are using PHP 8.2 and MySQL PDO driver 3.1.21 and images don’t work. The Content Length and Type are set:

Content Length and Type

But the image isn’t displayed:

Broken Image

I don’t know if versions of things make a difference but I’m drawing a blank on what might be wrong.

Edit: Just for comparison, the request on the left results in an image coming back, the request on the right doesn’t:

Browser Dev Tools

I don’t really know what to look for, but the same code is in both environments

Does anyone have any idea what might be going wrong, or where to look?

2

Answers


  1. Tested using litespeed, this works:

    <?php
    header('Content-Type: image/png');
    //header('Content-Length: '.filesize("test.png"));
    $data = readfile("test.png");
    // echo $data;  // EDIT: This is wrong because it outputs the size of the picture, and that was not supposed to happen..
    exit;
    

    It seems you do not need to send the Content-Length

    I noticed one strange behaviour…

    When doing curl http://localhost/test/image.php --output test2.png, my output image was 5 bytes larger than my input image.

    Examining revealed that the length of the original image (21215) was added the the test2.png file.

    root@ubuntu45:/usr/local/lsws/Example/html/test# hexdump -C test2.png | tail -3
    000052d0  71 9d ec 00 00 00 00 49  45 4e 44 ae 42 60 82 32  |q......IEND.B`.2|
    000052e0  31 32 31 35                                       |1215|
    000052e4
    root@ubuntu45:/usr/local/lsws/Example/html/test# hexdump -C test.png | tail -3
    000052c0  04 1a 81 16 00 00 00 01  26 fd ff 10 06 28 5b a5  |........&....([.|
    000052d0  71 9d ec 00 00 00 00 49  45 4e 44 ae 42 60 82     |q......IEND.B`.|
    000052df
    

    EDIT: I commented one of the lines in my PHP (and added comment to it) because it was outputting the length of the image.

    tested using: LiteSpeed/1.7.18 Open (BUILD built: Tue Aug 29 12:59:39 UTC 2023) on Ubuntu 22.04.3

    Login or Signup to reply.
  2. Having the same identical code produce two different results in two different environments usually means that there is a version discrepancy, or, more likely (in your case, I think) a configuration mismatch.

    I think your best bet is going to be to have a look at/change the Max Dynamic Response Body Size option for litespeed:

    Specifies the maximum body size of a dynamically generated response.

    I think this applies because you’re calling a .php script and not a file with a common extension that is known to produce static data (like .png for example).

    Your code looks somewhat correct, although the htmlspecialchar is a bit weird for making a request to a database. Usually you only use htmlspecialchar to output untrusted data to a browser client.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search