Command handler specifications

Command handlers enable you to specify how the broker responds to different commands issued by different users from within different environments. When users run commands, the Helix Broker searches for matching command handlers and uses the first match found. If no command handler matches the user’s command, the command is forwarded to the target Helix Core Server for normal processing.

The general syntax of a command handler specification is outlined in the sample broker.conf:

command: commandpattern
{
# Conditions for the command to meet (optional)
# Note that with the exception of 'flags', these are regex patterns.
  flags           = required-flags;
  args            = required-arguments;
  user            = required-user;
  workspace       = required-client-workspace;
  prog            = required-client-program;
  version         = required-version-of-client-program;

  # What to do with matching commands (required)
  action  = pass | reject | redirect | filter | respond ;

  # How to go about it
  destination = altserver;            # Required for action = redirect
  execute = /path/to/filter/program;  # Required for action = filter
  message = rejection-message;        # Required for action = reject
}

The commandpattern parameter can be a regular expression and can include the .* wildcard. For example, a commandpattern of user.* matches both the p4 user and p4 users commands. See Regular expression synopsis.

The following table describes the parameters in detail.

Parameter Meaning

flags

A list of options that must be present on the command line of the command being handled.

This feature enables you to specify different handling for the same p4 command, depending on which options the user specifies. Note that only single-character options can be specified here. Multi-character options, and options that take arguments should be handled by a filter program.

args

A list of arguments that must be present on the command line of the command being handled.

user

The name of the user who issued the command.

workspace

The Helix Core Server client workspace setting in effect when the command was issued.

prog

The Helix Core Server client application through which the user issued the command. This feature enables you to handle commands on a per-application basis.

version

The version of the Helix Core Server application through which the user issued the command.

action

Defines how the Helix Broker handles the specified commands. Valid values are: pass, reject, redirect, filter, or respond.

destination

For redirected commands, the name of the replica to which the commands are redirected. The destination must be the name of a previously defined alternate (replica) server listed in the altserver setting.

You can implement load-balancing by setting the destination to the keyword random. Commands are randomly redirected to any alternate (replica) server that you have already defined.

You can also set destination to the address:port of the server where you want commands redirected.

execute

The path to a filter program to be executed. For details about filter programs, see Filter programs.

message

A message to be sent to the user, typically before the command is executed. This can be used with any of the above actions.

checkauth

Authenticates the connection. If set to true, the Helix Broker checks that the user has access to the Helix Core Server before performing the action by running p4 protects -m with the user's connection. If set to false, or if not set, Helix Broker does not perform the check. If a filter program is run, the highest level permission that the user has is passed in as the maxPerm parameter. For details about filter programs, see Filter programs.

For example, the following command handler prevents user joe from invoking p4 submit from the buildonly client workspace.

command: submit
{
    user = joe;
    workspace = buildonly;
    action = reject;
    message = "Submit failed: Please do not submit from this workspace."
}

Regular expression synopsis

A regular expression, or regex, is a sequence of characters that forms a search pattern, for use in pattern matching with strings. The following is a short synopsis of the regex facility available in command handler specifications.

A regular expression is formed from zero or more branches. Branches are separated by |. The regex matches any string that matches at least one of the branches.

A branch is formed from zero or more pieces, concatenated together. A branch matches when all of its pieces match in sequence, that is, a match for the first piece, followed by a match for the second piece, and so on.

A piece is an atom possibly followed by a quantifier: *, +, or ?. An atom followed by * matches a sequence of 0 or more instances of the atom. An atom followed by + matches a sequence of 1 or more instances of the atom. An atom followed by ? matches a sequence of 0 or 1 instances of the atom.

An atom is:

  • a subordinate regular expression in parentheses - matches that subordinate regular expression
  • a range (see below),
  • . - matches any single character,
  • ^ - matches the beginning of the string,
  • $ - matches the end of the string,
  • a \ followed by a single character - matches that character,
  • or a single character with no other significance - matches that character.

