aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kostikov <max@kostikov.co>2020-09-08 14:20:12 +0200
committerMax Kostikov <max@kostikov.co>2020-09-08 14:20:12 +0200
commit9dd333a2f4320efbf5167a73bf53462c2299d654 (patch)
treea5671029bd47791546db27733011aba6ee1f3d1a
parentd53b3b242daca5d64886c5caa1c6aa93473239de (diff)
downloadvolse-hubzilla-9dd333a2f4320efbf5167a73bf53462c2299d654.tar.gz
volse-hubzilla-9dd333a2f4320efbf5167a73bf53462c2299d654.tar.bz2
volse-hubzilla-9dd333a2f4320efbf5167a73bf53462c2299d654.zip
Support remote host cache directives on profile photo fetching
-rw-r--r--include/photo/photo_driver.php124
1 files changed, 83 insertions, 41 deletions
diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php
index 284206161..f5cc6a2c9 100644
--- a/include/photo/photo_driver.php
+++ b/include/photo/photo_driver.php
@@ -190,25 +190,27 @@ function delete_thing_photo($url, $ob_hash) {
* * \e string \b 5 => modification date
*/
function import_xchan_photo($photo, $xchan, $thing = false, $force = false) {
+
$modified = '';
$o = null;
-
$flags = (($thing) ? PHOTO_THING : PHOTO_XCHAN);
$album = (($thing) ? 'Things' : 'Contact Photos');
logger('Updating channel photo from ' . $photo . ' for ' . $xchan, LOGGER_DEBUG);
- if($thing) {
+ if($thing)
$hash = photo_new_resource();
- } else {
- $r = q("select resource_id, edited, mimetype from photo where xchan = '%s' and photo_usage = %d and imgscale = 4 limit 1", dbesc($xchan), intval(PHOTO_XCHAN));
+ else {
+ $r = q("SELECT resource_id, edited, mimetype, expires, description FROM photo WHERE xchan = '%s' AND photo_usage = %d AND imgscale = 4 LIMIT 1", dbesc($xchan), intval(PHOTO_XCHAN));
if($r) {
$hash = $r[0]['resource_id'];
$modified = $r[0]['edited'];
$type = $r[0]['mimetype'];
- } else {
- $hash = photo_new_resource();
+ $exp = strtotime($r[0]['expires']);
+ $etag = $r[0]['description'];
}
+ else
+ $hash = photo_new_resource();
}
$photo_failure = false;
@@ -216,37 +218,72 @@ function import_xchan_photo($photo, $xchan, $thing = false, $force = false) {
if($photo) {
- if($force || $modified == '') {
+ if($force || empty($modified))
$result = z_fetch_url($photo, true);
- } else {
- $h = [
- 'headers' => [
- 'If-Modified-Since: ' . gmdate('D, d M Y H:i:s', strtotime($modified . 'Z')) . ' GMT'
- ]
- ];
- $result = z_fetch_url($photo, true, 0, $h);
+ elseif($exp - 60 < time()) {
+ $h = [];
+ $h[] = "If-Modified-Since: " . gmdate("D, d M Y H:i:s", $exp) . " GMT";
+ if(! empty($etag))
+ $h[] = "If-None-Match: " . $etag;
+ $result = z_fetch_url($photo, true, 0, [ 'headers' => $h ]);
}
- if($result['success']) {
- $img_str = $result['body'];
- $type = guess_image_type($photo, $result['header']);
- $modified = gmdate('Y-m-d H:i:s', (preg_match('/last-modified: (.+) \S+/i', $result['header'], $o) ? strtotime($o[1] . 'Z') : time()));
- if(is_null($type))
+ if(isset($result)) {
+ $hdrs = [];
+ $h = explode("\n", $result['header']);
+ foreach ($h as $l) {
+ list($t,$v) = array_map("trim", explode(":", trim($l), 2));
+ $hdrs[strtolower($t)] = $v;
+ }
+
+ if(array_key_exists('expires', $hdrs))
+ $expires = strtotime($hdrs['expires']);
+ else {
+ $cc = '';
+ if(array_key_exists('cache-control', $hdrs))
+ $cc = $hdrs['cache-control'];
+ if(strpos($cc, 'no-cache'))
+ $expires = time() + 60;
+ else {
+ $ttl = (preg_match('/max-age=(\d+)/i', $cc, $o) ? intval($o[1]) : 86400);
+ $expires = time() + $ttl;
+ }
+ }
+
+ $modified = gmdate('Y-m-d H:i:s', (array_key_exists('last-modified', $hdrs) ? strtotime($hdrs['last-modified']) : time()));
+
+ if($result['success']) {
+ $img_str = $result['body'];
+ $type = guess_image_type($photo, $result['header']);
+ if(is_null($type))
+ $photo_failure = true;
+ }
+ else
$photo_failure = true;
- } elseif($result['return_code'] == 304) {
+ }
+
+ if(! isset($result) || $result['return_code'] == 304) {
$photo = z_root() . '/photo/' . $hash . '-4';
$thumb = z_root() . '/photo/' . $hash . '-5';
$micro = z_root() . '/photo/' . $hash . '-6';
- } else {
+ if(isset($result))
+ q("UPDATE photo SET expires = '%s' WHERE xchan = '%s' and photo_usage = %d and imgscale IN (4, 5, 6)",
+ dbescdate(gmdate('Y-m-d H:i:s', (isset($expires) ? $expires : time() + 86400))),
+ dbesc($xchan),
+ intval(PHOTO_XCHAN)
+ );
+ $photo_notmofidied = true;
$photo_failure = true;
}
- } else {
- $photo_failure = true;
}
+ else
+ $photo_failure = true;
+
+ if(! $photo_failure) {
- if(!$photo_failure && $result['return_code'] != 304) {
$img = photo_factory($img_str, $type);
if($img->is_valid()) {
+
$width = $img->getWidth();
$height = $img->getHeight();
@@ -255,25 +292,28 @@ function import_xchan_photo($photo, $xchan, $thing = false, $force = false) {
// crop out the sides
$margin = $width - $height;
$img->cropImage(300, ($margin / 2), 0, $height, $height);
- } elseif(($height / $width) > 1.2) {
+ }
+ elseif(($height / $width) > 1.2) {
// crop out the bottom
$margin = $height - $width;
$img->cropImage(300, 0, 0, $width, $width);
- } else {
- $img->scaleImageSquare(300);
}
- } else {
- $photo_failure = true;
+ else
+ $img->scaleImageSquare(300);
}
+ else
+ $photo_failure = true;
$p = [
- 'xchan' => $xchan,
- 'resource_id' => $hash,
- 'filename' => basename($photo),
- 'album' => $album,
- 'photo_usage' => $flags,
- 'imgscale' => 4,
- 'edited' => $modified,
+ 'xchan' => $xchan,
+ 'resource_id' => $hash,
+ 'filename' => basename($photo),
+ 'album' => $album,
+ 'photo_usage' => $flags,
+ 'imgscale' => 4,
+ 'edited' => $modified,
+ 'description' => ($hdrs['etag'] ? $hdrs['etag'] : ''),
+ 'expires' => gmdate('Y-m-d H:i:s', (isset($expires) ? $expires : time() + 86400))
];
$r = $img->save($p);
@@ -295,12 +335,14 @@ function import_xchan_photo($photo, $xchan, $thing = false, $force = false) {
$photo = z_root() . '/photo/' . $hash . '-4';
$thumb = z_root() . '/photo/' . $hash . '-5';
$micro = z_root() . '/photo/' . $hash . '-6';
- } else {
+ }
+ else {
logger('Invalid image from ' . $photo);
$photo_failure = true;
}
}
- if($photo_failure) {
+
+ if($photo_failure && ! isset($photo_notmofidied)) {
$default = get_default_profile_photo();
$photo = z_root() . '/' . $default;
$thumb = z_root() . '/' . get_default_profile_photo(80);
@@ -309,12 +351,12 @@ function import_xchan_photo($photo, $xchan, $thing = false, $force = false) {
$modified = gmdate('Y-m-d H:i:s', filemtime($default));
}
- logger('HTTP code: ' . $result['return_code'] . '; modified: ' . $modified
- . '; failure: ' . ($photo_failure ? 'yes' : 'no') . '; URL: ' . $photo, LOGGER_DEBUG);
+ logger('xchan: ' . $xchan . '; HTTP code: ' . (isset($result) && array_key_exists('return_code', $result) ? $result['return_code'] : 'none') . '; modified: ' . $modified . '; URL: ' . $photo, LOGGER_DEBUG);
- return([$photo, $thumb, $micro, $type, $photo_failure, $modified]);
+ return([ $photo, $thumb, $micro, $type, $photo_failure, $modified ]);
}
+
/**
* @brief Import channel photo from a URL.
*