mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-14 12:49:12 +02:00
* Merging revisions 42743,42766,42767,42768,42782 from trunk:
------------------------------------------------------------------------ r42743 | michael | 2019-08-20 09:03:24 +0200 (Tue, 20 Aug 2019) | 1 line * Fix bug #0035985 ------------------------------------------------------------------------ r42766 | michael | 2019-08-23 08:45:11 +0200 (Fri, 23 Aug 2019) | 1 line * Fix bug ID #0035596: better detection of vcs device ------------------------------------------------------------------------ r42767 | michael | 2019-08-23 09:21:03 +0200 (Fri, 23 Aug 2019) | 1 line * Make TResponse.Content a RawByteString ------------------------------------------------------------------------ r42768 | michael | 2019-08-23 09:21:44 +0200 (Fri, 23 Aug 2019) | 1 line * Set content-type on response (bug ID 35990) ------------------------------------------------------------------------ r42782 | michael | 2019-08-24 10:54:24 +0200 (Sat, 24 Aug 2019) | 1 line * Add WideString support in json string constructor ------------------------------------------------------------------------ git-svn-id: branches/fixes_3_2@42844 -
This commit is contained in:
parent
b8b5501fb9
commit
909b54579d
@ -2497,6 +2497,8 @@ begin
|
|||||||
vtExtended : Result:=CreateJSON(VExtended^);
|
vtExtended : Result:=CreateJSON(VExtended^);
|
||||||
vtString : Result:=CreateJSON(vString^);
|
vtString : Result:=CreateJSON(vString^);
|
||||||
vtAnsiString : Result:=CreateJSON(UTF8Decode(StrPas(VPChar)));
|
vtAnsiString : Result:=CreateJSON(UTF8Decode(StrPas(VPChar)));
|
||||||
|
vtUnicodeString: Result:=CreateJSON(UnicodeString(VUnicodeString));
|
||||||
|
vtWideString: Result:=CreateJSON(WideString(VWideString));
|
||||||
vtPChar : Result:=CreateJSON(StrPas(VPChar));
|
vtPChar : Result:=CreateJSON(StrPas(VPChar));
|
||||||
vtPointer : If (VPointer<>Nil) then
|
vtPointer : If (VPointer<>Nil) then
|
||||||
TJSONData.DoError(SErrPointerNotNil,[SourceType])
|
TJSONData.DoError(SErrPointerNotNil,[SourceType])
|
||||||
|
@ -53,7 +53,7 @@ type
|
|||||||
Procedure SetUp; override;
|
Procedure SetUp; override;
|
||||||
Procedure TestItemCount(J : TJSONData;Expected : Integer);
|
Procedure TestItemCount(J : TJSONData;Expected : Integer);
|
||||||
Procedure TestJSONType(J : TJSONData;Expected : TJSONType);
|
Procedure TestJSONType(J : TJSONData;Expected : TJSONType);
|
||||||
Procedure TestJSON(J : TJSONData;Expected : String);
|
Procedure TestJSON(J : TJSONData;Expected : TJSONStringType);
|
||||||
Procedure TestIsNull(J : TJSONData;Expected : Boolean);
|
Procedure TestIsNull(J : TJSONData;Expected : Boolean);
|
||||||
Procedure TestAsBoolean(J : TJSONData;Expected : Boolean; ExpectError : boolean = False);
|
Procedure TestAsBoolean(J : TJSONData;Expected : Boolean; ExpectError : boolean = False);
|
||||||
Procedure TestAsInteger(J : TJSONData; Expected : Integer; ExpectError : boolean = False);
|
Procedure TestAsInteger(J : TJSONData; Expected : Integer; ExpectError : boolean = False);
|
||||||
@ -238,6 +238,8 @@ type
|
|||||||
procedure TestCreateBoolean;
|
procedure TestCreateBoolean;
|
||||||
procedure TestCreateBooleanUnquoted;
|
procedure TestCreateBooleanUnquoted;
|
||||||
procedure TestCreateObject;
|
procedure TestCreateObject;
|
||||||
|
procedure TestCreateJSONUnicodeString;
|
||||||
|
procedure TestCreateJSONWideString;
|
||||||
procedure TestCreateJSONString;
|
procedure TestCreateJSONString;
|
||||||
procedure TestCreateJSONStringUnquoted;
|
procedure TestCreateJSONStringUnquoted;
|
||||||
procedure TestCreateJSONObject;
|
procedure TestCreateJSONObject;
|
||||||
@ -1078,7 +1080,7 @@ begin
|
|||||||
AssertEquals(J.ClassName+'.JSONType',Ord(Expected),Ord(J.JSONType));
|
AssertEquals(J.ClassName+'.JSONType',Ord(Expected),Ord(J.JSONType));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Procedure TTestJSON.TestJSON(J: TJSONData; Expected: String);
|
Procedure TTestJSON.TestJSON(J: TJSONData; Expected: TJSONStringType);
|
||||||
begin
|
begin
|
||||||
AssertEquals(J.ClassName+'.AsJSON',Expected,J.AsJSON);
|
AssertEquals(J.ClassName+'.AsJSON',Expected,J.AsJSON);
|
||||||
end;
|
end;
|
||||||
@ -3926,6 +3928,44 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestObject.TestCreateJSONUnicodeString;
|
||||||
|
Const
|
||||||
|
A = 'A';
|
||||||
|
S : Unicodestring = 'A string';
|
||||||
|
|
||||||
|
Var
|
||||||
|
O : TJSONObject;
|
||||||
|
|
||||||
|
begin
|
||||||
|
O:=TJSONObject.Create([A,S]);
|
||||||
|
try
|
||||||
|
TestItemCount(O,1);
|
||||||
|
TestJSONType(O[A],jtString);
|
||||||
|
TestJSON(O,'{ "A" : "'+UTF8Encode(S)+'" }');
|
||||||
|
finally
|
||||||
|
FreeAndNil(O);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestObject.TestCreateJSONWideString;
|
||||||
|
Const
|
||||||
|
A = 'A';
|
||||||
|
W : WideString = 'A string';
|
||||||
|
|
||||||
|
Var
|
||||||
|
O : TJSONObject;
|
||||||
|
|
||||||
|
begin
|
||||||
|
O:=TJSONObject.Create([A,W]);
|
||||||
|
try
|
||||||
|
TestItemCount(O,1);
|
||||||
|
TestJSONType(O[A],jtString);
|
||||||
|
TestJSON(O,'{ "A" : "'+UTF8Encode(W)+'" }');
|
||||||
|
finally
|
||||||
|
FreeAndNil(O);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestObject.TestCreateNilPointer;
|
procedure TTestObject.TestCreateNilPointer;
|
||||||
|
|
||||||
Const
|
Const
|
||||||
|
@ -475,8 +475,8 @@ type
|
|||||||
FContentSent: Boolean;
|
FContentSent: Boolean;
|
||||||
FRequest : TRequest;
|
FRequest : TRequest;
|
||||||
FCookies : TCookies;
|
FCookies : TCookies;
|
||||||
function GetContent: String;
|
function GetContent: RawByteString;
|
||||||
procedure SetContent(const AValue: String);
|
procedure SetContent(const AValue: RawByteString);
|
||||||
procedure SetContents(AValue: TStrings);
|
procedure SetContents(AValue: TStrings);
|
||||||
procedure SetContentStream(const AValue: TStream);
|
procedure SetContentStream(const AValue: TStream);
|
||||||
procedure SetFirstHeaderLine(const line: String);
|
procedure SetFirstHeaderLine(const line: String);
|
||||||
@ -507,7 +507,7 @@ type
|
|||||||
Property RetryAfter : String Index Ord(hhRetryAfter) Read GetHeaderValue Write SetHeaderValue;
|
Property RetryAfter : String Index Ord(hhRetryAfter) Read GetHeaderValue Write SetHeaderValue;
|
||||||
Property FirstHeaderLine : String Read GetFirstHeaderLine Write SetFirstHeaderLine;
|
Property FirstHeaderLine : String Read GetFirstHeaderLine Write SetFirstHeaderLine;
|
||||||
Property ContentStream : TStream Read FContentStream Write SetContentStream;
|
Property ContentStream : TStream Read FContentStream Write SetContentStream;
|
||||||
Property Content : String Read GetContent Write SetContent;
|
Property Content : RawByteString Read GetContent Write SetContent;
|
||||||
property Contents : TStrings read FContents Write SetContents;
|
property Contents : TStrings read FContents Write SetContents;
|
||||||
Property HeadersSent : Boolean Read FHeadersSent;
|
Property HeadersSent : Boolean Read FHeadersSent;
|
||||||
Property ContentSent : Boolean Read FContentSent;
|
Property ContentSent : Boolean Read FContentSent;
|
||||||
@ -1985,7 +1985,7 @@ begin
|
|||||||
FContents:=TStringList.Create;
|
FContents:=TStringList.Create;
|
||||||
TStringList(FContents).OnChange:=@ContentsChanged;
|
TStringList(FContents).OnChange:=@ContentsChanged;
|
||||||
FCookies:=TCookies.Create(TCookie);
|
FCookies:=TCookies.Create(TCookie);
|
||||||
FCustomHeaders:=TStringList.Create;
|
FCustomHeaders:=TStringList.Create; // Destroyed in parent
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TResponse.destroy;
|
destructor TResponse.destroy;
|
||||||
@ -2074,14 +2074,18 @@ begin
|
|||||||
FContents.Assign(AValue);
|
FContents.Assign(AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TResponse.GetContent: String;
|
function TResponse.GetContent: RawByteString;
|
||||||
begin
|
begin
|
||||||
Result:=Contents.Text;
|
Result:=Contents.Text;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TResponse.SetContent(const AValue: String);
|
procedure TResponse.SetContent(const AValue: RawByteString);
|
||||||
begin
|
begin
|
||||||
FContentStream:=Nil;
|
if Assigned(FContentStream) then
|
||||||
|
if FreeContentStream then
|
||||||
|
FreeAndNil(FContentStream)
|
||||||
|
else
|
||||||
|
FContentStream:=Nil;
|
||||||
FContents.Text:=AValue;
|
FContents.Text:=AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -89,8 +89,10 @@ Type
|
|||||||
FOptions: TJSONRPCDispatchOptions;
|
FOptions: TJSONRPCDispatchOptions;
|
||||||
FRequest: TRequest;
|
FRequest: TRequest;
|
||||||
FResponse: TResponse;
|
FResponse: TResponse;
|
||||||
|
FResponseContentType: String;
|
||||||
procedure SetDispatcher(const AValue: TCustomJSONRPCDispatcher);
|
procedure SetDispatcher(const AValue: TCustomJSONRPCDispatcher);
|
||||||
Protected
|
Protected
|
||||||
|
Function GetResponseContentType : String;
|
||||||
Function CreateDispatcher : TCustomJSONRPCDispatcher; virtual;
|
Function CreateDispatcher : TCustomJSONRPCDispatcher; virtual;
|
||||||
procedure Notification(AComponent: TComponent; Operation: TOperation);override;
|
procedure Notification(AComponent: TComponent; Operation: TOperation);override;
|
||||||
Property Dispatcher : TCustomJSONRPCDispatcher Read FDispatcher Write SetDispatcher;
|
Property Dispatcher : TCustomJSONRPCDispatcher Read FDispatcher Write SetDispatcher;
|
||||||
@ -102,14 +104,19 @@ Type
|
|||||||
Property Request: TRequest Read FRequest;
|
Property Request: TRequest Read FRequest;
|
||||||
// Access to response
|
// Access to response
|
||||||
Property Response: TResponse Read FResponse;
|
Property Response: TResponse Read FResponse;
|
||||||
|
// Response Content-Type. If left empty, application/json is used.
|
||||||
|
Property ResponseContentType : String Read FResponseContentType Write FResponseContentType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TJSONRPCDataModule }
|
{ TJSONRPCDataModule }
|
||||||
|
|
||||||
|
{ TJSONRPCModule }
|
||||||
|
|
||||||
TJSONRPCModule = Class(TCustomJSONRPCModule)
|
TJSONRPCModule = Class(TCustomJSONRPCModule)
|
||||||
Published
|
Published
|
||||||
Property Dispatcher;
|
Property Dispatcher;
|
||||||
Property DispatchOptions;
|
Property DispatchOptions;
|
||||||
|
Property ResponseContentType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -118,6 +125,9 @@ implementation
|
|||||||
uses dbugintf;
|
uses dbugintf;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
Const
|
||||||
|
SApplicationJSON = 'application/json';
|
||||||
|
|
||||||
{ TCustomJSONRPCContentProducer }
|
{ TCustomJSONRPCContentProducer }
|
||||||
|
|
||||||
function TCustomJSONRPCContentProducer.GetIDProperty: String;
|
function TCustomJSONRPCContentProducer.GetIDProperty: String;
|
||||||
@ -133,7 +143,7 @@ Var
|
|||||||
Disp : TCustomJSONRPCDispatcher;
|
Disp : TCustomJSONRPCDispatcher;
|
||||||
P : TJSONParser;
|
P : TJSONParser;
|
||||||
Req,res : TJSONData;
|
Req,res : TJSONData;
|
||||||
R : String;
|
R : TJSONStringType;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Disp:=Self.GetDispatcher;
|
Disp:=Self.GetDispatcher;
|
||||||
@ -211,6 +221,13 @@ begin
|
|||||||
FDispatcher.FreeNotification(Self);
|
FDispatcher.FreeNotification(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomJSONRPCModule.GetResponseContentType: String;
|
||||||
|
begin
|
||||||
|
Result:=FResponseContentType;
|
||||||
|
if Result='' then
|
||||||
|
Result:=SApplicationJSON;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCustomJSONRPCModule.CreateDispatcher: TCustomJSONRPCDispatcher;
|
function TCustomJSONRPCModule.CreateDispatcher: TCustomJSONRPCDispatcher;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
@ -245,6 +262,7 @@ procedure TCustomJSONRPCModule.HandleRequest(ARequest: TRequest;
|
|||||||
Var
|
Var
|
||||||
Disp : TCustomJSONRPCDispatcher;
|
Disp : TCustomJSONRPCDispatcher;
|
||||||
res : TJSONData;
|
res : TJSONData;
|
||||||
|
R : TJSONStringType;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
If (Dispatcher=Nil) then
|
If (Dispatcher=Nil) then
|
||||||
@ -254,10 +272,15 @@ begin
|
|||||||
try
|
try
|
||||||
If Assigned(Res) then
|
If Assigned(Res) then
|
||||||
begin
|
begin
|
||||||
AResponse.Content:=Res.AsJSON;
|
AResponse.FreeContentStream:=True;
|
||||||
AResponse.ContentLength:=Length(AResponse.Content);
|
AResponse.ContentStream:=TMemoryStream.Create;
|
||||||
|
R:=Res.AsJSON;
|
||||||
|
AResponse.ContentStream.WriteBuffer(R[1],Length(R));
|
||||||
|
AResponse.ContentLength:=AResponse.ContentStream.Size;
|
||||||
|
R:=''; // Free up mem
|
||||||
|
AResponse.ContentType:=GetResponseContentType;
|
||||||
end;
|
end;
|
||||||
AResponse.SendResponse;
|
AResponse.SendResponse;
|
||||||
finally
|
finally
|
||||||
Res.Free;
|
Res.Free;
|
||||||
end;
|
end;
|
||||||
|
@ -82,73 +82,59 @@ end;
|
|||||||
procedure detect_linuxvcs;
|
procedure detect_linuxvcs;
|
||||||
|
|
||||||
var f:text;
|
var f:text;
|
||||||
f_open : boolean;
|
fields:array [0..60] of int64;
|
||||||
c,pc:char;
|
fieldct,i:integer;
|
||||||
pid,cpid,dummy:longint;
|
pid,ppid:longint;
|
||||||
device:dword;
|
magnitude:int64;
|
||||||
s:string[15];
|
s:string[15];
|
||||||
|
statln:ansistring;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
{Extremely aggressive VCSA detection. Works even through Midnight
|
{Extremely aggressive VCSA detection. Works even through Midnight
|
||||||
Commander. Idea from the C++ Turbo Vision project, credits go
|
Commander. Idea from the C++ Turbo Vision project, credits go
|
||||||
to Martynas Kunigelis <algikun@santaka.sc-uni.ktu.lt>.}
|
to Martynas Kunigelis <algikun@santaka.sc-uni.ktu.lt>.}
|
||||||
pid:=fpgetpid;
|
pid:=fpgetpid;
|
||||||
f_open:=false;
|
|
||||||
{$push}
|
|
||||||
{$I-}
|
|
||||||
{$R-}
|
|
||||||
repeat
|
repeat
|
||||||
cpid:=pid;
|
|
||||||
str(pid,s);
|
str(pid,s);
|
||||||
assign(f,'/proc/'+s+'/stat');
|
assign(f, '/proc/'+s+'/stat');
|
||||||
|
{$I-}
|
||||||
reset(f);
|
reset(f);
|
||||||
|
{$I+}
|
||||||
if ioresult<>0 then
|
if ioresult<>0 then
|
||||||
exit;
|
break;
|
||||||
f_open:=true;
|
readln(f, statln);
|
||||||
{ from here we can discard I/O errors, as long as we avoid
|
|
||||||
infinite loops }
|
|
||||||
{ first number is pid }
|
|
||||||
dummy:=0;
|
|
||||||
read(f,dummy);
|
|
||||||
if dummy<>pid then
|
|
||||||
exit;
|
|
||||||
{ after comes the name of the binary within (), look for closing brace followed by space }
|
|
||||||
c:=#0;
|
|
||||||
repeat
|
|
||||||
pc:=c;
|
|
||||||
read(f,c);
|
|
||||||
if ioresult<>0 then
|
|
||||||
break;
|
|
||||||
until (pc=')') and (c=' ');
|
|
||||||
{ now comes the state letter }
|
|
||||||
repeat
|
|
||||||
read(f,c);
|
|
||||||
if ioresult<>0 then
|
|
||||||
break;
|
|
||||||
until c=' ';
|
|
||||||
{ parent pid }
|
|
||||||
pid:=-1;
|
|
||||||
read(f,pid);
|
|
||||||
{ process group }
|
|
||||||
read(f,dummy);
|
|
||||||
{ session }
|
|
||||||
read(f,dummy);
|
|
||||||
{ device number }
|
|
||||||
device:=0;
|
|
||||||
read(f,device);
|
|
||||||
close(f);
|
close(f);
|
||||||
f_open:=false;
|
magnitude := 1;
|
||||||
if (device and $ffffffc0)=$00000400 then {/dev/tty*}
|
fieldct := 0;
|
||||||
|
fields[fieldct] := 0;
|
||||||
|
for i := high(statln) downto low(statln) do
|
||||||
begin
|
begin
|
||||||
vcs_device:=device and $3f;
|
case statln[i] of
|
||||||
|
'-': magnitude := -1;
|
||||||
|
'0'..'9': begin
|
||||||
|
fields[fieldct] := fields[fieldct]
|
||||||
|
+ (magnitude * (ord(statln[i]) - ord('0')));
|
||||||
|
magnitude := magnitude * 10;
|
||||||
|
end;
|
||||||
|
' ': begin
|
||||||
|
magnitude := 1;
|
||||||
|
fieldct := fieldct + 1;
|
||||||
|
fields[fieldct] := 0;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
ppid := pid;
|
||||||
|
pid := fields[fieldct - 1];
|
||||||
|
if (fields[fieldct - 4] and $ffffffc0) = $00000400 then {/dev/tty*}
|
||||||
|
begin
|
||||||
|
vcs_device:=fields[fieldct - 4] and $3f;
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
until (device=0) {Not attached to a terminal, i.e. an xterm.}
|
until (fields[fieldct - 4]=0) {Not attached to a terminal, i.e. an xterm.}
|
||||||
or (pid=-1)
|
or (pid=-1)
|
||||||
or (cpid=pid);
|
or (ppid=pid);
|
||||||
if f_open then
|
|
||||||
close(f);
|
|
||||||
{$pop}
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user