Logging variables -- $bytes_sent where is $bytes_read?

Is there a variable for bytes read ?

$content_length is what should be read, but if the request is terminated
early, it is wrong.
$request_length is not right either, it is logging 459 bytes on a 9mb
upload.

thanks

On Saturday 18 April 2015 08:23:37 jb wrote:

Is there a variable for bytes read ?

$content_length is what should be read, but if the request is terminated
early, it is wrong.
$request_length is not right either, it is logging 459 bytes on a 9mb
upload.

$request_length should work.

wbr, Valentin V. Bartenev

thanks and this is a popular answer on stack exchange but no, it does
not
work, because aborted requests have read less bytes – $request_length
reports how many bytes SHOULD have been read, but in the case of any
problem, abort by client, or whatever, this is not how many bytes were
actually read…

For accounting purposes, I’d want an exact mirror to $bytes_sent …
otherwise math does not add up :frowning: I think there should be a $bytes_recd

On Sat, Apr 18, 2015 at 9:47 AM, Valentin V. Bartenev [email protected]

And maybe I am approaching this the wrong way? can you comment…

I want an nginx upload target for POST that reads the content, discards
it,
and reports the amount read. This is what I have in essence:

location ~* “/upload” {
limit_except POST OPTIONS { deny all; }
client_max_body_size 0;
add_header Cache-Control “max-age=0, no-cache, no-store,
must-revalidate”;
keepalive_timeout 0;
add_header Content-Type ‘text/html’;
return 200 ‘$content_length bytes’;
}

The uploads are being done with XHR on the browser side. It works,
however
randomly (less than 1% of cases), browsers fail during the POST: they
return xhr with readyState 4 but status 0, and only a partial upload
progress recorded.
On the server side, no error is generated in error_log, and access_log
reports status 200.

$request_length is very short, just the header of the upload.

I am wondering if this is mis-use of upload handling by nginx. However I
do
not want to setup an upstream server to receive the POST content, it is
to
be discarded anyway.

Is there a more correct way to handle POST within nginx, with a response
after all data is read, but without an upstream server?

thanks.

On Saturday 18 April 2015 10:08:25 jb wrote:

thanks and this is a popular answer on stack exchange but no, it does not
work, because aborted requests have read less bytes – $request_length
reports how many bytes SHOULD have been read, but in the case of any
problem, abort by client, or whatever, this is not how many bytes were
actually read…
[…]

No, it reports how many bytes has been received by nginx.
If it’s not, I guess you have some 3rd-party modules or patches.

wbr, Valentin V. Bartenev

On Saturday 18 April 2015 10:24:17 jb wrote:

add_header Content-Type ‘text/html’;
This just adds duplicate “Content-Type” header.
See the “default_type” directive: Module ngx_http_core_module

$request_length is very short, just the header of the upload.

I am wondering if this is mis-use of upload handling by nginx. However I do
not want to setup an upstream server to receive the POST content, it is to
be discarded anyway.

Is there a more correct way to handle POST within nginx, with a response
after all data is read, but without an upstream server?

[…]

Oh, ok I see what happens. Indeed, the $request_length isn’t accounted
if
you discard request body this way.

The workaround can be using proxy_pass to nginx itself. You don’t need
to pass body however: Module ngx_http_proxy_module

wbr, Valentin V. Bartenev

gotcha, I saw the discarded body thing in the debug log. ok thanks,
um, how do you proxy_pass to nginx itself ?

can you give an example ?
just proxy_pass http://127.0.0.1/
and proxy_pass_request_body off

what about my return 200 “$content_length bytes” line still keep that?

On Sat, Apr 18, 2015 at 11:10 AM, Valentin V. Bartenev [email protected]

ok I figured it out, I proxy_pass to nginx

but I still have the same issue with aborted connection and bytes read
:slight_smile:

Here is my custom_log format:

… $body_bytes_sent rl=$request_length cl=$content_length …

Here is an example POST using proxy_pass to 127.0.0.1

… “POST /upload HTTP/1.1” 200 26 rl=456 cl=9885416 rt=15.874 …

You can see request_length is only 456 bytes, and content_length is
9.9mb
however the request was aborted after 15 seconds and some OTHER number
of
bytes were read, some number between those two figures. 9885416 was the
number given by the client.

thanks

On Saturday 18 April 2015 11:23:54 jb wrote:

gotcha, I saw the discarded body thing in the debug log. ok thanks,
um, how do you proxy_pass to nginx itself ?

can you give an example ?
just proxy_pass http://127.0.0.1/
and proxy_pass_request_body off

what about my return 200 “$content_length bytes” line still keep that?

[…]

events {}

http {
log_format lengths $request_length;

server {
location / {
proxy_pass http://unix:nginx.sock:;
proxy_pass_request_body off;

       proxy_set_header X-Response "$content_length bytes";
       proxy_set_header Content-Length "";

       access_log  logs/lengths.log  lengths;
   }

}

server {
listen unix:nginx.sock;
return 200 $http_x_response;
}
}

% telnet 127.0.0.1 8000
Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is ‘^]’.
POST / HTTP/1.0
Content-Length: 1000

bbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbb
^]
telnet> close
Connection closed.
% cat logs/lengths.log
145


wbr, Valentin V. Bartenev

thanks,

the part where you massage the content lengths I was missing – or had
no
clue would be needed.

On Sat, Apr 18, 2015 at 12:06 PM, Valentin V. Bartenev [email protected]