Skip to content
This repository has been archived by the owner on Apr 1, 2019. It is now read-only.

Proposition: setting image content-length header correctly and adding gzip output config option #12

Open
josua opened this issue Dec 14, 2010 · 0 comments

Comments

@josua
Copy link

josua commented Dec 14, 2010

Hi Michael,
Nice to see you have used my bugs fixes in your corrections.

Here is the working code for other suggestions i like you to consider.
I have tested them on the 9 main browsers and it seems to work correctly

This proposition mainly adds the following functionalities
1: sends the headers to the browser before outputting the image (and not after)
2: compute the content length correctly :-)
3: add gzip output compression config option and the code in order to gzip the image
4. exit the system

A- file: config/captcha.php
Add gzip compression configuration option

// Group Options:
// [+] gzip gzip compression flag, set to TRUE to enable gzip compression when outputting of the image resource

'default' => array( // [+] 'gzip' => FALSE ),

B- file: classes/captcha.php

public static $config = array( // [ + ] 'gzip' => FALSE );

public function image_render($html)
{
// Output html element
if ($html === TRUE)
return 'Captcha';

    // [-] [+] Main modifications are there

    // Pick the correct output function
    $function ='image'.$this->image_type;

    // Get the request instance singleton
    $request = Request::instance();

    // Detect the server HTTP protocol to use (HTTP/1.0 or HTTP/1.1) and set the HTTP status line header, code 200 and message OK (by default)
    $request->headers[ (isset($_SERVER['SERVER_PROTOCOL']))? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1' ] = $request->status.' '.Request::$messages[$request->status];

    // Set the correct HTTP headers to send to the browser
    $request->headers['Content-Type'] = 'image/'.$this->image_type;
    $request->headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0';
    $request->headers['Pragma'] = 'no-cache';


    // Check gzip compression config flag, if TRUE set content encoding header to gzip and output the image gzipped
    if(Captcha::$config['gzip'] === TRUE)
    {
            // Set the content encoding header to gzip 
            $request->headers['Content-Encoding'] = 'gzip';

            // Send the headers before outputing the image 
            $request->send_headers();

             // START the output buffer
             ob_start();

             // Start output buffer with ob_gzhandler callback function to gzip the output, in order to reduce captcha image response time
             // @note that the gzip compression gain is very small unless image uses big width and height
             ob_start("ob_gzhandler");

            // Output the image resource
            $function($this->image);

            // Flush gzipped ouput buffer
            ob_end_flush();
    }
    else
    {
            // Send the headers before outputing the image 
            $request->send_headers();

            // START the output buffer
            ob_start();

            // Output the image resource
            $function($this->image);

    }

    // Send the Content-Length header by getting the output buffer length
    header('Content-Length: '.ob_get_length(), TRUE);
    header('Connection: close', TRUE);

    // Flush (send) the output buffer and turn off output buffering
    ob_end_flush();

    // Free up the image resource from memory
    imagedestroy($this->image);

}

C- file: controller/captcha.php

class Controller_Captcha extends Controller
{

// This line should be removed
// [-] public $auto_render = FALSE;

public function action_index($group = 'default')
{
        Captcha::instance($group)->render(FALSE);
}

public function after()
{
        Captcha::instance()->update_response_session();

        // [+] exit from system as we have already sent the request headers and outputed the image as response to the browser
        exit;
}

} // End Captcha_Controller

I hope you will understand why the [output -> headers -> image] sequence is better designed than in the previous render method

Best regards
Philippe Jos

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant