Post by OSWorX » Wed Jun 03, 2020 4:33 pm

I would not have been posted the solution with the include if not tested before successfully.
So, there must be something wrong at your side.

Full Stack Web Developer :: Dedicated OpenCart Development & Support DACH Region
Contact for Custom Work / Fast Support.


User avatar
Guru Member

Posts

Joined
Mon Jan 11, 2010 10:52 pm
Location - Austria

Post by AndreyPopov » Wed Jun 03, 2020 5:38 pm

OSWorX wrote:
Wed Jun 03, 2020 4:33 pm
I would not have been posted the solution with the include if not tested before successfully.
So, there must be something wrong at your side.
may be all depend from hoster.

what host are you use? may be you can change include path for php?

what include path provide my hoster for PHP I already print.

and that's why whole code in ocmod file is best way for me.

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by AndreyPopov » Wed Jun 03, 2020 5:51 pm

is this right code for replace

Code: Select all

	foreach ($matches as $match) {
		$file = $match[2];
		$type = $match[3];
		if ($type === 'js') {
			if ($pushJs) $headersJs[] = '<'.$file.'>; rel=preload; as=script';
		} elseif ($type === 'css') {
			if ($pushCss) $headersCss[] = '<'.$file.'>; rel=preload; as=style';
		} elseif ($type === 'woff2') {
			if ($pushFont) $headersFont[] = '<'.$file.'>; rel=preload; as=font';
		} elseif ($type === 'mp3') {
			if ($pushMp3) $headersMp3[] = '<'.$file.'>; rel=preload; as=audio';
		} else {
			if ($pushImage) $headersImage[] = '<'.$file.'>; rel=preload; as=image';
		}
	}

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by sw!tch » Wed Jun 03, 2020 6:50 pm

may be all depend from hoster.
Has nothing to do with the "host".

AndreyPopov wrote:
Wed Jun 03, 2020 4:00 pm

Code: Select all

include 'http2_header.php';
Maybe try ...

Code: Select all

include_once(DIR_SYSTEM.'library/http2_header.php');

Full Stack Web Developer :: Send a PM for Custom Work.
Backup and learn how to recover before you make any changes!


Active Member

Posts

Joined
Sat Apr 28, 2012 2:32 pm

Post by AndreyPopov » Wed Jun 03, 2020 7:04 pm

sw!tch wrote:
Wed Jun 03, 2020 6:50 pm

Maybe try ...

Code: Select all

include_once(DIR_SYSTEM.'library/http2_header.php');
https://www.priazha-shop.com/info.php

Core
include_path .:/usr/local/pear/php72

PHP Variables
$_SERVER['DOCUMENT_ROOT'] /home/priazhas/priazha-shop.com/www

may be:

Code: Select all

include_once(DOCUMENT_ROOT. '/system/library/http2_header.php');
????

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by sw!tch » Wed Jun 03, 2020 7:13 pm

Did you try what I posted? Opencart already has constants in place, why are you referencing PHP Server Variables?

Full Stack Web Developer :: Send a PM for Custom Work.
Backup and learn how to recover before you make any changes!


Active Member

Posts

Joined
Sat Apr 28, 2012 2:32 pm

Post by AndreyPopov » Wed Jun 03, 2020 7:40 pm

sw!tch wrote:
Wed Jun 03, 2020 7:13 pm
Did you try what I posted? Opencart already has constants in place, why are you referencing PHP Server Variables?
because in error log I see PHP errors:

Code: Select all

2020-06-03 1:29:34 - PHP Warning:  include(): Failed opening 'system/library/http2_headers.php' for inclusion (include_path='.:/usr/local/pear/php72') in /home/priazhas/priazha-shop.com/storage/modification/system/library/response.php on line 123

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by letxobnav » Wed Jun 03, 2020 8:20 pm

While you are discussing how to implement it, let me share my current version I use myself which limits the re-pushing of assets.

There are two extremes:
1) push all assets all the time which in some cases may be overkill and certainly unnecessary.
2) keep track of every asset you already pushed as to not push them again which would be difficult to manage.

This code uses a compromise as it keeps track (via a cookie) which route (root, product,category, etc.) has already been asset-pushed.
This assuming that most js,css,font assets will be the same per route, images most likely are not so we make an exception there.

In order to know which route we are dealing with, we need to make the request available in the response class, so we need to make a small change in framework.php and in the response construct.

in short:
It reads all enabled static asset urls in the output.
Based on the extension it creates the various push headers and consolidates those.
If the assets for a route have not yet been pushed, it pushes those.
What route has been pushed is stored in an array json-ed in a cookie.

