问题
Here's my simple-dimple code for resuming a (possibly) interrupted upload to Google Drive:
Using message = New ByteArrayContent(New Byte() {})
message.Headers.ContentRange = New Headers.ContentRangeHeaderValue(Session.Size)
'message.Headers.TryAddWithoutValidation("Content-Range", "bytes */*")
Dim response = Await PutAsync("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" & Session.Code, message)
Dim msg = Await response.Content.ReadAsStringAsync
'ERR: this is always 'Failed to parse Content-Range header.'
Dim position = 0L
If response.Headers.Contains("Range") Then
Dim range = response.Headers.GetValues("Range")
position = range.First.SplitPlus("-")(1)
End If
but Google keeps on returning
Failed to parse Content-Range header.
I checked the header manually, and it seems ok:
Content-Range: bytes */389587456
Content-Length: 0
What may the matter be?
What I tried:
Using StringContent
instead of ByteArrayContent
Using TryAddWithoutValidation
with */*
Neither work
With appeciation,
UPDATE
I tried uploading a new file from scratch. Fresh upload. Here's the code:
If response.StatusCode = 308 Then
Using fileStream = New ThrottledFileStream(Session.FilePath)
fileStream.Position = position
Using Content = New StreamContent(fileStream)
Content.Headers.ContentRange = New Headers.ContentRangeHeaderValue(position, Session.Size, Session.Size)
Using Timer = New Timer(Sub(o)
Dim ps As Long
If fileStream.CanRead Then ps = fileStream.Position
Progress.Invoke(New CloudUploadState With {.Response = response, .Position = ps})
End Sub, Nothing, 0, 20000)
Dim finishResponse = Await Put("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" & Session.Code, Content)
Progress.Invoke(New CloudUploadState With {.Response = finishResponse})
End Using
End Using
End Using
End If
But i get the exact same response:Failed to parse Content-Range header.
This is after the entire file was uploaded (based on the time it takes to return, and the position of the filesteam)
Whats wrong with my request?
Thanks
For completeness, here's the entire code basically. I'd appreciate any help or pointers:
Public Async Function Upload(Session As DriveSession, Progress As Action(Of CloudUploadState)) As Task Implements ICloudStorage.Upload
Await EnsureCredentials()
If Session.Code Is Nothing Then
Dim path = Session.FilePath
If Debugger.IsAttached Then path = IO.Path.Combine("Test", path.Replace("\\", "\").Replace(":", ""))
Dim currentFolderId = ""
For Each nextFolderName In path.Split("\")
Dim url = $"https://www.googleapis.com/drive/v3/files?fields=files(name,id)&q=name='{nextFolderName}'"
If currentFolderId <> "" Then url &= $" and '{currentFolderId}' in parents"
If path.EndsWith("\" & nextFolderName) Then
Dim metadata = New JObject From {{"name", IO.Path.GetFileName(path)}}
metadata("parents") = New JArray From {currentFolderId}
Using message = New StringContent(metadata.ToString, Encoding.UTF8, "application/json")
message.Headers.Add("X-Upload-Content-Type", GetExtMime(IO.Path.GetExtension(path).LeftCut(".")))
message.Headers.Add("X-Upload-Content-Length", Session.Size)
Dim response = Await Post($"https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable", message)
Session.Code = response.Headers.Location.QueryParams("upload_id")
Using d = GetSystemContext(True)
Dim ds = d.Find(Of DriveSession)(Session.ID)
ds.Code = Session.Code
d.SaveChanges()
End Using
End Using
'End If
Else
url &= " and mimeType = 'application/vnd.google-apps.folder'"
Dim ret = Await GetString(url)
Dim files = ParseResponse(ret)
If files.Count > 1 Then DevError("identical names")
If files.Any Then
currentFolderId = files.First.Id
Else
Dim data = New JObject From {{"name", nextFolderName}, {"mimeType", "application/vnd.google-apps.folder"}}
If currentFolderId IsNot Nothing Then data.Add(New JProperty("parents", New JArray(currentFolderId)))
Using content = New StringContent(data.ToString, Encoding.UTF8, "application/json")
Using response = Await Post("https://www.googleapis.com/drive/v3/files", content)
Dim message = Await response.Content.ReadAsStringAsync
currentFolderId = JObject.Parse(message).Value(Of String)("id")
End Using
End Using
End If
End If
Next
End If
Using message = New ByteArrayContent(New Byte() {})
message.Headers.ContentRange = New Headers.ContentRangeHeaderValue(Session.Size)
Dim response = Await PutAsync("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" & Session.Code, message)
Dim position = 0L
If response.Headers.Contains("Range") Then
Dim range = response.Headers.GetValues("Range")
position = range.First.SplitPlus("-")(1)
End If
Progress.Invoke(New CloudUploadState With {.Response = response, .Position = position})
If response.StatusCode = 308 Then
Using fileStream = New ThrottledFileStream(Session.FilePath)
fileStream.Position = position
Using Content = New StreamContent(fileStream)
Content.Headers.ContentRange = New Headers.ContentRangeHeaderValue(position, Session.Size, Session.Size)
Using Timer = New Timer(Sub(o)
Dim ps As Long
If fileStream.CanRead Then ps = fileStream.Position
Progress.Invoke(New CloudUploadState With {.Response = response, .Position = ps})
End Sub, Nothing, 0, 30000)
Dim finishResponse = Await PutAsync("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" & Session.Code, Content)
Progress.Invoke(New CloudUploadState With {.Response = finishResponse})
End Using
End Using
End Using
End If
End Using
End Function
回答1:
Ok. got it. was missing in the request "content-Length:0"
来源:https://stackoverflow.com/questions/59478445/why-is-google-drive-returning-failed-to-parse-content-range-header