1
0
mirror of https://github.com/salvadordf/CEF4Delphi.git synced 2025-07-12 22:30:17 +02:00

ResponseFilterBrowser enhancements and fixes

- Added a statusbar to show then Content-Length HTTP header information, the raw stream size and the decoded string size.
- Fixed some synchronization bugs.
This commit is contained in:
Salvador Díaz Fau
2018-05-27 11:13:01 +02:00
parent ee61ac3c7b
commit 73f9318839
2 changed files with 118 additions and 49 deletions

View File

@ -20,13 +20,13 @@ object ResponseFilterBrowserFrm: TResponseFilterBrowserFrm
TextHeight = 13 TextHeight = 13
object Splitter1: TSplitter object Splitter1: TSplitter
Left = 0 Left = 0
Top = 407 Top = 477
Width = 1038 Width = 1038
Height = 3 Height = 3
Cursor = crVSplit Cursor = crVSplit
Align = alBottom Align = alBottom
ExplicitTop = 30 ExplicitTop = 30
ExplicitWidth = 505 ExplicitWidth = 450
end end
object AddressPnl: TPanel object AddressPnl: TPanel
Left = 0 Left = 0
@ -97,19 +97,53 @@ object ResponseFilterBrowserFrm: TResponseFilterBrowserFrm
Left = 0 Left = 0
Top = 30 Top = 30
Width = 1038 Width = 1038
Height = 377 Height = 447
Align = alClient Align = alClient
TabOrder = 1 TabOrder = 1
ExplicitHeight = 291
end end
object Memo1: TMemo object Panel2: TPanel
Left = 0 Left = 0
Top = 410 Top = 480
Width = 1038 Width = 1038
Height = 300 Height = 230
Align = alBottom Align = alBottom
ReadOnly = True BevelOuter = bvNone
ScrollBars = ssBoth ShowCaption = False
TabOrder = 2 TabOrder = 2
object Memo1: TMemo
Left = 0
Top = 0
Width = 1038
Height = 211
Align = alClient
ReadOnly = True
ScrollBars = ssBoth
TabOrder = 0
ExplicitLeft = 5
ExplicitTop = 31
ExplicitWidth = 760
ExplicitHeight = 159
end
object StatusBar1: TStatusBar
Left = 0
Top = 211
Width = 1038
Height = 19
Panels = <
item
Width = 250
end
item
Width = 250
end
item
Width = 250
end>
ExplicitLeft = 696
ExplicitTop = 216
ExplicitWidth = 0
end
end end
object Timer1: TTimer object Timer1: TTimer
Enabled = False Enabled = False

View File

