} elsif ($filename =~ m/\.jar$/) {
$ct = 'application/java-archive';
$nocomp = 1;
+ } elsif ($filename =~ m/\.woff$/) {
+ $ct = 'application/font-woff';
+ $nocomp = 1;
+ } elsif ($filename =~ m/\.woff2$/) {
+ $ct = 'application/font-woff2';
+ $nocomp = 1;
+ } elsif ($filename =~ m/\.ttf$/) {
+ $ct = 'application/font-snft';
+ $nocomp = 1;
+ } elsif ($filename =~ m/\.pdf$/) {
+ $ct = 'application/pdf';
+ $nocomp = 1;
+ } elsif ($filename =~ m/\.epub$/) {
+ $ct = 'application/epub+zip';
+ $nocomp = 1;
} else {
die "unable to detect content type";
}
}
if ($param->{port}) {
- $remhost = '127.0.0.1';
+ $remhost = 'localhost';
$remport = $param->{port};
} elsif ($param->{socket}) {
$remhost = 'unix/';
if ($opcode == 1 || $opcode == 2) {
$reqstate->{proxyhdl}->push_write($payload) if $reqstate->{proxyhdl};
} elsif ($opcode == 8) {
- # ignore close ?
print "websocket received close\n" if $self->{debug};
+ if ($reqstate->{proxyhdl}) {
+ $reqstate->{proxyhdl}->push_write($payload);
+ $reqstate->{proxyhdl}->push_shutdown();
+ }
+ $hdl->push_shutdown();
} else {
die "received unhandled websocket opcode $opcode\n";
}
$target = "http://$host:85$uri";
# keep alive for localhost is not worth (connection setup is about 0.2ms)
$keep_alive = 0;
+ } elsif (Net::IP::ip_is_ipv6($host)) {
+ $target = "https://[$host]:8006$uri";
} else {
$target = "https://$host:8006$uri";
}
}
sub handle_api2_request {
- my ($self, $reqstate, $auth, $upload_state) = @_;
+ my ($self, $reqstate, $auth, $method, $path, $upload_state) = @_;
eval {
my $r = $reqstate->{request};
- my $method = $r->method();
- my $path = $r->uri->path();
my ($rel_uri, $format) = split_abs_uri($path);
$rpcenv->set_user(undef); # clear after request
my $upgrade = $r->header('upgrade');
+ $upgrade = lc($upgrade) if $upgrade;
if (my $host = $res->{proxy}) {
return;
} elsif ($upgrade && ($method eq 'GET') && ($path =~ m|websocket$|)) {
- die "unable to upgrade protocol\n" if !$upgrade || ($upgrade ne 'websocket');
+ die "unable to upgrade to protocol '$upgrade'\n" if !$upgrade || ($upgrade ne 'websocket');
my $wsver = $r->header('sec-websocket-version');
die "unsupported websocket-version '$wsver'\n" if !$wsver || ($wsver ne '13');
my $wsproto_str = $r->header('sec-websocket-protocol');
$reqstate->{hdl}->timeout(0);
$reqstate->{hdl}->wbuf_max(64*10*1024);
- my $remhost = $remip ? $remip : "127.0.0.1";
+ my $remhost = $remip ? $remip : "localhost";
my $remport = $remip ? 3128 : $spiceport;
tcp_connect $remhost, $remport, sub {
}
sub handle_request {
- my ($self, $reqstate, $auth) = @_;
+ my ($self, $reqstate, $auth, $method, $path) = @_;
eval {
my $r = $reqstate->{request};
- my $method = $r->method();
- my $path = $r->uri->path();
# disable timeout on handle (we already have all data we need)
# we re-enable timeout in response()
$reqstate->{hdl}->timeout(0);
if ($path =~ m!$baseuri!) {
- $self->handle_api2_request($reqstate, $auth);
+ $self->handle_api2_request($reqstate, $auth, $method, $path);
return;
}
}
sub file_upload_multipart {
- my ($self, $reqstate, $auth, $rstate) = @_;
+ my ($self, $reqstate, $auth, $method, $path, $rstate) = @_;
eval {
my $boundary = $rstate->{boundary};
syslog('info', "multipart upload complete " .
"(size: %d time: %ds rate: %.2fMiB/s md5sum: $rstate->{md5sum})",
$rstate->{bytes}, $elapsed, $rate);
- $self->handle_api2_request($reqstate, $auth, $rstate);
+ $self->handle_api2_request($reqstate, $auth, $method, $path, $rstate);
}
}
};
my $r = $reqstate->{request};
if ($line eq '') {
- my $path = $r->uri->path();
+ my $path = uri_unescape($r->uri->path());
my $method = $r->method();
$r->push_header($state->{key}, $state->{val})
outfh => $outfh,
};
$reqstate->{tmpfilename} = $tmpfilename;
- $reqstate->{hdl}->on_read(sub { $self->file_upload_multipart($reqstate, $auth, $state); });
+ $reqstate->{hdl}->on_read(sub { $self->file_upload_multipart($reqstate, $auth, $method, $path, $state); });
return;
}
$reqstate->{hdl}->unshift_read(chunk => $len, sub {
my ($hdl, $data) = @_;
$r->content($data);
- $self->handle_request($reqstate, $auth);
+ $self->handle_request($reqstate, $auth, $method, $path);
});
} else {
$self->error($reqstate, 506, "upload 'Content-Type '$ctype' not implemented");
}
} else {
- $self->handle_request($reqstate, $auth);
+ $self->handle_request($reqstate, $auth, $method, $path);
}
} elsif ($line =~ /^([^:\s]+)\s*:\s*(.*)/) {
$r->push_header($state->{key}, $state->{val}) if $state->{key};
$reqstate->{proto}->{maj} = $maj;
$reqstate->{proto}->{min} = $min;
$reqstate->{proto}->{ver} = $maj*1000+$min;
- $reqstate->{request} = HTTP::Request->new($method, uri_unescape($url));
+ $reqstate->{request} = HTTP::Request->new($method, $url);
$reqstate->{starttime} = [gettimeofday],
$self->unshift_read_header($reqstate);
undef $self->{socket_watch};
+ $0 = "$0 (shutdown)" if $0 !~ m/\(shutdown\)$/;
+
if ($self->{conn_count} <= 0) {
$self->{end_cond}->send(1);
return;
}
+ # fork and exit, so that parent starts a new worker
+ if (fork()) {
+ exit(0);
+ }
+
# else we need to wait until all open connections gets closed
my $w; $w = AnyEvent->timer (after => 1, interval => 1, cb => sub {
eval {
}
if (my $sin = getpeername($clientfh)) {
- my ($pport, $phost) = Socket::unpack_sockaddr_in($sin);
- ($reqstate->{peer_port}, $reqstate->{peer_host}) = ($pport, Socket::inet_ntoa($phost));
+ my ($pfamily, $pport, $phost) = PVE::Tools::unpack_sockaddr_in46($sin);
+ ($reqstate->{peer_port}, $reqstate->{peer_host}) = ($pport, Socket::inet_ntop($pfamily, $phost));
}
if (!$self->{trusted_env} && !$self->check_host_access($reqstate->{peer_host})) {