If image always is set for a route it will still push the image assets every time even if the route was already pushed.
Here for category, product, search and root with query string.
This because the images there will most likely be different even if the route is the same.
For information route or root without querystring the images will probably stay the same so no need to push those again.


system/framework.php
change:

Code: Select all

$response = new Response();
to:

Code: Select all

$response = new Response($registry);
system/library/response.php
add:

Code: Select all

	public function __construct($registry) {
		$this->request = $registry->get('request');
	}

after:

Code: Select all

if ($this->output) {
add:

Code: Select all

/****************** HTTP/2 push asset headers ****************/
if ($_SERVER['SERVER_PROTOCOL'] == 'HTTP/2.0') {
	// Which assets to push
	$pushCss 	= true;		// push css assets
	$pushJs 	= true;		// push javascript assets
	$pushFont 	= true;		// push font assets
	$pushImage 	= true;		// push image assets
	$pushMp3 	= true;		// push audio assets
	
	// Arrays used
	$headersJs 		= array();
	$headersCss 	= array();
	$headersFont 	= array();
	$headersImage 	= array();
	$headersMp3 	= array();
	$headersAll 	= array();
	
	// control
	$use_cookie = true; 	// use cookies to limit pushes already pushed
	$relative 	= true; 	// use relative urls
	$subDir 	= ''; 		// sub-directory from domain if you use it
	
	// push methods per asset (preload or prefetch)
	$method_img 	= 'preload';
	$method_font 	= 'preload';
	$method_css 	= 'preload';
	$method_js 		= 'preload';
	$method_mp3 	= 'prefetch';

	// always push images for route
	$always_image_root 			= false;
	$always_image_root_query	= true;
	$always_image_category 		= true;
	$always_image_product 		= true;
	$always_image_search 		= true;
	$always_image_information 	= false;
	$always_image_other 		= false;
	
	// cookie preparation, set routes, which have already been pushed or not.
	if (!isset($_COOKIE['h2p'])) {
		$pushed_cookie_array = array(
			'ro' => 0,
			'ca' => 0,
			'pr' => 0,
			'se' => 0,
			'in' => 0,
			'ot' => 0
			);
	} else {
		$pushed_cookie_array = json_decode($_COOKIE['h2p'],true);
	}

	// prepare output, if ajax call, it will be in json so we need to json decode and get the html part
	$work_output =json_decode($this->output);
	if (json_last_error() === JSON_ERROR_NONE) {
		error_log(print_r($work_output,true));
		if (isset($work_output->html)) {
			$work_output = $work_output->html;
		} else {
			$work_output = false;
		}
	} else {
		$work_output = $this->output;
	}
	
	// Find the assets in the output, css, javascript, audio, fonts and images
	$ext = array();
	// prepare regex depending on what is enabled
	if ($pushCss) 	$ext[] = 'css';
	if ($pushJs) 	$ext[] = 'js';
	if ($pushFont) 	$ext[] = 'woff|woff2|ttf';
	if ($pushImage) $ext[] = 'jpg|webp|png';
	if ($pushMp3) 	$ext[] = 'mp3';
	$regexp = '#(data-src|src|src2|href)="([^"]+\.('.implode('|',$ext).')(\?[^"]+)?)"#';
	
	if (preg_match_all($regexp, $work_output, $matches, PREG_SET_ORDER)) {
		foreach ($matches as $match) {
			$file = $match[2];
			if ($relative) {
				if (substr($file,0,1) != '/' && substr($file,0,8) != 'https://') $file = $subDir.$file;
			} else {
				if (substr($file,0,1) != '/' && substr($file,0,8) != 'https://') $file = HTTPS_SERVER.$file;
			}
			$type = $match[3];
			if ($type === 'js' && $pushJs) 										{ $headersJs[] = '<'.$file.'>; rel='.$method_js.'; as=script';}
			elseif ($type === 'css' && $pushCss) 								{ $headersCss[] = '<'.$file.'>; rel='.$method_css.'; as=style';}
			elseif ($type === 'mp3' && $pushMp3) 								{ $headersMp3[] = '<'.$file.'>; rel='.$method_mp3.'; as=audio';}
			elseif (in_array($type, array('woff','woff2','ttf')) && $pushFont) 	{ $headersFont[] = '<'.$file.'>; rel='.$method_font.'; as=font';}
			elseif (in_array($type, array('jpg','webp')) && $pushImage) 		{ $headersImage[] = '<'.$file.'>; rel='.$method_img.'; as=image';}
		}
		
		// clear memory
		$matches = null;
		unset($matches);
		
		// merge the arrays and clean
		$headersAll = array_merge($headersCss,$headersJs,$headersFont,$headersImage,$headersMp3);
		$headersAll = array_unique($headersAll);
		$headersAlls = implode(',',$headersAll);
		
		// use cookie to track what has been pushed
		if ($use_cookie) {
			$always_img = true; // push images regardless, if most pages feature different images
			$push = false;
			if (!isset($this->request->get['route']) || $this->request->get['route'] == 'common/home' || $this->request->get['route'] == '') {
				if (!$pushed_cookie_array['ro']) $push = true; 											// push root assets
				if (strstr($_SERVER['REQUEST_URI'],'?')) {
					$always_img = $always_image_root_query;												// push images regardless if querystring
				} else {
					$always_img = $always_image_root;													// push images regardless if no querystring
				}
				$pushed_cookie_array['ro'] = 1; 														// set to pushed
			} elseif (isset($this->request->get['route']) && $this->request->get['route'] == 'product/category') {
				if (!$pushed_cookie_array['ca']) $push = true; 											// push category assets
				$pushed_cookie_array['ca'] = 1; 														// set to pushed
				$always_img = $always_image_category;
			} elseif (isset($this->request->get['route']) && $this->request->get['route'] == 'product/product') {
				if (!$pushed_cookie_array['pr']) $push = true; 											// push product assets
				$pushed_cookie_array['pr'] = 1; 														// set to pushed
				$always_img = $always_image_product;
			} elseif (isset($this->request->get['route']) && $this->request->get['route'] == 'product/search') {
				if (!$pushed_cookie_array['se']) $push = true; 											// push search assets
				$pushed_cookie_array['se'] = 1; 														// set to pushed
				$always_img = $always_image_search;
			} elseif (isset($this->request->get['route']) && $this->request->get['route'] == 'information/information') {
				if (!$pushed_cookie_array['in']) $push = true; 											// push information assets
				$pushed_cookie_array['in'] = 1; 														// set to pushed
				$always_img = $always_image_information; 												// push images regardless
			} else {
				// any other routes
				if (!$pushed_cookie_array['ot']) $push = true; 											// push other pages assets
				$pushed_cookie_array['ot'] = 1; 														// set to pushed
				$always_img = $always_image_other; 														// push images regardless
			}
			if ($push) {
				if ($headersAlls) header('Link: '.$headersAlls, false);
				// determine cookie domain
				$domain = str_replace('https://','',HTTPS_SERVER);
				$domain = str_replace($subDir,'',$domain);
				$domain = str_replace('www','',$domain);
				// set h2p (pushed routes) cookie for 24hrs
				setcookie("h2p", json_encode($pushed_cookie_array), time() + 60 * 60 * 24 * 1, "/", $domain, true);
			} elseif ($always_img) {
				// send push headers for images anyway
				if ($headersImage) {
					$headersImage = array_unique($headersImage);
					$headersImages = implode(',',$headersImage);
					header('Link: '.$headersImages, false);
				}
			}
		// push enabled assets every time
		} else {
			if ($headersAlls) header('Link: '.$headersAlls, false);
		}
	}
}
/********************** HTTP2 push headers ********************/

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by AndreyPopov » Wed Jun 03, 2020 8:55 pm

letxobnav wrote:
Wed Jun 03, 2020 8:20 pm

There are two extremes:
1) push all assets all the time which in some cases may be overkill and certainly unnecessary.
2) keep track of every asset you already pushed as to not push them again which would be difficult to manage.

