[pve-devel] r4840 - in pve-manager/pve2: . lib/PVE

svn-commits at proxmox.com svn-commits at proxmox.com
Thu Jun 24 14:51:56 CEST 2010


Author: dietmar
Date: 2010-06-24 12:51:56 +0000 (Thu, 24 Jun 2010)
New Revision: 4840

Modified:
   pve-manager/pve2/ChangeLog
   pve-manager/pve2/lib/PVE/APIDaemon.pm
   pve-manager/pve2/lib/PVE/REST.pm
Log:
* lib/PVE/REST.pm (proxy_handler): implement ability to proxy call to
  other nodes



Modified: pve-manager/pve2/ChangeLog
===================================================================
--- pve-manager/pve2/ChangeLog	2010-06-24 12:12:10 UTC (rev 4839)
+++ pve-manager/pve2/ChangeLog	2010-06-24 12:51:56 UTC (rev 4840)
@@ -1,3 +1,8 @@
+2010-06-24  Proxmox Support Team  <support at proxmox.com>
+
+	* lib/PVE/REST.pm (proxy_handler): implement ability to proxy call to
+	other nodes
+
 2010-06-21  Proxmox Support Team  <support at proxmox.com>
 
 	* just a test for the new svn commit list

Modified: pve-manager/pve2/lib/PVE/APIDaemon.pm
===================================================================
--- pve-manager/pve2/lib/PVE/APIDaemon.pm	2010-06-24 12:12:10 UTC (rev 4839)
+++ pve-manager/pve2/lib/PVE/APIDaemon.pm	2010-06-24 12:51:56 UTC (rev 4840)
@@ -191,6 +191,12 @@
     }
 }
 
+sub send_error {
+    my ($c, $code, $msg) = @_;
+
+    $c->send_response(HTTP::Response->new($code, $msg));
+}
+
 sub handle_requests {
     my $self = shift;
 
@@ -238,25 +244,33 @@
 		
 		    my $res = PVE::REST::rest_handler($method, $uri, $ticket, $params);
 
-		    my $response = HTTP::Response->new($res->{status});
-		    $response->header("Content-Type" => 'application/json');
-		    $response->header("Pragma", "no-cache");
+		    if ($res->{proxy}) {
 
-		    if ($res->{ticket}) {
-			my $cookie = PVE::REST::create_auth_cookie($res->{ticket});
-			$response->header("Set-Cookie" => $cookie);
-		    }
+			$res->{status} = 500;
+			$c->send_error($res->{status}, "proxy not allowed");
 
-		    if ($res->{data}) {
-			my $raw = to_json($res->{data}, {utf8 => 1});
-			$response->content($raw);
-			$response->header("Content-Length" => length($raw));
+		    } else {
 
-		    } else {
-			$response->header("Content-Length" => 0);
+			my $response = HTTP::Response->new($res->{status});
+			$response->header("Content-Type" => 'application/json');
+			$response->header("Pragma", "no-cache");
+
+			if ($res->{ticket}) {
+			    my $cookie = PVE::REST::create_auth_cookie($res->{ticket});
+			    $response->header("Set-Cookie" => $cookie);
+			}
+
+			if ($res->{data}) {
+			    my $raw = to_json($res->{data}, {utf8 => 1});
+			    $response->content($raw);
+			    $response->header("Content-Length" => length($raw));
+
+			} else {
+			    $response->header("Content-Length" => 0);
+			}
+			
+			$c->send_response($response);
 		    }
-			
-		    $c->send_response($response);
 
 		    syslog('info', "end $method $uri ($res->{status})");
 

Modified: pve-manager/pve2/lib/PVE/REST.pm
===================================================================
--- pve-manager/pve2/lib/PVE/REST.pm	2010-06-24 12:12:10 UTC (rev 4839)
+++ pve-manager/pve2/lib/PVE/REST.pm	2010-06-24 12:51:56 UTC (rev 4840)
@@ -76,10 +76,10 @@
     $r->print($raw);
 }
 
-sub local_proxy_handler {
-    my($r, $method, $abs_uri, $ticket, $params) = @_;
+sub proxy_handler {
+    my($r, $host, $method, $abs_uri, $ticket, $params) = @_;
 
-    syslog('info', "local proxy start $method, $abs_uri");
+    syslog('info', "proxy start $method $host:$abs_uri");
 
     my $ua = LWP::UserAgent->new(
 	protocols_allowed => [ 'http' ],
@@ -89,9 +89,17 @@
     $ua->default_header('cookie' => "${cookie_name}=$ticket") if $ticket;
 
     my $uri = URI->new();
-    $uri->scheme('http');
-    $uri->host('localhost');
-    $uri->port(85);
+
+    if ($host eq 'localhost') {
+	$uri->scheme('http');
+	$uri->host('localhost');
+	$uri->port(85);
+    } else {
+	$uri->scheme('https');
+	$uri->host($host);
+	$uri->port(443);
+    }
+
     $uri->path($abs_uri);
 
     my $response;
@@ -101,18 +109,24 @@
     } elsif ($method eq 'POST') {
 	$response = $ua->post($uri, $params);
     } else {
-	die "proxy method $method not implemented\n";
+	my $code = HTTP_NOT_IMPLEMENTED;
+	$r->status_line("$code proxy method '$method' not implemented");
+	return $code;
     }
 
+    my $ct = $response->header('Content-Type');
+    if ($ct ne 'application/json') {
+	my $code = HTTP_BAD_GATEWAY;
+	$r->status_line("$code proxy got unexpected content type '$ct'");
+	return $code;
+    }
+
     if (my $cookie = $response->header("Set-Cookie")) {
 	$r->err_headers_out()->add("Set-Cookie" => $cookie);
     }
 
     my $code = $response->code;
 
-    my $ct = $response->header('Content-Type');
-    die "got unexpected content type" if $ct ne 'application/json';
-
     if ($code && ($code != OK)) {
 	$r->status($code);
     }
@@ -124,7 +138,7 @@
     $r->content_type ('application/json');
     $r->print($response->decoded_content);
 
-    syslog('info', "local proxy end $code");
+    syslog('info', "proxy end $method $host:$abs_uri ($code)");
 
     return $code;
 }
@@ -141,7 +155,7 @@
 	my $user = $params->{username} || '';
 	my $pw = $params->{password} || '';
 
-	return { require_priv => 1,  status => FORBIDDEN } if ($euid != 0);
+	return { proxy => 'localhost' } if ($euid != 0);
 
 	#syslog('info', "ticket auth $user $pw");
 
@@ -202,8 +216,9 @@
 
      my $res = rest_handler($method, $r->uri, $ticket, $params);
 
-     return local_proxy_handler($r, $method, $r->uri, $ticket, $params)
-	 if $res->{require_priv};
+     if ($res->{proxy}) {
+	 return proxy_handler($r, $res->{proxy}, $method, $r->uri, $ticket, $params);
+     }
 
      if ($res->{ticket}) {
 	 my $cookie = create_auth_cookie($res->{ticket});




More information about the pve-devel mailing list