我正在尝试使用REST APi for Paperless ngx将文档上传到http服务器,它们的说明如下。。
张贴文档
API为文件上传提供了一个特殊的端点:
/api/documents/post_document/
将多部分表单POST到此端点,其中表单字段文档包含要上载到无纸化的文档。这个文件名被清除,然后用于将文档存储在临时目录,消费者将被指示消费那里的文件。
端点支持以下可选表单字段:
title:指定使用者应用于文档的标题。
created:指定创建文档的日期时间(例如"2016-04-19"或"2016-04-1906:15:00+02:00"(。
通讯器:指定使用者应用于文档的通讯器的ID。
document_type:类似于通讯员。
tags:类似于通讯员。多次指定此项可将多个标记添加到文档中。
如果文档消耗进程已成功启动。没有其他状态信息关于消费过程本身是可用的,因为发生了这种情况在不同的过程中
虽然我已经能够用curl实现我所需要的(见下文(,但我希望用Lua实现同样的结果。
curl -H "Authorization: Basic Y2hyaXM62tgbsgjunotmeY2hyaXNob3N0aW5n" -F "title=Companies House File 10" -F "correspondent=12" -F "document=@/mnt/nas/10.pdf" http://192.168.102.134:8777/api/documents/post_document/
在Lua方面,我尝试了各种方法来实现这一点,但都没有成功,充其量只是超时,结果为零。
更新:我已经从零超时进入400 table: 0x1593c00 HTTP/1.1 400 Bad Request {"document":["No file was submitted."]}
错误消息
请有人帮忙。。
local http = require("socket.http")
local ltn12 = require("ltn12")
local mime = require("mime")
local lfs = require("lfs")
local username = "username"
local password = "password"
local httpendpoint = 'http://192.168.102.134:8777/api/documents/post_document/'
local filepath = "/mnt/nas/10.pdf"
local file = io.open(filepath, "rb")
local contents = file:read( "*a" )
-- https://stackoverflow.com/questions/3508338/what-is-the-boundary-in-multipart-form-data
local boundary = "somerndstring"
local send = "--"..boundary..
"rnContent-Disposition: form-data; "..
"title='testdoc'; document="..filepath..
--"rnContent-type: image/png"..
"rnrn"..contents..
"rn--"..boundary.."--rn";
-- Execute request (returns response body, response code, response header)
local resp = {}
local body, code, headers, status = http.request {
url = httpendpoint,
method = 'POST',
headers = {
-- ['Content-Length'] = lfs.attributes(filepath, 'size') + string.len(send),
-- ["Content-Length"] = fileContent:len(),
-- ["Content-Length"] = string.len(fileContent),
["Content-Length"] = lfs.attributes(filepath, 'size'),
['Content-Type'] = "multipart/form-data; boundary="..boundary,
["Authorization"] = "Basic " .. (mime.b64(username ..":" .. password)),
--body = send
},
source = ltn12.source.file( io.open(filepath,"rb") ),
sink = ltn12.sink.table(resp)
}
print(body, code, headers, status)
print(table.concat(resp))
if headers then
for k,v in pairs(headers) do
print(k,v)
end
end
似乎您的Content-Length
标头值超过了您试图发送的实际内容长度。
这会导致远程服务器等待来自您的更多数据,而您不会提供这些数据。因此,连接因超时而终止。
检查您的代码:
local size = lfs.attributes(filepath, 'size') + string.len(send)
send
变量已包含您的文件内容,因此不应通过调用lfs.attributes
两次添加文件内容长度。
试试这个:
local size = string.len(send)
您也没有在实际请求中的任何位置使用send
变量,这是另一个错误。
非常感谢GitHub上的一个人,他帮助了我,并且有自己的模块来做这件事-https://github.com/catwell/lua-multipart-post。
local http = require("socket.http")
local ltn12 = require("ltn12")
local lfs = require "lfs"
http.TIMEOUT = 5
local function upload_file ( url, filename )
local fileHandle = io.open( filename,"rb")
local fileContent = fileHandle:read( "*a" )
fileHandle:close()
local boundary = 'abcd'
local header_b = 'Content-Disposition: form-data; name="document"; filename="' .. filename .. '"rnContent-Type: application/pdf'
local header_c = 'Content-Disposition: form-data; name="title"rnrnCompanies House File'
local header_d = 'Content-Disposition: form-data; name="correspondent"rnrn12'
local MP_b = '--'..boundary..'rn'..header_b..'rnrn'..fileContent..'rn'
local MP_c = '--'..boundary..'rn'..header_c..'rn'
local MP_d = '--'..boundary..'rn'..header_d..'rn'
local MPCombined = MP_b..MP_c..MP_d..'--'..boundary..'--rn'
local response_body = { }
local _, code = http.request {
url = url ,
method = "POST",
headers = { ["Content-Length"] = MPCombined:len(),
['Content-Type'] = 'multipart/form-data; boundary=' .. boundary
},
source = ltn12.source.string(MPCombined) ,
sink = ltn12.sink.table(response_body),
}
return code, table.concat(response_body)
end
local rc,content = upload_file ('http://httpbin.org/post', '/mnt/nas/10.pdf' )
print(rc,content)