Jump to content
FloppyDesk

Help: Ics wrong recieve response app-json!

Recommended Posts

Hello, i have a problem when i recieve response from only one response!

I tried to analyze the request which i send from SOFT by "http analyzer/debugger" and analyzer shows me good !!!JSON!!! response which is:

Quote

{"error":"invalid_grant","error_description":"Invalid Grant"}

But, if i write "rcvdstream" to a file for see the result i got ANOTHER result which is not JSON!

 

Here is my code:

 

1. Headers:

procedure TConnector.SetHttpHeadersCFV;
begin

  FHttpIcs.Agent := FUserAgent;
  FHttpIcs.ContentTypePost := cAppFormUrlEnc;
  FHttpIcs.Accept := ' application/json, text/javascript, */*; q=0.01';
  FHttpIcs.AcceptLanguage := 'en-US;q=0.5,en;q=0.3';

  FHeaders := '';

  AddHeader('X-CORRELATION-ID: ' + FColeractionId);

  AddHeader('x-via-hint_dca: ' + '1_MTM0Mw==');
  AddHeader('Origin: ' + 'https://cnn.com/');
  AddHeader('Referer: ' +
    'https://google.com');
  AddHeader('X-THMID: ' + FXtmId);
  AddHeader('dfpSessionID: ' + FSessionId);
  AddHeader('X-Requested-With: ' + 'XMLHttpRequest');
  AddHeader('Accept-Encoding: gzip, deflate');

  FHttpIcs.ExtraHeaders.Text := FHeaders;

end;

Note: about encoding, i tried to delete accept-encoding header, no helps...

 

2. Sending request:

  // set post params
  // set headers

  // requesting....
  FHttpIcs.RcvdStream := FResponseStream;
  // url .. https://..../
  FHttpIcs.Url := Url;
  try

    FHttpIcs.Post();

    if (FHttpIcs.StatusCode = cTooManyReqCode) then
      raise Exception.Create('err connection');

    FHtmlResponse := FConnectorUtils.StreamToString(FResponseStream,
      TEncoding.Default);

    // !!!!! HTML RESPONSE IS INCORRECT !!!!! ////
    FConnectorUtils.LogToFile('htmlresponse_.txt', FHtmlResponse);

    // status code is correct!
    FConnectorUtils.LogToFile('statuscode_.txt', FHttpIcs.StatusCode.ToString);
    // phrase is correct!
    FConnectorUtils.LogToFile('phrase_.txt', FHttpIcs.ReasonPhrase);
    // last response is EMPTY!!!!
    FConnectorUtils.LogToFile('lastresponse_.txt', FHttpIcs.LastResponse);
  except
    // !!!!! HTML RESPONSE IS INCORRECT !!!!! ////
    FConnectorUtils.LogToFile('htmlresponse_.txt', FHtmlResponse);

    // status code is correct!
    FConnectorUtils.LogToFile('statuscode_.txt', FHttpIcs.StatusCode.ToString);
    // phrase is correct!
    FConnectorUtils.LogToFile('phrase_.txt', FHttpIcs.ReasonPhrase);
    // last response is EMPTY!!!!
    FConnectorUtils.LogToFile('lastresponse_.txt', FHttpIcs.LastResponse);
    ReCheck(TMethods.SendRequestM);
  end;

Can someone help me please?

thank you in advance!

Share this post


Link to post

Don't know what FConnectorUtils.StreamToString does, but you always have to seek to beginning of the stream before reading it. 

 

There is a new function that convert an HTML page in the buffer to unicode string with the correct codepage:

FResponseRaw := IcsHtmlToStr(FResponseStream, FContentType, true);

Last boolean option converts HTML entries like £ and ☍ to unicode. 

 

That function is used in the new TSslHttpRest unit that hides a lot of the low level stuff you are doing returning Json.

 

Angus

  • Like 1

Share this post


Link to post
49 minutes ago, Angus Robertson said:

Don't know what FConnectorUtils.StreamToString does, but you always have to seek to beginning of the stream before reading it. 

 

There is a new function that convert an HTML page in the buffer to unicode string with the correct codepage:

FResponseRaw := IcsHtmlToStr(FResponseStream, FContentType, true);

Last boolean option converts HTML entries like £ and ☍ to unicode. 

 

That function is used in the new TSslHttpRest unit that hides a lot of the low level stuff you are doing returning Json.

 

Angus

Tried this code

Quote

  const

   cAppFormUrlEnc = 'application/x-www-form-urlencoded';

 

FHtmlResponse := IcsHtmlToStr(FResponseStream, cAppFormUrlEnc, True);

But problem not solved, same result in txt files in folder.

 

Here is FConnectorUtils.StreamToStringCode:

function TConnectorUtils.StreamToString(const Stream: TStream;
  const Encoding: TEncoding): string;
var
  StringBytes: TBytes;
begin
  Stream.Position := 0;
  SetLength(StringBytes, Stream.Size);

  Stream.ReadBuffer(StringBytes[0], Stream.Size);
  Result := Encoding.GetString(StringBytes);
end;

 

 

UPD!!!: PROBLEM SOLVED

Problem was in EXCEPT BLOCK:

 I tried to parse html only on TRY block, but not in except. (Result Code of response is 400)

 

One more question, can i disable this function like in indy? If  responsecode > 400 then raise exception?

 

Edited by FloppyDesk

Share this post


Link to post

It is better to process the response in the onRequestDone event. 

 

There is a new property added a year ago ResponseNoException which will help you.

 

Angus

 

  • Like 1

Share this post


Link to post
4 hours ago, Angus Robertson said:

It is better to process the response in the onRequestDone event. 

 

There is a new property added a year ago ResponseNoException which will help you.

 

Angus

 

Thank you so much  - Angus!

Tried this property, all works!

 

But this "OnRequestDone" event, i tried to write some code and i got stucked at one question.

For example, we have error = 1 (which is bad connection) how i can reconnect same request with same headers/post parameters?

 

I have much methods with requests, new headers, new post params, how i can handle this in this event?

 

Thanks!

Share this post


Link to post

Most better ICS applications use Async methods so are fully event driven, allowing multiple connections are the same time in a single thread.  So most of the code goes in various event 

 

But sync calls are easier to use from a program flow perspective and the code can either be in the event are after the sync call, although exceptions cause trouble which is why I added ResponseNoException. But sync programs are less suited to multiple connections or tasks at the same time. 

 

In event driven applications, you usually use messages from an event to start something new  or a triggers in a timer event to start another connection 60 seconds later of something, I do that a lot.

 

Angus

 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×