Why is Google Drive returning 'Failed to parse Content-Range header.'?

不问归期 提交于 2021-01-28 02:11:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!