Jump to content

Edit History

hakeryk2

hakeryk2

Na grupie zamkniętej Prestashop Polska ktoś poruszył temat zwiększonego zużycia CPU na hostingu ostatnimi na czasy i w sumie lekko temat olałem, dopóki nie powiązałem tego z krótkimi skokami zużycia na serwerze. Ostatnio też miałem dosyć duże skoki w którym po kilkanaście sekund lub nawet nieco dłużej wszystkie 4 rdzenie były na 100% i gdy szybko podglądałem co to za proces w PHP (komendą strace) to gdzieś tam śmigało odpalane zapytanie z PHP do MySQL o SUM('quantity') FROM `ps_cart_product` where bla bla i id_cart". No cóż, myślałem, że sobie z botami generującymi koszyki poradziłem (na forum są o tym tematy jak je blokować), ale jeden wybitnie ma gdzieś moje zabezpieczenia i wygenerował koszyk w którym było ponad 1000 produktów i gdy dodawał każdy kolejny produkt odpalały się wszystkie reguły koszyków itp, które dosyć mocno obliczeniowe były i obstawiam, że i u Was się to robiło.

Tak więc na start diagnoza i naprawa:
1) Sprawdzić czy nie ma porzuconych koszyków, mój był na kilkanaście milionów złotych xD
2) Wprowadzić limit na produkty dodane do koszyka, można to na szybko zrobić o tak https://youtu.be/wAlXtr8u5Qo choć można sobie nieco to doprecyzować lub skopiować całą funkcję processChangeProductInCart stąd i podmienić w pliku controllers/front/CartController:php Można ustawić zmienne pod siebie zmieniając zmienne  $max_cart_quantity oraz $max_cart_products.

    protected function processChangeProductInCart()
    {
        $mode = (Tools::getIsset('update') && $this->id_product) ? 'update' : 'add';

        if ($this->qty == 0) {
            $this->errors[] = Tools::displayError('Null quantity.', !Tools::getValue('ajax'));
        } elseif (!$this->id_product) {
            $this->errors[] = Tools::displayError('Product not found', !Tools::getValue('ajax'));
        }

        $product = new Product($this->id_product, true, $this->context->language->id);
        if (!$product->id || !$product->active || !$product->checkAccess($this->context->cart->id_customer)) {
            $this->errors[] = Tools::displayError('This product is no longer available.', !Tools::getValue('ajax'));
            return;
        }

        $qty_to_check = $this->qty;
        $cart_products = $this->context->cart->getProducts();

        $total_cart_quantity = 0;
        $total_cart_products = count($cart_products);

        if (is_array($cart_products)) {
            foreach ($cart_products as $cart_product) {
                $total_cart_quantity += $cart_product['cart_quantity'];
                if ((!isset($this->id_product_attribute) || $cart_product['id_product_attribute'] == $this->id_product_attribute) &&
                    (isset($this->id_product) && $cart_product['id_product'] == $this->id_product)) {
                    $qty_to_check = $cart_product['cart_quantity'];

                    if (Tools::getValue('op', 'up') == 'down') {
                        $qty_to_check -= $this->qty;
                    } else {
                        $qty_to_check += $this->qty;
                    }

                    break;
                }
            }
        }

        $max_cart_quantity = 100; // Limit max quantity of all products
        $max_cart_products = 20; // limit products

        // limit the max add products to the cart added 
        if (Tools::getValue('op', 'up') == 'up' && $mode == 'add'){
            if ($total_cart_products >= $max_cart_products ){
                $this->errors[] = sprintf(Tools::displayError('Przekroczono limit %s dodanych produktów do koszyka'), $max_cart_products);
            } else if ($total_cart_quantity + $this->qty > $max_cart_quantity) {
                $this->errors[] = sprintf(Tools::displayError('Przekroczono limit %s ilości sztuk w koszyku'), $max_cart_quantity);
            }
        }

        // Check product quantity availability
        if ($this->id_product_attribute) {
            if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
                $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
            }
        } elseif ($product->hasAttributes()) {
            $minimumQuantity = ($product->out_of_stock == 2) ? !Configuration::get('PS_ORDER_OUT_OF_STOCK') : !$product->out_of_stock;
            $this->id_product_attribute = Product::getDefaultAttribute($product->id, $minimumQuantity);
            // @todo do something better than a redirect admin !!
            if (!$this->id_product_attribute) {
                Tools::redirectAdmin($this->context->link->getProductLink($product));
            } elseif (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
                $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
            }
        } elseif (!$product->checkQty($qty_to_check)) {
            $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
        }

        // If no errors, process product addition
        if (!$this->errors && $mode == 'add') {
            // Add cart if no cart found
            if (!$this->context->cart->id) {
                if (Context::getContext()->cookie->id_guest) {
                    $guest = new Guest(Context::getContext()->cookie->id_guest);
                    $this->context->cart->mobile_theme = $guest->mobile_theme;
                }
                $this->context->cart->add();
                if ($this->context->cart->id) {
                    $this->context->cookie->id_cart = (int)$this->context->cart->id;
                }
            }

            // Check customizable fields
            if (!$product->hasAllRequiredCustomizableFields() && !$this->customization_id) {
                $this->errors[] = Tools::displayError('Please fill in all of the required fields, and then save your customizations.', !Tools::getValue('ajax'));
            }

            if (!$this->errors) {
                $cart_rules = $this->context->cart->getCartRules();
                $available_cart_rules = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
                $update_quantity = $this->context->cart->updateQty($this->qty, $this->id_product, $this->id_product_attribute, $this->customization_id, Tools::getValue('op', 'up'), $this->id_address_delivery);
                if ($update_quantity < 0) {
                    // If product has attribute, minimal quantity is set with minimal quantity of attribute
                    $minimal_quantity = ($this->id_product_attribute) ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity;
                    $this->errors[] = sprintf(Tools::displayError('You must add %d minimum quantity', !Tools::getValue('ajax')), $minimal_quantity);
                } elseif (!$update_quantity) {
                    $this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', !Tools::getValue('ajax'));
                } elseif ((int)Tools::getValue('allow_refresh')) {
                    // If the cart rules has changed, we need to refresh the whole cart
                    $cart_rules2 = $this->context->cart->getCartRules();
                    if (count($cart_rules2) != count($cart_rules)) {
                        $this->ajax_refresh = true;
                    } elseif (count($cart_rules2)) {
                        $rule_list = array();
                        foreach ($cart_rules2 as $rule) {
                            $rule_list[] = $rule['id_cart_rule'];
                        }
                        foreach ($cart_rules as $rule) {
                            if (!in_array($rule['id_cart_rule'], $rule_list)) {
                                $this->ajax_refresh = true;
                                break;
                            }
                        }
                    } else {
                        $available_cart_rules2 = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
                        if (count($available_cart_rules2) != count($available_cart_rules)) {
                            $this->ajax_refresh = true;
                        } elseif (count($available_cart_rules2)) {
                            $rule_list = array();
                            foreach ($available_cart_rules2 as $rule) {
                                $rule_list[] = $rule['id_cart_rule'];
                            }
                            foreach ($cart_rules2 as $rule) {
                                if (!in_array($rule['id_cart_rule'], $rule_list)) {
                                    $this->ajax_refresh = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        $removed = CartRule::autoRemoveFromCart();
        CartRule::autoAddToCart();
        if (count($removed) && (int)Tools::getValue('allow_refresh')) {
            $this->ajax_refresh = true;
        }
    }


3) Wywalić te ogromne koszyki ze sklepu
4) Sprawdzić w logach apache IP bota wyszukując seokicks i na początku będziecie mieli ich IP. Bot jest na tyle bezczelny, że wchodzi w crawl z tym samym ciastkiem i jego IP to w moim przypadku 95.216.2.43. Wystarczy w htaccess w głównym folderze sklepu dodać w wolnej linii taki kod

5) Do robots.txt dodać regułę Disallow: /*?add= by profilaktycznie odsiać roboty które przestrzegają reguł, ponieważ Prestashop w wersji 1.6 i chyba w 1.7 nie dodaje domyślnie tej reguły do tego pliku.
 

Deny from 95.216.2.43 95.216.11.210

Napisałem do autorów by coś z tymi zrobili.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
EDYCJA:

Otrzymałem odpowiedź twórców crawlera i ogólnie byli zdziwieni tym, że do koszyka dodaje się poprzez przekazanie parametru z URL koszyka oraz to, że Prestashop domyślnie do robots.txt nie dodaje Disallow: /*?add= ponieważ ich robot przestrzega reguł. No wszystko byłoby spoko gdyby nie sam fakt, że u mnie robots.txt miał odpowiednie reguły blokujące wszelakie takie akcje więc nie powinno się to wydarzyć. Ponoć w 1.7 nie powinno się to dziać.

hakeryk2

hakeryk2

Na grupie zamkniętej Prestashop Polska ktoś poruszył temat zwiększonego zużycia CPU na hostingu ostatnimi na czasy i w sumie lekko temat olałem, dopóki nie powiązałem tego z krótkimi skokami zużycia na serwerze. Ostatnio też miałem dosyć duże skoki w którym po kilkanaście sekund lub nawet nieco dłużej wszystkie 4 rdzenie były na 100% i gdy szybko podglądałem co to za proces w PHP (komendą strace) to gdzieś tam śmigało odpalane zapytanie z PHP do MySQL o SUM('quantity') FROM `ps_cart_product` where bla bla i id_cart". No cóż, myślałem, że sobie z botami generującymi koszyki poradziłem (na forum są o tym tematy jak je blokować), ale jeden wybitnie ma gdzieś moje zabezpieczenia i wygenerował koszyk w którym było ponad 1000 produktów i gdy dodawał każdy kolejny produkt odpalały się wszystkie reguły koszyków itp, które dosyć mocno obliczeniowe były i obstawiam, że i u Was się to robiło.

Tak więc na start diagnoza i naprawa:
1) Sprawdzić czy nie ma porzuconych koszyków, mój był na kilkanaście milionów złotych xD
2) Wprowadzić limit na produkty dodane do koszyka, można to na szybko zrobić o tak https://youtu.be/wAlXtr8u5Qo choć można sobie nieco to doprecyzować lub skopiować całą funkcję processChangeProductInCart stąd i podmienić w pliku controllers/front/CartController:php Można ustawić zmienne pod siebie zmieniając zmienne  $max_cart_quantity oraz $max_cart_products.

    protected function processChangeProductInCart()
    {
        $mode = (Tools::getIsset('update') && $this->id_product) ? 'update' : 'add';

        if ($this->qty == 0) {
            $this->errors[] = Tools::displayError('Null quantity.', !Tools::getValue('ajax'));
        } elseif (!$this->id_product) {
            $this->errors[] = Tools::displayError('Product not found', !Tools::getValue('ajax'));
        }

        $product = new Product($this->id_product, true, $this->context->language->id);
        if (!$product->id || !$product->active || !$product->checkAccess($this->context->cart->id_customer)) {
            $this->errors[] = Tools::displayError('This product is no longer available.', !Tools::getValue('ajax'));
            return;
        }

        $qty_to_check = $this->qty;
        $cart_products = $this->context->cart->getProducts();

        $total_cart_quantity = 0;
        $total_cart_products = count($cart_products);

        if (is_array($cart_products)) {
            foreach ($cart_products as $cart_product) {
                $total_cart_quantity += $cart_product['cart_quantity'];
                if ((!isset($this->id_product_attribute) || $cart_product['id_product_attribute'] == $this->id_product_attribute) &&
                    (isset($this->id_product) && $cart_product['id_product'] == $this->id_product)) {
                    $qty_to_check = $cart_product['cart_quantity'];

                    if (Tools::getValue('op', 'up') == 'down') {
                        $qty_to_check -= $this->qty;
                    } else {
                        $qty_to_check += $this->qty;
                    }

                    break;
                }
            }
        }

        $max_cart_quantity = 100; // Limit max quantity of all products
        $max_cart_products = 20; // limit products

        // limit the max add products to the cart added 
        if (Tools::getValue('op', 'up') == 'up' && $mode == 'add'){
            if ($total_cart_products >= $max_cart_products ){
                $this->errors[] = sprintf(Tools::displayError('Przekroczono limit %s dodanych produktów do koszyka'), $max_cart_products);
            } else if ($total_cart_quantity + $this->qty > $max_cart_quantity) {
                $this->errors[] = sprintf(Tools::displayError('Przekroczono limit %s ilości sztuk w koszyku'), $max_cart_quantity);
            }
        }

        // Check product quantity availability
        if ($this->id_product_attribute) {
            if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
                $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
            }
        } elseif ($product->hasAttributes()) {
            $minimumQuantity = ($product->out_of_stock == 2) ? !Configuration::get('PS_ORDER_OUT_OF_STOCK') : !$product->out_of_stock;
            $this->id_product_attribute = Product::getDefaultAttribute($product->id, $minimumQuantity);
            // @todo do something better than a redirect admin !!
            if (!$this->id_product_attribute) {
                Tools::redirectAdmin($this->context->link->getProductLink($product));
            } elseif (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
                $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
            }
        } elseif (!$product->checkQty($qty_to_check)) {
            $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
        }

        // If no errors, process product addition
        if (!$this->errors && $mode == 'add') {
            // Add cart if no cart found
            if (!$this->context->cart->id) {
                if (Context::getContext()->cookie->id_guest) {
                    $guest = new Guest(Context::getContext()->cookie->id_guest);
                    $this->context->cart->mobile_theme = $guest->mobile_theme;
                }
                $this->context->cart->add();
                if ($this->context->cart->id) {
                    $this->context->cookie->id_cart = (int)$this->context->cart->id;
                }
            }

            // Check customizable fields
            if (!$product->hasAllRequiredCustomizableFields() && !$this->customization_id) {
                $this->errors[] = Tools::displayError('Please fill in all of the required fields, and then save your customizations.', !Tools::getValue('ajax'));
            }

            if (!$this->errors) {
                $cart_rules = $this->context->cart->getCartRules();
                $available_cart_rules = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
                $update_quantity = $this->context->cart->updateQty($this->qty, $this->id_product, $this->id_product_attribute, $this->customization_id, Tools::getValue('op', 'up'), $this->id_address_delivery);
                if ($update_quantity < 0) {
                    // If product has attribute, minimal quantity is set with minimal quantity of attribute
                    $minimal_quantity = ($this->id_product_attribute) ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity;
                    $this->errors[] = sprintf(Tools::displayError('You must add %d minimum quantity', !Tools::getValue('ajax')), $minimal_quantity);
                } elseif (!$update_quantity) {
                    $this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', !Tools::getValue('ajax'));
                } elseif ((int)Tools::getValue('allow_refresh')) {
                    // If the cart rules has changed, we need to refresh the whole cart
                    $cart_rules2 = $this->context->cart->getCartRules();
                    if (count($cart_rules2) != count($cart_rules)) {
                        $this->ajax_refresh = true;
                    } elseif (count($cart_rules2)) {
                        $rule_list = array();
                        foreach ($cart_rules2 as $rule) {
                            $rule_list[] = $rule['id_cart_rule'];
                        }
                        foreach ($cart_rules as $rule) {
                            if (!in_array($rule['id_cart_rule'], $rule_list)) {
                                $this->ajax_refresh = true;
                                break;
                            }
                        }
                    } else {
                        $available_cart_rules2 = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
                        if (count($available_cart_rules2) != count($available_cart_rules)) {
                            $this->ajax_refresh = true;
                        } elseif (count($available_cart_rules2)) {
                            $rule_list = array();
                            foreach ($available_cart_rules2 as $rule) {
                                $rule_list[] = $rule['id_cart_rule'];
                            }
                            foreach ($cart_rules2 as $rule) {
                                if (!in_array($rule['id_cart_rule'], $rule_list)) {
                                    $this->ajax_refresh = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        $removed = CartRule::autoRemoveFromCart();
        CartRule::autoAddToCart();
        if (count($removed) && (int)Tools::getValue('allow_refresh')) {
            $this->ajax_refresh = true;
        }
    }


3) Wywalić te ogromne koszyki ze sklepu
4) Sprawdzić w logach apache IP bota wyszukując seokicks i na początku będziecie mieli ich IP. Bot jest na tyle bezczelny, że wchodzi w crawl z tym samym ciastkiem i jego IP to w moim przypadku 95.216.2.43. Wystarczy w htaccess w głównym folderze sklepu dodać w wolnej linii taki kod

5) Do robots.txt dodać regułę Disallow: /*?add= by profilaktycznie odsiać roboty które przestrzegają reguł, ponieważ Prestashop w wersji 1.6 i chyba w 1.7 nie dodaje domyślnie tej reguły do tego pliku.
 

Deny from 95.216.2.43 95.216.11.210

Napisałem do autorów by coś z tymi zrobili.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
EDYCJA:

Otrzymałem odpowiedź twórców crawlera i ogólnie byli zdziwieni tym, że do koszyka dodaje się poprzez przekazanie parametru z URL koszyka oraz to, że Prestashop domyślnie do robots.txt nie dodaje Disallow: /*?add= ponieważ ich robot przestrzega reguł. Ponoć w 1.7 nie powinno się to wydarzyć.

hakeryk2

hakeryk2

Na grupie zamkniętej Prestashop Polska ktoś poruszył temat zwiększonego zużycia CPU na hostingu ostatnimi na czasy i w sumie lekko temat olałem, dopóki nie powiązałem tego z krótkimi skokami zużycia na serwerze. Ostatnio też miałem dosyć duże skoki w którym po kilkanaście sekund lub nawet nieco dłużej wszystkie 4 rdzenie były na 100% i gdy szybko podglądałem co to za proces w PHP (komendą strace) to gdzieś tam śmigało odpalane zapytanie z PHP do MySQL o SUM('quantity') FROM `ps_cart_product` where bla bla i id_cart". No cóż, myślałem, że sobie z botami generującymi koszyki poradziłem (na forum są o tym tematy jak je blokować), ale jeden wybitnie ma gdzieś moje zabezpieczenia i wygenerował koszyk w którym było ponad 1000 produktów i gdy dodawał każdy kolejny produkt odpalały się wszystkie reguły koszyków itp, które dosyć mocno obliczeniowe były i obstawiam, że i u Was się to robiło.

Tak więc na start diagnoza i naprawa:
1) Sprawdzić czy nie ma porzuconych koszyków, mój był na kilkanaście milionów złotych xD
2) Wprowadzić limit na produkty dodane do koszyka, można to na szybko zrobić o tak https://youtu.be/wAlXtr8u5Qo choć można sobie nieco to doprecyzować lub skopiować całą funkcję processChangeProductInCart stąd i podmienić w pliku controllers/front/CartController:php Można ustawić zmienne pod siebie zmieniając zmienne  $max_cart_quantity oraz $max_cart_products.

    protected function processChangeProductInCart()
    {
        $mode = (Tools::getIsset('update') && $this->id_product) ? 'update' : 'add';

        if ($this->qty == 0) {
            $this->errors[] = Tools::displayError('Null quantity.', !Tools::getValue('ajax'));
        } elseif (!$this->id_product) {
            $this->errors[] = Tools::displayError('Product not found', !Tools::getValue('ajax'));
        }

        $product = new Product($this->id_product, true, $this->context->language->id);
        if (!$product->id || !$product->active || !$product->checkAccess($this->context->cart->id_customer)) {
            $this->errors[] = Tools::displayError('This product is no longer available.', !Tools::getValue('ajax'));
            return;
        }

        $qty_to_check = $this->qty;
        $cart_products = $this->context->cart->getProducts();

        $total_cart_quantity = 0;
        $total_cart_products = count($cart_products);

        if (is_array($cart_products)) {
            foreach ($cart_products as $cart_product) {
                $total_cart_quantity += $cart_product['cart_quantity'];
                if ((!isset($this->id_product_attribute) || $cart_product['id_product_attribute'] == $this->id_product_attribute) &&
                    (isset($this->id_product) && $cart_product['id_product'] == $this->id_product)) {
                    $qty_to_check = $cart_product['cart_quantity'];

                    if (Tools::getValue('op', 'up') == 'down') {
                        $qty_to_check -= $this->qty;
                    } else {
                        $qty_to_check += $this->qty;
                    }

                    break;
                }
            }
        }

        $max_cart_quantity = 100; // Limit max quantity of all products
        $max_cart_products = 20; // limit products

        // limit the max add products to the cart added 
        if (Tools::getValue('op', 'up') == 'up' && $mode == 'add'){
            if ($total_cart_products >= $max_cart_products ){
                $this->errors[] = sprintf(Tools::displayError('Przekroczono limit %s dodanych produktów do koszyka'), $max_cart_products);
            } else if ($total_cart_quantity + $this->qty > $max_cart_quantity) {
                $this->errors[] = sprintf(Tools::displayError('Przekroczono limit %s ilości sztuk w koszyku'), $max_cart_quantity);
            }
        }

        // Check product quantity availability
        if ($this->id_product_attribute) {
            if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
                $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
            }
        } elseif ($product->hasAttributes()) {
            $minimumQuantity = ($product->out_of_stock == 2) ? !Configuration::get('PS_ORDER_OUT_OF_STOCK') : !$product->out_of_stock;
            $this->id_product_attribute = Product::getDefaultAttribute($product->id, $minimumQuantity);
            // @todo do something better than a redirect admin !!
            if (!$this->id_product_attribute) {
                Tools::redirectAdmin($this->context->link->getProductLink($product));
            } elseif (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
                $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
            }
        } elseif (!$product->checkQty($qty_to_check)) {
            $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
        }

        // If no errors, process product addition
        if (!$this->errors && $mode == 'add') {
            // Add cart if no cart found
            if (!$this->context->cart->id) {
                if (Context::getContext()->cookie->id_guest) {
                    $guest = new Guest(Context::getContext()->cookie->id_guest);
                    $this->context->cart->mobile_theme = $guest->mobile_theme;
                }
                $this->context->cart->add();
                if ($this->context->cart->id) {
                    $this->context->cookie->id_cart = (int)$this->context->cart->id;
                }
            }

            // Check customizable fields
            if (!$product->hasAllRequiredCustomizableFields() && !$this->customization_id) {
                $this->errors[] = Tools::displayError('Please fill in all of the required fields, and then save your customizations.', !Tools::getValue('ajax'));
            }

            if (!$this->errors) {
                $cart_rules = $this->context->cart->getCartRules();
                $available_cart_rules = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
                $update_quantity = $this->context->cart->updateQty($this->qty, $this->id_product, $this->id_product_attribute, $this->customization_id, Tools::getValue('op', 'up'), $this->id_address_delivery);
                if ($update_quantity < 0) {
                    // If product has attribute, minimal quantity is set with minimal quantity of attribute
                    $minimal_quantity = ($this->id_product_attribute) ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity;
                    $this->errors[] = sprintf(Tools::displayError('You must add %d minimum quantity', !Tools::getValue('ajax')), $minimal_quantity);
                } elseif (!$update_quantity) {
                    $this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', !Tools::getValue('ajax'));
                } elseif ((int)Tools::getValue('allow_refresh')) {
                    // If the cart rules has changed, we need to refresh the whole cart
                    $cart_rules2 = $this->context->cart->getCartRules();
                    if (count($cart_rules2) != count($cart_rules)) {
                        $this->ajax_refresh = true;
                    } elseif (count($cart_rules2)) {
                        $rule_list = array();
                        foreach ($cart_rules2 as $rule) {
                            $rule_list[] = $rule['id_cart_rule'];
                        }
                        foreach ($cart_rules as $rule) {
                            if (!in_array($rule['id_cart_rule'], $rule_list)) {
                                $this->ajax_refresh = true;
                                break;
                            }
                        }
                    } else {
                        $available_cart_rules2 = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
                        if (count($available_cart_rules2) != count($available_cart_rules)) {
                            $this->ajax_refresh = true;
                        } elseif (count($available_cart_rules2)) {
                            $rule_list = array();
                            foreach ($available_cart_rules2 as $rule) {
                                $rule_list[] = $rule['id_cart_rule'];
                            }
                            foreach ($cart_rules2 as $rule) {
                                if (!in_array($rule['id_cart_rule'], $rule_list)) {
                                    $this->ajax_refresh = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        $removed = CartRule::autoRemoveFromCart();
        CartRule::autoAddToCart();
        if (count($removed) && (int)Tools::getValue('allow_refresh')) {
            $this->ajax_refresh = true;
        }
    }


3) Wywalić te ogromne koszyki ze sklepu
4) Sprawdzić w logach apache IP bota wyszukując seokicks i na początku będziecie mieli ich IP. Bot jest na tyle bezczelny, że wchodzi w crawl z tym samym ciastkiem i jego IP to w moim przypadku 95.216.2.43. Wystarczy w htaccess w głównym folderze sklepu dodać w wolnej linii taki kod

5) Do robots.txt dodać regułę Disallow: /*?add= by profilaktycznie odsiać roboty które przestrzegają reguł, ponieważ Prestashop w wersji 1.6 i chyba w 1.7 nie dodaje domyślnie tej reguły do tego pliku.
 

Deny from 95.216.2.43 95.216.11.210

Napisałem do autorów by coś z tymi zrobili.
----------------------------------------------------------------------------------------------------------------------------------------------------------------
EDYCJA:

Otrzymałem odpowiedź twórców crawlera i ogólnie byli zdziwieni tym, że do koszyka dodaje się poprzez przekazanie parametru z URL koszyka oraz to, że Prestashop domyślnie do robots.txt nie dodaje Disallow: /*?add= ponieważ ich robot przestrzega reguł.

hakeryk2

hakeryk2

Na grupie zamkniętej Prestashop Polska ktoś poruszył temat zwiększonego zużycia CPU na hostingu ostatnimi na czasy i w sumie lekko temat olałem, dopóki nie powiązałem tego z krótkimi skokami zużycia na serwerze. Ostatnio też miałem dosyć duże skoki w którym po kilkanaście sekund lub nawet nieco dłużej wszystkie 4 rdzenie były na 100% i gdy szybko podglądałem co to za proces w PHP (komendą strace) to gdzieś tam śmigało odpalane zapytanie z PHP do MySQL o SUM('quantity') FROM `ps_cart_product` where bla bla i id_cart". No cóż, myślałem, że sobie z botami generującymi koszyki poradziłem (na forum są o tym tematy jak je blokować), ale jeden wybitnie ma gdzieś moje zabezpieczenia i wygenerował koszyk w którym było ponad 1000 produktów i gdy dodawał każdy kolejny produkt odpalały się wszystkie reguły koszyków itp, które dosyć mocno obliczeniowe były i obstawiam, że i u Was się to robiło.

Tak więc na start diagnoza i naprawa:
1) Sprawdzić czy nie ma porzuconych koszyków, mój był na kilkanaście milionów złotych xD
2) Wprowadzić limit na produkty dodane do koszyka, można to na szybko zrobić o tak https://youtu.be/wAlXtr8u5Qo choć można sobie nieco to doprecyzować lub skopiować całą funkcję processChangeProductInCart stąd i podmienić w pliku controllers/front/CartController:php Można ustawić zmienne pod siebie zmieniając zmienne  $max_cart_quantity oraz $max_cart_products.

    protected function processChangeProductInCart()
    {
        $mode = (Tools::getIsset('update') && $this->id_product) ? 'update' : 'add';

        if ($this->qty == 0) {
            $this->errors[] = Tools::displayError('Null quantity.', !Tools::getValue('ajax'));
        } elseif (!$this->id_product) {
            $this->errors[] = Tools::displayError('Product not found', !Tools::getValue('ajax'));
        }

        $product = new Product($this->id_product, true, $this->context->language->id);
        if (!$product->id || !$product->active || !$product->checkAccess($this->context->cart->id_customer)) {
            $this->errors[] = Tools::displayError('This product is no longer available.', !Tools::getValue('ajax'));
            return;
        }

        $qty_to_check = $this->qty;
        $cart_products = $this->context->cart->getProducts();

        $total_cart_quantity = 0;
        $total_cart_products = count($cart_products);

        if (is_array($cart_products)) {
            foreach ($cart_products as $cart_product) {
                $total_cart_quantity += $cart_product['cart_quantity'];
                if ((!isset($this->id_product_attribute) || $cart_product['id_product_attribute'] == $this->id_product_attribute) &&
                    (isset($this->id_product) && $cart_product['id_product'] == $this->id_product)) {
                    $qty_to_check = $cart_product['cart_quantity'];

                    if (Tools::getValue('op', 'up') == 'down') {
                        $qty_to_check -= $this->qty;
                    } else {
                        $qty_to_check += $this->qty;
                    }

                    break;
                }
            }
        }

        $max_cart_quantity = 100; // Limit max quantity of all products
        $max_cart_products = 20; // limit products

        // limit the max add products to the cart added 
        if (Tools::getValue('op', 'up') == 'up' && $mode == 'add'){
            if ($total_cart_products >= $max_cart_products ){
                $this->errors[] = sprintf(Tools::displayError('Przekroczono limit %s dodanych produktów do koszyka'), $max_cart_products);
            } else if ($total_cart_quantity + $this->qty > $max_cart_quantity) {
                $this->errors[] = sprintf(Tools::displayError('Przekroczono limit %s ilości sztuk w koszyku'), $max_cart_quantity);
            }
        }

        // Check product quantity availability
        if ($this->id_product_attribute) {
            if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
                $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
            }
        } elseif ($product->hasAttributes()) {
            $minimumQuantity = ($product->out_of_stock == 2) ? !Configuration::get('PS_ORDER_OUT_OF_STOCK') : !$product->out_of_stock;
            $this->id_product_attribute = Product::getDefaultAttribute($product->id, $minimumQuantity);
            // @todo do something better than a redirect admin !!
            if (!$this->id_product_attribute) {
                Tools::redirectAdmin($this->context->link->getProductLink($product));
            } elseif (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
                $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
            }
        } elseif (!$product->checkQty($qty_to_check)) {
            $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
        }

        // If no errors, process product addition
        if (!$this->errors && $mode == 'add') {
            // Add cart if no cart found
            if (!$this->context->cart->id) {
                if (Context::getContext()->cookie->id_guest) {
                    $guest = new Guest(Context::getContext()->cookie->id_guest);
                    $this->context->cart->mobile_theme = $guest->mobile_theme;
                }
                $this->context->cart->add();
                if ($this->context->cart->id) {
                    $this->context->cookie->id_cart = (int)$this->context->cart->id;
                }
            }

            // Check customizable fields
            if (!$product->hasAllRequiredCustomizableFields() && !$this->customization_id) {
                $this->errors[] = Tools::displayError('Please fill in all of the required fields, and then save your customizations.', !Tools::getValue('ajax'));
            }

            if (!$this->errors) {
                $cart_rules = $this->context->cart->getCartRules();
                $available_cart_rules = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
                $update_quantity = $this->context->cart->updateQty($this->qty, $this->id_product, $this->id_product_attribute, $this->customization_id, Tools::getValue('op', 'up'), $this->id_address_delivery);
                if ($update_quantity < 0) {
                    // If product has attribute, minimal quantity is set with minimal quantity of attribute
                    $minimal_quantity = ($this->id_product_attribute) ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity;
                    $this->errors[] = sprintf(Tools::displayError('You must add %d minimum quantity', !Tools::getValue('ajax')), $minimal_quantity);
                } elseif (!$update_quantity) {
                    $this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', !Tools::getValue('ajax'));
                } elseif ((int)Tools::getValue('allow_refresh')) {
                    // If the cart rules has changed, we need to refresh the whole cart
                    $cart_rules2 = $this->context->cart->getCartRules();
                    if (count($cart_rules2) != count($cart_rules)) {
                        $this->ajax_refresh = true;
                    } elseif (count($cart_rules2)) {
                        $rule_list = array();
                        foreach ($cart_rules2 as $rule) {
                            $rule_list[] = $rule['id_cart_rule'];
                        }
                        foreach ($cart_rules as $rule) {
                            if (!in_array($rule['id_cart_rule'], $rule_list)) {
                                $this->ajax_refresh = true;
                                break;
                            }
                        }
                    } else {
                        $available_cart_rules2 = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
                        if (count($available_cart_rules2) != count($available_cart_rules)) {
                            $this->ajax_refresh = true;
                        } elseif (count($available_cart_rules2)) {
                            $rule_list = array();
                            foreach ($available_cart_rules2 as $rule) {
                                $rule_list[] = $rule['id_cart_rule'];
                            }
                            foreach ($cart_rules2 as $rule) {
                                if (!in_array($rule['id_cart_rule'], $rule_list)) {
                                    $this->ajax_refresh = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        $removed = CartRule::autoRemoveFromCart();
        CartRule::autoAddToCart();
        if (count($removed) && (int)Tools::getValue('allow_refresh')) {
            $this->ajax_refresh = true;
        }
    }


3) Wywalić te ogromne koszyki ze sklepu
4) Sprawdzić w logach apache IP bota wyszukując seokicks i na początku będziecie mieli ich IP. Bot jest na tyle bezczelny, że wchodzi w crawl z tym samym ciastkiem i jego IP to w moim przypadku 95.216.2.43. Wystarczy w htaccess w głównym folderze sklepu dodać w wolnej linii taki kod
 

Deny from 95.216.2.43 95.216.11.210

Napisałem do autorów by coś z tymi zrobili.

hakeryk2

hakeryk2

Na grupie zamkniętej Prestashop Polska ktoś poruszył temat zwiększonego zużycia CPU na hostingu ostatnimi na czasy i w sumie lekko temat olałem, dopóki nie powiązałem tego z krótkimi skokami zużycia na serwerze. Ostatnio też miałem dosyć duże skoki w którym po kilkanaście sekund lub nawet nieco dłużej wszystkie 4 rdzenie były na 100% i gdy szybko podglądałem co to za proces w PHP (komendą strace) to gdzieś tam śmigało odpalane zapytanie z PHP do MySQL o SUM('quantity') FROM `ps_cart_product` where bla bla i id_cart". No cóż, myślałem, że sobie z botami generującymi koszyki poradziłem (na forum są o tym tematy jak je blokować), ale jeden wybitnie ma gdzieś moje zabezpieczenia i wygenerował koszyk w którym było ponad 1000 produktów i gdy dodawał każdy kolejny produkt odpalały się wszystkie reguły koszyków itp, które dosyć mocno obliczeniowe były i obstawiam, że i u Was się to robiło.

Tak więc na start diagnoza i naprawa:
1) Sprawdzić czy nie ma porzuconych koszyków, mój był na kilkanaście milionów złotych xD
2) Wprowadzić limit na produkty dodane do koszyka, można to na szybko zrobić o tak https://youtu.be/wAlXtr8u5Qo choć można sobie nieco to doprecyzować lub skopiować całą funkcję processChangeProductInCart stąd i podmienić w pliku controllers/front/CartController: Można ustawić zmienne pod siebie zmieniając zmienne  $max_cart_quantity oraz $max_cart_products.

    protected function processChangeProductInCart()
    {
        $mode = (Tools::getIsset('update') && $this->id_product) ? 'update' : 'add';

        if ($this->qty == 0) {
            $this->errors[] = Tools::displayError('Null quantity.', !Tools::getValue('ajax'));
        } elseif (!$this->id_product) {
            $this->errors[] = Tools::displayError('Product not found', !Tools::getValue('ajax'));
        }

        $product = new Product($this->id_product, true, $this->context->language->id);
        if (!$product->id || !$product->active || !$product->checkAccess($this->context->cart->id_customer)) {
            $this->errors[] = Tools::displayError('This product is no longer available.', !Tools::getValue('ajax'));
            return;
        }

        $qty_to_check = $this->qty;
        $cart_products = $this->context->cart->getProducts();

        $total_cart_quantity = 0;
        $total_cart_products = count($cart_products);

        if (is_array($cart_products)) {
            foreach ($cart_products as $cart_product) {
                $total_cart_quantity += $cart_product['cart_quantity'];
                if ((!isset($this->id_product_attribute) || $cart_product['id_product_attribute'] == $this->id_product_attribute) &&
                    (isset($this->id_product) && $cart_product['id_product'] == $this->id_product)) {
                    $qty_to_check = $cart_product['cart_quantity'];

                    if (Tools::getValue('op', 'up') == 'down') {
                        $qty_to_check -= $this->qty;
                    } else {
                        $qty_to_check += $this->qty;
                    }

                    break;
                }
            }
        }

        $max_cart_quantity = 100; // Limit max quantity of all products
        $max_cart_products = 20; // limit products

        // limit the max add products to the cart added 
        if (Tools::getValue('op', 'up') == 'up' && $mode == 'add'){
            if ($total_cart_products >= $max_cart_products ){
                $this->errors[] = sprintf(Tools::displayError('Przekroczono limit %s dodanych produktów do koszyka'), $max_cart_products);
            } else if ($total_cart_quantity + $this->qty > $max_cart_quantity) {
                $this->errors[] = sprintf(Tools::displayError('Przekroczono limit %s ilości sztuk w koszyku'), $max_cart_quantity);
            }
        }

        // Check product quantity availability
        if ($this->id_product_attribute) {
            if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
                $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
            }
        } elseif ($product->hasAttributes()) {
            $minimumQuantity = ($product->out_of_stock == 2) ? !Configuration::get('PS_ORDER_OUT_OF_STOCK') : !$product->out_of_stock;
            $this->id_product_attribute = Product::getDefaultAttribute($product->id, $minimumQuantity);
            // @todo do something better than a redirect admin !!
            if (!$this->id_product_attribute) {
                Tools::redirectAdmin($this->context->link->getProductLink($product));
            } elseif (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $qty_to_check)) {
                $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
            }
        } elseif (!$product->checkQty($qty_to_check)) {
            $this->errors[] = Tools::displayError('There isn\'t enough product in stock.', !Tools::getValue('ajax'));
        }

        // If no errors, process product addition
        if (!$this->errors && $mode == 'add') {
            // Add cart if no cart found
            if (!$this->context->cart->id) {
                if (Context::getContext()->cookie->id_guest) {
                    $guest = new Guest(Context::getContext()->cookie->id_guest);
                    $this->context->cart->mobile_theme = $guest->mobile_theme;
                }
                $this->context->cart->add();
                if ($this->context->cart->id) {
                    $this->context->cookie->id_cart = (int)$this->context->cart->id;
                }
            }

            // Check customizable fields
            if (!$product->hasAllRequiredCustomizableFields() && !$this->customization_id) {
                $this->errors[] = Tools::displayError('Please fill in all of the required fields, and then save your customizations.', !Tools::getValue('ajax'));
            }

            if (!$this->errors) {
                $cart_rules = $this->context->cart->getCartRules();
                $available_cart_rules = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
                $update_quantity = $this->context->cart->updateQty($this->qty, $this->id_product, $this->id_product_attribute, $this->customization_id, Tools::getValue('op', 'up'), $this->id_address_delivery);
                if ($update_quantity < 0) {
                    // If product has attribute, minimal quantity is set with minimal quantity of attribute
                    $minimal_quantity = ($this->id_product_attribute) ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity;
                    $this->errors[] = sprintf(Tools::displayError('You must add %d minimum quantity', !Tools::getValue('ajax')), $minimal_quantity);
                } elseif (!$update_quantity) {
                    $this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', !Tools::getValue('ajax'));
                } elseif ((int)Tools::getValue('allow_refresh')) {
                    // If the cart rules has changed, we need to refresh the whole cart
                    $cart_rules2 = $this->context->cart->getCartRules();
                    if (count($cart_rules2) != count($cart_rules)) {
                        $this->ajax_refresh = true;
                    } elseif (count($cart_rules2)) {
                        $rule_list = array();
                        foreach ($cart_rules2 as $rule) {
                            $rule_list[] = $rule['id_cart_rule'];
                        }
                        foreach ($cart_rules as $rule) {
                            if (!in_array($rule['id_cart_rule'], $rule_list)) {
                                $this->ajax_refresh = true;
                                break;
                            }
                        }
                    } else {
                        $available_cart_rules2 = CartRule::getCustomerCartRules($this->context->language->id, (isset($this->context->customer->id) ? $this->context->customer->id : 0), true, true, true, $this->context->cart, false, true);
                        if (count($available_cart_rules2) != count($available_cart_rules)) {
                            $this->ajax_refresh = true;
                        } elseif (count($available_cart_rules2)) {
                            $rule_list = array();
                            foreach ($available_cart_rules2 as $rule) {
                                $rule_list[] = $rule['id_cart_rule'];
                            }
                            foreach ($cart_rules2 as $rule) {
                                if (!in_array($rule['id_cart_rule'], $rule_list)) {
                                    $this->ajax_refresh = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        $removed = CartRule::autoRemoveFromCart();
        CartRule::autoAddToCart();
        if (count($removed) && (int)Tools::getValue('allow_refresh')) {
            $this->ajax_refresh = true;
        }
    }


3) Wywalić te ogromne koszyki ze sklepu
4) Sprawdzić w logach apache IP bota wyszukując seokicks i na początku będziecie mieli ich IP. Bot jest na tyle bezczelny, że wchodzi w crawl z tym samym ciastkiem i jego IP to w moim przypadku 95.216.2.43. Wystarczy w htaccess w głównym folderze sklepu dodać w wolnej linii taki kod
 

Deny from 95.216.2.43 95.216.11.210

Napisałem do autorów by coś z tymi zrobili.

hakeryk2

hakeryk2

Na grupie zamkniętej Prestashop Polska ktoś poruszył temat zwiększonego zużycia CPU na hostingu ostatnimi na czasy i w sumie lekko temat olałem, dopóki nie powiązałem tego z krótkimi skokami zużycia na serwerze. Ostatnio też miałem dosyć duże skoki w którym po kilkanaście sekund lub nawet nieco dłużej wszystkie 4 rdzenie były na 100% i gdy szybko podglądałem co to za proces w PHP (komendą strace) to gdzieś tam śmigało odpalane zapytanie z PHP do MySQL o SUM('quantity') FROM `ps_cart_product` where bla bla i id_cart". No cóż, myślałem, że sobie z botami generującymi koszyki poradziłem (na forum są o tym tematy jak je blokować), ale jeden wybitnie ma gdzieś moje zabezpieczenia i wygenerował koszyk w którym było ponad 1000 produktów i gdy dodawał każdy kolejny produkt odpalały się wszystkie reguły koszyków itp, które dosyć mocno obliczeniowe były i obstawiam, że i u Was się to robiło.

Tak więc na start diagnoza i naprawa:
1) Sprawdzić czy nie ma porzuconych koszyków, mój był na kilkanaście milionów złotych xD
2) Wprowadzić limit na produkty dodane do koszyka, można to na szybko zrobić https://youtu.be/wAlXtr8u5Qo ale jeszcze sobie funkcję nieco dopieściłem pod swoje potrzeby.
3) Wywalić te ogromne koszyki
4) Po logach zdiagnozowałem tego robota który był na tyle bezczelny, że nawet z tym samym ciastkiem wchodził i również faktycznie jest to Seokicks ale z innego IP i było to 95.216.2.43 więc zablokowany również w httaccess jak i w Cloudflare. Wystarczy w htaccess dodać w wolnej linii taki kod
 

Deny from 95.216.2.43 95.216.11.210

Napisałem do autorów by coś z tymi zrobili.

hakeryk2

hakeryk2

Na grupie zamkniętej Prestashop Polska ktoś poruszył temat zwiększonego zużycia CPU na hostingu ostatnimi na czasy i w sumie lekko temat olałem, dopóki nie powiązałem tego z krótkimi skokami zużycia na serwerze. Ostatnio też miałem dosyć duże skoki w którym po kilkanaście sekund lub nawet nieco dłużej wszystkie 4 rdzenie były na 100% i gdy szybko podglądałem co to za proces w PHP (komendą strace) to gdzieś tam śmigało odpalane zapytanie z PHP do MySQL o SUM('quantity') FROM `ps_cart_product` where bla bla i id_cart". No cóż, myślałem, że sobie z botami generującymi koszyki poradziłem (na forum są o tym tematy jak je blokować), ale jeden wybitnie ma gdzieś moje zabezpieczenia i wygenerował koszyk w którym było ponad 1000 produktów i gdy dodawał każdy kolejny produkt odpalały się wszystkie reguły koszyków itp, które dosyć mocno obliczeniowe były i obstawiam, że i u Was się to robiło.

Tak więc na start diagnoza i naprawa:
1) Sprawdzić czy nie ma porzuconych koszyków, mój był na kilkanaście milionów złotych xD
2) Wprowadzić limit na produkty dodane do koszyka, można to na szybko zrobić https://youtu.be/wAlXtr8u5Qo ale jeszcze sobie funkcję nieco dopieściłem pod swoje potrzeby.
3) Wywalić te ogromne koszyki
4) Po logach zdiagnozowałem tego robota który był na tyle bezczelny, że nawet z tym samym ciastkiem wchodził i również faktycznie jest to Seokicks ale z innego IP i było to 95.216.2.43 więc zablokowany również w httaccess jak i w Cloudflare. Wystarczy w htaccess dodać w wolnej linii taki kod
 

Deny from 95.216.2.43 95.216.11.210

Napisałem do autorów by coś z tymi zrobili.

×
×
  • Create New...