I wrote some lua script for wrk to generate multiple POST requests.
My problem is that my script is working only for the first request. All further generated requests are exactly the same as the first one. I would like that user variable will be new generated for each POST request:
lowerCase = "abcdefghijklmnopqrstuvwxyz"
characterSet = lowerCase
keyLength = 13
user = ""
math.randomseed(os.time())
for i = 1, keyLength do
rand = math.random(#characterSet)
user = user .. string.sub(characterSet, rand, rand )
end
wrk.path = "/somepath"
wrk.method = "POST"
wrk.body = [[{"username":"]].. user .. [[,"password":"somepassword"}]]
wrk.headers["Content-Type"] = "application/json"
Try something like this. It should execute request3 ~50% of the time, and the other two ~25% of the time. Cheers!
names = { "Maverick", "Goose", "Viper", "Iceman", "Merlin", "Sundown", "Cougar", "Hollywood", "Wolfman", "Jester" }
request1 = function()
headers = {}
headers["Content-Type"] = "application/json"
body = '{"name": ' .. names[math.random(#names)] .. '}'
return wrk.format("POST", "/test1", headers, body)
end
request2 = function()
headers = {}
headers["Content-Type"] = "application/json"
body = '{"name": ' .. names[math.random(#names)] .. '}'
return wrk.format("POST", "/test2", headers, body)
end
request3 = function()
headers = {}
headers["Content-Type"] = "application/json"
body = '{"name": ' .. names[math.random(#names)] .. '}'
return wrk.format("GET", "/test3", headers, body)
end
requests = {}
requests[0] = request1
requests[1] = request2
requests[2] = request3
requests[3] = request3
request = function()
return requests[math.random(0, 3)]()
end
response = function(status, headers, body)
if status ~= 200 then
io.write("------------------------------\n")
io.write("Response with status: ".. status .."\n")
io.write("------------------------------\n")
io.write("[response] Body:\n")
io.write(body .. "\n")
end
end
I'm not familiar with wrk.
I guess you're running that code multiple times within a second. As os.time has second accuracy you'll have the same randomseed and hence the same user name within that second.
From looking into the scripting examples I'd say the script is only evaluated once or maybe once per thread. Those examples implement functions that will be called by wrk. It wouldn't make sense to define those functions for every request.
Add a print to your script to make sure.
Here is an example that counts requests. You probably can put your code into that function
function request()
requests = requests + 1
return wrk.request()
end
Related
I'm coding a Discord bot in Lua and I thought it would be fun to implement OpenAI's api somehow, and I've got everything right except I keep getting a 401 error. Here's a portion of my code
coroutine.wrap(function()
local s,e = pcall(function()
local Headers = {
["Authorization"] = "Bearer "..key,
["Content-Type"] = "application/json",
}
local Body = json.encode({
model = "text-davinci-002",
prompt = "Human: ".. table.concat(Args, " ") .. "\n\nAI:",
temperature = 0.9,
max_tokens = 47, --150
top_p = 1,
frequency_penalty = 0.0,
presence_penalty = 0.6,
stop = {" Human:", " AI:"}
})
res,body = coro.request("POST", link, Headers, Body, 5000)
if res == nil then
Message:reply("didnt return anything")
return
end
if res.code < 200 or res.code >= 300 then
Message:reply("Failed to send request: " .. res.reason); return --Always ends up here "Failed to send request: Unauthorized"
end
Message:reply("Request sent successfully!")
end)
end)()
The "key" is the API key I got from the website. I feel like the mistake is simple and stupid but regardless I'm stuck
It's good code, though I'd do some checks on the types before you validate the codes.
Another reason behind this, is some domains may require a proxy rather than a direct connection.
coroutine.resume(coroutine.create(function()
local headers = {
Authorization = "Bearer " .. key,
["Content-Type"] = "application/json",
}
local body = json.encode({
model = "text-davinci-002",
prompt = "Human: " .. table.concat(Args, " ") .. "\n\nAI:",
temperature = 0.9,
max_tokens = 47, --150
top_p = 1,
frequency_penalty = 0.0,
presence_penalty = 0.6,
stop = { " Human:", " AI:" },
})
local success, http_result, http_body = pcall(coro.request, "POST", link, headers, body, 5e3)
if success ~= true then
return error(http_result, 0)
elseif type(http_result) == "table" and type(http_result.code) == "number" and http_result.code < 200 or http_result.code >= 300 then
return Message:reply("Failed to send request: " .. type(http_result.reason) == "string" and http_result.reason or "No reason provided.")
end
return Message:reply("Request sent successfully!")
end))
#tornado.web.authenticated
#tornado.web.asynchronous
#tornado.gen.coroutine
def post(self):
try:
files_body = self.request.files['file']
except:
error_msg = u"failed to upload file"
error_msg = self.handle_error(error_msg)
self.finish(dict(is_succ=False, error_msg=error_msg))
return
file_ = files_body[0]
filename = file_['filename']
# asynchronous request, obtain OCR info
files = [('image', filename, file_['body'])]
fields = (('api_key', config.OCR_API_KEY), ('api_secret', config.OCR_API_SECRET))
content_type, body = encode_multipart_formdata(fields, files)
headers = {"Content-Type": content_type, 'content-length': str(len(body))}
request = tornado.httpclient.HTTPRequest(config.OCR_HOST, method="POST", headers=headers, body=body,
validate_cert=False, request_timeout = 30)
try:
response = yield tornado.httpclient.AsyncHTTPClient().fetch(request)
except Exception, e:
logging.error(u'orc timeout {}'.format(e))
error_msg = u"OCR timeout"
error_msg = self.handle_error(error_msg)
self.finish(dict(is_succ=False, error_msg=error_msg))
return
if not response.error and response.body:
data = json.loads(response.body)
self.extra_info(data)
result = dict(is_succ=True, error_msg=u"", data=data)
else:
result = dict(is_succ=False, error_msg=u"request timeout", data={})
self.finish(result)
as the code shown, I want to write an api to handle id-card picture upload, and post a request to third part interface for getting the information of id-card.
This api can run well on my PC,however it timeouts on Testing Server. I cannot figure out where the problem is.
I'm trying to upload an image using luaSocket.
Here is my Lua code:
function uploadFile(dir)
local resp = {}
local body,code,headers,status = http.request{
url = "my_url",
method = "POST",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
["Content-Length"] = file_size
},
source = ltn12.source.file(io.open(dir),"rb"),
sink = ltn12.sink.table(resp)
}
print(body,code,status)
if headers then for k,v in pairs(headers) do print(k,v) end end end
My php code is:
<?php
copy("php://input","test");
echo("OK");
?>
When I try to upload the image I don't get any error but body and status are nil, but code is "timeout".
But the script works fine if I try to upload a text file.
Any help is appreciated. Thanks.
You are passing "rb" as parameter to ltn12.sink.file instead of io.open. Change the statement to:
source = ltn12.source.file( io.open(dir,"rb") ),
I'm learning web development with lua (wsapi and uWSGI).
I'm trying to create a request object (https://keplerproject.github.io/wsapi/libraries.html) to see what it look like (and how to use it). So I've set up a example code :
require "wsapi.cgi"
function run(wsapi_env)
local headers = { ["Content-type"] = "text/html" }
local function hello_text()
local result = "<html><body>\n"
result = result .. "<p> Hello Wsapi !</p>\n"
result = result .. "<p>PATH_INFO wsapi_env: " .. wsapi_env.PATH_INFO .. "</p>\n"
-- problematic code
local req = wsapi.request.new(wsapi_env)
if req
then
--condition to see if req was nill
result = result .. "<p>PATH INFO_POST : " .. req.POST .. "</p>\n"
result = result .. "<p>PATH INFO_GET : " .. req.GET .. "</p>\n"
else
result = result .. "<p> No request <\p>\n"
end
-- end of the problematic code
result = result .. "<p><form method=\"post\" action=\"hello.lua\">\n"
result = result .. "<textarea name=\"message\"> test </textarea>\n"
result = result .. "</form></p>\n"
result = result .. "</body></html>\n"
coroutine.yield(result)
end
return 200, headers, coroutine.wrap(hello_text)
end
return run
But when I use the request object, the client receive a blank page.
How can I create and use a request object ?
Thanks you for your answers !
Extra question : How do I redirect to another page ( to a static page on the same domain ) ?
Maybe this little code snippet will help:
local ws_request = require "wsapi.request"
function run(wsapi_env)
local qs = wsapi_env.QUERY_STRING
print("QUERY_STRING: " .. qs)
local req = ws_request.new(wsapi_env)
print(req.params.q)
end
I have a funciton that calls Net::HTTP.new(google_url.host, google_url.port) and I am trying to figure out how to stub the result for testing. Basically I don't want to be hitting the google URL shortener every time I run my test.
def shorten_url(long_url)
google_url = URI.parse("https://www.googleapis.com/urlshortener/v1/url")
data = JSON.generate({"longUrl" => "#{long_url}"})
header = {"Content-Type" => "application/json"}
http = Net::HTTP.new(google_url.host, google_url.port)
http.use_ssl = true
short_url = ""
res = http.request_post(google_url.path, data, header)
jsonResponse = JSON.parse(res.body)
short_url = jsonResponse["id"]
end
Basically I want to be able to set the result of that function.
I've tried things like: Net::HTTP.any_instance.stubs(:HTTP.new).returns("www.test.com") but cannot figure out how to get it to work.
class HTTP < Protocol
....
# Creates a new Net::HTTP object.
# If +proxy_addr+ is given, creates an Net::HTTP object with proxy support.
# This method does not open the TCP connection.
def HTTP.new(address, port = nil, p_addr = nil, p_port = nil, p_user = nil, p_pass = nil)
h = Proxy(p_addr, p_port, p_user, p_pass).newobj(address, port)
h.instance_eval {
#newimpl = ::Net::HTTP.version_1_2?
}
h
end
....
end
Check out webmock - this sounds like it will do exactly what you're looking for.