Skip to content

Commit 03e1e5d

Browse files
committed
1 parent 1f538e9 commit 03e1e5d

File tree

5 files changed

+76
-15
lines changed

5 files changed

+76
-15
lines changed

Examples/Easy_Http/PhotoInfo/f_Main.dfm

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ object fmMain: TfmMain
66
BorderStyle = bsSingle
77
Caption = 'File upload demo'
88
ClientHeight = 200
9-
ClientWidth = 309
9+
ClientWidth = 321
1010
Color = clBtnFace
1111
Font.Charset = DEFAULT_CHARSET
1212
Font.Color = clWindowText
@@ -46,15 +46,15 @@ object fmMain: TfmMain
4646
object edUrl: TEdit
4747
Left = 37
4848
Top = 8
49-
Width = 257
49+
Width = 272
5050
Height = 21
5151
TabOrder = 1
5252
Text = 'http://localhost/php_curl/photoinfo/action.php'
5353
end
5454
object memoResponse: TMemo
5555
Left = 15
5656
Top = 97
57-
Width = 282
57+
Width = 294
5858
Height = 95
5959
TabOrder = 0
6060
end
@@ -94,10 +94,19 @@ object fmMain: TfmMain
9494
TabOrder = 5
9595
OnClick = btSynthMemoryClick
9696
end
97+
object btCloneDemo: TButton
98+
Left = 216
99+
Top = 35
100+
Width = 93
101+
Height = 25
102+
Caption = 'ICurl.Clone demo'
103+
TabOrder = 6
104+
OnClick = btCloneDemoClick
105+
end
97106
object od: TOpenDialog
98107
Filter = 'Images (*.jpg; *.jpeg; *.png)|*.jpg; *.jpeg; *.png'
99108
Options = [ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofEnableSizing]
100-
Left = 264
101-
Top = 8
109+
Left = 24
110+
Top = 108
102111
end
103112
end