@ -49,7 +49,8 @@ uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, SyncObjs,
{$ENDIF} {$ENDIF}
uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uCEFResponseFilter; uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, uCEFResponseFilter,
Vcl.ComCtrls;
const const
STREAM_COPY_COMPLETE = WM_APP + $B00; STREAM_COPY_COMPLETE = WM_APP + $B00;
@ -62,11 +63,13 @@ type
Chromium1: TChromium; Chromium1: TChromium;
CEFWindowParent1: TCEFWindowParent; CEFWindowParent1: TCEFWindowParent;
Splitter1: TSplitter; Splitter1: TSplitter;
Memo1: TMemo;
Panel1: TPanel; Panel1: TPanel;
GoBtn: TButton; GoBtn: TButton;
Label1: TLabel; Label1: TLabel;
RscNameEdt: TEdit; RscNameEdt: TEdit;
Panel2: TPanel;
Memo1: TMemo;
StatusBar1: TStatusBar;
procedure GoBtnClick(Sender: TObject); procedure GoBtnClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject); procedure Timer1Timer(Sender: TObject);
procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser);
@ -95,6 +98,7 @@ type
FRscCompleted : boolean; // This variable will be used to handle the results only once. FRscCompleted : boolean; // This variable will be used to handle the results only once.
FRscEncoding : TEncoding; // The resource response Encoding. When encoding is unicode. The response data may be sent by multi chains, will cause encoding parsing problem. FRscEncoding : TEncoding; // The resource response Encoding. When encoding is unicode. The response data may be sent by multi chains, will cause encoding parsing problem.
FRscMimeType : String; FRscMimeType : String;
FFilterInit : boolean;
// Variables to control when can we destroy the form safely // Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
FClosing : boolean; // Set to True in the CloseQuery event. FClosing : boolean; // Set to True in the CloseQuery event.
@ -156,41 +160,43 @@ begin
try try
FStreamCS.Acquire; FStreamCS.Acquire;
// This event will be called repeatedly until the input buffer has been fully read. if FFilterInit then
// When there's no more data then data_in is nil and you can show the stream contents.
if (data_in = nil) then
begin begin
data_in_read := 0; // This event will be called repeatedly until the input buffer has been fully read.
data_out_written := 0; // When there's no more data then data_in is nil and you can show the stream contents.
aResult := RESPONSE_FILTER_DONE;
if not(FRscCompleted) and if (data_in = nil) then
(FStream <> nil) and
(FStream.Size > 0) and
((FRscSize = -1) or (FRscSize = FStream.Size)) then
FRscCompleted := PostMessage(Handle, STREAM_COPY_COMPLETE, 0, 0);
end
else
begin
if (data_out <> nil) then
begin begin
data_out_written := min(data_in_size, data_out_size); data_in_read := 0;
data_out_written := 0;
aResult := RESPONSE_FILTER_DONE;
if (data_out_written > 0) then if not(FRscCompleted) and
Move(data_in^, data_out^, data_out_written); (FStream.Size > 0) and
end; ((FRscSize = -1) or (FRscSize = FStream.Size)) then
FRscCompleted := PostMessage(Handle, STREAM_COPY_COMPLETE, 0, 0);
end
else
begin
if (data_out <> nil) then
begin
data_out_written := min(data_in_size, data_out_size);
if (data_in_size > 0) then if (data_out_written > 0) then
data_in_read := FStream.Write(data_in^, data_in_size); Move(data_in^, data_out^, data_out_written);
end;
// Send the STREAM_COPY_COMPLETE message only if the server sent the data size in if (data_in_size > 0) then
// a Content-Length header and we can compare it with the stream size data_in_read := FStream.Write(data_in^, data_in_size);
if not(FRscCompleted) and (FRscSize <> -1) and (FRscSize = FStream.Size) then
FRscCompleted := PostMessage(Handle, STREAM_COPY_COMPLETE, 0, 0);
aResult := RESPONSE_FILTER_NEED_MORE_DATA; // Send the STREAM_COPY_COMPLETE message only if the server sent the data size in
end; // a Content-Length header and we can compare it with the stream size
if not(FRscCompleted) and (FRscSize <> -1) and (FRscSize = FStream.Size) then
FRscCompleted := PostMessage(Handle, STREAM_COPY_COMPLETE, 0, 0);
aResult := RESPONSE_FILTER_NEED_MORE_DATA;
end;
end;
except except
on e : exception do on e : exception do
begin begin
@ -229,6 +235,7 @@ end;
procedure TResponseFilterBrowserFrm.FormCreate(Sender: TObject); procedure TResponseFilterBrowserFrm.FormCreate(Sender: TObject);
begin begin
FFilterInit := False;
FRscCompleted := False; FRscCompleted := False;
FRscSize := -1; FRscSize := -1;
FStream := TMemoryStream.Create; FStream := TMemoryStream.Create;
@ -281,8 +288,7 @@ begin
Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]); Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]);
end; end;
procedure TResponseFilterBrowserFrm.Chromium1Close(Sender: TObject; procedure TResponseFilterBrowserFrm.Chromium1Close(Sender: TObject; const browser: ICefBrowser; out Result: Boolean);
const browser: ICefBrowser; out Result: Boolean);
begin begin
PostMessage(Handle, CEF_DESTROY, 0, 0); PostMessage(Handle, CEF_DESTROY, 0, 0);
Result := True; Result := True;
@ -300,15 +306,28 @@ var
begin begin
if not(FRscCompleted) and (response <> nil) and IsMyResource(request) then if not(FRscCompleted) and (response <> nil) and IsMyResource(request) then
begin begin
Result := FFilter; try
TempHeader := trim(response.GetHeader('Content-Length')); FStreamCS.Acquire;
if TryStrToInt(TempHeader, TempLen) and (TempLen > 0) then Result := FFilter;
FRscSize := TempLen FFilterInit := True;
else TempHeader := trim(response.GetHeader('Content-Length'));
FRscSize := -1;
UpdateRscEncoding(response.MimeType, response.GetHeader('Content-Type')); if TryStrToInt(TempHeader, TempLen) and (TempLen > 0) then
begin
FRscSize := TempLen;
StatusBar1.Panels[0].Text := 'Content-Length : ' + inttostr(FRscSize);
end
else
begin
FRscSize := -1;
StatusBar1.Panels[0].Text := 'Content-Length : not available';
end;
UpdateRscEncoding(response.MimeType, response.GetHeader('Content-Type'));
finally
FStreamCS.Release;
end;
end end
else else
Result := nil; Result := nil;
@ -383,6 +402,8 @@ begin
(FRscMimeType = 'text/javascript') or (FRscMimeType = 'text/javascript') or
(FRscMimeType = 'application/javascript') then (FRscMimeType = 'application/javascript') then
begin begin
StatusBar1.Panels[1].Text := 'Stream size : ' + inttostr(FStream.Size);
SetLength(LAS, FStream.Size); SetLength(LAS, FStream.Size);
FStream.Read(LAS[Low(LAS)], FStream.Size); FStream.Read(LAS[Low(LAS)], FStream.Size);
@ -392,12 +413,13 @@ begin
LS := string(LAS); // Others encoding text LS := string(LAS); // Others encoding text
Memo1.Lines.Add(LS); Memo1.Lines.Add(LS);
StatusBar1.Panels[2].Text := 'Decoded size : ' + inttostr(length(LS));
end end
else else
Memo1.Lines.LoadFromStream(FStream); // Image or others Memo1.Lines.LoadFromStream(FStream); // Image or others
FStream.Clear; FStream.Clear;
FRscSize := -1;
end end
else else
Memo1.Lines.Clear; Memo1.Lines.Clear;
@ -408,7 +430,20 @@ end;
procedure TResponseFilterBrowserFrm.GoBtnClick(Sender: TObject); procedure TResponseFilterBrowserFrm.GoBtnClick(Sender: TObject);
begin begin
FRscCompleted := False; try
FStreamCS.Acquire;
FRscCompleted := False;
FRscSize := -1;
StatusBar1.Panels[0].Text := '';
StatusBar1.Panels[1].Text := '';
StatusBar1.Panels[2].Text := '';
Memo1.Lines.Clear;
FStream.Clear;
finally
FStreamCS.Release;
end;
Chromium1.LoadURL(AddressEdt.Text); Chromium1.LoadURL(AddressEdt.Text);
end; end;