我正在使用Delphi Rest Client组件将文件上传到Google云端硬盘。
我使用可恢复的下载。在第一次请求之后,响应代码应该来308上传不完整,之后有必要发送部分文件。
System.HTTPPClient
正在尝试执行某些操作,因为默认情况下308 =永久重定向并最终提供访问冲突。如何解决这种情况呢?
这是上传文件
UploadStream := TMemoryStream.Create;
fFile := TFileStream.Create(fileName,fmOpenRead);
GetMem(buffer, onePartion);
fFileSize := fFile.Size;
alreadyWrite := 0;
try
while(fFile.Position < 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;
此System.Net.HTTPClient
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 <> sHTTPMethodHead) then
begin
Inc(State.Redirections);
if State.Redirections > 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;
Status = 308,然后执行DoProcessStatus函数(LRequest,LResponse)
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 >= 300) and (AResponse.StatusCode < 400) then //Redirect
begin
LURI := TURI.Create(TURI.PathRelativeToAbs(LResponse.GetHeaderValue('Location'), LRequest.FURL));
if SameText(LRequest.GetMethodString, 'POST')
and ( (AResponse.StatusCode >= 301) and (AResponse.StatusCode <= 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;
LURI:= TURI.Create(TURI.PathRelativeToAbs(LResponse.GetHeaderValue('Location'),LRequest.FURL));
在这一行 - AV。我认为因为Response没有带有此名称的标题,并且他不能拥有此标题。