TScHttpWebRequest.GetResponse When an exception occurs, the object is freed , Result.Free adjust to FreeAndNil(Result) is it better ???

TScHttpWebRequest.GetResponse When an exception occurs, the object is freed , Result.Free adjust to FreeAndNil(Result) is it better ???

function {$IFNDEF SBRIDGE}TCRHttpWebRequest{$ELSE}TScHttpWebRequest{$ENDIF}.GetResponse(CancellationToken: TScCancellationToken = nil): {$IFNDEF SBRIDGE}TCRHttpWebResponse{$ELSE}TScHttpWebResponse{$ENDIF};

  function StatusIsTimeout(StatusCode: integer): boolean;
  begin
    Result := (StatusCode = 502) or (StatusCode = 503) or (StatusCode = 504);
  end;

  function StatusIsRedirection(StatusCode: integer): boolean;
  begin
    Result := (StatusCode >= 300) and (StatusCode <= 308);
  end;

var
  ConnectionParameters: TScSecureConnectionParameters;
  Hostname: string;
  Port: integer;
  UserName, Password: string;
  ServerMessage: string;
  RetryCount, Redirections: integer;
  IsInternalTimeout: boolean;
  IsSecure: boolean;
  UsePooling: boolean;
begin
  CheckInactive;
  CheckRequest;

  FStatusCode := 0;
  FStatusDescription := '';
  ServerMessage := '';
  RetryCount := 0;
  Redirections := 0;
  IsInternalTimeout := False;

  Result := {$IFNDEF SBRIDGE}TCRHttpWebResponse{$ELSE}TScHttpWebResponse{$ENDIF}.Create;
  try
    try
      repeat
        DoBeforeSendRequest;

        TScHttpParser.ParseURL(FAddress, FScheme, UserName, Password,
          FNetworkLocation, FPort, FPath, FResource, FParameters, FQuery, FFragment);
        if FScheme = '' then
          FScheme := HttpScheme;

        if (UserName <> '') or (Password <> '') then begin
          FCredentials.UserName := UserName;
          FCredentials.Password := Password;
        end;

        if FPort = '' then
          FPortNo := StrToInt(DefaultPort(FScheme))
        else
          FPortNo := StrToInt(Copy(FPort, 2, Length(FPort)));

        if (FProxy.Address <> '') and (FProxy.SocksVersion = svNoSocks) then begin
          Hostname := FProxy.Address;
          Port := FProxy.Port;
        end
        else begin
          Hostname := FNetworkLocation;
          Port := FPortNo;
        end;

        IsInternalTimeout := False;
        IsSecure := AnsiSameText(FScheme, 'https:') or AnsiSameText(FScheme, 'wss:');
        FSSLOptions.IdentityDNSName := FNetworkLocation;

        Assert(FSecureConnection = nil);
        UsePooling := (FConnectionGroupName <> '') and FKeepAlive;

        ConnectionParameters := TScSecureConnectionParameters.Create;
        try
          ConnectionParameters.ConnectionGroupName := FConnectionGroupName;
          ConnectionParameters.Hostname := Hostname;
          ConnectionParameters.Port := Port;
          ConnectionParameters.IPVersion := FIPVersion;
          ConnectionParameters.Timeout := FReadWriteTimeout;
          ConnectionParameters.IsSecure := IsSecure;
          ConnectionParameters.SSLOptions.Assign(FSSLOptions);
          if FProxy.SocksVersion <> svNoSocks then begin
            ConnectionParameters.ProxyOptions.Hostname := FProxy.Address;
            ConnectionParameters.ProxyOptions.Port := FProxy.Port;
            ConnectionParameters.ProxyOptions.Username := FProxy.Credentials.UserName;
            ConnectionParameters.ProxyOptions.Password := FProxy.Credentials.Password;
            ConnectionParameters.ProxyOptions.SocksVersion := FProxy.SocksVersion;
          end;

        {$IFNDEF SBRIDGE}
          ConnectionParameters.IOHandler := FIOHandler;
        {$ENDIF}

          if UsePooling then begin
            FSecureConnection := TScConnectionPoolManager.GetConnection(ConnectionParameters);
            FSecureConnection.AddRef;
            FSecureConnection.SetReadWriteTimeout(FReadWriteTimeout);
          end
          else begin
            FSecureConnection := TScSecureConnection.Create;
            FSecureConnection.CreateVio(ConnectionParameters);
          end;
        finally
          ConnectionParameters.Free;
        end;

        Result.FSecureConnection := FSecureConnection;
        Result.FSecureConnection.AddRef;
        Result.FStatusCode := 0;

        if CancellationToken <> nil then
          CancellationToken.ThrowIfCancellationRequested;

        if not FSecureConnection.IsConnected then begin
          FSecureConnection.Connect(CancellationToken);

          if (FProxy.Address <> '') and (FProxy.SocksVersion = svNoSocks) and (FMethod <> rmCONNECT) then begin
            FOldMethod := FMethod;
            try
              FMethod := rmCONNECT;
              SendRequest(CancellationToken);
              Result.FMethod := FMethod;
              Result.RetrieveHeaders(CancellationToken);
            finally
              FMethod := FOldMethod;
            end;
          end;
        end;

        try
          if (Result.FStatusCode = 0) or (Result.FStatusCode = 200) then begin
            Result.FStatusCode := 0;
            if IsSecure then begin
            {$IFDEF SBRIDGE}
              if FAssignedSessionInfo <> nil then
                FSecureConnection.AssignSession(FAssignedSessionInfo);
            {$ENDIF}
              FSecureConnection.IsSecure := True;
            end;

            FOldMethod := FMethod;

            SendRequest(CancellationToken);

            DoAfterSendRequest;

            if Assigned(FOnConnected) then
              FOnConnected(Self);

            Result.FMethod := FMethod;
            Result.RetrieveHeaders(CancellationToken);
            DoAfterRetrieveHeaders;
          end;
        except
          on SocketException do
            if UsePooling then begin
              IsInternalTimeout := True;
              Result.FStatusCode := 504;
            end
            else
              raise;
        end;

        if StatusIsTimeout(Result.FStatusCode) then begin
          Inc(RetryCount);
          if RetryCount > FMaximumAutomaticReconnections then
            if IsInternalTimeout then
              FSecureConnection.RaiseLastError
            else
              raise HttpException.Create(Result.FStatusCode, Result.FStatusDescription);

          if Result.FStatusCode = 503 then begin
            if (Result.FRetryAfter > 0) and (Result.FRetryAfter <= ReadWriteTimeout) then
              Sleep(Result.FRetryAfter * 1000)
            else
              raise HttpException.Create(Result.FStatusCode, Result.FStatusDescription);
          end
          else
            Sleep(RetryCount * 1000);
        end
        else
        if StatusIsRedirection(Result.FStatusCode) then begin
          Inc(Redirections);
          if (Redirections > FMaximumAutomaticRedirections) or (Result.FLocation = '') or (FAddress = Result.FLocation) then
            raise HttpException.Create(Result.FStatusCode, Result.FStatusDescription)
          else
          if Result.FStatusCode = 305 then begin
            FProxy.Address := Result.FLocation;
            FProxy.SocksVersion := svNoSocks;
          end
          else
            FAddress := Result.FLocation;

          if Result.FCookies.Count > 0 then begin
            FCookies.Clear;
            FCookies.AddStrings(Result.FCookies);
          end;

          if FMethod = rmCONNECT then
            FMethod := rmGET;

          // FURL := 'http://' + Host + '/' + FURL;
          if (FAddress <> '') and (Pos('//', FAddress) = 0) and (FAddress[1] = '/') then
            FAddress := FScheme + '//' + FNetworkLocation + FPort + FAddress;
        end
        else
        if (Result.FStatusCode = 401) and Assigned(FOnAuthenticationNeeded) then
          FOnAuthenticationNeeded(Self)
        else
        if Result.FStatusCode >= 400 then begin
          if (Result.ContentLength > 0) or Result.FChunked then
            ServerMessage := Result.ReadAsString;

          if not (ConvertToStatusCode(Result.FStatusCode) in FAllowedStatuses) then
            raise HttpException.Create(Result.FStatusCode, Result.FStatusDescription, ServerMessage);
        end;

        if StatusIsRedirection(Result.FStatusCode) or StatusIsTimeout(Result.FStatusCode) then begin
          if FSecureConnection <> nil then begin
            FSecureConnection.Disconnect;
            FSecureConnection.Release;
            FSecureConnection := nil;
          end;
          Result.FSecureConnection.Release;
          Result.FSecureConnection := nil;
        end;

      until not StatusIsRedirection(Result.FStatusCode) and not StatusIsTimeout(Result.FStatusCode);
    finally
      if Assigned(FOnConnected) then
        FOnConnected(Self);
    end;

    Result.FResponseUri := FAddress;

  except
    on E: Exception do begin
      FStatusCode := Result.FStatusCode;
      FStatusDescription := Result.FStatusDescription;
      if FStatusDescription = '' then
        FStatusDescription := E.Message;

      if FSecureConnection <> nil then begin
        FSecureConnection.Disconnect;
        FSecureConnection.Release;
        FSecureConnection := nil;
      end;

      Result.Free;    //  FreeAndNil(Result) ;

      if not IsInternalTimeout and (FStatusCode <> 0) and (FStatusCode <> 200) then
        raise HttpException.Create(FStatusCode, FStatusDescription, ServerMessage)
      else
        raise;
    end;
  end;
end;