0

我正在尝试使用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 请求到达它,但显然没有签名请求被拒绝。

4

2 回答 2

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()

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

于 2013-04-01T13:30:47.423 回答
0

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

文件 = ( NVPair("self", "form.py"), ) 参数 = ( 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)
于 2013-10-10T01:26:38.610 回答