Examples/Easy_Http/PhotoInfo/f_Main.pas

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ TfmMain = class(TForm)
1818
btSynthStream: TButton;
1919
od: TOpenDialog;
2020
btSynthMemory: TButton;
21+
btCloneDemo: TButton;
2122
procedure btHardClick(Sender: TObject);
2223
procedure FormCreate(Sender: TObject);
2324
procedure FormDestroy(Sender: TObject);
2425
procedure btEasyClick(Sender: TObject);
2526
procedure btSynthStreamClick(Sender: TObject);
2627
procedure btSynthMemoryClick(Sender: TObject);
28+
procedure btCloneDemoClick(Sender: TObject);
2729
private
2830
{ Private declarations }
2931
stream : TRawByteStream;
@@ -84,6 +86,29 @@ function TfmMain.GetFile(
8486
Exit(true);
8587
end;
8688

89+
procedure TfmMain.btCloneDemoClick(Sender: TObject);
90+
var
91+
curl1, curl2 : ICurl;
92+
fname : string;
93+
ftype : RawByteString;
94+
begin
95+
// It is BAD code!! — it is just an illustration that options are copied.
96+
// cur1 and curl2 share streams, so problems will rise when we use them
97+
// simultaneously, or destroy curl1 prematurely.
98+
if not GetFile(fname, ftype) then Exit;
99+
100+
curl1 := CurlGet;
101+
curl1.SetRecvStream(stream, [csfAutoRewind]);
102+
curl1.SetUrl(edUrl.Text);
103+
curl1.SetOpt(CURLOPT_POST, true);
104+
105+
curl1.Form := CurlGetForm.AddFile('photo', fname, ftype);
106+
107+
curl2 := curl1.Clone;
108+
curl2.Perform;
109+
memoResponse.Text := UTF8ToString(stream.Data);
110+
end;
111+
87112
procedure TfmMain.btEasyClick(Sender: TObject);
88113
var
89114
curl : ICurl;

Src/Curl.Easy.pas

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,20 @@ interface
130130
function GetResponseCode : longint;
131131

132132
/// Makes an exact copy, e.g. for multithreading.
133+
/// @warning Receiver, sender and header streams will be shared,
134+
/// but not auto-destroyed. Form, together with its streams,
135+
/// will be shared. So it is wise to replace all streams with unique
136+
/// copies for each clone.
137+
/// @warning String lists assigned via SetXXX are shared and,
138+
/// as they are ref-counted, destroyed when the last reference
139+
/// disappears. For large objects assigned via SetOpt the programmer
140+
/// should bother about destruction for himself.
133141
function Clone : ICurl;
134142

135143
property Form : ICurlForm read GetForm write SetForm;
136144
end;
137145

138146
TEasyCurlImpl = class (TInterfacedObject, ICurl)
139-
private
140-
type
141-
TSListEntry = record
142-
str : RawByteString;
143-
entry : TCurlSList;
144-
end;
145-
OaSListEntry = array of TSListEntry;
146147
private
147148
fHandle : TCurlHandle;
148149
fCustomHeaders, fPostQuote, fTelnetOptions, fPreQuote,
@@ -290,6 +291,9 @@ constructor ECurlError.Create(aObject : TEasyCurlImpl; aCode : TCurlCode);
290291
constructor TEasyCurlImpl.Create;
291292
begin
292293
inherited;
294+
fSendStream.Init;
295+
fRecvStream.Init;
296+
fHeaderStream.Init;
293297
fHandle := curl_easy_init;
294298
if fHandle = nil then
295299
raise ECurlInternal.Create('[TEasyCurlImpl.Create] Cannot create cURL object.');
@@ -298,12 +302,24 @@ constructor TEasyCurlImpl.Create;
298302
constructor TEasyCurlImpl.Create(aSource : TEasyCurlImpl);
299303
begin
300304
inherited Create;
301-
fSendStream.Init;
302-
fRecvStream.Init;
303-
fHeaderStream.Init;
305+
// Streams
306+
fSendStream.InitFrom(aSource.fSendStream);
307+
fRecvStream.InitFrom(aSource.fRecvStream);
308+
fHeaderStream.InitFrom(aSource.fHeaderStream);
309+
// Handle
304310
fHandle := curl_easy_duphandle(aSource.fHandle);
305311
if fHandle = nil then
306312
raise ECurlInternal.Create('[TEasyCurlImpl.Create(TEasyCurlImpl)] Cannot clone cURL object.');
313+
// Copy settings!
314+
fForm := aSource.fForm;
315+
fCustomHeaders := aSource.fCustomHeaders;
316+
fPostQuote := aSource.fPostQuote;
317+
fTelnetOptions := aSource.fTelnetOptions;
318+
fPreQuote := aSource.fPreQuote;
319+
fHttp200Aliases := aSource.fHttp200Aliases;
320+
fMailRcpt := aSource.fMailRcpt;
321+
fResolveList := aSource.fResolveList;
322+
fProxyHeader := aSource.fProxyHeader;
307323
end;
308324

309325
destructor TEasyCurlImpl.Destroy;

Src/Curl.Interfaces.pas

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ TCurlAutoStream = record
2525
Flags : TCurlStreamFlags;
2626

2727
procedure Init; inline;
28+
procedure InitFrom(const v : TCurlAutoStream);
2829
procedure Assign(aStream : TStream; aFlags : TCurlStreamFlags);
2930
procedure RewindRead;
3031
procedure RewindWrite;
@@ -173,4 +174,12 @@ procedure TCurlAutoStream.Assign(aStream : TStream; aFlags : TCurlStreamFlags);
173174
then Flags := aFlags;
174175
end;
175176

177+
178+
procedure TCurlAutoStream.InitFrom(const v : TCurlAutoStream);
179+
begin
180+
Stream := v.Stream;
181+
Flags := v.Flags - [csfAutoDestroy];
182+
end;
183+
184+
176185
end.

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,6 @@ Forms (one field is set in a simple way, the other in more complex one).
6565

6666
File uploading: disk file (2 ways), memory buffer, stream.
6767

68+
ICurl cloning demo (not particularly good, it is more an illustration that Clone works).
69+
6870
Please copy `php_curl` directory to a PHP-capable web server.

0 commit comments

Comments
 (0)