# Upload progress module: "track\_uploads" directive inside an "if" block

**URL:** <https://www.ruby-forum.com/t/upload-progress-module-track-uploads-directive-inside-an-if-block/158066>\
**Category:** NGINX\
**Created:** [January 19, 2009, 12:15am UTC](https://www.ruby-forum.com/t/upload-progress-module-track-uploads-directive-inside-an-if-block/158066 "2009-01-19T00:15:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bitsmith](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/9de053/32.png) [@bitsmith](https://www.ruby-forum.com/u/bitsmith)\
**Post date:** [January 19, 2009, 12:15am UTC](https://www.ruby-forum.com/t/upload-progress-module-track-uploads-directive-inside-an-if-block/158066/1 "2009-01-19T00:15:45Z")

</div>

Hi,

I am using nginx as a proxy in front of a mongrel cluster running a  
rails application.

I can’t seem to get nginx to serve static files _and_ use the upload  
progress module (I can achieve one or the other, but not both at the  
same time).

For example, if I use an “if” block so that requests for static files  
aren’t passed to the mongrel cluster:

location / {  
…  
if (!-f $request\_filename) {  
proxy\_pass http://mongrel\_cluster;  
track\_uploads proxied 30s;  
}  
}

This gives the following error message:

[emerg] 12265#0: “track\_uploads” directive is not allowed here

If I try, instead:

location / {  
…  
if (!-f $request\_filename) {  
proxy\_pass http://mongrel\_cluster;  
}  
track\_uploads proxied 30s;  
}

I get the following error message:

[emerg] 12266#0: “track\_uploads” directive track\_upload should be  
the last directive in the location, after either proxy\_pass or  
fastcgi\_pass

If I remove the “if” condition completely:

location / {  
proxy\_pass http://mongrel\_cluster;  
track\_uploads proxied 30s;  
}

That works, but then all requests are proxied to the mongrel cluster,  
even requests for static files, and even requests for the  
“maintenance.html” page which I put up (with a separate rewrite rule)  
when I want to take the mongrel cluster down for maintenance (rails  
developers will be familiar with this). The request for the  
“maintenance.html” file is sent to the mongrels, which are down,  
resulting in a “502 Bad Gateway” error. And even the request for my  
“50x.html” error page is proxied to the mongrel cluster (which is  
down) so users get the default nginx 502 error page.

Does anyone know of a way around this, or a better way to configure  
the proxy\_pass to avoid this issue? Any help would be _much_  
appreciated.

My full nginx config file is pasted below.

Regards,  
–Dave R…

user xxx xxx;  
worker\_processes 4;

pid /var/run/nginx.pid;

error\_log logs/error.log notice;

events {  
worker\_connections 1024;  
}

http {  
include mime.types;  
default\_type application/octet-stream;

```
 upload_progress proxied 1m;

 # This log format is compatible with any tool like awstats
 # that can parse standard apache logs.
 log_format main '$remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent

```

“$http\_referer” ’  
‘"$http\_user\_agen" “$http\_x\_forwarded\_for”’;

```
 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;

 keepalive_timeout 65;

 gzip on;
 gzip_http_version 1.0;
 gzip_comp_level 2;
 gzip_proxied any;
 gzip_types text/plain text/html text/css application/x-javascript
             text/xml application/xml application/xml+rss text/

```

javascript;

```
 # Load balance to mongrels
 upstream mongrel_cluster {
     server 0.0.0.0:8000;
     server 0.0.0.0:8001;
 }

 server {
     listen 80;
     server_name xxxx.com
     root /home/xxxx/xxxx/current/public;
     access_log /home/xxxx/xxxx/shared/log/nginx.access.log main;
     error_page 500 502 503 504 /50x.html;
     client_max_body_size 50M; # Avoid attempts to overload the

```

server

```
     # Rewrite rule: Display maintenance page if it exists
     # (capistrano disable task creates this maintenance page)
     # BUT allow the image in the maintenance page to be displayed
     if ($request_filename ~ ^/images/) {
         break;
     }
     if (-f $document_root/system/maintenance.html) {
         rewrite ^(.*)$ /system/maintenance.html last;
         break;
     }

     location / {
         index index.html index.htm;

         location ~ ^/(images|javascripts|stylesheets)/ {
             expires 10y;
         }

         if (-f $request_filename) {
             break;
         }

         # Directly serve cached pages
         if (-f $request_filename.html) {
             rewrite (.*) $1.html break;
         }

         # Otherwise let mongrel handle the request
         #if (!-f $request_filename) { # Commented because of

```

“track\_uploads” problem  
proxy\_pass http://mongrel\_cluster;  
track\_uploads proxied 30s;  
#}

```
         location ^~ /upload_progress {
             report_uploads proxied;
         }
     }
 }

```

}

---

<div class="post-metadata">

**Author:** ![bitsmith](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/9de053/32.png) [@bitsmith](https://www.ruby-forum.com/u/bitsmith)\
**Post date:** [January 19, 2009, 1:36am UTC](https://www.ruby-forum.com/t/upload-progress-module-track-uploads-directive-inside-an-if-block/158066/2 "2009-01-19T01:36:30Z")

</div>

It is because upload progress module’s directives do not have flag which  
tells nginx to allow them in if block. Patch in attachment might help.

---

<div class="post-metadata">

**Author:** ![bitsmith](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/9de053/32.png) [@bitsmith](https://www.ruby-forum.com/u/bitsmith)\
**Post date:** [January 19, 2009, 2:49am UTC](https://www.ruby-forum.com/t/upload-progress-module-track-uploads-directive-inside-an-if-block/158066/3 "2009-01-19T02:49:00Z")

</div>

Thanks for the suggestion. I’ve tried the patch on my staging server,  
and it does indeed allow the configuration file to validate, but the  
actual progress bar is not working.

With the patch, but without using an “if” block, the progress bar does  
work correctly, as before.

I will have to investigate further tomorrow as it is getting late. 🙂

Cheers  
Dave R…

---

<div class="post-metadata">

**Author:** ![bitsmith](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/9de053/32.png) [@bitsmith](https://www.ruby-forum.com/u/bitsmith)\
**Post date:** [January 19, 2009, 2:03pm UTC](https://www.ruby-forum.com/t/upload-progress-module-track-uploads-directive-inside-an-if-block/158066/4 "2009-01-19T14:03:07Z")

</div>

After further investigation, it seems that the upload progress tracker  
is stuck at ‘state: starting’.

(while uploading a large file, if I do a GET for /upload\_progress?X-  
Progress-ID=xxxx in a separate browser window, I get:

new Object({ ‘state’ : ‘starting’ })

even a minute after it has started uploading).

Once again, this only happens if the “track\_uploads” directive is  
inside an “if” block; otherwise it works fine.

Regards,  
Dave. Rothlisberger.

---

<div class="post-metadata">

**Author:** ![bitsmith](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/9de053/32.png) [@bitsmith](https://www.ruby-forum.com/u/bitsmith)\
**Post date:** [July 14, 2009, 6:57am UTC](https://www.ruby-forum.com/t/upload-progress-module-track-uploads-directive-inside-an-if-block/158066/5 "2009-07-14T06:57:36Z")

</div>

Dave R. wrote:

> After further investigation, it seems that the upload progress tracker  
> is stuck at ‘state: starting’.
> 
> (while uploading a large file, if I do a GET for /upload\_progress?X-  
> Progress-ID=xxxx in a separate browser window, I get:
> 
> new Object({ ‘state’ : ‘starting’ })
> 
> even a minute after it has started uploading).
> 
> Once again, this only happens if the “track\_uploads” directive is  
> inside an “if” block; otherwise it works fine.
> 
> Regards,  
> Dave. Rothlisberger.

I think I have found a solution to this issue. I’ve created a location  
block that grabs the static file extensions and does the normal  
processing on them without the track\_uploads call. Essentially, this  
means I can’t track uploads to URLs ending in CSS, JS, etc. I can live  
with that. It also means that full page caching probably won’t work, but  
I don’t use that. Here’s my new location block:

```
location ~* \.(jpg|gif|png|css|js|htm|html)(\?[0-9]+)?$ {
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect false;
  proxy_max_temp_file_size 0;
  if (!-f $request_filename) {
    proxy_pass http://mongrel; break;
  }
}
```
