Moving from govendor to dep, updated dependencies (#48)

* Moving from govendor to dep.

* Making the pull request template more friendly.

* Fixing akward space in PR template.

* goimports run on whole project using ` goimports -w $(find . -type f -name '*.go' -not -path "./vendor/*" -not -path "./gen-go/*")`

source of command: https://gist.github.com/bgentry/fd1ffef7dbde01857f66
This commit is contained in:
Renan DelValle 2018-01-07 13:13:47 -08:00 committed by GitHub
parent 9631aa3aab
commit 8d445c1c77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2186 changed files with 400410 additions and 352 deletions

193
vendor/git.apache.org/thrift.git/lib/perl/lib/Thrift.pm generated vendored Normal file
View file

@ -0,0 +1,193 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
package Thrift;
our $VERSION = '0.10.0';
require 5.6.0;
use strict;
use warnings;
#
# Data types that can be sent via Thrift
#
package TType;
use constant STOP => 0;
use constant VOID => 1;
use constant BOOL => 2;
use constant BYTE => 3;
use constant I08 => 3;
use constant DOUBLE => 4;
use constant I16 => 6;
use constant I32 => 8;
use constant I64 => 10;
use constant STRING => 11;
use constant UTF7 => 11;
use constant STRUCT => 12;
use constant MAP => 13;
use constant SET => 14;
use constant LIST => 15;
use constant UTF8 => 16;
use constant UTF16 => 17;
1;
#
# Message types for RPC
#
package TMessageType;
use constant CALL => 1;
use constant REPLY => 2;
use constant EXCEPTION => 3;
use constant ONEWAY => 4;
1;
package Thrift::TException;
use overload '""' => sub {
return
ref( $_[0] )
. " error: "
. ( $_[0]->{message} || 'empty message' )
. " (code "
. ( defined $_[0]->{code} ? $_[0]->{code} : 'undefined' ) . ")";
};
sub new {
my $classname = shift;
my $self = {message => shift, code => shift || 0};
return bless($self,$classname);
}
1;
package TApplicationException;
use base('Thrift::TException');
use constant UNKNOWN => 0;
use constant UNKNOWN_METHOD => 1;
use constant INVALID_MESSAGE_TYPE => 2;
use constant WRONG_METHOD_NAME => 3;
use constant BAD_SEQUENCE_ID => 4;
use constant MISSING_RESULT => 5;
use constant INTERNAL_ERROR => 6;
use constant PROTOCOL_ERROR => 7;
use constant INVALID_TRANSFORM => 8;
use constant INVALID_PROTOCOL => 9;
use constant UNSUPPORTED_CLIENT_TYPE => 10;
sub new {
my $classname = shift;
my $self = $classname->SUPER::new(@_);
return bless($self,$classname);
}
sub read {
my $self = shift;
my $input = shift;
my $xfer = 0;
my $fname = undef;
my $ftype = 0;
my $fid = 0;
$xfer += $input->readStructBegin(\$fname);
while (1)
{
$xfer += $input->readFieldBegin(\$fname, \$ftype, \$fid);
if ($ftype == TType::STOP) {
last; next;
}
SWITCH: for($fid)
{
/1/ && do{
if ($ftype == TType::STRING) {
$xfer += $input->readString(\$self->{message});
} else {
$xfer += $input->skip($ftype);
}
last;
};
/2/ && do{
if ($ftype == TType::I32) {
$xfer += $input->readI32(\$self->{code});
} else {
$xfer += $input->skip($ftype);
}
last;
};
$xfer += $input->skip($ftype);
}
$xfer += $input->readFieldEnd();
}
$xfer += $input->readStructEnd();
return $xfer;
}
sub write {
my $self = shift;
my $output = shift;
my $xfer = 0;
$xfer += $output->writeStructBegin('TApplicationException');
if ($self->getMessage()) {
$xfer += $output->writeFieldBegin('message', TType::STRING, 1);
$xfer += $output->writeString($self->getMessage());
$xfer += $output->writeFieldEnd();
}
if ($self->getCode()) {
$xfer += $output->writeFieldBegin('type', TType::I32, 2);
$xfer += $output->writeI32($self->getCode());
$xfer += $output->writeFieldEnd();
}
$xfer += $output->writeFieldStop();
$xfer += $output->writeStructEnd();
return $xfer;
}
sub getMessage
{
my $self = shift;
return $self->{message};
}
sub getCode
{
my $self = shift;
return $self->{code};
}
1;

View file

@ -0,0 +1,511 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use utf8;
use Encode;
use Thrift;
use Thrift::Protocol;
use Bit::Vector;
#
# Binary implementation of the Thrift protocol.
#
package Thrift::BinaryProtocol;
use base('Thrift::Protocol');
use constant VERSION_MASK => 0xffff0000;
use constant VERSION_1 => 0x80010000;
use constant IS_BIG_ENDIAN => unpack("h*", pack("s", 1)) =~ /01/;
sub new
{
my $classname = shift;
my $trans = shift;
my $self = $classname->SUPER::new($trans);
return bless($self,$classname);
}
sub writeMessageBegin
{
my $self = shift;
my ($name, $type, $seqid) = @_;
return
$self->writeI32(VERSION_1 | $type) +
$self->writeString($name) +
$self->writeI32($seqid);
}
sub writeMessageEnd
{
my $self = shift;
return 0;
}
sub writeStructBegin{
my $self = shift;
my $name = shift;
return 0;
}
sub writeStructEnd
{
my $self = shift;
return 0;
}
sub writeFieldBegin
{
my $self = shift;
my ($fieldName, $fieldType, $fieldId) = @_;
return
$self->writeByte($fieldType) +
$self->writeI16($fieldId);
}
sub writeFieldEnd
{
my $self = shift;
return 0;
}
sub writeFieldStop
{
my $self = shift;
return $self->writeByte(TType::STOP);
}
sub writeMapBegin
{
my $self = shift;
my ($keyType, $valType, $size) = @_;
return
$self->writeByte($keyType) +
$self->writeByte($valType) +
$self->writeI32($size);
}
sub writeMapEnd
{
my $self = shift;
return 0;
}
sub writeListBegin
{
my $self = shift;
my ($elemType, $size) = @_;
return
$self->writeByte($elemType) +
$self->writeI32($size);
}
sub writeListEnd
{
my $self = shift;
return 0;
}
sub writeSetBegin
{
my $self = shift;
my ($elemType, $size) = @_;
return
$self->writeByte($elemType) +
$self->writeI32($size);
}
sub writeSetEnd
{
my $self = shift;
return 0;
}
sub writeBool
{
my $self = shift;
my $value = shift;
my $data = pack('c', $value ? 1 : 0);
$self->{trans}->write($data, 1);
return 1;
}
sub writeByte
{
my $self = shift;
my $value= shift;
my $data = pack('c', $value);
$self->{trans}->write($data, 1);
return 1;
}
sub writeI16
{
my $self = shift;
my $value= shift;
my $data = pack('n', $value);
$self->{trans}->write($data, 2);
return 2;
}
sub writeI32
{
my $self = shift;
my $value= shift;
my $data = pack('N', $value);
$self->{trans}->write($data, 4);
return 4;
}
sub writeI64
{
my $self = shift;
my $value= shift;
my $data;
my $vec;
#stop annoying error
$vec = Bit::Vector->new_Dec(64, $value);
$data = pack 'NN', $vec->Chunk_Read(32, 32), $vec->Chunk_Read(32, 0);
$self->{trans}->write($data, 8);
return 8;
}
sub writeDouble
{
my $self = shift;
my $value= shift;
my $data = pack('d', $value);
if (IS_BIG_ENDIAN) {
$self->{trans}->write($data, 8);
}
else {
$self->{trans}->write(scalar reverse($data), 8);
}
return 8;
}
sub writeString{
my $self = shift;
my $value= shift;
if( utf8::is_utf8($value) ){
$value = Encode::encode_utf8($value);
}
my $len = length($value);
my $result = $self->writeI32($len);
if ($len) {
$self->{trans}->write($value,$len);
}
return $result + $len;
}
#
#All references
#
sub readMessageBegin
{
my $self = shift;
my ($name, $type, $seqid) = @_;
my $version = 0;
my $result = $self->readI32(\$version);
if (($version & VERSION_MASK) > 0) {
if (($version & VERSION_MASK) != VERSION_1) {
die new Thrift::TException('Missing version identifier')
}
$$type = $version & 0x000000ff;
return
$result +
$self->readString($name) +
$self->readI32($seqid);
} else { # old client support code
return
$result +
$self->readStringBody($name, $version) + # version here holds the size of the string
$self->readByte($type) +
$self->readI32($seqid);
}
}
sub readMessageEnd
{
my $self = shift;
return 0;
}
sub readStructBegin
{
my $self = shift;
my $name = shift;
$$name = '';
return 0;
}
sub readStructEnd
{
my $self = shift;
return 0;
}
sub readFieldBegin
{
my $self = shift;
my ($name, $fieldType, $fieldId) = @_;
my $result = $self->readByte($fieldType);
if ($$fieldType == TType::STOP) {
$$fieldId = 0;
return $result;
}
$result += $self->readI16($fieldId);
return $result;
}
sub readFieldEnd() {
my $self = shift;
return 0;
}
sub readMapBegin
{
my $self = shift;
my ($keyType, $valType, $size) = @_;
return
$self->readByte($keyType) +
$self->readByte($valType) +
$self->readI32($size);
}
sub readMapEnd()
{
my $self = shift;
return 0;
}
sub readListBegin
{
my $self = shift;
my ($elemType, $size) = @_;
return
$self->readByte($elemType) +
$self->readI32($size);
}
sub readListEnd
{
my $self = shift;
return 0;
}
sub readSetBegin
{
my $self = shift;
my ($elemType, $size) = @_;
return
$self->readByte($elemType) +
$self->readI32($size);
}
sub readSetEnd
{
my $self = shift;
return 0;
}
sub readBool
{
my $self = shift;
my $value = shift;
my $data = $self->{trans}->readAll(1);
my @arr = unpack('c', $data);
$$value = $arr[0] == 1;
return 1;
}
sub readByte
{
my $self = shift;
my $value = shift;
my $data = $self->{trans}->readAll(1);
my @arr = unpack('c', $data);
$$value = $arr[0];
return 1;
}
sub readI16
{
my $self = shift;
my $value = shift;
my $data = $self->{trans}->readAll(2);
my @arr = unpack('n', $data);
$$value = $arr[0];
if ($$value > 0x7fff) {
$$value = 0 - (($$value - 1) ^ 0xffff);
}
return 2;
}
sub readI32
{
my $self = shift;
my $value= shift;
my $data = $self->{trans}->readAll(4);
my @arr = unpack('N', $data);
$$value = $arr[0];
if ($$value > 0x7fffffff) {
$$value = 0 - (($$value - 1) ^ 0xffffffff);
}
return 4;
}
sub readI64
{
my $self = shift;
my $value = shift;
my $data = $self->{trans}->readAll(8);
my ($hi,$lo)=unpack('NN',$data);
my $vec = new Bit::Vector(64);
$vec->Chunk_Store(32,32,$hi);
$vec->Chunk_Store(32,0,$lo);
$$value = $vec->to_Dec();
return 8;
}
sub readDouble
{
my $self = shift;
my $value = shift;
my $data;
if (IS_BIG_ENDIAN) {
$data = $self->{trans}->readAll(8);
}
else {
$data = scalar reverse($self->{trans}->readAll(8));
}
my @arr = unpack('d', $data);
$$value = $arr[0];
return 8;
}
sub readString
{
my $self = shift;
my $value = shift;
my $len;
my $result = $self->readI32(\$len);
if ($len) {
$$value = $self->{trans}->readAll($len);
} else {
$$value = '';
}
return $result + $len;
}
sub readStringBody
{
my $self = shift;
my $value = shift;
my $len = shift;
if ($len) {
$$value = $self->{trans}->readAll($len);
} else {
$$value = '';
}
return $len;
}
#
# Binary Protocol Factory
#
package Thrift::BinaryProtocolFactory;
use base('TProtocolFactory');
sub new
{
my $classname = shift;
my $self = $classname->SUPER::new();
return bless($self,$classname);
}
sub getProtocol{
my $self = shift;
my $trans = shift;
return new Thrift::BinaryProtocol($trans);
}
1;

View file

@ -0,0 +1,136 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
use Thrift::Transport;
package Thrift::BufferedTransport;
use base('Thrift::Transport');
sub new
{
my $classname = shift;
my $transport = shift;
my $rBufSize = shift || 512;
my $wBufSize = shift || 512;
my $self = {
transport => $transport,
rBufSize => $rBufSize,
wBufSize => $wBufSize,
wBuf => '',
rBuf => '',
};
return bless($self,$classname);
}
sub isOpen
{
my $self = shift;
return $self->{transport}->isOpen();
}
sub open
{
my $self = shift;
$self->{transport}->open();
}
sub close()
{
my $self = shift;
$self->{transport}->close();
}
sub readAll
{
my $self = shift;
my $len = shift;
return $self->{transport}->readAll($len);
}
sub read
{
my $self = shift;
my $len = shift;
my $ret;
# Methinks Perl is already buffering these for us
return $self->{transport}->read($len);
}
sub write
{
my $self = shift;
my $buf = shift;
$self->{wBuf} .= $buf;
if (length($self->{wBuf}) >= $self->{wBufSize}) {
$self->{transport}->write($self->{wBuf});
$self->{wBuf} = '';
}
}
sub flush
{
my $self = shift;
if (length($self->{wBuf}) > 0) {
$self->{transport}->write($self->{wBuf});
$self->{wBuf} = '';
}
$self->{transport}->flush();
}
#
# BufferedTransport factory creates buffered transport objects from transports
#
package Thrift::BufferedTransportFactory;
sub new {
my $classname = shift;
my $self = {};
return bless($self,$classname);
}
#
# Build a buffered transport from the base transport
#
# @return Thrift::BufferedTransport transport
#
sub getTransport
{
my $self = shift;
my $trans = shift;
my $buffered = Thrift::BufferedTransport->new($trans);
return $buffered;
}
1;

View file

@ -0,0 +1,193 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
use strict;
use warnings;
use Thrift;
use Thrift::Transport;
#
# Framed transport. Writes and reads data in chunks that are stamped with
# their length.
#
# @package thrift.transport
#
package Thrift::FramedTransport;
use base('Thrift::Transport');
sub new
{
my $classname = shift;
my $transport = shift;
my $read = shift || 1;
my $write = shift || 1;
my $self = {
transport => $transport,
read => $read,
write => $write,
wBuf => '',
rBuf => '',
};
return bless($self,$classname);
}
sub isOpen
{
my $self = shift;
return $self->{transport}->isOpen();
}
sub open
{
my $self = shift;
$self->{transport}->open();
}
sub close
{
my $self = shift;
if (defined $self->{transport}) {
$self->{transport}->close();
}
}
#
# Reads from the buffer. When more data is required reads another entire
# chunk and serves future reads out of that.
#
# @param int $len How much data
#
sub read
{
my $self = shift;
my $len = shift;
if (!$self->{read}) {
return $self->{transport}->read($len);
}
if (length($self->{rBuf}) == 0) {
$self->_readFrame();
}
# Just return full buff
if ($len > length($self->{rBuf})) {
my $out = $self->{rBuf};
$self->{rBuf} = '';
return $out;
}
# Return substr
my $out = substr($self->{rBuf}, 0, $len);
$self->{rBuf} = substr($self->{rBuf}, $len);
return $out;
}
#
# Reads a chunk of data into the internal read buffer.
# (private)
sub _readFrame
{
my $self = shift;
my $buf = $self->{transport}->readAll(4);
my @val = unpack('N', $buf);
my $sz = $val[0];
$self->{rBuf} = $self->{transport}->readAll($sz);
}
#
# Writes some data to the pending output buffer.
#
# @param string $buf The data
# @param int $len Limit of bytes to write
#
sub write
{
my $self = shift;
my $buf = shift;
my $len = shift;
unless($self->{write}) {
return $self->{transport}->write($buf, $len);
}
if ( defined $len && $len < length($buf)) {
$buf = substr($buf, 0, $len);
}
$self->{wBuf} .= $buf;
}
#
# Writes the output buffer to the stream in the format of a 4-byte length
# followed by the actual data.
#
sub flush
{
my $self = shift;
unless ($self->{write}) {
return $self->{transport}->flush();
}
my $out = pack('N', length($self->{wBuf}));
$out .= $self->{wBuf};
$self->{transport}->write($out);
$self->{transport}->flush();
$self->{wBuf} = '';
}
#
# FramedTransport factory creates framed transport objects from transports
#
package Thrift::FramedTransportFactory;
sub new {
my $classname = shift;
my $self = {};
return bless($self, $classname);
}
#
# Build a framed transport from the base transport
#
# @return Thrift::FramedTransport transport
#
sub getTransport
{
my $self = shift;
my $trans = shift;
my $buffered = Thrift::FramedTransport->new($trans);
return $buffered;
}
1;

View file

@ -0,0 +1,200 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
use Thrift::Transport;
use HTTP::Request;
use LWP::UserAgent;
use IO::String;
package Thrift::HttpClient;
use base('Thrift::Transport');
sub new
{
my $classname = shift;
my $url = shift || 'http://localhost:9090';
my $debugHandler = shift;
my $out = IO::String->new;
binmode($out);
my $self = {
url => $url,
out => $out,
debugHandler => $debugHandler,
debug => 0,
sendTimeout => 100,
recvTimeout => 750,
handle => undef,
};
return bless($self,$classname);
}
sub setSendTimeout
{
my $self = shift;
my $timeout = shift;
$self->{sendTimeout} = $timeout;
}
sub setRecvTimeout
{
my $self = shift;
my $timeout = shift;
$self->{recvTimeout} = $timeout;
}
#
#Sets debugging output on or off
#
# @param bool $debug
#
sub setDebug
{
my $self = shift;
my $debug = shift;
$self->{debug} = $debug;
}
#
# Tests whether this is open
#
# @return bool true if the socket is open
#
sub isOpen
{
return 1;
}
sub open {}
#
# Cleans up the buffer.
#
sub close
{
my $self = shift;
if (defined($self->{io})) {
close($self->{io});
$self->{io} = undef;
}
}
#
# Guarantees that the full amount of data is read.
#
# @return string The data, of exact length
# @throws TTransportException if cannot read data
#
sub readAll
{
my $self = shift;
my $len = shift;
my $buf = $self->read($len);
if (!defined($buf)) {
die new Thrift::TException('TSocket: Could not read '.$len.' bytes from input buffer');
}
return $buf;
}
#
# Read and return string
#
sub read
{
my $self = shift;
my $len = shift;
my $buf;
my $in = $self->{in};
if (!defined($in)) {
die new Thrift::TException("Response buffer is empty, no request.");
}
eval {
my $ret = sysread($in, $buf, $len);
if (! defined($ret)) {
die new Thrift::TException("No more data available.");
}
}; if($@){
die new Thrift::TException($@);
}
return $buf;
}
#
# Write string
#
sub write
{
my $self = shift;
my $buf = shift;
$self->{out}->print($buf);
}
#
# Flush output (do the actual HTTP/HTTPS request)
#
sub flush
{
my $self = shift;
my $ua = LWP::UserAgent->new('timeout' => ($self->{sendTimeout} / 1000),
'agent' => 'Perl/THttpClient'
);
$ua->default_header('Accept' => 'application/x-thrift');
$ua->default_header('Content-Type' => 'application/x-thrift');
$ua->cookie_jar({}); # hash to remember cookies between redirects
my $out = $self->{out};
$out->setpos(0); # rewind
my $buf = join('', <$out>);
my $request = new HTTP::Request(POST => $self->{url}, undef, $buf);
my $response = $ua->request($request);
my $content_ref = $response->content_ref;
my $in = IO::String->new($content_ref);
binmode($in);
$self->{in} = $in;
$in->setpos(0); # rewind
# reset write buffer
$out = IO::String->new;
binmode($out);
$self->{out} = $out;
}
1;

View file

@ -0,0 +1,146 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
use Thrift::Transport;
package Thrift::MemoryBuffer;
use base('Thrift::Transport');
sub new
{
my $classname = shift;
my $bufferSize= shift || 1024;
my $self = {
buffer => '',
bufferSize=> $bufferSize,
wPos => 0,
rPos => 0,
};
return bless($self,$classname);
}
sub isOpen
{
return 1;
}
sub open
{
}
sub close
{
}
sub peek
{
my $self = shift;
return($self->{rPos} < $self->{wPos});
}
sub getBuffer
{
my $self = shift;
return $self->{buffer};
}
sub resetBuffer
{
my $self = shift;
my $new_buffer = shift || '';
$self->{buffer} = $new_buffer;
$self->{bufferSize} = length($new_buffer);
$self->{wPos} = length($new_buffer);
$self->{rPos} = 0;
}
sub available
{
my $self = shift;
return ($self->{wPos} - $self->{rPos});
}
sub read
{
my $self = shift;
my $len = shift;
my $ret;
my $avail = ($self->{wPos} - $self->{rPos});
return '' if $avail == 0;
#how much to give
my $give = $len;
$give = $avail if $avail < $len;
$ret = substr($self->{buffer},$self->{rPos},$give);
$self->{rPos} += $give;
return $ret;
}
sub readAll
{
my $self = shift;
my $len = shift;
my $avail = ($self->{wPos} - $self->{rPos});
if ($avail < $len) {
die new TTransportException("Attempt to readAll($len) found only $avail available");
}
my $data = '';
my $got = 0;
while (($got = length($data)) < $len) {
$data .= $self->read($len - $got);
}
return $data;
}
sub write
{
my $self = shift;
my $buf = shift;
$self->{buffer} .= $buf;
$self->{wPos} += length($buf);
}
sub flush
{
}
1;

View file

@ -0,0 +1,32 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
use strict;
use warnings;
package Thrift::MessageType;
use strict;
use constant CALL => 1;
use constant REPLY => 2;
use constant EXCEPTION => 3;
use constant ONEWAY => 4;
1;

View file

@ -0,0 +1,121 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
use strict;
use warnings;
use Thrift;
use Thrift::Protocol;
use Thrift::MultiplexedProtocol;
use Thrift::ProtocolDecorator;
use Thrift::MessageType;
package Thrift::StoredMessageProtocol;
use base qw(Thrift::ProtocolDecorator);
use strict;
sub new {
my $classname = shift;
my $protocol = shift;
my $fname = shift;
my $mtype = shift;
my $rseqid = shift;
my $self = $classname->SUPER::new($protocol);
$self->{fname} = $fname;
$self->{mtype} = $mtype;
$self->{rseqid} = $rseqid;
return bless($self,$classname);
}
sub readMessageBegin
{
my $self = shift;
my $name = shift;
my $type = shift;
my $seqid = shift;
$$name = $self->{fname};
$$type = $self->{mtype};
$$seqid = $self->{rseqid};
}
package Thrift::MultiplexedProcessor;
use strict;
sub new {
my $classname = shift;
my $self = {};
$self->{serviceProcessorMap} = {};
return bless($self,$classname);
}
sub registerProcessor {
my $self = shift;
my $serviceName = shift;
my $processor = shift;
$self->{serviceProcessorMap}->{$serviceName} = $processor;
}
sub process{
my $self = shift;
my $input = shift;
my $output = shift;
#
# Use the actual underlying protocol (e.g. BinaryProtocol) to read the
# message header. This pulls the message "off the wire", which we'll
# deal with at the end of this method.
#
my ($fname, $mtype, $rseqid);
$input->readMessageBegin(\$fname, \$mtype, \$rseqid);
if ($mtype ne Thrift::MessageType::CALL && $mtype ne Thrift::MessageType::ONEWAY) {
die new Thrift::TException("This should not have happened!?");
}
# Extract the service name and the new Message name.
if (index($fname, Thrift::MultiplexedProtocol::SEPARATOR) == -1) {
die new Thrift::TException("Service name not found in message name: {$fname}. Did you " .
"forget to use a MultiplexProtocol in your client?");
}
(my $serviceName, my $messageName) = split(':', $fname, 2);
if (!exists($self->{serviceProcessorMap}->{$serviceName})) {
die new Thrift::TException("Service name not found: {$serviceName}. Did you forget " .
"to call registerProcessor()?");
}
#Dispatch processing to the stored processor
my $processor = $self->{serviceProcessorMap}->{$serviceName};
return $processor->process(
new Thrift::StoredMessageProtocol($input, $messageName, $mtype, $rseqid), $output
);
}
1;

View file

@ -0,0 +1,67 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
use strict;
use warnings;
use Thrift::Protocol;
use Thrift::ProtocolDecorator;
use Thrift::MessageType;
package Thrift::MultiplexedProtocol;
use base qw(Thrift::ProtocolDecorator);
use strict;
use constant SEPARATOR => ':';
sub new {
my $classname = shift;
my $protocol = shift;
my $serviceName = shift;
my $self = $classname->SUPER::new($protocol);
$self->{serviceName} = $serviceName;
return bless($self,$classname);
}
#
# Writes the message header.
# Prepends the service name to the function name, separated by MultiplexedProtocol::SEPARATOR.
#
# @param string $name Function name.
# @param int $type Message type.
# @param int $seqid The sequence id of this message.
#
sub writeMessageBegin
{
my $self = shift;
my ($name, $type, $seqid) = @_;
if ($type == Thrift::MessageType::CALL || $type == Thrift::MessageType::ONEWAY) {
my $nameWithService = $self->{serviceName}.SEPARATOR.$name;
$self->SUPER::writeMessageBegin($nameWithService, $type, $seqid);
}
else {
$self->SUPER::writeMessageBegin($name, $type, $seqid);
}
}
1;

View file

@ -0,0 +1,544 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
#
# Protocol exceptions
#
package TProtocolException;
use base('Thrift::TException');
use constant UNKNOWN => 0;
use constant INVALID_DATA => 1;
use constant NEGATIVE_SIZE => 2;
use constant SIZE_LIMIT => 3;
use constant BAD_VERSION => 4;
use constant NOT_IMPLEMENTED => 5;
use constant DEPTH_LIMIT => 6;
sub new {
my $classname = shift;
my $self = $classname->SUPER::new();
return bless($self,$classname);
}
#
# Protocol base class module.
#
package Thrift::Protocol;
sub new {
my $classname = shift;
my $self = {};
my $trans = shift;
$self->{trans}= $trans;
return bless($self,$classname);
}
sub getTransport
{
my $self = shift;
return $self->{trans};
}
#
# Writes the message header
#
# @param string $name Function name
# @param int $type message type TMessageType::CALL or TMessageType::REPLY
# @param int $seqid The sequence id of this message
#
sub writeMessageBegin
{
my ($name, $type, $seqid);
die "abstract";
}
#
# Close the message
#
sub writeMessageEnd {
die "abstract";
}
#
# Writes a struct header.
#
# @param string $name Struct name
# @throws TException on write error
# @return int How many bytes written
#
sub writeStructBegin {
my ($name);
die "abstract";
}
#
# Close a struct.
#
# @throws TException on write error
# @return int How many bytes written
#
sub writeStructEnd {
die "abstract";
}
#
# Starts a field.
#
# @param string $name Field name
# @param int $type Field type
# @param int $fid Field id
# @throws TException on write error
# @return int How many bytes written
#
sub writeFieldBegin {
my ($fieldName, $fieldType, $fieldId);
die "abstract";
}
sub writeFieldEnd {
die "abstract";
}
sub writeFieldStop {
die "abstract";
}
sub writeMapBegin {
my ($keyType, $valType, $size);
die "abstract";
}
sub writeMapEnd {
die "abstract";
}
sub writeListBegin {
my ($elemType, $size);
die "abstract";
}
sub writeListEnd {
die "abstract";
}
sub writeSetBegin {
my ($elemType, $size);
die "abstract";
}
sub writeSetEnd {
die "abstract";
}
sub writeBool {
my ($bool);
die "abstract";
}
sub writeByte {
my ($byte);
die "abstract";
}
sub writeI16 {
my ($i16);
die "abstract";
}
sub writeI32 {
my ($i32);
die "abstract";
}
sub writeI64 {
my ($i64);
die "abstract";
}
sub writeDouble {
my ($dub);
die "abstract";
}
sub writeString
{
my ($str);
die "abstract";
}
#
# Reads the message header
#
# @param string $name Function name
# @param int $type message type TMessageType::CALL or TMessageType::REPLY
# @parem int $seqid The sequence id of this message
#
sub readMessageBegin
{
my ($name, $type, $seqid);
die "abstract";
}
#
# Read the close of message
#
sub readMessageEnd
{
die "abstract";
}
sub readStructBegin
{
my($name);
die "abstract";
}
sub readStructEnd
{
die "abstract";
}
sub readFieldBegin
{
my ($name, $fieldType, $fieldId);
die "abstract";
}
sub readFieldEnd
{
die "abstract";
}
sub readMapBegin
{
my ($keyType, $valType, $size);
die "abstract";
}
sub readMapEnd
{
die "abstract";
}
sub readListBegin
{
my ($elemType, $size);
die "abstract";
}
sub readListEnd
{
die "abstract";
}
sub readSetBegin
{
my ($elemType, $size);
die "abstract";
}
sub readSetEnd
{
die "abstract";
}
sub readBool
{
my ($bool);
die "abstract";
}
sub readByte
{
my ($byte);
die "abstract";
}
sub readI16
{
my ($i16);
die "abstract";
}
sub readI32
{
my ($i32);
die "abstract";
}
sub readI64
{
my ($i64);
die "abstract";
}
sub readDouble
{
my ($dub);
die "abstract";
}
sub readString
{
my ($str);
die "abstract";
}
#
# The skip function is a utility to parse over unrecognized data without
# causing corruption.
#
# @param TType $type What type is it
#
sub skip
{
my $self = shift;
my $type = shift;
my $ref;
my $result;
my $i;
if($type == TType::BOOL)
{
return $self->readBool(\$ref);
}
elsif($type == TType::BYTE){
return $self->readByte(\$ref);
}
elsif($type == TType::I16){
return $self->readI16(\$ref);
}
elsif($type == TType::I32){
return $self->readI32(\$ref);
}
elsif($type == TType::I64){
return $self->readI64(\$ref);
}
elsif($type == TType::DOUBLE){
return $self->readDouble(\$ref);
}
elsif($type == TType::STRING)
{
return $self->readString(\$ref);
}
elsif($type == TType::STRUCT)
{
$result = $self->readStructBegin(\$ref);
while (1) {
my ($ftype,$fid);
$result += $self->readFieldBegin(\$ref, \$ftype, \$fid);
if ($ftype == TType::STOP) {
last;
}
$result += $self->skip($ftype);
$result += $self->readFieldEnd();
}
$result += $self->readStructEnd();
return $result;
}
elsif($type == TType::MAP)
{
my($keyType,$valType,$size);
$result = $self->readMapBegin(\$keyType, \$valType, \$size);
for ($i = 0; $i < $size; $i++) {
$result += $self->skip($keyType);
$result += $self->skip($valType);
}
$result += $self->readMapEnd();
return $result;
}
elsif($type == TType::SET)
{
my ($elemType,$size);
$result = $self->readSetBegin(\$elemType, \$size);
for ($i = 0; $i < $size; $i++) {
$result += $self->skip($elemType);
}
$result += $self->readSetEnd();
return $result;
}
elsif($type == TType::LIST)
{
my ($elemType,$size);
$result = $self->readListBegin(\$elemType, \$size);
for ($i = 0; $i < $size; $i++) {
$result += $self->skip($elemType);
}
$result += $self->readListEnd();
return $result;
}
die new Thrift::TException("Type $type not recognised --- corrupt data?");
}
#
# Utility for skipping binary data
#
# @param TTransport $itrans TTransport object
# @param int $type Field type
#
sub skipBinary
{
my $self = shift;
my $itrans = shift;
my $type = shift;
if($type == TType::BOOL)
{
return $itrans->readAll(1);
}
elsif($type == TType::BYTE)
{
return $itrans->readAll(1);
}
elsif($type == TType::I16)
{
return $itrans->readAll(2);
}
elsif($type == TType::I32)
{
return $itrans->readAll(4);
}
elsif($type == TType::I64)
{
return $itrans->readAll(8);
}
elsif($type == TType::DOUBLE)
{
return $itrans->readAll(8);
}
elsif( $type == TType::STRING )
{
my @len = unpack('N', $itrans->readAll(4));
my $len = $len[0];
if ($len > 0x7fffffff) {
$len = 0 - (($len - 1) ^ 0xffffffff);
}
return 4 + $itrans->readAll($len);
}
elsif( $type == TType::STRUCT )
{
my $result = 0;
while (1) {
my $ftype = 0;
my $fid = 0;
my $data = $itrans->readAll(1);
my @arr = unpack('c', $data);
$ftype = $arr[0];
if ($ftype == TType::STOP) {
last;
}
# I16 field id
$result += $itrans->readAll(2);
$result += $self->skipBinary($itrans, $ftype);
}
return $result;
}
elsif($type == TType::MAP)
{
# Ktype
my $data = $itrans->readAll(1);
my @arr = unpack('c', $data);
my $ktype = $arr[0];
# Vtype
$data = $itrans->readAll(1);
@arr = unpack('c', $data);
my $vtype = $arr[0];
# Size
$data = $itrans->readAll(4);
@arr = unpack('N', $data);
my $size = $arr[0];
if ($size > 0x7fffffff) {
$size = 0 - (($size - 1) ^ 0xffffffff);
}
my $result = 6;
for (my $i = 0; $i < $size; $i++) {
$result += $self->skipBinary($itrans, $ktype);
$result += $self->skipBinary($itrans, $vtype);
}
return $result;
}
elsif($type == TType::SET || $type == TType::LIST)
{
# Vtype
my $data = $itrans->readAll(1);
my @arr = unpack('c', $data);
my $vtype = $arr[0];
# Size
$data = $itrans->readAll(4);
@arr = unpack('N', $data);
my $size = $arr[0];
if ($size > 0x7fffffff) {
$size = 0 - (($size - 1) ^ 0xffffffff);
}
my $result = 5;
for (my $i = 0; $i < $size; $i++) {
$result += $self->skipBinary($itrans, $vtype);
}
return $result;
}
die new Thrift::TException("Type $type not recognised --- corrupt data?");
}
#
# Protocol factory creates protocol objects from transports
#
package TProtocolFactory;
sub new {
my $classname = shift;
my $self = {};
return bless($self,$classname);
}
#
# Build a protocol from the base transport
#
# @return TProtcol protocol
#
sub getProtocol
{
my ($trans);
die "interface";
}
1;

View file

@ -0,0 +1,360 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
use strict;
use warnings;
use Thrift::Protocol;
package Thrift::ProtocolDecorator;
use base qw(Thrift::Protocol);
sub new {
my $classname = shift;
my $protocol = shift;
my $self = $classname->SUPER::new($protocol->getTransport());
$self->{concreteProtocol} = $protocol;
return bless($self,$classname);
}
#
# Writes the message header
#
# @param string $name Function name
# @param int $type message type TMessageType::CALL or TMessageType::REPLY
# @param int $seqid The sequence id of this message
#
sub writeMessageBegin {
my $self = shift;
my ($name, $type, $seqid) = @_;
return $self->{concreteProtocol}->writeMessageBegin($name, $type, $seqid);
}
#
# Close the message
#
sub writeMessageEnd {
my $self = shift;
return $self->{concreteProtocol}->writeMessageEnd();
}
#
# Writes a struct header.
#
# @param string $name Struct name
# @throws TException on write error
# @return int How many bytes written
#
sub writeStructBegin {
my $self = shift;
my ($name) = @_;
return $self->{concreteProtocol}->writeStructBegin($name);
}
#
# Close a struct.
#
# @throws TException on write error
# @return int How many bytes written
#
sub writeStructEnd {
my $self = shift;
return $self->{concreteProtocol}->writeStructEnd();
}
#
# Starts a field.
#
# @param string $name Field name
# @param int $type Field type
# @param int $fid Field id
# @throws TException on write error
# @return int How many bytes written
#
sub writeFieldBegin {
my $self = shift;
my ($fieldName, $fieldType, $fieldId) = @_;
return $self->{concreteProtocol}->writeFieldBegin($fieldName, $fieldType, $fieldId);
}
sub writeFieldEnd {
my $self = shift;
return $self->{concreteProtocol}->writeFieldEnd();
}
sub writeFieldStop {
my $self = shift;
return $self->{concreteProtocol}->writeFieldStop();
}
sub writeMapBegin {
my $self = shift;
my ($keyType, $valType, $size) = @_;
return $self->{concreteProtocol}->writeMapBegin($keyType, $valType, $size);
}
sub writeMapEnd {
my $self = shift;
return $self->{concreteProtocol}->writeMapEnd();
}
sub writeListBegin {
my $self = shift;
my ($elemType, $size) = @_;
return $self->{concreteProtocol}->writeListBegin($elemType, $size);
}
sub writeListEnd {
my $self = shift;
return $self->{concreteProtocol}->writeListEnd();
}
sub writeSetBegin {
my $self = shift;
my ($elemType, $size) = @_;
return $self->{concreteProtocol}->writeSetBegin($elemType, $size);
}
sub writeSetEnd {
my $self = shift;
return $self->{concreteProtocol}->writeListEnd();
}
sub writeBool {
my $self = shift;
my $bool = shift;
return $self->{concreteProtocol}->writeBool($bool);
}
sub writeByte {
my $self = shift;
my $byte = shift;
return $self->{concreteProtocol}->writeByte($byte);
}
sub writeI16 {
my $self = shift;
my $i16 = shift;
return $self->{concreteProtocol}->writeI16($i16);
}
sub writeI32 {
my $self = shift;
my ($i32) = @_;
return $self->{concreteProtocol}->writeI32($i32);
}
sub writeI64 {
my $self = shift;
my $i64 = shift;
return $self->{concreteProtocol}->writeI64($i64);
}
sub writeDouble {
my $self = shift;
my $dub = shift;
return $self->{concreteProtocol}->writeDouble($dub);
}
sub writeString {
my $self = shift;
my $str = shift;
return $self->{concreteProtocol}->writeString($str);
}
#
# Reads the message header
#
# @param string $name Function name
# @param int $type message type TMessageType::CALL or TMessageType::REPLY
# @parem int $seqid The sequence id of this message
#
sub readMessageBegin
{
my $self = shift;
my ($name, $type, $seqid) = @_;
return $self->{concreteProtocol}->readMessageBegin($name, $type, $seqid);
}
#
# Read the close of message
#
sub readMessageEnd
{
my $self = shift;
return $self->{concreteProtocol}->readMessageEnd();
}
sub readStructBegin
{
my $self = shift;
my $name = shift;
return $self->{concreteProtocol}->readStructBegin($name);
}
sub readStructEnd
{
my $self = shift;
return $self->{concreteProtocol}->readStructEnd();
}
sub readFieldBegin
{
my $self = shift;
my ($name, $fieldType, $fieldId) = @_;
return $self->{concreteProtocol}->readFieldBegin($name, $fieldType, $fieldId);
}
sub readFieldEnd
{
my $self = shift;
return $self->{concreteProtocol}->readFieldEnd();
}
sub readMapBegin
{
my $self = shift;
my ($keyType, $valType, $size) = @_;
return $self->{concreteProtocol}->readMapBegin($keyType, $valType, $size);
}
sub readMapEnd
{
my $self = shift;
return $self->{concreteProtocol}->readMapEnd();
}
sub readListBegin
{
my $self = shift;
my ($elemType, $size) = @_;
return $self->{concreteProtocol}->readListBegin($elemType, $size);
}
sub readListEnd
{
my $self = shift;
return $self->{concreteProtocol}->readListEnd();
}
sub readSetBegin
{
my $self = shift;
my ($elemType, $size) = @_;
return $self->{concreteProtocol}->readSetBegin($elemType, $size);
}
sub readSetEnd
{
my $self = shift;
return $self->{concreteProtocol}->readSetEnd();
}
sub readBool
{
my $self = shift;
my $bool = shift;
return $self->{concreteProtocol}->readBool($bool);
}
sub readByte
{
my $self = shift;
my $byte = shift;
return $self->{concreteProtocol}->readByte($byte);
}
sub readI16
{
my $self = shift;
my $i16 = shift;
return $self->{concreteProtocol}->readI16($i16);
}
sub readI32
{
my $self = shift;
my $i32 = shift;
return $self->{concreteProtocol}->readI32($i32);
}
sub readI64
{
my $self = shift;
my $i64 = shift;
return $self->{concreteProtocol}->readI64($i64);
}
sub readDouble
{
my $self = shift;
my $dub = shift;
return $self->{concreteProtocol}->readDouble($dub);
}
sub readString
{
my $self = shift;
my $str = shift;
return $self->{concreteProtocol}->readString($str);
}
1;

View file

@ -0,0 +1,68 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
use Thrift::SSLSocket;
use IO::Socket::SSL;
use IO::Select;
package Thrift::SSLServerSocket;
use base qw( Thrift::ServerSocket );
#
# Constructor.
# Takes a hash:
# See Thirft::Socket for base class parameters.
# @param[in] ca certificate authority filename - not required
# @param[in] cert certificate filename; may contain key in which case key is not required
# @param[in] key private key filename for the certificate if it is not inside the cert file
#
sub new
{
my $classname = shift;
my $self = $classname->SUPER::new(@_);
return bless($self, $classname);
}
sub __client
{
return new Thrift::SSLSocket();
}
sub __listen
{
my $self = shift;
return IO::Socket::SSL->new(LocalAddr => $self->{host},
LocalPort => $self->{port},
Proto => 'tcp',
Listen => $self->{queue},
ReuseAddr => 1,
SSL_cert_file => $self->{cert},
SSL_key_file => $self->{key},
SSL_ca_file => $self->{ca});
}
1;

View file

@ -0,0 +1,93 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
use Thrift::Transport;
use IO::Socket::SSL;
use IO::Select;
package Thrift::SSLSocket;
# TODO: Does not provide cipher selection or authentication hooks yet.
use base qw( Thrift::Socket );
sub new
{
my $classname = shift;
my $self = $classname->SUPER::new(@_);
return bless($self, $classname);
}
sub __open
{
my $self = shift;
return IO::Socket::SSL->new(PeerAddr => $self->{host},
PeerPort => $self->{port},
Proto => 'tcp',
Timeout => $self->{sendTimeout} / 1000);
}
sub __close
{
my $self = shift;
my $sock = ($self->{handle}->handles())[0];
if ($sock) {
$sock->close(SSL_no_shutdown => 1);
}
}
sub __recv
{
my $self = shift;
my $sock = shift;
my $len = shift;
my $buf = undef;
if ($sock) {
sysread($sock, $buf, $len);
}
return $buf;
}
sub __send
{
my $self = shift;
my $sock = shift;
my $buf = shift;
return syswrite($sock, $buf);
}
sub __wait
{
my $self = shift;
my $sock = ($self->{handle}->handles())[0];
if ($sock and $sock->pending() eq 0) {
return $self->SUPER::__wait();
}
return $sock;
}
1;

View file

@ -0,0 +1,315 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
use Thrift::BufferedTransport;
use Thrift::BinaryProtocol;
#
# Server base class module
#
package Thrift::Server;
# 3 possible constructors:
# 1. (processor, serverTransport)
# 2. (processor, serverTransport, transportFactory, protocolFactory)
# 3. (processor, serverTransport,
# inputTransportFactory, outputTransportFactory,
# inputProtocolFactory, outputProtocolFactory)
sub new
{
my $classname = shift;
my @args = @_;
my $self;
if (scalar @args == 2)
{
$self = _init($args[0], $args[1],
Thrift::BufferedTransportFactory->new(),
Thrift::BufferedTransportFactory->new(),
Thrift::BinaryProtocolFactory->new(),
Thrift::BinaryProtocolFactory->new());
}
elsif (scalar @args == 4)
{
$self = _init($args[0], $args[1], $args[2], $args[2], $args[3], $args[3]);
}
elsif (scalar @args == 6)
{
$self = _init($args[0], $args[1], $args[2], $args[3], $args[4], $args[5]);
}
else
{
die "Thrift::Server expects exactly 2, 4, or 6 args";
}
return bless($self,$classname);
}
sub _init
{
my $processor = shift;
my $serverTransport = shift;
my $inputTransportFactory = shift;
my $outputTransportFactory = shift;
my $inputProtocolFactory = shift;
my $outputProtocolFactory = shift;
my $self = {
processor => $processor,
serverTransport => $serverTransport,
inputTransportFactory => $inputTransportFactory,
outputTransportFactory => $outputTransportFactory,
inputProtocolFactory => $inputProtocolFactory,
outputProtocolFactory => $outputProtocolFactory,
};
}
sub serve
{
die "abstract";
}
sub _clientBegin
{
my $self = shift;
my $iprot = shift;
my $oprot = shift;
if (exists $self->{serverEventHandler} and
defined $self->{serverEventHandler})
{
$self->{serverEventHandler}->clientBegin($iprot, $oprot);
}
}
sub _handleException
{
my $self = shift;
my $e = shift;
if ($e =~ m/TException/ and exists $e->{message}) {
my $message = $e->{message};
my $code = $e->{code};
my $out = $code . ':' . $message;
$message =~ m/TTransportException/ and die $out;
if ($message =~ m/Socket/) {
# suppress Socket messages
} else {
warn $out;
}
} else {
warn $e;
}
}
#
# SimpleServer from the Server base class that handles one connection at a time
#
package Thrift::SimpleServer;
use base qw( Thrift::Server );
sub new
{
my $classname = shift;
my @args = @_;
my $self = $classname->SUPER::new(@args);
return bless($self,$classname);
}
sub serve
{
my $self = shift;
$self->{serverTransport}->listen();
while (1)
{
my $client = $self->{serverTransport}->accept();
my $itrans = $self->{inputTransportFactory}->getTransport($client);
my $otrans = $self->{outputTransportFactory}->getTransport($client);
my $iprot = $self->{inputProtocolFactory}->getProtocol($itrans);
my $oprot = $self->{outputProtocolFactory}->getProtocol($otrans);
eval {
$self->_clientBegin($iprot, $oprot);
while (1)
{
$self->{processor}->process($iprot, $oprot);
}
}; if($@) {
$self->_handleException($@);
}
$itrans->close();
$otrans->close();
}
}
#
# ForkingServer that forks a new process for each request
#
package Thrift::ForkingServer;
use base qw( Thrift::Server );
use POSIX ":sys_wait_h";
sub new
{
my $classname = shift;
my @args = @_;
my $self = $classname->SUPER::new(@args);
return bless($self,$classname);
}
sub serve
{
my $self = shift;
# THRIFT-3848: without ignoring SIGCHLD, perl ForkingServer goes into a tight loop
$SIG{CHLD} = 'IGNORE';
$self->{serverTransport}->listen();
while (1)
{
my $client = $self->{serverTransport}->accept();
$self->_client($client);
}
}
sub _client
{
my $self = shift;
my $client = shift;
eval {
my $itrans = $self->{inputTransportFactory}->getTransport($client);
my $otrans = $self->{outputTransportFactory}->getTransport($client);
my $iprot = $self->{inputProtocolFactory}->getProtocol($itrans);
my $oprot = $self->{outputProtocolFactory}->getProtocol($otrans);
$self->_clientBegin($iprot, $oprot);
my $pid = fork();
if ($pid) #parent
{
$self->_parent($pid, $itrans, $otrans);
} else {
$self->_child($itrans, $otrans, $iprot, $oprot);
}
}; if($@) {
$self->_handleException($@);
}
}
sub _parent
{
my $self = shift;
my $pid = shift;
my $itrans = shift;
my $otrans = shift;
# add before collect, otherwise you race w/ waitpid
$self->{children}->{$pid} = 1;
$self->_collectChildren();
# Parent must close socket or the connection may not get closed promptly
$self->tryClose($itrans);
$self->tryClose($otrans);
}
sub _child
{
my $self = shift;
my $itrans = shift;
my $otrans = shift;
my $iprot = shift;
my $oprot = shift;
my $ecode = 0;
eval {
while (1)
{
$self->{processor}->process($iprot, $oprot);
}
}; if($@) {
$ecode = 1;
$self->_handleException($@);
}
$self->tryClose($itrans);
$self->tryClose($otrans);
exit($ecode);
}
sub tryClose
{
my $self = shift;
my $file = shift;
eval {
if (defined $file)
{
$file->close();
}
}; if($@) {
if ($@ =~ m/TException/ and exists $@->{message}) {
my $message = $@->{message};
my $code = $@->{code};
my $out = $code . ':' . $message;
warn $out;
} else {
warn $@;
}
}
}
sub _collectChildren
{
my $self = shift;
while (scalar keys %{$self->{children}})
{
my $pid = waitpid(-1, WNOHANG);
if ($pid>0)
{
delete $self->{children}->{$pid};
}
else
{
last;
}
}
}
1;

View file

@ -0,0 +1,114 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use IO::Socket::INET;
use IO::Select;
use Thrift;
use Thrift::Socket;
package Thrift::ServerSocket;
use base qw( Thrift::ServerTransport );
#
# Constructor.
# Legacy construction takes one argument, port number.
# New construction takes a hash:
# @param[in] host host interface to listen on (undef = all interfaces)
# @param[in] port port number to listen on (required)
# @param[in] queue the listen queue size (default if not specified is 128)
# @example my $serversock = new Thrift::ServerSocket(host => undef, port => port)
#
sub new
{
my $classname = shift;
my $args = shift;
my $self;
# Support both old-style "port number" construction and newer...
if (ref($args) eq 'HASH') {
$self = $args;
} else {
$self = { port => $args };
}
if (not defined $self->{queue}) {
$self->{queue} = 128;
}
return bless($self, $classname);
}
sub listen
{
my $self = shift;
my $sock = $self->__listen() || do {
my $error = ref($self) . ': Could not bind to ' . '*:' . $self->{port} . ' (' . $! . ')';
if ($self->{debug}) {
$self->{debugHandler}->($error);
}
die new Thrift::TException($error);
};
$self->{handle} = $sock;
}
sub accept
{
my $self = shift;
if ( exists $self->{handle} and defined $self->{handle} )
{
my $client = $self->{handle}->accept();
my $result = $self->__client();
$result->{handle} = new IO::Select($client);
return $result;
}
return 0;
}
###
### Overridable methods
###
sub __client
{
return new Thrift::Socket();
}
sub __listen
{
my $self = shift;
return IO::Socket::INET->new(LocalAddr => $self->{host},
LocalPort => $self->{port},
Proto => 'tcp',
Listen => $self->{queue},
ReuseAddr => 1);
}
1;

View file

@ -0,0 +1,317 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
use Thrift::Transport;
use IO::Socket::INET;
use IO::Select;
package Thrift::Socket;
use base qw( Thrift::Transport );
sub new
{
my $classname = shift;
my $host = shift || "localhost";
my $port = shift || 9090;
my $debugHandler = shift;
my $self = {
host => $host,
port => $port,
debugHandler => $debugHandler,
debug => 0,
sendTimeout => 10000,
recvTimeout => 10000,
handle => undef,
};
return bless($self,$classname);
}
sub setSendTimeout
{
my $self = shift;
my $timeout = shift;
$self->{sendTimeout} = $timeout;
}
sub setRecvTimeout
{
my $self = shift;
my $timeout = shift;
$self->{recvTimeout} = $timeout;
}
#
#Sets debugging output on or off
#
# @param bool $debug
#
sub setDebug
{
my $self = shift;
my $debug = shift;
$self->{debug} = $debug;
}
#
# Tests whether this is open
#
# @return bool true if the socket is open
#
sub isOpen
{
my $self = shift;
if( defined $self->{handle} ){
return ($self->{handle}->handles())[0]->connected;
}
return 0;
}
#
# Connects the socket.
#
sub open
{
my $self = shift;
my $sock = $self->__open() || do {
my $error = ref($self).': Could not connect to '.$self->{host}.':'.$self->{port}.' ('.$!.')';
if ($self->{debug}) {
$self->{debugHandler}->($error);
}
die new Thrift::TException($error);
};
$self->{handle} = new IO::Select( $sock );
}
#
# Closes the socket.
#
sub close
{
my $self = shift;
if( defined $self->{handle} ) {
$self->__close();
}
}
#
# Uses stream get contents to do the reading
#
# @param int $len How many bytes
# @return string Binary data
#
sub readAll
{
my $self = shift;
my $len = shift;
return unless defined $self->{handle};
my $pre = "";
while (1) {
my $sock = $self->__wait();
my $buf = $self->__recv($sock, $len);
if (!defined $buf || $buf eq '') {
die new Thrift::TException(ref($self).': Could not read '.$len.' bytes from '.
$self->{host}.':'.$self->{port});
} elsif ((my $sz = length($buf)) < $len) {
$pre .= $buf;
$len -= $sz;
} else {
return $pre.$buf;
}
}
}
#
# Read from the socket
#
# @param int $len How many bytes
# @return string Binary data
#
sub read
{
my $self = shift;
my $len = shift;
return unless defined $self->{handle};
my $sock = $self->__wait();
my $buf = $self->__recv($sock, $len);
if (!defined $buf || $buf eq '') {
die new TException(ref($self).': Could not read '.$len.' bytes from '.
$self->{host}.':'.$self->{port});
}
return $buf;
}
#
# Write to the socket.
#
# @param string $buf The data to write
#
sub write
{
my $self = shift;
my $buf = shift;
return unless defined $self->{handle};
while (length($buf) > 0) {
#check for timeout
my @sockets = $self->{handle}->can_write( $self->{sendTimeout} / 1000 );
if(@sockets == 0){
die new Thrift::TException(ref($self).': timed out writing to bytes from '.
$self->{host}.':'.$self->{port});
}
my $sent = $self->__send($sockets[0], $buf);
if (!defined $sent || $sent == 0 ) {
die new Thrift::TException(ref($self).': Could not write '.length($buf).' bytes '.
$self->{host}.':'.$self->{host});
}
$buf = substr($buf, $sent);
}
}
#
# Flush output to the socket.
#
sub flush
{
my $self = shift;
return unless defined $self->{handle};
my $ret = ($self->{handle}->handles())[0]->flush;
}
###
### Overridable methods
###
#
# Open a connection to a server.
#
sub __open
{
my $self = shift;
return IO::Socket::INET->new(PeerAddr => $self->{host},
PeerPort => $self->{port},
Proto => 'tcp',
Timeout => $self->{sendTimeout} / 1000);
}
#
# Close the connection
#
sub __close
{
my $self = shift;
CORE::close(($self->{handle}->handles())[0]);
}
#
# Read data
#
# @param[in] $sock the socket
# @param[in] $len the length to read
# @returns the data buffer that was read
#
sub __recv
{
my $self = shift;
my $sock = shift;
my $len = shift;
my $buf = undef;
$sock->recv($buf, $len);
return $buf;
}
#
# Send data
#
# @param[in] $sock the socket
# @param[in] $buf the data buffer
# @returns the number of bytes written
#
sub __send
{
my $self = shift;
my $sock = shift;
my $buf = shift;
return $sock->send($buf);
}
#
# Wait for data to be readable
#
# @returns a socket that can be read
#
sub __wait
{
my $self = shift;
my @sockets = $self->{handle}->can_read( $self->{recvTimeout} / 1000 );
if (@sockets == 0) {
die new Thrift::TException(ref($self).': timed out reading from '.
$self->{host}.':'.$self->{port});
}
return $sockets[0];
}
1;

View file

@ -0,0 +1,177 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
#
# Transport exceptions
#
package TTransportException;
use base('Thrift::TException');
use constant UNKNOWN => 0;
use constant NOT_OPEN => 1;
use constant ALREADY_OPEN => 2;
use constant TIMED_OUT => 3;
use constant END_OF_FILE => 4;
sub new{
my $classname = shift;
my $self = $classname->SUPER::new(@_);
return bless($self,$classname);
}
package Thrift::Transport;
#
# Whether this transport is open.
#
# @return boolean true if open
#
sub isOpen
{
die "abstract";
}
#
# Open the transport for reading/writing
#
# @throws TTransportException if cannot open
#
sub open
{
die "abstract";
}
#
# Close the transport.
#
sub close
{
die "abstract";
}
#
# Read some data into the array.
#
# @param int $len How much to read
# @return string The data that has been read
# @throws TTransportException if cannot read any more data
#
sub read
{
my ($len);
die("abstract");
}
#
# Guarantees that the full amount of data is read.
#
# @return string The data, of exact length
# @throws TTransportException if cannot read data
#
sub readAll
{
my $self = shift;
my $len = shift;
my $data = '';
my $got = 0;
while (($got = length($data)) < $len) {
$data .= $self->read($len - $got);
}
return $data;
}
#
# Writes the given data out.
#
# @param string $buf The data to write
# @throws TTransportException if writing fails
#
sub write
{
my ($buf);
die "abstract";
}
#
# Flushes any pending data out of a buffer
#
# @throws TTransportException if a writing error occurs
#
sub flush {}
#
# TransportFactory creates transport objects from transports
#
package Thrift::TransportFactory;
sub new {
my $classname = shift;
my $self = {};
return bless($self,$classname);
}
#
# Build a transport from the base transport
#
# @return Thrift::Transport transport
#
sub getTransport
{
my $self = shift;
my $trans = shift;
return $trans;
}
#
# ServerTransport base class module
#
package Thrift::ServerTransport;
sub listen
{
die "abstract";
}
sub accept
{
die "abstract";
}
sub close
{
die "abstract";
}
1;

View file

@ -0,0 +1,84 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
use Thrift::UnixSocket;
use IO::Socket::UNIX;
use IO::Select;
package Thrift::UnixServerSocket;
use base qw( Thrift::ServerSocket );
#
# Constructor.
# If a single argument is given that is not a hash, that is the unix domain socket path.
# If a single argument is given that is a hash:
# @param[in] path unix domain socket file name
# @param[in] queue the listen queue size (default is not specified is supplied by ServerSocket)
# @example my $serversock = new Thrift::UnixServerSocket($path);
# @example my $serversock = new Thrift::UnixServerSocket(path => "somepath", queue => 64);
#
sub new
{
my $classname = shift;
my $args = shift;
my $self;
if (ref($args) eq 'HASH') {
$self = $classname->SUPER::new($args);
} else {
$self = $classname->SUPER::new();
$self->{path} = $args;
}
return bless($self, $classname);
}
sub __client
{
return new Thrift::UnixSocket();
}
sub __listen
{
my $self = shift;
my $sock = IO::Socket::UNIX->new(
Type => IO::Socket::SOCK_STREAM,
Local => $self->{path},
Listen => $self->{queue})
|| do {
my $error = 'UnixServerSocket: Could not bind to ' .
$self->{path} . ' (' . $! . ')';
if ($self->{debug}) {
$self->{debugHandler}->($error);
}
die new Thrift::TException($error);
};
return $sock;
}
1;

View file

@ -0,0 +1,68 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require 5.6.0;
use strict;
use warnings;
use Thrift;
use Thrift::Transport;
use IO::Socket::UNIX;
use IO::Select;
package Thrift::UnixSocket;
use base qw( Thrift::Socket );
#
# Constructor.
# Takes a unix domain socket filename.
# See Thirft::Socket for base class parameters.
# @param[in] path path to unix socket file
# @example my $sock = new Thrift::UnixSocket($path);
#
sub new
{
my $classname = shift;
my $self = $classname->SUPER::new();
$self->{path} = shift;
return bless($self, $classname);
}
sub __open
{
my $self = shift;
my $sock = IO::Socket::UNIX->new(
Type => IO::Socket::SOCK_STREAM,
Peer => $self->{path})
|| do {
my $error = 'UnixSocket: Could not connect to ' .
$self->{path} . ' (' . $! . ')';
if ($self->{debug}) {
$self->{debugHandler}->($error);
}
die new Thrift::TException($error);
};
return $sock;
}
1;