in short:
It reads all enabled static asset urls in the output.
Based on the extension it creates the various push headers and consolidates those.
If the assets for a route have not yet been pushed, it pushes those.
What route has been pushed is stored in an array json-ed in a cookie.


great thanks for expand answer.
I try later at 00:00 CET

but have question.
letxobnav wrote:
Wed Jun 03, 2020 8:20 pm

Code: Select all

/****************** HTTP/2 push asset headers ****************/
if ($_SERVER['SERVER_PROTOCOL'] == 'HTTP/2.0') {
all tests acknowledgment that site support HTTP/2 ( https://tools.keycdn.com/http2-test https://http2.pro)

but PHP report

Code: Select all

$_SERVER['SERVER_PROTOCOL']	HTTP/1.0
hoster says that's why OpenLitespeed over Nginx and Nginx communicate with OpenLitespeed by HTTP/1.0.

I remove this check when try.

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by letxobnav » Wed Jun 03, 2020 10:03 pm

http/1.0 is pretty bad, used mostly by old proxies nowadays (I actually block all http/1.0 requests as they are mostly used by cheap spammers), even http/1.1 is old.

Don't think you will get much improvent with those as even http/1.1 does not mutiplex requests over the same tcp connection which means you are limited to the connections the browser allows to open for a domain and thus how many parallel requests you can send.
Compare it to a 4 lane highway with http/1.1 only allowing 1 car per lane whereas http/2 allows multiple cars per lane.

You could also try https://instant.page/
But be aware that that issues html preload requests (not static asset pre-load pushes) when hovering over a link and when a link is in view on a mobile.
So better filter those pre-load requests when using analytics or you will find many page requests which are not really page requests.
And certainly do not use it in combination with server asset push or your server will be inundated with needless requests.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by AndreyPopov » Wed Jun 03, 2020 10:29 pm

letxobnav wrote:
Wed Jun 03, 2020 10:03 pm
http/1.0 is pretty bad
as I write prior - test says HTTP/2 supported

Image
Image

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by AndreyPopov » Thu Jun 04, 2020 6:17 am

try use

Code: Select all

Fatal error: Uncaught ArgumentCountError: Too few arguments to function Response::__construct(), 0 passed in /home/priazhas/priazha-shop.com/www/system/framework.php on line 73 and exactly 1 expected in /home/priazhas/priazha-shop.com/storage/modification/system/library/response.php:25 Stack trace: #0 /home/priazhas/priazha-shop.com/www/system/framework.php(73): Response->__construct() #1 /home/priazhas/priazha-shop.com/www/system/startup.php(104): require_once('/home/priazhas/...') #2 /home/priazhas/priazha-shop.com/www/index.php(19): start('catalog') #3 {main} thrown in /home/priazhas/priazha-shop.com/storage/modification/system/library/response.php on line 25

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by letxobnav » Thu Jun 04, 2020 8:41 am

did you make the change in system/framework.php?

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by AndreyPopov » Thu Jun 04, 2020 5:19 pm

letxobnav wrote:
Thu Jun 04, 2020 8:41 am
did you make the change in system/framework.php?
yes. by ocmod.

or system/framework.php I need change directly?

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by letxobnav » Thu Jun 04, 2020 6:33 pm

or system/framework.php I need change directly?
no, but it doesn't look like the change was made.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by AndreyPopov » Thu Jun 04, 2020 8:29 pm

letxobnav wrote:
Thu Jun 04, 2020 6:33 pm
or system/framework.php I need change directly?
no, but it doesn't look like the change was made.
I delete modifications cache
than Refresh modifications cache

and check
/storage/modification/system/

framework.php appear there with chahges.

but if read error message, it say : 0 passed in /www/system/framework.php

system not use modified framework.php from /storage/modification/system/?

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by letxobnav » Thu Jun 04, 2020 9:44 pm

in system/startup.php

Code: Select all

function start($application_config) {
	require_once(DIR_SYSTEM . 'framework.php');	
}
yes, seems like framework.php cannot be modified via ocmod or at least it is not loaded from modifications.

you can double check by adding an error_log('hello'); in there and check your php error log to see if it shows or put an echo in that file.

I cannot check as I do not use ocmod for changes.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan

Post by AndreyPopov » Thu Jun 04, 2020 10:19 pm

letxobnav wrote:
Thu Jun 04, 2020 9:44 pm

yes, seems like framework.php cannot be modified via ocmod
ok. try change framework.php directly tonight.

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by AndreyPopov » Fri Jun 05, 2020 12:22 am

try on test site
Image
Image

probably working!!!
later try on main site.

New member

Posts

Joined
Sat Feb 04, 2017 2:53 am

Post by letxobnav » Fri Jun 05, 2020 10:13 am

looks good.

ps. you can also see directly in web developer tools whether a connection is h2, no need to verify by an external site.

Crystal Light Centrum Taiwan
Extensions: MailQueue | SUKHR | VBoces

“Data security is paramount at [...], and we are committed to protecting the privacy of anyone who is associated with our [...]. We’ve made a lot of improvements and will continue to make them.”
When you know your life savings are gone.


User avatar
Expert Member

Posts

Joined
Fri Aug 18, 2017 4:35 pm
Location - Taiwan
Who is online

Users browsing this forum: No registered users and 128 guests