Leyland

 view release on metacpan or  search on metacpan

lib/Leyland/Negotiator.pm  view on Meta::CPAN

		$prefix .= $suffix;
		$route = $' || '/';
		$i++;
	}

	return $pref_routes;
}

sub _matching_routes {
	my ($class, $app_routes, $pref_routes, $internal) = @_;

	my $routes = [];
	foreach (@$pref_routes) {
		my $pref_name = $_->{prefix} || '_root_';

		next unless $app_routes->EXISTS($pref_name);

		my $pref_routes = $app_routes->FETCH($pref_name);
		
		next unless $pref_routes;
		
		# find matching routes in this prefix
		ROUTE: foreach my $r ($pref_routes->Keys) {
			# does the requested route match the current route?
			next unless my @captures = ($_->{route} =~ m/$r/);
			
			shift @captures if scalar @captures == 1 && $captures[0] eq '1';

			my $route_meths = $pref_routes->FETCH($r);

			# find all routes that support the request method (i.e. GET, POST, etc.)
			METH: foreach my $m (sort { $a eq 'any' || $b eq 'any' } keys %$route_meths) {
				# do not match internal routes
				RULE: foreach my $rule (@{$route_meths->{$m}->{rules}->{is} || []}) {
					next METH if $rule eq 'internal' && !$internal;
				}

				# okay, add this route
				push(@$routes, { method => $m, class => $route_meths->{$m}->{class}, prefix => $_->{prefix}, route => $r, code => $route_meths->{$m}->{code}, rules => $route_meths->{$m}->{rules}, captures => \@captures });
			}
		}
	}

	return $routes;
}

sub _negotiate_method {
	my ($class, $method, $routes) = @_;

	return [grep { $class->method_name($_->{method}) eq $method || $_->{method} eq 'any' } @$routes];
}

sub _negotiate_receive_media {
	my ($class, $c, $all_routes) = @_;

	return $all_routes unless my $ct = $c->content_type;

	# will hold all routes with acceptable receive types
	my $routes = [];

	# remove charset from content-type
	if ($ct =~ m/^([^;]+)/) {
		$ct = $1;
	}

	$c->log->debug("I have received $ct");

	ROUTE: foreach (@$all_routes) {
		# does this route accept all media types?
		unless (exists $_->{rules}->{accepts}) {
			push(@$routes, $_);
			next ROUTE;
		}

		# okay, it has, what are we accepting?
		foreach my $accept (@{$_->{rules}->{accepts}}) {
			if ($accept eq $ct) {
				push(@$routes, $_);
				next ROUTE;
			}
		}
	}

	return $routes;
}

sub _negotiate_return_media {
	my ($class, $c, $all_routes) = @_;

	my @mimes;
	foreach (@{$c->wanted_mimes}) {
		push(@mimes, $_->{mime});
	}
	$c->log->debug('Remote address wants '.join(', ', @mimes));

	# will hold all routes with acceptable return types
	my $routes = [];
	
	ROUTE: foreach (@$all_routes) {
		# does this route return any media type?
		if ($_->{rules}->{returns_all}) {
			$_->{media} = '*/*';
			push(@$routes, $_);
			next ROUTE;
		}

		# what media types does this route return?
		my @have = exists $_->{rules}->{returns} ? 
			@{$_->{rules}->{returns}} :
			('text/html');

		# what routes do the client want?
		if (@{$c->wanted_mimes}) {
			foreach my $want (@{$c->wanted_mimes}) {
				# does the client accept _everything_?
				# if so, just return the first type we support.
				# this will happen only in the end of the
				# wanted_mimes list, so if the client explicitely
				# accepts a type we support, it will have
				# preference over this
				if ($want->{mime} eq '*/*' && $want->{q} > 0) {



( run in 0.986 second using v1.01-cache-2.11-cpan-524268b4103 )