CodeIgniter Forums
CI bug with is_really_writable - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forum-20.html)
+--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forum-23.html)
+--- Thread: CI bug with is_really_writable (/thread-21639.html)



CI bug with is_really_writable - El Forum - 08-16-2009

[eluser]Unknown[/eluser]
So,
This took me several hours to find, but I believe I have found the cause of a reproducible bug.

Basically the bug will exhibit itself when CI framework is ran several times in a short amount of time. You may be wondering why would someone do that, well for one I use GD to resize an image to thumbnail size before the user sees it. On the site that I am developing, on the admin side anyways, the user will see a list of all the products and a thumbnail of that picture. The "bug" would manifest itself by not displaying a thumbnail, even though when I went directly to it in a new tab the image displayed fine (and random other pictures would show/no show). The thumbnail img src is set to a CI controller that generates the thumbnail using PHP+GD. Which, the browser will execute every time it requests the picture. At first I thought Apache was doing something funky, but I noticed that the Content-Type to be "text/html" which is the *default* for PHP (at least in my install), the default for Apache is "text/plain" (again at least on my install). Also, Content-Length was 0, which would make some sense because there was no data.

So, doing some tests - I find that die(); or exit(); will product a Content-Type of "text/html" and Content-Length of 0. But, nothing in my code was making it die or exit and I couldn't find any calls to those functions inside of CI framework.

So...
Checking out the CI logs I noticed some funny lines:
ERROR - 2009-08-15 13:25:16 --&gt; Severity: Warning --&gt; unlink(x:\system/cache/67c6a1e7ce56d3d6fa748ab6d9af3fd7) [<a href='function.unlink'>function.unlink</a>]: Permission denied C:\www\bethlemgifts.com\system\codeigniter\Common.php 63
I find that kind of funny because this is a Windows system and Apache as the "Local System" account, which meant that if Windows couldn't delete that file, then there was something really wrong here. But, when I went to go look at the cache directory it was blank every time (except for index.html, of course). Which I began to think - I believe that the system is running into sort of like a "deadlock" where the CI framework is trying to delete the same file. I examined line 63 in Common.php and found:
Code:
@unlink($file);
Well the error makes sense, but the code doesn't -
Quote:(Common.php)// For windows servers and safe_mode "on" installations we'll actually
Windows servers? Hmm, well then...my advice
Instead of trying to write then delete a file, just check the owner and permission mask. It should return proper values even in Windows. If you are really in need of a Windows specific test then try one of the following:
* Try Windows API to create/delete using w32api_register_function
* Try http://us2.php.net/manual/en/function.is-writable.php#73596
* If the user has DB credentials in the config file, do all file I/O inside of the database and let the database server worry about file I/O.
* Delete the files at a later date, ie store the files to be deleted in a database and delete them 60 seconds later to let the OS, disk, script breathe.

[See post below, sorry ran out of characters!]


CI bug with is_really_writable - El Forum - 08-16-2009

[eluser]Unknown[/eluser]
My hacked together solution is to use a custom cron class library. Which, in the constructor I just call some "cleanup functions". Basically, if the file is 30 seconds old AND not being run from the thumbnail controller, then go ahead and delete the cache files.
Code:
&lt;?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Cron {
    function Cron()
    {
        $this->cleanCache();
    }
        function cleanCache()
    {
        $CI =& get_instance();
        $url = $CI->uri->segment(1);
        if ($url != "thumb")
        {
            $last_change = 0;
            if ($dh = opendir(getcwd() . "/system/cache")) {
            while (($file = readdir($dh)) !== false) {
            if ($file != "." && $file != ".." && $file != "index.html")
            {
                if ((time() - filemtime(getcwd() . "/system/cache/" .$file)) >= 30) //tick tock, 60 seconds until the cache gets deleted!
                {
                    @unlink(getcwd() . "/system/cache/" .$file);
                }
                 //echo "$file was last modified: " . date ("F d Y H:i:s.", filemtime(getcwd() . "/system/cache/" .$file)) . "<br>";
                //echo $file . '<br>';
            }
            }
                closedir($dh);
            }
        }
    }
}
?&gt;

To show that this is a bug - this classless PHP file runs fine:
Code:
&lt;?php
$dir = "C:\somedir";

// Open a known directory, and proceed to read its contents
if (!isset($_GET['p']))
{
if (is_dir($dir)) {
    if ($dh = opendir($dir)) {
        while (($file = readdir($dh)) !== false) {
        if ($file != "." && $file != "..")
        {
            echo '<img src="testcache.php?p=' . $file . '"><br>';
            echo "filename: $file <br>\n";
        }
        }
        closedir($dh);
    }
}
} else {
    readfile(getcwd() . "\\cache\\" . $_GET['p']);
}
?&gt;
==========================
But if you were to put that into a controller...for example:
Code:
&lt;?php
class Thumb extends Controller
{
    function show($file="")
    {
        readfile($file);
    }
}
?&gt;
and
Code:
&lt;?php
class Pics extends Controller
{
    function look()
    {
                $dir = "C:\somedir";
        if (is_dir($dir)) {
            if ($dh = opendir($dir)) {
                while (($file = readdir($dh)) !== false) {
                if ($file != "." && $file != "..")
                {
                    echo '<img src="' . site_url("><br>';
                    echo "filename: $file <br>\n";
                }
                }
                closedir($dh);
            }
        }
    }
}
?&gt;

Now, of course, this may be a bug with PHP, Windows, and/or Apache specifically my mix of versions...
Apache: Apache/2.2.11 (Win32) DAV/2 mod_ssl/2.2.11 OpenSSL/0.9.8i PHP/5.2.9
OS: Windows XP Tablet (which is really just XP Pro).
I did install Apache from the XAMPP package.


CI bug with is_really_writable - El Forum - 08-16-2009

[eluser]quest13[/eluser]
Hi, I need some help in deleting file from the physical path.

I tried the same way you did and I get the following error:

Severity: Warning

Message: unlink() [function.unlink]: http does not allow unlinking

Filename: models/my_model.php

Line Number: 3678

What may be the cause ?

My model look like this,

Code:
....performed delete query here

Code:
if($this->db->affected_rows() >0)
        {
            
        $this->load->helper('file');
        unlink($full_path);        
        return $query;
                }