使用 httr(在 R 上)将空 body 放入 webHDFS

PUT with an empty body using httr (on R) to webHDFS

当尝试放入 WebHDFS 以创建文件并写入文件时(使用以下 link:https://hadoop.apache.org/docs/r1.0.4/webhdfs.html#CREATE)我 运行 使用 [=18= 遇到问题].

无法使用 RCurl 或 RWebHDFS,因为目标 Hadoop 集群是安全的。

这是我尝试使用的代码:

library(httr)
r <- PUT("https://hadoopmgr1p.global.ad:14000/webhdfs/v1/user/testuser/temp/loadfile_testuser_2019-11-28_15_28_41411?op=CREATE&permission=755&user.name=testuser", 
          authenticate(":", "", type = "gssnegotiate"),
          verbose())

testuser 是具有 R/W 权限的超级用户。我收到以下错误:

<- HTTP/1.1 400 Data upload requests must have content-type set to 'application/octet-stream'
<- Date: Fri, 29 Nov 2019 15:42:30 GMT
<- Date: Fri, 29 Nov 2019 15:42:30 GMT
<- Pragma: no-cache
<- X-Content-Type-Options: nosniff
<- X-XSS-Protection: 1; mode=block
<- Content-Length: 0

这个错误很容易解释,所以我尝试用 content-type:

进行 PUT
r <- PUT("https://hadoopmgr1p.global.ad:14000/webhdfs/v1/user/testuser/temp/loadfile_testuser_2019-11-28_15_28_41411?op=CREATE&permission=755&user.name=testuser", 
          authenticate(":", "", type = "gssnegotiate"),
          content_type("application/octet-stream"),
          verbose())

我成功了 - 然而它并不是真正的成功:

<- Date: Fri, 29 Nov 2019 16:04:52 GMT
<- Cache-Control: no-cache
<- Expires: Fri, 29 Nov 2019 16:04:52 GMT
<- Date: Fri, 29 Nov 2019 16:04:52 GMT
<- Pragma: no-cache
<- Content-Type: application/json;charset=utf-8
<- X-Content-Type-Options: nosniff
<- X-XSS-Protection: 1; mode=block
<- Content-Length: 0

没有上传的文件。使用第一个请求上传文件,给我另一个错误:

<- HTTP/1.1 307 Temporary Redirect
<- Date: Fri, 29 Nov 2019 16:07:24 GMT
<- Cache-Control: no-cache
<- Expires: Fri, 29 Nov 2019 16:07:24 GMT
<- Date: Fri, 29 Nov 2019 16:07:24 GMT
<- Pragma: no-cache
<- Content-Type: application/json;charset=utf-8
<- X-Content-Type-Options: nosniff
<- X-XSS-Protection: 1; mode=block
Error in curl::curl_fetch_memory(url, handle = handle) : 
  necessary data rewind wasn't possible

有问题的代码:

library(httr)
temp_file <- httr::upload_file(lfs_temp_file, type = "text/plain")
r <- PUT("https://hadoopmgr1p.global.ad:14000/webhdfs/v1/user/testuser/temp/loadfile_testuser_2019-11-28_15_28_41411?op=CREATE&permission=755&user.name=testuser", 
          authenticate(":", "", type = "gssnegotiate"),
          body=temp_file,
          content_type("application/octet-stream"),
          verbose())

使用 curl 尝试执行相同的命令没有问题: curl -i -k -X PUT --negotiate -u : "https://hadoopmgr1p.global.ad:14000/webhdfs/v1/user/testuser/temp/loadfile_testuser_2019-11-28_15_28_4141?op=CREATE&permission=755&user.name=testuser"

结果如下:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0HTTP/1.1 307 Temporary Redirect
Date: Thu, 28 Nov 2019 23:27:16 GMT
Cache-Control: no-cache
Expires: Thu, 28 Nov 2019 23:27:16 GMT
Date: Thu, 28 Nov 2019 23:27:16 GMT
Pragma: no-cache
Content-Type: application/json;charset=utf-8
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
WWW-Authenticate: Negotiate <stuff>/
Set-Cookie: hadoop.auth="<stuff>"; Path=/; Secure; HttpOnly
Location: https://hadoopmgr1p.global.ad:14000/webhdfs/v1/user/testuser/temp/loadfile_testuser_2019-11-28_15_28_4141?op=CREATE&data=true&user.name=testuser&permission=755
Content-Length: 0

按照Location header让我们成功创建文件。

我做错了什么?

谢谢

干得好,包括 curl 输出。我相信这就是答案。

您的 curl 命令使用 PUT,您的 httr 命令使用 POST。尝试 https://www.rdocumentation.org/packages/httr/versions/1.4.1/topics/PUT .

供将来参考的提示:POST 命令通常不会在您指定确切位置时使用。这就是 PUT 的目的。

httr 正在尝试遵循重定向,但失败了。要解决此问题,请告诉 httr 停止关注位置 config(followlocation = 0L)

PUT命令如下:

r <- PUT("https://hadoopmgr1p.global.ad:14000/webhdfs/v1/user/testuser/temp/
          loadfile_testuser_2019-11-28_15_28_41411?op=CREATE&permission=755&user.name=testuser", 
          authenticate(":", "", type = "gssnegotiate"),
          body=NULL,
          config(followlocation = 0L),
          verbose())

这应该 return 一个有效的响应,其位置 header。