google-drive-api - 为什么 Google Drive 返回“无法解析 Content-Range 标头。”?
问题描述
这是我用于恢复(可能)中断上传到 Google 云端硬盘的简单酒窝代码:
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
但谷歌不断回归
无法解析 Content-Range 标头。
我手动检查了标题,似乎没问题:
Content-Range: bytes */389587456
Content-Length: 0
可能是什么问题?
我尝试了什么:
使用StringContent
代替ByteArrayContent
与TryAddWithoutValidation
_*/*
都不工作
满怀期待,
更新
我尝试从头开始上传新文件。新鲜上传。这是代码:
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
但我得到了完全相同的回应:Failed to parse Content-Range header.
这是在整个文件上传之后(基于返回所需的时间,以及文件流的位置)
我的要求有什么问题?
谢谢
为了完整起见,这里基本上是整个代码。我将不胜感激任何帮助或指示:
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
解决方案
好的。知道了。请求中缺少“内容长度:0”
推荐阅读
- drools - 如何在 Kie(RedHat 决策管理器)中将决策服务作为无状态会话调用
- reactjs - 上下文 API 组件WillUnmount
- powershell - 如何使用 get-aduser 命令中的多个 where-object 条件获取“那些被排除的用户”的报告?
- python-3.x - 如何将唯一标识符列添加到熊猫数据框中?
- sql - SQL Server:当条件匹配且不重复时从第二个表中获取数据
- angular - 使用表单数组中另一个控件的值的最大验证器值
- javascript - 函数内的 fullcalendar-4
- c++ - 安装包时 vcpkg 找不到 cmake.cmd
- python - 您如何根据顺序比较两组列表?
- sql - 将两个不同的时间戳记入日期时间桶