mirror of
				https://github.com/weiss/ngx_http_upload.git
				synced 2025-10-31 01:21:01 +00:00 
			
		
		
		
	Avoid copying of the PUT body if possible
In the case where Nginx wrote the PUT body to a temporary file, try to rename() that file instead of copying the data.
This commit is contained in:
		
							parent
							
								
									ee9c39ca6f
								
							
						
					
					
						commit
						b9141ef899
					
				
							
								
								
									
										64
									
								
								upload.pm
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								upload.pm
									
									
									
									
									
								
							| @ -128,42 +128,52 @@ sub handle_put_body { | |||||||
|         return HTTP_FORBIDDEN; # Assume EACCES. |         return HTTP_FORBIDDEN; # Assume EACCES. | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (sysopen(my $fh, $file_path, O_WRONLY|O_CREAT|O_EXCL, $file_mode)) { |     my $request_body = $r->request_body; | ||||||
|         if (not binmode($fh)) { |     my $request_body_file = $r->request_body_file; | ||||||
|             $r->log_error($!, "Cannot set binary mode for $file_path"); |  | ||||||
|             return HTTP_INTERNAL_SERVER_ERROR; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         my $request_body = $r->request_body; |     if ($request_body) { | ||||||
|         my $request_body_file = $r->request_body_file; |         if (sysopen(my $fh, $file_path, O_WRONLY|O_CREAT|O_EXCL, $file_mode)) { | ||||||
| 
 |             if (not binmode($fh)) { | ||||||
|         if ($request_body) { |                 $r->log_error($!, "Cannot set binary mode for $file_path"); | ||||||
|  |                 return HTTP_INTERNAL_SERVER_ERROR; | ||||||
|  |             } | ||||||
|             if (not syswrite($fh, $request_body)) { |             if (not syswrite($fh, $request_body)) { | ||||||
|                 $r->log_error($!, "Cannot write $file_path"); |                 $r->log_error($!, "Cannot write $file_path"); | ||||||
|                 return HTTP_INTERNAL_SERVER_ERROR; |                 return HTTP_INTERNAL_SERVER_ERROR; | ||||||
|             } |             } | ||||||
|         } elsif ($request_body_file) { |             if (not close($fh)) { | ||||||
|             if (not move($request_body_file, $fh)) { |                 $r->log_error($!, "Cannot close $file_path"); | ||||||
|                 $r->log_error($!, "Cannot move data to $file_path"); |  | ||||||
|                 return HTTP_INTERNAL_SERVER_ERROR; |                 return HTTP_INTERNAL_SERVER_ERROR; | ||||||
|             } |             } | ||||||
|         } else { # Huh? |         } elsif ($!{EEXIST}) { | ||||||
|             $r->log_error(0, "Got no data to write to $file_path"); |             $r->log_error($!, "Won't overwrite $file_path"); | ||||||
|             return HTTP_BAD_REQUEST; |             return HTTP_CONFLICT; | ||||||
|         } |         } elsif ($!{EACCES}) { | ||||||
|         if (not close($fh)) { |             $r->log_error($!, "Cannot create $file_path"); | ||||||
|             $r->log_error($!, "Cannot close $file_path"); |             return HTTP_FORBIDDEN; | ||||||
|  |         } else { | ||||||
|  |             $r->log_error($!, "Cannot open $file_path"); | ||||||
|             return HTTP_INTERNAL_SERVER_ERROR; |             return HTTP_INTERNAL_SERVER_ERROR; | ||||||
|         } |         } | ||||||
|     } elsif ($!{EEXIST}) { |     } elsif ($request_body_file) { | ||||||
|         $r->log_error($!, "Won't overwrite $file_path"); |         # We could hand over the file handle created by the above sysopen() as | ||||||
|         return HTTP_CONFLICT; |         # the second argument to move(), but we want to let move() use rename() | ||||||
|     } elsif ($!{EACCES}) { |         # if possible. | ||||||
|         $r->log_error($!, "Cannot create $file_path"); |         if (-e $file_path) { | ||||||
|         return HTTP_FORBIDDEN; |             $r->log_error(0, "Won't overwrite $file_path"); | ||||||
|     } else { |             return HTTP_CONFLICT; | ||||||
|         $r->log_error($!, "Cannot open $file_path"); |         } | ||||||
|         return HTTP_INTERNAL_SERVER_ERROR; |         if (not move($request_body_file, $file_path)) { | ||||||
|  |             $r->log_error($!, "Cannot move data to $file_path"); | ||||||
|  |             return HTTP_INTERNAL_SERVER_ERROR; | ||||||
|  |         } | ||||||
|  |         if (chmod($file_mode, $file_path) < 1) { | ||||||
|  |             $r->log_error($!, "Cannot change permissions of $file_path"); | ||||||
|  |             return HTTP_INTERNAL_SERVER_ERROR; | ||||||
|  |         } | ||||||
|  |     } else { # Huh? | ||||||
|  |         $r->log_error(0, "Got no data to write to $file_path"); | ||||||
|  |         return HTTP_BAD_REQUEST; | ||||||
|     } |     } | ||||||
|     return HTTP_CREATED; |     return HTTP_CREATED; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user