Implement stream-based reading/writing to get a more accurate slowdown
After reading N bytes from the input socket (destination host) we delay an interval calculated to be around 56k modem speeds, then write that data to the output socket (proxy client)
This commit is contained in:
parent
a721b81665
commit
3d5bb09bb2
|
@ -3,8 +3,13 @@ private with Ada.Streams,
|
|||
AWS.Client,
|
||||
AWS.Headers,
|
||||
AWS.Messages,
|
||||
AWS.Resources,
|
||||
AWS.Resources.Streams,
|
||||
AWS.Response,
|
||||
AWS.Status;
|
||||
AWS.Status,
|
||||
AWS.Translator;
|
||||
|
||||
with Delayed_Stream;
|
||||
|
||||
package body Callbacks is
|
||||
use Ada.Text_IO;
|
||||
|
@ -58,10 +63,16 @@ package body Callbacks is
|
|||
-- Everything else we can slowly proxy
|
||||
when others =>
|
||||
declare
|
||||
Buf : constant String := AWS.Response.Message_Body (Result);
|
||||
Response_Stream : AWS.Resources.Streams.Stream_Access := new Delayed_Stream.Delayed;
|
||||
begin
|
||||
return AWS.Response.Build (Content_Type => AWS.Response.Content_Type (Result),
|
||||
Message_Body => Buf,
|
||||
Delayed_Stream.Create (Resource => Response_Stream.all,
|
||||
Response => Result,
|
||||
Size => 0,
|
||||
Undefined_Size => True);
|
||||
|
||||
|
||||
return AWS.Response.Stream (Content_Type => AWS.Response.Content_Type (Result),
|
||||
Handle => Response_Stream,
|
||||
Status_Code => Response_Code);
|
||||
end;
|
||||
end case;
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
private with Ada.Text_IO;
|
||||
|
||||
package body Delayed_Stream is
|
||||
-----------
|
||||
-- Close --
|
||||
-----------
|
||||
|
||||
procedure Close (File : in out Delayed) is
|
||||
begin
|
||||
null;
|
||||
end Close;
|
||||
|
||||
------------
|
||||
-- Create --
|
||||
------------
|
||||
|
||||
procedure Create
|
||||
(Resource : in out AWS.Resources.Streams.Stream_Type'Class;
|
||||
Response : in out AWS.Response.Data;
|
||||
Size : Stream_Element_Offset;
|
||||
Undefined_Size : Boolean) is
|
||||
begin
|
||||
Delayed (Resource).Undefined_Size := Undefined_Size;
|
||||
Delayed (Resource).Size := Size;
|
||||
Delayed (Resource).Offset := 0;
|
||||
Delayed (Resource).Response := Response;
|
||||
|
||||
AWS.Response.Message_Body (Response, Delayed(Resource).Handle);
|
||||
end Create;
|
||||
|
||||
-----------------
|
||||
-- End_Of_File --
|
||||
-----------------
|
||||
|
||||
function End_Of_File
|
||||
(Resource : Delayed) return Boolean is
|
||||
begin
|
||||
return Resource.Offset >= Resource.Size;
|
||||
end End_Of_File;
|
||||
|
||||
----------
|
||||
-- Read --
|
||||
----------
|
||||
|
||||
procedure Read
|
||||
(Resource : in out Delayed;
|
||||
Buffer : out Stream_Element_Array;
|
||||
Last : out Stream_Element_Offset)
|
||||
is
|
||||
use Ada.Text_IO;
|
||||
|
||||
Buffer_Length : constant Stream_Element_Offset := Buffer'Last;
|
||||
Delay_Interval : constant Float := (Float (Buffer_Length) / 7168.0);
|
||||
|
||||
Data_Stream : Ada.Streams.Stream_Element_Array (1 .. Buffer_Length);
|
||||
Data_Last : Ada.Streams.Stream_Element_Offset;
|
||||
begin
|
||||
Last := Buffer'First - 1;
|
||||
|
||||
AWS.Resources.Read (Resource.Handle, Data_Stream, Data_Last);
|
||||
|
||||
-- If our input stream is empty, might as well bail now, nothing to
|
||||
-- write to the output stream
|
||||
if Data_Last < 0 then
|
||||
return;
|
||||
end if;
|
||||
|
||||
delay Duration (Delay_Interval);
|
||||
|
||||
for I in 1 .. Data_Last loop
|
||||
Buffer (I) := Data_Stream (I);
|
||||
Last := I;
|
||||
end loop;
|
||||
end Read;
|
||||
|
||||
-----------
|
||||
-- Reset --
|
||||
-----------
|
||||
|
||||
procedure Reset (File : in out Delayed) is
|
||||
begin
|
||||
null;
|
||||
end Reset;
|
||||
|
||||
---------------
|
||||
-- Set_Index --
|
||||
---------------
|
||||
|
||||
procedure Set_Index
|
||||
(File : in out Delayed;
|
||||
Position : Stream_Element_Offset) is
|
||||
begin
|
||||
null;
|
||||
end Set_Index;
|
||||
|
||||
----------
|
||||
-- Size --
|
||||
----------
|
||||
|
||||
function Size (File : Delayed) return Stream_Element_Offset is
|
||||
begin
|
||||
if File.Undefined_Size then
|
||||
return AWS.Resources.Undefined_Length;
|
||||
else
|
||||
return File.Size;
|
||||
end if;
|
||||
end Size;
|
||||
|
||||
end Delayed_Stream;
|
|
@ -0,0 +1,50 @@
|
|||
--
|
||||
--
|
||||
--
|
||||
|
||||
with Ada.Streams,
|
||||
AWS.Response,
|
||||
AWS.Resources,
|
||||
AWS.Resources.Streams;
|
||||
|
||||
|
||||
package Delayed_Stream is
|
||||
use Ada.Streams,
|
||||
AWS.Resources;
|
||||
|
||||
type Delayed is new Streams.Stream_Type with private;
|
||||
|
||||
function End_Of_File (Resource : Delayed) return Boolean;
|
||||
|
||||
procedure Read
|
||||
(Resource : in out Delayed;
|
||||
Buffer : out Stream_Element_Array;
|
||||
Last : out Stream_Element_Offset);
|
||||
|
||||
function Size (File : Delayed) return Stream_Element_Offset;
|
||||
|
||||
procedure Close (File : in out Delayed);
|
||||
|
||||
procedure Reset (File : in out Delayed);
|
||||
|
||||
procedure Set_Index
|
||||
(File : in out Delayed;
|
||||
Position : Stream_Element_Offset);
|
||||
|
||||
procedure Create
|
||||
(Resource : in out AWS.Resources.Streams.Stream_Type'Class;
|
||||
Response : in out AWS.Response.Data;
|
||||
Size : Stream_Element_Offset;
|
||||
Undefined_Size : Boolean);
|
||||
|
||||
private
|
||||
|
||||
type Delayed is new Streams.Stream_Type with record
|
||||
Offset : Stream_Element_Offset;
|
||||
Size : Stream_Element_Offset;
|
||||
Undefined_Size : Boolean;
|
||||
Response : AWS.Response.Data;
|
||||
Handle : AWS.Resources.File_Type;
|
||||
end record;
|
||||
|
||||
end Delayed_Stream;
|
|
@ -20,7 +20,7 @@ begin
|
|||
|
||||
AWS.Server.Start (Web_Server => Server,
|
||||
Name => "Dispersion Proxy",
|
||||
Max_Connection => 5,
|
||||
Max_Connection => 2,
|
||||
Port => 8980,
|
||||
Callback => Callbacks.Simple'Access);
|
||||
|
||||
|
|
Loading…
Reference in New Issue