mirror of
https://github.com/weiss/ngx_http_upload.git
synced 2025-07-01 02:09:40 +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.
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
my $request_body = $r->request_body;
|
||||
my $request_body_file = $r->request_body_file;
|
||||
|
||||
if ($request_body) {
|
||||
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;
|
||||
}
|
||||
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");
|
||||
if (not close($fh)) {
|
||||
$r->log_error($!, "Cannot close $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");
|
||||
} elsif ($!{EEXIST}) {
|
||||
$r->log_error($!, "Won't overwrite $file_path");
|
||||
return HTTP_CONFLICT;
|
||||
} elsif ($!{EACCES}) {
|
||||
$r->log_error($!, "Cannot create $file_path");
|
||||
return HTTP_FORBIDDEN;
|
||||
} else {
|
||||
$r->log_error($!, "Cannot open $file_path");
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
} elsif ($!{EEXIST}) {
|
||||
$r->log_error($!, "Won't overwrite $file_path");
|
||||
return HTTP_CONFLICT;
|
||||
} elsif ($!{EACCES}) {
|
||||
$r->log_error($!, "Cannot create $file_path");
|
||||
return HTTP_FORBIDDEN;
|
||||
} else {
|
||||
$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