Technical Overview of Delivering WAP Push Using Perl
Last month in Jack's Hacks, we examined how to deliver WAP Push messages by
using Java Servlets, the Openwave WAP Push Libraries and MySQL. Since servlets
don't fit everyone's needs, this month we're going to take a deeper look at WAP
Push, the Push Access Protocol, and how WAP Push messages can be generated using
other languages (specifically perl).
The term "WAP Push" is used to encompas an architecture which is composed of
several pieces:
A WAP Push capable Handset
A WAP Push Proxy Gateway (PPG)
A Wap Push Initiator (PI)
The Protocol between the PI and the PPG (PAP)
The Protocol between the PPG and the Handset (Push OTA)
The overall architecture of WAP Push is described by the
WAP Push Architectural Overview that is part of the June 2000 Conformance release from the WAP Forum (also know as WAP 1.2.1). The
most relevant part of the WAP Push system for developers is PAP.
Openwave makes available a WAP Push library package that contains some sample
code and classes that simplifiy PAP, and allow developers to simply integrate
push into java based applications without needing extensive knowledge of PAP or
WAP Push. However, Java based libraries do not meet the needs of all developers,
so lets take a look at how PAP can be implemented without using the Openwave WAP
Push libaray.
There are a few essential pieces needed to construct a WAP Push Service load
The Subscriber address
The PPG address
The URL to be pushed
A text string to be displayed
A unique identifier for the push message
Once this information is collected, it can be
used to build the Push entity.
We will take a look at how all of these pieces can be brought together using
an HTML front end, we can capture the data that will change from message to
message, and pass it on to some simple prel processing scripts. The source code
that this sample application is based on can be found in the following 3 files:
newpush.html, newpush.cgi,
and pushUtils.pm.
This information realistaclly will come from some buisness logic or triggered
even in a back end system, however for the purposes of this example, we will
employ a manual push initation.
The data submitted will be decoded on the server side by
newpush.cgi, and is processed in 5 steps:
Parse the query string &parse_string;
Generate a unique ID for the push $id = &getid;
Create the XML Push entity &create_content($id);
Post the push entity to the PPG $request =
HTTP::Request->new(POST, $url, $headers, $content); $ua =
LWP::UserAgent->new; $response = $ua->request($request);
Display back some results &print_html($string, $content, $$response{_content}, $url);
As we step through each of the functions in newpush.cgi we can see that
the bulk of the work will be done in the create_content method.
parse_string simply takes the arguments that are delivered on the query string
to the sciprt and populates an array of variables.
As we mentioned earlier, there are
only certain values that will change with each new push, so we also assign
static values at this stage for the delivery method, the bearer, if the bearer
we specify should be required, and the urgency of the alert. Notice that the variable url is not the url that is being
pushed, but instead is the URL on the PPG that is listening for PAP input.
Port 9002 is specified as the public, non-secure port for WAP Push
In the getID method, we need to generate a unique ID for each push that is sent by the
application. Furthermore, this ID must be unique across all push messages sent to any particular
PPG. So, we maintain a file that we increment the push ID from and append this to a string unique
to our particular application.
open (ID,">/tmp/pushid");
$newid = $id;
$newid += 1;
print ID "$newid\n";
# return value
return "testpush-".$id;
At this point in the application, we start the heavy lifting of
building the PUSH in the create_content method. Here we build an
mime-multipart that is composed of 2 parts, the control entity, and the
content entity. The control entity covers the addressing and delivery
specifics, while the content entity contains the data that is to be delivered
to the handset. The construction of these is done by the
newPush.pm library.
The createControl method builds the XML control entity first
ensuring that all required fields have been passed in. Next, the variables
gathered from the form are placed in their appropriate locations in the
addressing scheme, and then the entire XML entity is returned back to the
calling script.
The createContentSI method build the other half of the
PUSH entity. This is again, and XML contsruct that accepts the URL to be
pushed to the user along with a text message to be displayed by the device.
Upon completion, this method returns the XML back to the calling script
Once the multipart has been completely assembled, we can now open up
an HTTP connection to the PPG that has been specified, and POST the entity. To accomplish
this, we rely on some public libraries to manage the HTTP connection, these are:
which are available from CPAN. if they are not
present in your current perl environment. We send the
multipart to the address of our PPG on port 9002, set the headers indicating
that we are delivering a multipart entity, and then setup to capture the
response from our POST
### POST to the url
$request = HTTP::Request->new(POST, $url, $headers, $content);
$ua = LWP::UserAgent->new;
### get the response
$response = $ua->request($request);
The final step is simply presenting back to the user a
readable presentation of the multipart that was assembled as well as the XML
response that came back from the PPG. For an application deployed in a
production enviroment, this step would likely involve only writing some of the
information out to a database, or undertaking some additional processing based
on the response.
This application has built a simple ServiceIndication, and does not address all
of the features that are available via WAP Push. Developers can also send ServiceLoad,
and CacheOperations, in addtion to querying client capabilities. Furthermore, many other
optional delivery attirbutes can be set including deliver before and deliver after times.
These are discussed in detail in the Openwave WAP Push Library.
Thank you for taking the time to read this note, and if you have any comments, suggestions, or feedback,
please visit us in the Openwave Developer Forum.