@@ -935,34 +935,44 @@ ngx_http_upload_read_event_handler(ngx_http_request_t *r)
935
935
ngx_http_request_body_t * rb ;
936
936
ngx_int_t rc ;
937
937
ngx_chain_t * in ;
938
+ ssize_t n , limit , buf_read_size , next_buf_size , remaining ;
939
+ ngx_msec_t delay ;
940
+ ngx_event_t * rev ;
938
941
939
942
if (ngx_exiting || ngx_terminate ) {
940
943
ngx_http_finalize_request (r , NGX_HTTP_CLOSE );
941
944
return ;
942
945
}
943
946
947
+ rev = r -> connection -> read ;
944
948
rb = r -> request_body ;
945
949
946
950
if (rb == NULL ) {
947
951
ngx_http_finalize_request (r , NGX_HTTP_INTERNAL_SERVER_ERROR );
948
952
return ;
949
953
}
950
954
955
+ r -> read_event_handler = ngx_http_upload_read_event_handler ;
956
+
951
957
u = ngx_http_get_module_ctx (r , ngx_http_upload_module );
952
958
953
- rc = NGX_OK ;
959
+ for ( ;; ) {
960
+ buf_read_size = 0 ;
954
961
955
- in = rb -> bufs ;
962
+ for (in = rb -> bufs ; in ; in = in -> next ) {
963
+ n = in -> buf -> last - in -> buf -> pos ;
964
+
965
+ rc = u -> data_handler (u , in -> buf -> pos , in -> buf -> pos + n );
966
+
967
+ in -> buf -> pos += n ;
968
+ u -> received += n ;
969
+ buf_read_size += n ;
956
970
957
- for ( ;; ) {
958
- while (in ) {
959
- rc = u -> data_handler (u , in -> buf -> pos , in -> buf -> last );
960
971
if (rc != NGX_OK ) {
961
972
goto err ;
962
973
}
963
- in -> buf -> pos = in -> buf -> last ;
964
- in = in -> next ;
965
974
}
975
+ rb -> bufs = NULL ;
966
976
967
977
// We're done reading the request body, break out of loop
968
978
if (!r -> reading_body ) {
@@ -974,19 +984,43 @@ ngx_http_upload_read_event_handler(ngx_http_request_t *r)
974
984
}
975
985
}
976
986
987
+ // Check whether we have exceeded limit_rate and should delay the next
988
+ // buffer read
989
+ if (u -> limit_rate ) {
990
+ remaining = ((ssize_t ) r -> headers_in .content_length_n ) - u -> received ;
991
+ next_buf_size = (buf_read_size > remaining ) ? remaining : buf_read_size ;
992
+ limit = u -> limit_rate * (ngx_time () - r -> start_sec + 1 ) - (u -> received + next_buf_size );
993
+ if (limit < 0 ) {
994
+ rev -> delayed = 1 ;
995
+ ngx_add_timer (rev , (ngx_msec_t ) ((limit * -1000 / u -> limit_rate ) + 1 ));
996
+ return ;
997
+ }
998
+ }
999
+
977
1000
rc = ngx_http_read_unbuffered_request_body (r );
978
1001
979
1002
if (rc >= NGX_HTTP_SPECIAL_RESPONSE ) {
980
1003
goto err ;
981
1004
}
982
1005
983
- in = rb -> bufs ;
984
- rb -> bufs = NULL ;
985
-
986
- if (in == NULL ) {
987
- r -> read_event_handler = ngx_http_upload_read_event_handler ;
1006
+ if (rb -> bufs == NULL ) {
988
1007
return ;
989
1008
}
1009
+
1010
+ // Check whether we should delay processing the latest request body
1011
+ // buffers to stay within limit_rate
1012
+ if (u -> limit_rate ) {
1013
+ buf_read_size = 0 ;
1014
+ for (in = rb -> bufs ; in ; in = in -> next ) {
1015
+ buf_read_size += (in -> buf -> last - in -> buf -> pos );
1016
+ }
1017
+ delay = (ngx_msec_t ) (buf_read_size * 1000 / u -> limit_rate + 1 );
1018
+ if (delay > 0 ) {
1019
+ rev -> delayed = 1 ;
1020
+ ngx_add_timer (rev , delay );
1021
+ return ;
1022
+ }
1023
+ }
990
1024
}
991
1025
992
1026
// Finally, send the response
0 commit comments