I'm using StringStream to read the result of a command that is sent to chromedriver.
The problem is that the returned result is messing up the memory addresses and it give me an Access Violation error.
I have tried multiple different methods to catch the exceptions, but the program stops working. When I use breakpoints, I see that the DataString has the requested value, but when it tries to put it in the variable, it terminates the program.
This is the code I'm using:
function TDelphiCommand.ExecutePost(port: WORD; const URL, Data: string): string;
var
Header : TStringStream;
pSession : HINTERNET;
pConnection : HINTERNET;
pRequest : HINTERNET;
flags : DWord;
AcceptType: array[0..1] of PChar;// = ('*/*', nil);
sStream: TStringStream;
Buffer: array[0..255] of Byte;
aBufferSize: Cardinal;
b1: Boolean;
AData: TMemoryStream;
sUrl: string;
aMem: PByte;
begin
Result := '';
pSession := InternetOpen('Mozila/5.0', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(pSession) then
try
pConnection := InternetConnect(pSession, '127.0.0.1', port, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
if Assigned(pConnection) then
try
AcceptType[0] := 'application/json';
AcceptType[1] := nil;
sUrl := Copy(URL, Pos(IntToStr(port), URL)+Length(IntToStr(port))+1, Length(URL));
pRequest := HTTPOpenRequest(pConnection, 'POST', PChar(sUrl), 'HTTP/1.1', nil, @AcceptType[0], INTERNET_FLAG_KEEP_CONNECTION or INTERNET_FLAG_ASYNC or INTERNET_FLAG_MAKE_PERSISTENT, 0);
if Assigned(pRequest) then
try
Header := TStringStream.Create('');
try
with Header do
begin
WriteString('Accept: text/html, application/json, application/xhtml+xml, image/jxr, */*' + sLineBreak);
WriteString('Accept-Encoding: gzip, deflate' + sLineBreak);
WriteString('Accept-Language: en-US, en; q=0.5' + sLineBreak);
//text/html
WriteString('Content-Type: application/json; charset=UTF-8' + sLineBreak);
WriteString('Connection: keep-alive'+ SlineBreak);
WriteString('Host: 127.0.0.1' + sLineBreak);
WriteString('User-Agent: Mozilla/5.0'+ sLineBreak);
end;
HttpAddRequestHeaders(pRequest, PChar(Header.DataString), Length(Header.DataString), HTTP_ADDREQ_FLAG_ADD);
AData := TMemoryStream.Create;
try
AData.Write(TEncoding.UTF8.GetBytes(Data), Length(Data));
b1 := HTTPSendRequest(pRequest, nil, 0, AData.Memory, AData.Size);
if b1 then
begin
sStream := TStringStream.Create('');
try
try
sStream.Position := 0;
while InternetReadFile(pRequest, @Buffer[0], SizeOf(Buffer), aBufferSize) and (aBufferSize <> 0) do
sStream.Write(Buffer[0], aBufferSize);
Result := sStream.Datastring;//UTF8ToString(RawByteString(sStream.Datastring));
except
sStream.Free;
end;
finally
sStream.Free;
end;
end;
finally
AData.Free;
end;
finally
Header.Free;
end;
finally
InternetCloseHandle(pRequest);
end;
finally
InternetCloseHandle(pConnection);
end;
finally
InternetCloseHandle(pSession);
end;
end;
This is one of the other ways that I have tried, and this one also gives the same error:
function TDelphiCommand.ExecutePost(const URL, Data: string): string;
type
PMemArray = ^TMemArray;
TMemArray = array [0..0] of byte;
var
RespStream: TMemoryStream;
ResBytes: TBytes;
aPointer: PMemArray;
PostStream: TStringStream;
S: string;
begin
Result := '{"value":""}';
PostStream := TStringStream.Create(Data, TEncoding.UTF8);
RespStream := TMemoryStream.Create;
try
PostStream.WriteString(Data);
PostStream.Position := 0;
RespStream.Size := 0;
RespStream.Position := 0;
InitHeader;
Fhttp.Request.ContentLength := PostStream.Size;
try
// Fhttp.Post(URL, PostStream, aResponseStream);
Fhttp.Post(URL, PostStream, RespStream);
RespStream.Seek(0, soFromBeginning);
aPointer := HeapAlloc(GetProcessHeap, 0, Fhttp.Response.ContentLength);
RespStream.Read(aPointer^, Fhttp.Response.ContentLength);
SetLength(ResBytes, Fhttp.Response.ContentLength);
RespStream.Read(aPointer, Fhttp.Response.ContentLength);
// VirtualProtect(@NOP_Proc, FSizeOfNOP_Proc, PAGE_EXECUTE_READWRITE, @c1);
if PByte(ResBytes)^ > 0 then
Result := TEncoding.UTF8.GetString(ResBytes);
Debug_Log(Result);
except
Debug_Log('ExecuteGet POST: ' + Result);
// Result := 'Disconnected!';
FreeAndNil(PostStream);
FreeAndNil(PostStream);
FreeAndNil(RespStream);
FreeAndNil(RespStream);
end;
finally
if Assigned(PostStream) then
FreeAndNil(PostStream);
if Assigned(RespStream) then
FreeAndNil(RespStream);
end;
end;