Change website

From Jan 16 2015,


All post content will be move to we's offical website with many content...

Can access website here: http://justox.com

Thanks for your visit!

Wednesday, 18 December 2013

Nginx Download File Trigger

Few days ago i had a chance to work bit different with Nginx, and what was needed to be done is how to determinate if user had successfully downloaded file. Why this is needed because file should be erased from server after download and PHP would be bad solution, also they told me that they don’t want to use any additional application eg. programming languages.

As you can see we had one Nginx server, already setup to meet they requirements, and they had one web service for deleting files eg. counter as shown below.
Let’s wget some file from server
wget http://www.codestance.com/somefile.tar
--2013-07-03 16:04:14--  http://www.codestance.com/somefile.tar
Resolving www.codestance.com... 93.139.143.110
Connecting to www.codestance.com|93.139.143.110|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 46397440 (44M) [text/plain]
Saving to: "somefile.tar"

100%[======================================================================>] 46,397,440   273M/s   in 0.2s

2013-07-03 16:04:14 (273 MB/s) - "somefile.tar"
By checking nginx access log we can see that client downloaded file but we can not check if download was successful or not, maybe is canceled? Anyway, log file is not for this kind of information.
93.139.143.110 - - [03/Jul/2013:16:04:14 +0000] "GET /somefile.tar HTTP/1.1" 200 46397440 "-" "Wget/1.12 (linux-gnu)" "-"
Now let’s add some configuration to nginx vhost (i added simple php script which point to /download and also one RESTful server)
location /download {
    post_action /adcounter;
}

location /adcounter{
    proxy_pass http://www.codestance.com/api/v1/adcounter?FileName=$request&ClientIP=$remote_addr& bytes_sent=$body_bytes_sent&status=$request_completion&params=$args;
    internal;
}
By upper example, no matter if user was downloaded file successfully or he canceled internal post will be on our counting API or any other app which need this information. You must notice internal command.
Let’s download same file again
wget http://www.codestance.com/somefile.tar
--2013-07-03 16:12:53--  http://www.codestance.com/somefile.tar
Resolving www.codestance.com... 93.139.143.110
Connecting to www.codestance.com|93.139.143.110|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 46397440 (44M) [text/plain]
Saving to: "somefile.tar"

100%[======================================================================>] 46,397,440   298M/s   in 0.2s

2013-07-03 16:12:53 (298 MB/s) - "somefile.tar"
We will check again our access log
93.139.143.110 - - [03/Jul/2013:16:12:53 +0000] "GET /api/v1/adcounter?FileName=GET /somefile.tar HTTP/1.1&ClientIP=93.139.143.110&bytes_sent=46397440&status=OK&params= HTTP/1.0" 200 10 "-" "Wget/1.12 (linux-gnu)"
And here we go, our access log is very clear about it, it shows status OK and now we know that client has downloaded file.
Now we can start download again but we will push Ctrl+C to break download and we can again check what access log show to us.
93.139.143.110 - - [03/Jul/2013:16:18:01 +0000] "GET /api/v1/adcounter?FileName=GET /somefile.tar HTTP/1.1&ClientIP=93.139.143.110&bytes_sent=27838464&status=&params= HTTP/1.0" 200 10 "-" "Wget/1.12 (linux-gnu)"
You see that status is blanked right? This means that file download was interrupted some how maybe connection broken or user canceled download.
So, you can use Nginx post_action to define sub request upon completion of another request which can be successful or no.
Notice:
Thanks to Zippo, NginX with version 1.2.1 should be setup as FileName=$uri instead of $request
I hope you will find this helpful.
Happy Hacking!

No comments:

Post a Comment