使用Grinder API使用HTTP PUT请求发送表单数据

时间:2013-03-30 20:44:47

标签: jython grinder

我尝试使用Grinder复制以下成功的cURL操作。

curl -X PUT -d "title=Here%27s+the+title&content=Here%27s+the+content&signature=myusername%3A3ad1117dab0ade17bdbd47cc8efd5b08" http://www.mysite.com/api

这是我的剧本:

from net.grinder.script import Test
from net.grinder.script.Grinder import grinder
from net.grinder.plugin.http import HTTPRequest
from HTTPClient import NVPair
import hashlib

test1 = Test(1, "Request resource")
request1 = HTTPRequest(url="http://www.mysite.com/api")
test1.record(request1)
log = grinder.logger.info
test1.record(log)
m = hashlib.md5()

class TestRunner:
    def __call__(self):
        params = [NVPair("title","Here's the title"),NVPair("content", "Here's the content")]
        params.sort(key=lambda param: param.getName())
        ps = ""
    for param in params:
            ps = ps + param.getValue() + ":"
        ps = ps + "myapikey"
        m.update(ps)
        params.append(NVPair("signature", ("myusername:" + m.hexdigest())))
        request1.setFormData(tuple(params))
        result = request1.PUT()

测试运行正常,但似乎我的脚本实际上并没有将任何params数据发送到API,我无法解决原因。没有生成错误,但是我从API获得了401 Unauthorized响应,表明成功的PUT请求到达了它,但显然没有签名,请求被拒绝。

2 个答案:

答案 0 :(得分:0)

这不是一个答案,更多的是我提出的解决方法,我决定发布,因为这个问题还没有收到任何回复,它可能会帮助其他人试图达到同样的目的的事情。

解决方法基本上是使用httplib和urllib模块来构建和发出PUT请求而不是HTTPClient模块。

import hashlib
import httplib, urllib

....

params = [("title", "Here's the title"),("content", "Here's the content")]
params.sort(key=lambda param: param[0])
ps = ""
for param in params:
    ps = ps + param[1] + ":"
ps = ps + "myapikey"
m = hashlib.md5()
m.update(ps)
params.append(("signature", "myusername:" + m.hexdigest()))

params = urllib.urlencode(params)
print params
headers = {"Content-type": "application/x-www-form-urlencoded"}
conn = httplib.HTTPConnection("www.mysite.com:80")
conn.request("PUT", "/api", params, headers)
response = conn.getresponse()
print response.status, response.reason
print response.read()
conn.close()

(基于this文档页面底部的示例。)

答案 1 :(得分:0)

您必须参考Grinder脚本库中的多表单发布示例,但将Post更改为Put。它对我有用。

files =(NVPair(“self”,“form.py”),)         parameters =(NVPair(“run number”,str(grinder.runNumber)),)

    # This is the Jython way of creating an NVPair[] Java array
    # with one element.
    headers = zeros(1, NVPair)

    # Create a multi-part form encoded byte array.
    data = Codecs.mpFormDataEncode(parameters, files, headers)
    grinder.logger.output("Content type set to %s" % headers[0].value)

    # Call the version of POST that takes a byte array.
    result = request1.PUT("/upload", data, headers)