title: Delphi Rest Api Google Drive Upload File
body: <p>I'm using Delphi Rest Client component to upload file to Google Drive. 
  I use a resumable download. After the first request, the response code should come 308 upload is not complete, and afterwards it is necessary to send parts of the files.
  <code>System.HTTPPClient</code> is trying to do something, because by default 308 = permanent redirect and eventually gives an Access Violation. How can this situation be solved?</p>
  
  <p>This is upload file</p>
  
  <pre><code>UploadStream := TMemoryStream.Create;
  fFile := TFileStream.Create(fileName,fmOpenRead);
  GetMem(buffer, onePartion);
  
  fFileSize := fFile.Size;
  alreadyWrite := 0;
  try
      while(fFile.Position &lt; fFile.Size) do
    begin
      FillChar(buffer[0], onePartion, #0);
      UploadStream.Clear;
  
      liReaded := fFile.Read(buffer[0], onePartion);
      UploadStream.Write(buffer[0], liReaded);
      UploadStream.Position := 0;
  
      addAuthParam;
  
      fRESTRequest.Params.Add;
      fRESTRequest.Params[1].Kind:=TRESTRequestParameterKind.pkHTTPHEADER;
          fRESTRequest.Params[1].name:='Content-Range';
          fRESTRequest.Params[1].Options:=[poDoNotEncode];
          fRESTRequest.Params[1].Value:='bytes ' + IntToStr(alreadyWrite) + '-' + IntToStr(alreadyWrite+liReaded-1) + '/' + IntToStr(fFileSize);
          fRESTRequest.ClearBody;
          fRESTRequest.AddBody(UploadStream,ctAPPLICATION_ZIP);
      try
          fRESTRequest.Execute;
      except
  
      end;
  
  
      alreadyWrite := alreadyWrite + liReaded;
    end;
  </code></pre>
  
  <p>This System.Net.HTTPClient</p>
  
  <pre><code>if LRequest.FCancelled then
      Exit;
    LExecResult := DoExecuteRequest(LRequest, LResponse, AContentStream);
    if LRequest.FCancelled then
      Exit;
    case LExecResult of
      TExecutionResult.Success:
        begin
          if not SameText(LRequest.FMethodString, sHTTPMethodHead) then
            LResponse.DoReadData(LResponse.FStream);
          if LRequest.FCancelled then
            Exit;
          Status := LResponse.GetStatusCode;
          case Status of
            200:
              begin
                Break;
              end;
            401:
              begin
                State.Status := InternalState.ServerAuthRequired;
              end;
            407:
              begin
                State.Status := InternalState.ProxyAuthRequired;
              end;
            else
              begin
                case Status of
                  301..304, 307:
                    if FHandleRedirects and (LRequest.FMethodString &lt;&gt; sHTTPMethodHead) then
                    begin
                      Inc(State.Redirections);
                      if State.Redirections &gt; FMaxRedirects then
                        raise ENetHTTPRequestException.CreateResFmt(@SNetHttpMaxRedirections, [FMaxRedirects]);
                    end
                    else
                      Break;
                else
                end;
                State.Status := InternalState.Other;
                if DoProcessStatus(LRequest, LResponse) then
                  Break;
              end;
          end;
        end;
  </code></pre>
  
  <p>Status = 308, then do function DoProcessStatus(LRequest, LResponse)</p>
  
  <pre><code>function TWinHTTPClient.DoProcessStatus(const ARequest: IHTTPRequest; const AResponse: IHTTPResponse): Boolean;
  var
    LRequest: TWinHTTPRequest;
    LResponse: TWinHTTPResponse;
    LURI: TURI;
  begin
    LRequest := ARequest as TWinHTTPRequest;
    LResponse := AResponse as TWinHTTPResponse;
    // If the result is true then the while ends
  
    Result := True;
    if (AResponse.StatusCode &gt;= 300) and (AResponse.StatusCode &lt; 400) then //Redirect
    begin
      LURI := TURI.Create(TURI.PathRelativeToAbs(LResponse.GetHeaderValue('Location'), LRequest.FURL));
  if SameText(LRequest.GetMethodString, 'POST')
    and ( (AResponse.StatusCode &gt;= 301) and (AResponse.StatusCode &lt;= 303) ) then
    begin
      LRequest.FMethodString := 'GET'; // Change from POST to GET
      LRequest.FSourceStream := nil;  // Donot send any data
    end;
  
      LRequest.UpdateRequest(LURI);
      LResponse.UpdateHandles(LRequest.FWConnect, LRequest.FWRequest);
      Result := False;
    end;
  end;
  </code></pre>
  
  <p>LURI := TURI.Create(TURI.PathRelativeToAbs(LResponse.GetHeaderValue('Location'), LRequest.FURL));</p>
  
  <p>On this line - AV. I think because Response doesn't have header with this name, and he mustn't have this header. </p>