AMF-Connection
view release on metacpan or search on metacpan
lib/AMF/Connection.pm view on Meta::CPAN
if( $class->{'encoding'} == 3 ) { # AMF3
$body->setTarget( 'null' );
my (@operation) = split('\.',$operation);
my $method = pop @operation;
my $service = join('.',@operation);
my $destination = (defined $call->{'destination'}) ? $call->{'destination'} : $service;
my $remoting_message = $class->_brew_flex_remoting_message( $service, $method, {}, $arguments, $destination);
$body->setData( [ $remoting_message ] ); # it seems we need array ref here - to be checked
} else {
$body->setTarget( $operation );
$body->setData( $arguments );
};
$request->addBody( $body );
}
my $request_stream = new AMF::Connection::OutputStream($class->{'output_amf_options'});
# serialize request
$request->serialize($request_stream);
#use Data::Dumper;
#print STDERR Dumper( $request );
# set any extra HTTP header
map { $class->{'ua'}->default_header( $_ => $class->{'http_headers'}->{$_} ); } keys %{ $class->{'http_headers'} };
my $http_response = $class->{'ua'}->post(
$class->{'endpoint'}.$class->{'append_to_endpoint'}, # TODO - check if append to URL this really work for HTTP POST
Content_Type => "application/x-amf",
Content => $request_stream->getStreamData()
);
croak "HTTP POST error: ".$http_response->status_line."\n"
unless($http_response->is_success);
my $response_stream = new AMF::Connection::InputStream( $http_response->decoded_content, $class->{'input_amf_options'});
my $response = new AMF::Connection::Message;
$response->deserialize( $response_stream );
#print STDERR Dumper( $response )."\n";
# process AMF response headers
$class->_process_response_headers( $response );
my @all = @{ $response->getBodies() };
# we make sure the main response is always returned first
return (wantarray) ? @all : $all[0];
};
# TODO
#
# sub command { } - to send "flex.messaging.messages.CommandMessage" instead
#
sub setCredentials {
my ($class, $username, $password) = @_;
$class->addHeader( 'Credentials', { 'userid' => $username,'password' => $password }, 0 );
};
sub _process_response_headers {
my ($class,$message) = @_;
foreach my $header (@{ $message->getHeaders()}) {
if($header->getName eq 'ReplaceGatewayUrl') { # another way used by server to keep cookies-less sessions
$class->setEndpoint( $header->getValue )
unless( ref($header->getValue) );
} elsif($header->getName eq 'AppendToGatewayUrl') { # generally used for cokies-less sessions E.g. ';jsessionid=99226346ED3FF5296D08146B02ECCA28'
$class->{'append_to_endpoint'} = $header->getValue
unless( ref($header->getValue) );
};
};
};
# just an hack to avoid rewrite class mapping local-to-remote and viceversa and make Storable::AMF happy
sub _brew_flex_remoting_message {
my ($class,$source,$operation,$headers,$body,$destination) = @_;
return bless( {
'clientId' => _generateID(),
'destination' => $destination,
'messageId' => _generateID(),
'timestamp' => time() . '00',
'timeToLive' => 0,
'headers' => ($headers) ? $headers : {},
'body' => $body,
'correlationId' => undef,
'operation' => $operation,
'source' => $source # for backwards compatibility - google for it!
}, 'flex.messaging.messages.RemotingMessage' );
};
sub _generateID {
my $uniqueid;
if($HASUUID) {
eval {
my $ug = new Data::UUID;
$uniqueid = $ug->to_string( $ug->create() );
};
} elsif ($HASMD5) {
eval {
$uniqueid = substr(Digest::MD5::md5_hex(Digest::MD5::md5_hex(time(). {}. rand(). $$)), 0, 32);
};
} else {
$uniqueid ="";
my $length=16;
my $j;
for(my $i=0 ; $i< $length ;) {
$j = chr(int(rand(127)));
if($j =~ /[a-zA-Z0-9]/) {
$uniqueid .=$j;
$i++;
};
};
lib/AMF/Connection.pm view on Meta::CPAN
Future versions of AMF::Connection may add a proper configurable factory for application specific ActionScript/Flex object mappings.
=head1 METHODS
=head2 new ($endpoint)
Create new AMF::Connection object. An endpoint can be specified as the only parameter. Or set in a second moment with the setEndpoint() method.
=head2 call ($operation, $arguments)
Call the remote service method with given parameters/arguments on the set endpoint and return an AMF::Connection::MessageBody response. Or an array of responses if requsted (wantarray call scope). The $arguments is generally an array reference, but t...
=head2 callBatch (@batch)
Call the remote service once in batch. Each element of @batch must be an hash like { "operation" => $operation, "arguments" => $arguments }, where $operation and $arguments are as specified in C<call>. The commands are called and responses returned i...
=head2 setEndpoint ($endpoint)
Set the AMF service endpoint.
=head2 getEndpoint ()
Return the AMF service endpoint.
=head2 setEncoding ($encoding)
Set the AMF encoding to use.
=head2 getEncoding ()
Return the AMF encoding in use.
=head2 setHTTPProxy ($proxy)
Set the HTTP/S proxy to use. If LWP::Protocol is installed SOCKS proxies are supported.
=head2 getHTTPProxy ()
Return the HTTP/S procy in use if any.
=head2 addHeader ($header[, $value, $required])
Add an AMF AMF::Connection::MessageHeader to the requests. If $header is a string the header value $value and $required flag can be specified.
=head2 addHTTPHeader ($name, $value)
Add an HTTP header to sub-sequent HTTP requests.
=head2 setUserAgent ($ua)
Allow to specify an alternative LWP::UserAgent. The $ua must support the post() method, proxy() and cookie_jar() if necessary.
=head2 setHTTPCookieJar ($cookie_jar)
Allow to specify an alternative HTTP::Cookies jar. By default AMF::Connection keeps cookies into main-memory and the cookie jar is reset when a new connection is created. When a new cookies jar is set, any existing AMF::Connection cookie is copied ov...
=head2 getHTTPCookieJar ()
Return the current HTTP::Cookies jar in use.
=head2 setCredentials ($username,$password)
Minimal support for AMF authentication. Password seems to be wanted in clear.
=head2 setInputAMFOptions ($options)
Set input stream parsing options. See Storable::AMF0 for available options.
=head2 setOutputAMFOptions ($options)
Set output stream serialization options. See Storable::AMF0 for available options.
=head2 setAMFOptions ($options)
Set input and output options the same. See Storable::AMF0 for available options.
=head2 getInputAMFOptions ()
Get input stream parsing options.
=head2 getOutputAMFOptions ()
Get output stream serialization options.
=head1 CODE
See http://github.com/areggiori/AMF-Connection
=head1 SEE ALSO
AMF::Connection::MessageBody
Storable::AMF, Storable::AMF0, LWP::UserAgent
Flex messaging framework / LiveCycle Data Services
http://livedocs.adobe.com/blazeds/1/javadoc/flex/messaging/io/amf/client/package-summary.html
http://livedocs.adobe.com/blazeds/1/javadoc/flex/messaging/io/amf/client/AMFConnection.html
http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/net/NetConnection.html
http://help.adobe.com/en_US/LiveCycleDataServicesES/3.1/Developing/lcds31_using.pdf
http://help.adobe.com/en_US/Flex/4.0/AccessingData/flex_4_accessingdata.pdf
http://www.adobe.com/support/documentation/en/livecycledataservices/documentation.html
Specifications
http://download.macromedia.com/pub/labs/amf/amf0_spec_121207.pdf (AMF0)
http://opensource.adobe.com/wiki/download/attachments/1114283/amf3_spec_05_05_08.pdf (AMF3)
SabreAMF
http://code.google.com/p/sabreamf/
=head1 AUTHOR
Alberto Attilio Reggiori, <areggiori at cpan dot org>
=head1 THANKS
Anatoliy Grishayev for prompt support and developments on Storable::AMF
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2010-2011 by Alberto Attilio Reggiori
This library is free software; you can redistribute it and/or modify
( run in 1.759 second using v1.01-cache-2.11-cpan-d06a3f9ecfd )