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
					
				
							
								
								
									
										38
									
								
								upload.pm
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								upload.pm
									
									
									
									
									
								
							| @ -128,29 +128,19 @@ sub handle_put_body { | ||||
|         return HTTP_FORBIDDEN; # Assume EACCES. | ||||
|     } | ||||
| 
 | ||||
|     my $request_body = $r->request_body; | ||||
|     my $request_body_file = $r->request_body_file; | ||||
| 
 | ||||
|     if ($request_body) { | ||||
|         if (sysopen(my $fh, $file_path, O_WRONLY|O_CREAT|O_EXCL, $file_mode)) { | ||||
|             if (not binmode($fh)) { | ||||
|                 $r->log_error($!, "Cannot set binary mode for $file_path"); | ||||
|                 return HTTP_INTERNAL_SERVER_ERROR; | ||||
|             } | ||||
| 
 | ||||
|         my $request_body = $r->request_body; | ||||
|         my $request_body_file = $r->request_body_file; | ||||
| 
 | ||||
|         if ($request_body) { | ||||
|             if (not syswrite($fh, $request_body)) { | ||||
|                 $r->log_error($!, "Cannot write $file_path"); | ||||
|                 return HTTP_INTERNAL_SERVER_ERROR; | ||||
|             } | ||||
|         } elsif ($request_body_file) { | ||||
|             if (not move($request_body_file, $fh)) { | ||||
|                 $r->log_error($!, "Cannot move data to $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; | ||||
|         } | ||||
|             if (not close($fh)) { | ||||
|                 $r->log_error($!, "Cannot close $file_path"); | ||||
|                 return HTTP_INTERNAL_SERVER_ERROR; | ||||
| @ -165,6 +155,26 @@ sub handle_put_body { | ||||
|             $r->log_error($!, "Cannot open $file_path"); | ||||
|             return HTTP_INTERNAL_SERVER_ERROR; | ||||
|         } | ||||
|     } elsif ($request_body_file) { | ||||
|         # We could hand over the file handle created by the above sysopen() as | ||||
|         # the second argument to move(), but we want to let move() use rename() | ||||
|         # if possible. | ||||
|         if (-e $file_path) { | ||||
|             $r->log_error(0, "Won't overwrite $file_path"); | ||||
|             return HTTP_CONFLICT; | ||||
|         } | ||||
|         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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user