Closed therealfakemoot closed 8 years ago
I've tried another invocation of Vegeta to try to eliminate my targets file as the culprit:
echo "POST http://ndumas.com" |./vegeta attack -body tests/write.json -duration 10s -rate 1 -output whatever.bin
No success. POST requests are received by the server but by every indication I can check, there's no POST body. This makes me lean heavily towards something being wrong with my JSON file, but then I tried this.
Python 2.6.6 (r266:84292, Jul 23 2015, 15:22:56)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> with open('write.json') as f:
... write_json = json.load(f)
...
>>> write_json
{u'loadtest': u'true', u'write': u'true', u'key': u'1234', u'value': u'1234'}
>>>
Please run this small Go program and direct the attack there instead. Tell me what you see then.
package main
import (
"fmt"
"net/http"
"net/http/httputil"
)
func main() {
http.ListenAndServe(":9000", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
dump, err := httputil.DumpRequest(r, true)
if err != nil {
panic(err)
}
fmt.Println(string(dump))
}))
}
It looks like the POST body is being sent, as literal JSON. The issue I'm having is that it isn't being sent as form-urlencoded, which is what PHP expects. I think it'd be useful to allow an attack/target specify this option.
POST / HTTP/1.1
Host: 199.223.114.18:9000
Accept-Encoding: gzip
User-Agent: Go-http-client/1.1
{"loadtest": "true", "write": "true", "value": "1234", "key": "1234"}
For reference, I ran my Python test script against the debug service to demonstrate the difference.
POST / HTTP/1.1
Host: 199.223.114.18:9000
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
User-Agent: python-requests/2.9.1
loadtest=true&write=true&value=sup+jadon&key=1234
If you want to send URL encoded POST request bodies then do so, but you can't expect JSON to be automatically converted to them. Don't forget to set the appropriate Content-Type header.
Yeah, as it turns out, I was using Vegeta wrong. I was confused by the section of the README relating to defining targets with custom bodies. They referenced a JSON file and it wasn't immediately clear that the body file was sent raw. Thanks for clarifying this.
As per the specification in the docs, I'm pretty sure I've spelled everything correctly. The main possibility I see here is that my JSON file is somehow wrong. I generated it using Python's
json.dumps()
method which has never failed me before. I was able to confirm that Vegeta is hitting my server (entries in the access log bearing the go-http-client useragent string), but the POST bodies are 100% empty.Is my target file formatted/spelled incorrectly? Is my JSON malformed? Is there some vegeta flag I need to add to my invocation? Inquiring minds must know.
The contents of my target file:
The contents of my JSON file:
Vegeta version:
Vegeta Invocation:
Access Logs
POST Body Log:
For operational security, I'd rather not expose the full breadth of my code but the relevant segment for producing the log above: