πŸ“œ ⬆️ ⬇️

Simple solutions. We pump pictures



We all love simple solutions. There is an opinion that we value religion so much, trainings on personal growth and succumb to divorces because the brain with great pleasure makes simple decisions instead of complex ones, generously rewarding us with dopamine. In this article I will talk about such a decision on one of our projects. There is nothing complicated in it, nothing especially witty, but it works reliably, it is relatively simple to implement and it solves many problems at once. I really hope that it will bring you practical benefits or push you to the idea of ​​the further development of your project.

Initial requirements


The bottom line was this: our project ars Mail.Ru has a lot of ads, several of which are attached to each of them. Photos can be uploaded by users manually, or they can be downloaded by the crawler from partner sites and attached to ads automatically. At the same time, the photos themselves are quite large (up to 10 MB), and there are almost always several pieces per ad. The photos themselves are stored on several synchronous DAVs, cut into several sizes, and watermark can be supplied. Those. processing a single photo (crop-resize-split-upload) is very expensive and requires time and resources (CPU, disks, grid).

An almost ideal architecture for us should minimize the use of these resources and be able to solve the following tasks:

If you wrote a vertical search or import from partners many entities with attached pictures, then the situation is undoubtedly familiar to you.
')

Solution to the forehead


Direct solution is quite traditional. When submitting an ad manually, we make a POST form with <input type=Β«fileΒ» ...> , the user sends all pictures to POST, they are uploaded to the project, and their id attached to the ad if it is successfully added to the database. We can use a preloader, and put temporary photos into temporary files, memory, a table, etc. When automatically importing photos, download photos, upload them to the project, attach them to ads, perhaps use download caching (if the photo from this URL has already been downloaded, we take it from the disk and not from the partner). Removing the ad, we first remove all the pictures of this ad from the project and only then we demolish the ad itself.

We list some of the disadvantages of this solution.

Easier - better


We really didn’t like all this, and we decided to slap all these hares at once. Previously, each photo was tied to a specific ad, while the existence of unbound photos was not allowed, and the table that stores information about the photos had a structure like this:

 CREATE TABLE Images ( image_id: char(32) PRIMARY KEY, -- id ,    , ,       .. offer_id: int unsigned NOT NULL FOREIGN KEY REFERENCES offers_table(id) ON DELETE RESTRICT, --        url_hash: char(32) NULL, -- md5  ,     body_hash: char(32) NULL, -- md5    num: tinyint unsigned NOT NULL, --      last_update: timestamp NOT NULL, --     ); 

As I promised, the solution is very simple - we just let the photos exist that are not tied to the ads, and the records about them are duplicated. Those. simply made the offer_id foreign key offer_id , and removed UNIQUE from image_id . Like this:

  image_id: char(32), --  image_id ,    offer_id: int unsigned NULL FOREIGN KEY REFERENCES Offers(id) ON DELETE SET NULL 

Now any entry in the table corresponds to the existing, processed photo, but some of them are not tied to any of the ads and are used in deferred mode or deleted by the garbage collector. Processing photos separately, communication with ads - separately.
To do this, we implemented the following scripts:

1. User add ads


The form of adding ads does not contain POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
     POST   .        ,          id .      ajax url,       ,     image_id : 

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
     POST   .        ,          id .      ajax url,       ,     image_id : 

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
     POST   .        ,          id .      ajax url,       ,     image_id : 

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
     POST   .        ,          id .      ajax url,       ,     image_id : 

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
     POST   .        ,          id .      ajax url,       ,     image_id : 

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
     POST   .        ,          id .      ajax url,       ,     image_id : 

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
     POST   .        ,          id .      ajax url,       ,     image_id : 

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
     POST   .        ,          id .      ajax url,       ,     image_id : 

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!
POST . , id . ajax url, , image_id :

<a href="#" data-photo-num="1" class="photo_upload"> 1</a> <input type="hidden" name="photo1" value=""> <a href="#" data-photo-num="2" class="photo_upload"> 2</a> <input type="hidden" name="photo2" value=""> <script type="text/javascript"> $(document).ready(function() { $(".photo_upload").click(function() { // // URL /pre-upload-photo/ // , image_id var image_id = pre_upload_result.image_id; var num = $(this).attr("data-photo-num"); $("input[name="photo" + num + "]").val(image_id); return false; }); }); </script>
URL /pre-upload-photo/ ( ) :

this_body_hash(md5 ); body_hash == this_body_hash; IF ( ) { last_update ; offer_id image_id; } ELSE { crop-resize-spilt-upload; body_hash, last_update, offer_id image_id; } image_id ;
, , image_id , input:

<input type="hidden" name="photo1" value="0cc175b9c0f1b6a831c399e269772661"> <input type="hidden" name="photo2" value="92eb5ffee6ae2fec3ad71c777531578f">
:

photo1: 0cc175b9c0f1b6a831c399e269772661 photo2: 92eb5ffee6ae2fec3ad71c777531578f photo3: 4a8a08f09d37b73795649038408b5f33
, , β€” , ..

offer_id: NULL, num: 0, image_id: 4a8a08f09d37b73795649038408b5f33 offer_id: 1234, num: 3, image_id: 92eb5ffee6ae2fec3ad71c777531578f offer_id: 1234, num: 1, image_id: 0cc175b9c0f1b6a831c399e269772661
, .

, , , , , .., crop-resize-split-upload . , . rate-limit URL β€” DoS-.

2.
, . .. , body_hash url_hash (md5 URL ). , . .. N , , , crop-resize-split-upload.

, offer_id URL, . URL :

this_url_hash URL; , url_hash == this_url_hash; IF ( ) { # crop-resize-spilt-upload; c offer_id, url_hash, num, last_update; } ELSIF ( , , offer_id) { # , c image_id, offer_id, url_hash, num last_update; } ELSE { # , , offer_id num, last_update; }
, URL β€” , .

3.
DELETE FROM Offers WHERE id=?
. ON DELETE SET NULL offer_id , N , . , , .

4.
SELECT image_id FROM ImagesTable i WHERE offer_id IS NULL AND (last_update + INTERVAL ? DAY) < NOW();
, N .

- , , , .. , , . , image_id , . , . , .. , , , , .

, , , . , , ( crop-resize-split-upload). N- «» , , , .

5.
, , , ! -, , , - , . , , , , . , , , . , , . .

, β€” , . , , . , .

: , , , , , β€” . : , , , .

: , , , , . . , , . , . , . .

, ( url_hash body_hash ) . , , image_id β€” . , , , , . . β€” .

debug, . , .. . , .. , , ..


:

«» ( N crop-resize-split-upload ) ( memcached -) ( , crop-resize-split-upload) , , , ..
!

Source: https://habr.com/ru/post/248443/


All Articles