aliyun / aliyun-oss-cpp-sdk

Aliyun OSS SDK for C++
Other
188 stars 88 forks source link

GetObject 请求 Range 失败 #13

Closed yanminhui closed 5 years ago

yanminhui commented 5 years ago

获取存储对象当 设置请求范围 时,返回 Failure when receiving data from the peer,示例如下:

bool COssDownload::DownloadPart(int iPartNumber
    , std::shared_ptr<std::iostream>& rpiosContent
    , std::int64_t& ri64ContentLength
    , COssError& rError)
{
    GetObjectRequest request(GetBucket(), GetKey());

    std::int64_t const ki64Start = (iPartNumber - 1) * GetPartSize();
    std::int64_t const ki64Amt = GetContentLength() - ki64Start;
    std::int64_t const ki64End = ki64Start + (GetPartSize() < ki64Amt ? GetPartSize() : ki64Amt);
    request.setRange(ki64Start, ki64End);  // FAILED
    request.setResponseStreamFactory([&rpiosContent]() { return rpiosContent;  });

    auto res = GetProxy()->GetObject(request);
    if (res.isSuccess())
    {
        return true;
    }
    rError = res.error();
    return false;
}
  • 不调用 setRange 可正常返回结果。
  • 环境: Windows 7 + VS2015
  • 区域: oss-cn-shenzhen
yanminhui commented 5 years ago

经验证,该问题发生在公司内PC上,在阿里云的服务器上测试正常。

FunriLy commented 5 years ago

可以尝试抓包对比一下报文区别

yanminhui commented 5 years ago

可以尝试抓包对比一下报文区别

@FunriLy 使用 CURLOPT_RANGE 想指定范围,依然返回整个对象,似乎服务器不理会这个值。

FunriLy commented 5 years ago

可以尝试抓包对比一下报文区别

@FunriLy 使用 CURLOPT_RANGE 想指定范围,依然返回整个对象,似乎服务器不理会这个值。

@yanminhui 我的疑惑点在于为什么阿里云服务器上是测试成功的,两个之间的报文有什么区别之处。 另外可能报文格式上不同导致返回整个对象,你可以看一下官方GetObject的报文格式 image

yanminhui commented 5 years ago

可以尝试抓包对比一下报文区别

@FunriLy 使用 CURLOPT_RANGE 想指定范围,依然返回整个对象,似乎服务器不理会这个值。

@yanminhui 我的疑惑点在于为什么阿里云服务器上是测试成功的,两个之间的报文有什么区别之处。 另外可能报文格式上不同导致返回整个对象,你可以看一下官方GetObject的报文格式 image

@FunriLy 公司禁止在外网机上安装软件(无权限安装 winpcap),暂无实验环境。

huiguangjun commented 5 years ago

你把要请求的对象设置为公开读,然后在windows 环境下,通过curl(你可以自己通过源码编译执行文件) 命令 测试一下range请求行为。先把环境的问题(例如 公司内部的proxy )排除掉。

yanminhui commented 5 years ago

你把要请求的对象设置为公开读,然后在windows 环境下,通过curl(你可以自己通过源码编译执行文件) 命令 测试一下range请求行为。先把环境的问题(例如 公司内部的proxy )排除掉。

初步 确认公司网络环境问题。

# curl -v -r 10-11 http://www.baidu.com/index.html
*   Trying 14.215.177.39...
* Connected to www.baidu.com (14.215.177.39) port 80 (#0)
> GET /index.html HTTP/1.1
> Host: www.baidu.com
> Range: bytes=10-11
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 206 Partial Content
< Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
< Connection: Keep-Alive
< Content-Length: 2
< Content-Range: bytes 10-11/2381
< Content-Type: text/html
< Date: Mon, 06 May 2019 05:35:28 GMT
< Etag: "588604dd-94d"
< Last-Modified: Mon, 23 Jan 2017 13:27:57 GMT
< Pragma: no-cache
< Server: bfe/1.0.8.18
< Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
<
* Connection #0 to host www.baidu.com left intact
PS > ./curl.exe -v -r 10-11 http://www.baidu.com/index.html
* About to connect() to www.baidu.com port 80 (#0)
*   Trying 14.215.177.39...
* Connected to www.baidu.com (14.215.177.39) port 80 (#0)
> GET /index.html HTTP/1.1
> Range: bytes=10-11
> User-Agent: curl/7.29.0
> Host: www.baidu.com
> Accept: */*
>
* Recv failure: Connection was reset
* Closing connection 0
curl: (56) Recv failure: Connection was reset