A range is a sequence of characters enclosed in square brackets ([]), and normally matches any single character from the sequence. If the sequence begins with ^, it matches any single character that is not in the sequence. If two characters in the sequence are separated by -, this is shorthand for the full list of ASCII characters between them (for example, [0-9] matches any decimal digit, [a-z] matches any lowercase alphabetical character). To include a literal ] in the sequence, make it the first character (following a possible ^). To include a literal -, make it the first or last character.

Filter programs

When the action for a command handler is filter, the Helix Broker executes the program or script specified by the execute parameter and performs the action returned by the program. Filter programs enable you to enforce policies beyond the capabilities provided by the broker configuration file.

The Helix Broker invokes the filter program by passing command details to the program’s standard input in the following format:

Command detail Definition

command:

User command

brokerListenPort:

Port on which the broker is listening

brokerTargetPort:

Port on which the target server is listening

clientPort:

P4PORT setting of the client

clientProg:

Client application program

clientVersion:

Version of client application program

clientProtocol:

Level of client protocol

apiProtocol:

Level of api protocol

maxLockTime:

Maximum lock time (in ms) to lock tables before aborting

maxMemory:

Maximum megabytes of memory a command can consume

maxOpenFiles:

Maximum number of files a command can open

maxPerm

Highest permission (if checkauth is set)

maxResults:

Maximum number of rows of result data to be returned

maxScanRows:

Maximum number of rows of data scanned by a command

workspace:

Name of client workspace

user:

Name of requesting user

clientIp:

IP address of client

proxyIp:

IP address of proxy (if any)

cwd:

Client’s working directory

argCount:

Number of arguments to command

Arg0:

First argument (if any)

Arg1:

Second argument (if any)

clientHost:

Hostname of the client

brokerLevel:

The internal version level of the broker.

proxyLevel:

The internal version level of the proxy (if any).

Non-printable characters in command arguments are sent to filter programs as a percent sign followed by a pair of hex characters representing the ASCII code for the non-printable character in question. For example, the tab character is encoded as %09.

Your filter program must read this data from STDIN before performing any additional processing, regardless of whether the script requires the data. If the filter script does not read the data from STDIN, "broken pipe" errors can occur, and the broker rejects the user’s command.

Your filter program must respond to the Broker on standard output (stdout) with data in one of the four following formats:

action: PASS
message: a message for the user (optional)
action: REJECT
message: a message for the user (required)
action: REDIRECT
altserver: (an alternate server name)
message: a message for the user (optional)
action: RESPOND
message: a message for the user (required)
action: CONTINUE
Note

The values for the action are case-sensitive.

The action keyword is always required and tells the Broker how to respond to the user’s request. The available actions are:

Action Definition

PASS

Run the user’s command unchanged. A message for the user is optional.

REJECT

Reject the user’s command and return an error message. A message for the user is required.

REDIRECT

Redirect the command to a different (alternate) replica server. An altserver is required. See Configuring alternate servers to work with central authorization servers for details. A message for the user is optional.

To implement this action, the broker makes a new connection to the alternate server and routes all messages from the client to the alternate server rather than to the original server. This is unlike HTTP redirection where the client is requested to make its own direct connection to an alternate web server.

RESPOND

Do not run the command; return an informational message. A message for the user is required.

CONTINUE

Defer to the next command handler matching a given command.

For information on using multiple handlers, see the Perforce Knowledge Base article, How the Broker can process multiple command handlers.

If the filter program returns any response other than something complying with the four message formats above, the user’s command is rejected. If errors occur during the execution of your filter script code cause the broker to reject the user’s command, the broker returns an error message.

Broker filter programs have difficulty handling multi-line message responses. You must use syntax like the following to have new lines be interpreted correctly when sent from the broker:

message="\"line 1\nline 3\nline f\n\""

That is, the string must be quoted twice.

Next step

Alternate server definitions