S3 PHP putObject timeout for small files [Fix provided!]
I was getting this error today when trying to upload a small file to my S3 bucket:
S3::putObject(): [RequestTimeout] Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed
I’ve been using this library for a while, with large file uploads and didn’t get this problem, so I figured it was something to do with the smaller files. It seems others have had this issue too.
Assuming you are using the putObjectFile method like I was, it calls another method to create the request inputFile. In this method, I basically added a hack so that if the file size is small, it reads it and uploads it using a string of data, rather than the file pointers (where this bug lies, it seems).
My fix is simply to add this code to inputFile:
if (filesize($file) < 512 * 1024)
{
return file_get_contents($file);
}
So for any file under 512k, it will upload it from memory, rather than the file pointer. I'm sure my server can handle this. I guess if you wanted, you could try a whole bunch of files until you found the size at which the code works, or even fix the problem at the source, but I have more pressing priorities. I suspect it's well under the 100k mark, so my 512k figure represents an abundance of caution.
Making the complete method at least in version 47:
/**
* Create input info array for putObject()
*
* @param string $file Input file
* @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own)
* @return array | false
*/
public static function inputFile($file, $md5sum = true) {
if (!file_exists($file) || !is_file($file) || !is_readable($file)) {
trigger_error('S3::inputFile(): Unable to open input file: '.$file, E_USER_WARNING);
return false;
}
if (filesize($file) < 512 * 1024)
{
return file_get_contents($file);
}
return array('file' => $file, 'size' => filesize($file),
'md5sum' => $md5sum !== false ? (is_string($md5sum) ? $md5sum :
base64_encode(md5_file($file, true))) : '');
}
