Skip to content

Commit

Permalink
THRIFT-4841 THTTPTransport relies on activeX component
Browse files Browse the repository at this point in the history
Client: Delphi
Patch: Jens Geyer

This closes #1778
  • Loading branch information
Jens-G committed Apr 6, 2019
1 parent c9b1e29 commit 0223091
Show file tree
Hide file tree
Showing 20 changed files with 1,473 additions and 242 deletions.
9 changes: 4 additions & 5 deletions CHANGES.md
Expand Up @@ -6,14 +6,12 @@

### Deprecated Languages

- [THRIFT-4723](https://issues.apache.org/jira/browse/THRIFT-4723) - CSharp and Netcore targets are deprecated and will be removed with the next release - use NetStd instead.

### Removed Languages

- [THRIFT-4719](https://issues.apache.org/jira/browse/THRIFT-4719) - Cocoa language was removed - use swift instead.

### Deprecated Languages

- [THRIFT-4723](https://issues.apache.org/jira/browse/THRIFT-4723) - CSharp and Netcore targets are deprecated and will be removed with the next release - use NetStd instead.

### Breaking Changes

- [THRIFT-4743](https://issues.apache.org/jira/browse/THRIFT-4743) - compiler: removed the plug-in mechanism
Expand All @@ -22,12 +20,13 @@
- [THRIFT-4732](https://issues.apache.org/jira/browse/THRIFT-4732) - cpp: CMake build changed to use BUILD_SHARED_LIBS
- [THRIFT-4735](https://issues.apache.org/jira/browse/THRIFT-4735) - cpp: Removed Qt4 support
- [THRIFT-4740](https://issues.apache.org/jira/browse/THRIFT-4740) - cpp: Use std::chrono::duration for timeouts
- [THRIFT-4672](https://issues.apache.org/jira/browse/THRIFT-4672) - cpp: TTransport::getOrigin() is now const
- [THRIFT-4762](https://issues.apache.org/jira/browse/THRIFT-4762) - cpp: TTransport::getOrigin() is now const
- [THRIFT-4702](https://issues.apache.org/jira/browse/THRIFT-4702) - java: class org.apache.thrift.AutoExpandingBuffer is no longer public
- [THRIFT-4709](https://issues.apache.org/jira/browse/THRIFT-4709) - java: changes to UTF-8 handling require JDK 1.7 at a minimum
- [THRIFT-4712](https://issues.apache.org/jira/browse/THRIFT-4712) - java: class org.apache.thrift.ShortStack is no longer public
- [THRIFT-4725](https://issues.apache.org/jira/browse/THRIFT-4725) - java: change return type signature of 'process' methods
- [THRIFT-4675](https://issues.apache.org/jira/browse/THRIFT-4675) - js: now uses node-int64 for 64 bit integer constants
- [THRIFT-4841](https://issues.apache.org/jira/browse/THRIFT-4841) - delphi: old THTTPTransport is now TMsxmlHTTPTransport

### Known Issues (Blocker or Critical)

Expand Down
255 changes: 255 additions & 0 deletions lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas
@@ -0,0 +1,255 @@
(*
* 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.
*)
unit Thrift.Transport.MsxmlHTTP;

{$I Thrift.Defines.inc}
{$SCOPEDENUMS ON}

interface

uses
Classes,
SysUtils,
Math,
Generics.Collections,
{$IFDEF OLD_UNIT_NAMES}
ActiveX, msxml,
{$ELSE}
Winapi.ActiveX, Winapi.msxml,
{$ENDIF}
Thrift.Collections,
Thrift.Transport,
Thrift.Exception,
Thrift.Utils,
Thrift.Stream;

type
TMsxmlHTTPClientImpl = class( TTransportImpl, IHTTPClient)
private
FUri : string;
FInputStream : IThriftStream;
FOutputStream : IThriftStream;
FDnsResolveTimeout : Integer;
FConnectionTimeout : Integer;
FSendTimeout : Integer;
FReadTimeout : Integer;
FCustomHeaders : IThriftDictionary<string,string>;

function CreateRequest: IXMLHTTPRequest;
protected
function GetIsOpen: Boolean; override;
procedure Open(); override;
procedure Close(); override;
function Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer; override;
procedure Write( const pBuf : Pointer; off, len : Integer); override;
procedure Flush; override;

procedure SetDnsResolveTimeout(const Value: Integer);
function GetDnsResolveTimeout: Integer;
procedure SetConnectionTimeout(const Value: Integer);
function GetConnectionTimeout: Integer;
procedure SetSendTimeout(const Value: Integer);
function GetSendTimeout: Integer;
procedure SetReadTimeout(const Value: Integer);
function GetReadTimeout: Integer;

function GetCustomHeaders: IThriftDictionary<string,string>;
procedure SendRequest;
property DnsResolveTimeout: Integer read GetDnsResolveTimeout write SetDnsResolveTimeout;
property ConnectionTimeout: Integer read GetConnectionTimeout write SetConnectionTimeout;
property SendTimeout: Integer read GetSendTimeout write SetSendTimeout;
property ReadTimeout: Integer read GetReadTimeout write SetReadTimeout;
property CustomHeaders: IThriftDictionary<string,string> read GetCustomHeaders;
public
constructor Create( const AUri: string);
destructor Destroy; override;
end;


implementation


{ TMsxmlHTTPClientImpl }

constructor TMsxmlHTTPClientImpl.Create(const AUri: string);
begin
inherited Create;
FUri := AUri;

// defaults according to MSDN
FDnsResolveTimeout := 0; // no timeout
FConnectionTimeout := 60 * 1000;
FSendTimeout := 30 * 1000;
FReadTimeout := 30 * 1000;

FCustomHeaders := TThriftDictionaryImpl<string,string>.Create;
FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
end;

function TMsxmlHTTPClientImpl.CreateRequest: IXMLHTTPRequest;
var
pair : TPair<string,string>;
srvHttp : IServerXMLHTTPRequest;
begin
{$IF CompilerVersion >= 21.0}
Result := CoServerXMLHTTP.Create;
{$ELSE}
Result := CoXMLHTTPRequest.Create;
{$IFEND}

// setting a timeout value to 0 (zero) means "no timeout" for that setting
if Supports( result, IServerXMLHTTPRequest, srvHttp)
then srvHttp.setTimeouts( DnsResolveTimeout, ConnectionTimeout, SendTimeout, ReadTimeout);

Result.open('POST', FUri, False, '', '');
Result.setRequestHeader( 'Content-Type', 'application/x-thrift');
Result.setRequestHeader( 'Accept', 'application/x-thrift');
Result.setRequestHeader( 'User-Agent', 'Delphi/IHTTPClient');

for pair in FCustomHeaders do begin
Result.setRequestHeader( pair.Key, pair.Value );
end;
end;

destructor TMsxmlHTTPClientImpl.Destroy;
begin
Close;
inherited;
end;

function TMsxmlHTTPClientImpl.GetDnsResolveTimeout: Integer;
begin
Result := FDnsResolveTimeout;
end;

procedure TMsxmlHTTPClientImpl.SetDnsResolveTimeout(const Value: Integer);
begin
FDnsResolveTimeout := Value;
end;

function TMsxmlHTTPClientImpl.GetConnectionTimeout: Integer;
begin
Result := FConnectionTimeout;
end;

procedure TMsxmlHTTPClientImpl.SetConnectionTimeout(const Value: Integer);
begin
FConnectionTimeout := Value;
end;

function TMsxmlHTTPClientImpl.GetSendTimeout: Integer;
begin
Result := FSendTimeout;
end;

procedure TMsxmlHTTPClientImpl.SetSendTimeout(const Value: Integer);
begin
FSendTimeout := Value;
end;

function TMsxmlHTTPClientImpl.GetReadTimeout: Integer;
begin
Result := FReadTimeout;
end;

procedure TMsxmlHTTPClientImpl.SetReadTimeout(const Value: Integer);
begin
FReadTimeout := Value;
end;

function TMsxmlHTTPClientImpl.GetCustomHeaders: IThriftDictionary<string,string>;
begin
Result := FCustomHeaders;
end;

function TMsxmlHTTPClientImpl.GetIsOpen: Boolean;
begin
Result := True;
end;

procedure TMsxmlHTTPClientImpl.Open;
begin
FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
end;

procedure TMsxmlHTTPClientImpl.Close;
begin
FInputStream := nil;
FOutputStream := nil;
end;

procedure TMsxmlHTTPClientImpl.Flush;
begin
try
SendRequest;
finally
FOutputStream := nil;
FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
ASSERT( FOutputStream <> nil);
end;
end;

function TMsxmlHTTPClientImpl.Read( const pBuf : Pointer; const buflen : Integer; off: Integer; len: Integer): Integer;
begin
if FInputStream = nil then begin
raise TTransportExceptionNotOpen.Create('No request has been sent');
end;

try
Result := FInputStream.Read( pBuf, buflen, off, len)
except
on E: Exception
do raise TTransportExceptionUnknown.Create(E.Message);
end;
end;

procedure TMsxmlHTTPClientImpl.SendRequest;
var
xmlhttp : IXMLHTTPRequest;
ms : TMemoryStream;
a : TBytes;
len : Integer;
begin
xmlhttp := CreateRequest;

ms := TMemoryStream.Create;
try
a := FOutputStream.ToArray;
len := Length(a);
if len > 0 then begin
ms.WriteBuffer( Pointer(@a[0])^, len);
end;
ms.Position := 0;
xmlhttp.send( IUnknown( TStreamAdapter.Create( ms, soReference )));
FInputStream := nil;
FInputStream := TThriftStreamAdapterCOM.Create( IUnknown( xmlhttp.responseStream) as IStream);
finally
ms.Free;
end;
end;

procedure TMsxmlHTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer);
begin
FOutputStream.Write( pBuf, off, len);
end;



end.

0 comments on commit 0223091

Please sign in to comment.