| # |
| # 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 5.10.0; |
| use strict; |
| use warnings; |
| |
| use HTTP::Request; |
| use IO::String; |
| use LWP::UserAgent; |
| use Thrift; |
| use Thrift::Exception; |
| use Thrift::Transport; |
| |
| package Thrift::HttpClient; |
| use base('Thrift::Transport'); |
| use version 0.77; our $VERSION = version->declare("$Thrift::VERSION"); |
| |
| sub new |
| { |
| my $classname = shift; |
| my $url = shift || 'http://localhost:9090'; |
| |
| my $out = IO::String->new; |
| binmode($out); |
| |
| my $self = { |
| url => $url, |
| out => $out, |
| timeout => 100, |
| handle => undef, |
| headers => {}, |
| }; |
| |
| return bless($self,$classname); |
| } |
| |
| sub setTimeout |
| { |
| my $self = shift; |
| my $timeout = shift; |
| |
| $self->{timeout} = $timeout; |
| } |
| |
| sub setRecvTimeout |
| { |
| warn 'setRecvTimeout is deprecated - use setTimeout instead'; |
| # note: recvTimeout was never used so we do not need to do anything here |
| } |
| |
| sub setSendTimeout |
| { |
| my $self = shift; |
| my $timeout = shift; |
| |
| warn 'setSendTimeout is deprecated - use setTimeout instead'; |
| |
| $self->setTimeout($timeout); |
| } |
| |
| sub setHeader |
| { |
| my $self = shift; |
| my ($name, $value) = @_; |
| |
| $self->{headers}->{$name} = $value; |
| } |
| |
| # |
| # 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 Thrift::TTransportException->new("TSocket: Could not read $len bytes from input buffer", |
| Thrift::TTransportException::END_OF_FILE); |
| } |
| return $buf; |
| } |
| |
| # |
| # Read and return string |
| # |
| sub read |
| { |
| my $self = shift; |
| my $len = shift; |
| |
| my $buf; |
| |
| my $in = $self->{in}; |
| |
| if (!defined($in)) { |
| die Thrift::TTransportException->new('Response buffer is empty, no request.', |
| Thrift::TTransportException::END_OF_FILE); |
| } |
| eval { |
| my $ret = sysread($in, $buf, $len); |
| if (! defined($ret)) { |
| die Thrift::TTransportException->new('No more data available.', |
| Thrift::TTransportException::TIMED_OUT); |
| } |
| }; |
| if($@){ |
| die Thrift::TTransportException->new("$@", Thrift::TTransportException::UNKNOWN); |
| } |
| |
| 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->{timeout} / 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 = HTTP::Request->new(POST => $self->{url}, undef, $buf); |
| map { $request->header($_ => $self->{headers}->{$_}) } keys %{$self->{headers}}; |
| 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; |