Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature added to __parse_post_data function to parse -T argument #239

Merged
merged 1 commit into from
Jul 20, 2024

Conversation

Gbell26
Copy link

@Gbell26 Gbell26 commented Jul 17, 2024

Siege can only assign content type from the command line or if POST data is saved to a file limiting the ability to hit many endpoints that require different content types in a single siege session.

Feature added to __parse_post_data() to parse -T argument allowing siege to dynamically assign content type per URL in URL file.

Lines in the URL file can be constructed as follows to pass varying content types when passing data:

https://url POST -T application/json; {data}

…wing siege to dynamically assign content type from URL file
@JoeDog
Copy link
Owner

JoeDog commented Jul 17, 2024

I like it but how are you getting away with this without it being quoted? I would think you'd need this:

https://url POST -T "application/json; {data}"

@Gbell26
Copy link
Author

Gbell26 commented Jul 17, 2024

My understanding is because I am not defining any new string after -T I am just manipulating the existing string that the function is handling. I am treating it very similarly to how the function already acts. I am checking for -T in the string similar to how the __url_parse() function checks for "POST" "PUT" "DELETE" etc. here:

  if (! post) {
   post = strstr(this->url, " PUT");
 }

 if (! post) {
   post = strstr(this->url, " PATCH");
 }

 if (! post) {
   post = strstr(this->url, " OPTIONS");
 }

 if (! post) {
   post = strstr(this->url, " DELETE");
}

and if it exists then changing the ';' delimeter to a null terminator splitting the string into two strings.
Then using xstrdup() to copy the first string to this->contenttype the same way it is copying datap to this->postdata. And moving the pointer past the argument similarly to this section that moves past the whitespace:

for (; isspace((unsigned int)*datap); datap++) {
/* Advance past white space */

}

So its mostly working the same way it already was just copying the section between -T and ; first. Does that make sense?

@Gbell26
Copy link
Author

Gbell26 commented Jul 18, 2024

This:

POST -T application/json; {data}

is all already in memory, the __url_parse() function pulls POST|PUT|DELETE etc out and then passes the rest to __parse_post_data(). Before it was just moving past the white space and copying {data} to this->postdata (or loading in the data from file). So now instead of just moving past the white space we check for the -T argument, copy that to this->contenttype then continue on the same way

@JoeDog
Copy link
Owner

JoeDog commented Jul 19, 2024

If I do this, it blows up:

$ ./siege -c1 -r1 POST -T application/json; haha=papa https://www.joedog.org/
** SIEGE 4.1.7-b6
** Preparing 1 concurrent users for battle.
The server is now under siege...
[error] Address resolution failed at sock.c:158 with the following error:: Resource temporarily unavailable
[error] Temporary failure in name resolution: POST: Resource temporarily unavailable

But if I quote it, then it works:
$ ./siege -c1 -r1 POST -T "application/json; haha=papa" https://www.joedog.org/siege/echo.php
** SIEGE 4.1.7-b6
** Preparing 1 concurrent users for battle.
The server is now under siege...
HTTP/1.1 200 0.52 secs: 467 bytes ==> GET /siege/echo.php

But I don't understand why you can't just do this:

$ ./siege -c1 -r1 -T "application/json" "https://www.joedog.org/siege/echo.php POST haha=papa"
** SIEGE 4.1.7-b6
** Preparing 1 concurrent users for battle.
The server is now under siege...
HTTP/1.1 200 0.60 secs: 488 bytes ==> POST https://www.joedog.org/siege/echo.php

@Gbell26
Copy link
Author

Gbell26 commented Jul 19, 2024

Yes, this is specifically when using the URL file to hit multiple different endpoints. It should have no effect on the way the command line parsing is working.

So the call would be

./siege -c1 -r1 -f url_file.txt

Where url_file.txt looks something like this:

https://url POST -T application/json; {data}
https://url POST -T text/plain; data
etc. 

Previously you would have to pass the content type at the command line which would then apply to all urls in that file.

Or your data would have to be saved to many different files and siege would infer content type based on file extension so it would have to be like this

https://url POST > data.json
https://url POST > data.txt

So this offers a solution allowing you to use the url file and write the data directly to the URL file and while using multiple content-types

Also it is written to only overwrite the contenttype for each line so for example if you had 10 endpoints that want application/json data and only 1 that wants text/plain you should be able to write the url file like this:

https://url POST {data}
https://url POST -T text/plain; data
etc. 

and call siege with:

  ./siege -c1 -r1 -T "application/json" -f url_file.txt

and it will treat application/json as the default and set those endpoints that dont pass -T on the line with that content-type.

@JoeDog
Copy link
Owner

JoeDog commented Jul 19, 2024 via email

@JoeDog JoeDog merged commit af8f936 into JoeDog:master Jul 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants