Implement getArgumentsTree(), which returns a hash tree representing the first value of each unique argument name in a branch, using dots as the separator. Finally replaced the hardcoded non-extensible meta data stuff with a proper getMetaData() API. Implemented that in the various Input modules. Renamed 'parameter' to 'property' in the CGI Input module. Added '--batch-force-defaults' as an argument handled by the CommandLine Input module. Made CommandLine derive from Default instead of Arguments, so that it can pick up the default handling of metadata and default output protocol.

This commit is contained in:
ian%hixie.ch 2002-07-06 15:59:56 +00:00
Родитель 3bb535081c
Коммит 4c715c89ad
5 изменённых файлов: 108 добавлений и 142 удалений

Просмотреть файл

@ -186,12 +186,54 @@ sub getArgumentsBranch {
$self->notImplemented();
}
# if a key has multiple values, getArgumentsTree drops later values on the floor
sub getArgumentsTree {
my $self = shift;
my($root) = @_;
my $arguments = $self->getArgumentsBranch($root);
my $data = {};
foreach my $argument (keys(%$arguments)) {
my @parts = split(/\./, $argument);
my $key = pop(@parts);
my $pointer = $data;
foreach my $part (@parts) {
if (not defined($pointer->{$part})) {
$pointer->{$part} = {};
} elsif (ref($pointer->{$part}) ne 'HASH') {
$pointer->{$part} = {
'' => $pointer->{$part},
};
}
$pointer = $pointer->{$part};
}
while (exists($pointer->{$key}) and (ref($pointer->{$key}) eq 'HASH')) {
$pointer = $pointer->{$key};
$key = '';
}
$pointer->{$key} = $arguments->{$argument}->[0];
# if a key has multiple values, getArgumentsTree drops later values on the floor
}
return $data;
}
sub getMetaData {
my $self = shift;
my($field) = @_;
$self->notImplemented();
}
sub hash {
my $self = shift;
return {
'arguments' => $self->getArguments(),
'protocol' => $self->defaultOutputProtocol(),
# XXX also UA, etc...
'ua' => $self->getMetaData('UA'),
'referrer' => $self->getMetaData('referrer'),
'host' => $self->getMetaData('host'),
'acceptType' => $self->getMetaData('acceptType'),
'acceptCharset' => $self->getMetaData('acceptCharset'),
'acceptEncoding' => $self->getMetaData('acceptEncoding'),
'acceptLanguage' => $self->getMetaData('acceptLanguage'),
};
}
@ -209,41 +251,14 @@ sub hash {
# 'address' is an out of band argument that should only be provided
# for input devices that know the address of the user (and can thus
# construct the username).
# XXX I don't like having these here:
sub UA {
my $self = shift;
$self->notImplemented();
}
sub referrer {
my $self = shift;
$self->notImplemented();
}
sub host {
my $self = shift;
$self->notImplemented();
}
sub acceptType {
my $self = shift;
$self->notImplemented();
}
sub acceptCharset {
my $self = shift;
$self->notImplemented();
}
sub acceptEncoding {
my $self = shift;
$self->notImplemented();
}
sub acceptLanguage {
my $self = shift;
$self->notImplemented();
}
#
# These are separate from the metadata fields, which are available
# from getMetaData(). The following metadata fields are defined:
#
# UA
# referrer
# host
# acceptType
# acceptCharset
# acceptEncoding
# acceptLanguage

Просмотреть файл

@ -184,3 +184,9 @@ sub propertyGet {
# }
}
}
sub getMetaData {
my $self = shift;
my($field) = @_;
return '';
}

Просмотреть файл

@ -57,18 +57,29 @@ sub defaultOutputProtocol {
sub splitArguments {
my $self = shift;
foreach my $parameter (qw(SERVER_SOFTWARE SERVER_NAME
# register typical CGI variables
foreach my $property (qw(SERVER_SOFTWARE SERVER_NAME
GATEWAY_INTERFACE SERVER_PROTOCOL SERVER_PORT REQUEST_METHOD
PATH_INFO PATH_TRANSLATED SCRIPT_NAME QUERY_STRING REMOTE_HOST
REMOTE_ADDR AUTH_TYPE REMOTE_USER REMOTE_IDENT CONTENT_TYPE
CONTENT_LENGTH)) {
$self->propertySet($parameter, $ENV{$parameter});
$self->propertySet($property, $ENV{$property});
}
foreach my $parameter (keys(%ENV)) {
if ($parameter =~ /^HTTP_/o) {
$self->propertySet($parameter, $ENV{$parameter});
foreach my $property (keys(%ENV)) {
if ($property =~ /^HTTP_/o) {
$self->propertySet($property, $ENV{$property});
}
}
# hook in the metadata variables
$self->metaData({}); # empty the list of meta data first
$self->registerPropertyAsMetaData('UA', 'HTTP_USER_AGENT');
$self->registerPropertyAsMetaData('referrer', 'HTTP_REFERER');
$self->registerPropertyAsMetaData('host', 'REMOTE_HOST', 'REMOTE_ADDR');
$self->registerPropertyAsMetaData('acceptType', 'HTTP_ACCEPT');
$self->registerPropertyAsMetaData('acceptCharset', 'HTTP_ACCEPT_CHARSET');
$self->registerPropertyAsMetaData('acceptEncoding', 'HTTP_ACCEPT_ENCODING');
$self->registerPropertyAsMetaData('acceptLanguage', 'HTTP_ACCEPT_LANGUAGE');
# decode the arguments
my $method = $ENV{'REQUEST_METHOD'} || '';
if ($method eq 'POST') {
local $/ = undef;
@ -143,6 +154,7 @@ sub splitArguments {
} else {
# should also deal with HTTP HEAD, PUT, etc, here XXX
}
# decode username and password data
if (defined($ENV{'HTTP_AUTHORIZATION'})) {
if ($self->HTTP_AUTHORIZATION =~ /^Basic +(.*)$/os) {
# HTTP Basic Authentication
@ -165,37 +177,20 @@ sub setCommandArgument {
}
}
sub UA {
sub getMetaData {
my $self = shift;
return $self->getArgument('overrideUserAgent') or $self->HTTP_USER_AGENT;
my($field) = @_;
return $self->metaData->{$field};
}
sub referrer {
sub registerPropertyAsMetaData {
my $self = shift;
return $self->getArgument('overrideReferrer') or $self->HTTP_REFERER; # (sic)
}
sub host {
my $self = shift;
return $self->REMOTE_HOST or $self->REMOTE_ADDR;
}
sub acceptType {
my $self = shift;
return $self->getArgument('overrideAcceptType') or $self->HTTP_ACCEPT;
}
sub acceptCharset {
my $self = shift;
return $self->getArgument('overrideAcceptCharset') or $self->HTTP_ACCEPT_CHARSET;
}
sub acceptEncoding {
my $self = shift;
return $self->getArgument('overrideAcceptEncoding') or $self->HTTP_ACCEPT_ENCODING;
}
sub acceptLanguage {
my $self = shift;
return $self->getArgument('overrideAcceptLanguage') or $self->HTTP_ACCEPT_LANGUAGE;
my($field, @propertys) = @_;
foreach my $property (@propertys) {
my $value = $self->propertyGet($property);
if (defined($value)) {
$self->metaData->{$field} = $value;
last;
}
}
}

Просмотреть файл

@ -29,8 +29,8 @@
package PLIF::Input::CommandLine;
use strict;
use vars qw(@ISA);
use PLIF::Input::Arguments;
@ISA = qw(PLIF::Input::Arguments);
use PLIF::Input::Default;
@ISA = qw(PLIF::Input::Default);
1;
sub init {
@ -44,10 +44,6 @@ sub applies {
return @ARGV > 0;
}
sub defaultOutputProtocol {
return 'stdout';
}
sub splitArguments {
my $self = shift;
# first, make sure the command argument is created even if it is
@ -88,7 +84,7 @@ sub createArgument {
# @_ also contains @default, but to save copying it about we don't
# use it directly in this method
my($argument) = @_;
if ($argument eq 'batch') {
if ($argument eq 'batch' or $argument eq 'batch-force-defaults') {
# if --batch was not set, then we assume that means that
# we are not in --batch mode... no point asking the user,
# cos if we are, he won't reply, and if he isn't, we know
@ -96,7 +92,11 @@ sub createArgument {
$self->setArgument($argument, 0);
} else {
if ($self->getArgument('batch')) {
# defer to superclass
$self->SUPER::createArgument(@_);
} elsif ($self->getArgument('batch-force-defaults')) {
# set this argument to its default value
$self->setArgument(@_);
} else {
$self->app->output->request(@_);
# get input from user
@ -127,34 +127,3 @@ sub term {
}
return $self->{'term'};
}
# XXX Grrrr:
sub UA {
return '';
}
sub referrer {
return '';
}
sub host {
return 'localhost';
}
sub acceptType {
return 'text/plain';
}
sub acceptCharset {
return '';
}
sub acceptEncoding {
return '';
}
sub acceptLanguage {
return '';
}

Просмотреть файл

@ -41,36 +41,17 @@ sub defaultOutputProtocol {
return 'stdout';
}
sub getMetaData {
my $self = shift;
my($field) = @_;
if ($field eq 'host') {
return 'localhost';
} elsif ($field eq 'acceptType') {
return 'text/plain';
} else {
return $self->SUPER::getMetaData($field);
}
}
# Everything else that PLIF::Input::Arguments does by default is great
# for this. Namely, no command, and returning 'undef' for everything.
# XXX Grrrr:
sub UA {
return '';
}
sub referrer {
return '';
}
sub host {
return 'localhost';
}
sub acceptType {
return 'text/plain';
}
sub acceptCharset {
return '';
}
sub acceptEncoding {
return '';
}
sub acceptLanguage {
return '';
}