Search code examples
g-wanserver-configurationhttp-request-parametershttpentity

GWAN query string length issue


I am using GWAN (v4.3.14) and facing a strange issue. I am trying to pass some long text in the query string. I have figured out that GWAN does not allow me to pass query parameters beyond a total request size of 537 characters.
It responds with a 400 Bad Request

An example string is :

http://xxx.xxx.xxx.xxx:yyyy/?t.cpp&c=DbE9kdOJGMm9yr7aypGlQBY1a9rZuiaMDAAnTJSbOBRJZo45YHbpAO5VENLa6IcmlSadZnTucpKBKb0E0G15pFHCgB4oNxqQ3m1K0CX8K15RQkawb8MThuoIHKp02vk9WwJFU5NkBJtwu80onudOkwWPUiGxKKcJiSwJJNcgDY1LQIJ1GnvgRGgomthoxppsZ1cl7zxIf5CjWggzsbUnADDTq5W4pBXveVnugOBHryqdTylhI4tudeae2jUnswezxtQM1qKG3ezGkM2dN68R7YxpCEfZ2N1nXggUkYdGn6em7veq5G5LpTVrdexn0fSozGbeNfHXS2OLjWGhffcEdGeu1dFKnFxNac6IETbIiVvTjv55wcZI7WBiTA0r60KJkUZYNn59W6XhnAwTk0zCYN2Rq8LraOjHzjXHjcyL9Sk6jw4D9K0wWLsiZHDfTOlnPr9jYp2SesyHlUJsCHPiHOR4fCBVwQMwh5YOddcpl2Kbr6CjSjWabaac

The code in my C++ file is:

# include "gwan.h"
# include <iostream>
using namespace std;

int main (int argc, char * argv[])
{
    if(argc)
    {
        cout<<argv[0];
        xbuf_cat(get_reply(argv), argv[0]);
    }
    else
    {
        xbuf_cat(get_reply(argv), "pass something to me to see it on your screen.");
    }

    return 200; 
}

Can someone help me to make GWAN accept a query parameter of 1000 characters or more?


Solution

  • The error with G-WAN v4.5+ is "414: Request URI too large".

    Many production HTTP servers disable PUT/POST Entities to avoid abuse.

    G-WAN first used a limit slightly larger than 4KiB, but most requests do not need so much room so we have made it possible for developers to decide.

    The example below (see entity_size.c for a working example) shows how to modify the G-WAN (server-global) PUT/POST Entity size limit from a servlet but this can also be done in the init() or the main() calls of a connection handler, and from the gwan/init.c script available in v4.10+:

    u32 *max_entity_size = (int*)get_env(argv, MAX_ENTITY_SIZE);
    *max_entity_size = 200 * 1024; // new size in bytes (200 KiB)
    

    You can change the limit at any time (even while a given user is connected) by using IP filtering in a connection handler.

    Your servlets will decide what to do with the entity anyway so you can dispose or store on disk or do real-time processing, see the entity.c example.

    Beyond this, there are a few things to keep in mind:

    • to avoid DoS attacks letting everybody send huge entities to your server (in the GBs), you might enlarge the request size of authorized users only;

    • when dealing with requests without a PUT/POST Entity you may also dynamically enlarge the read buffer by allocating more memoy to the READ_XBUF by using xbuf_growto().

    Now you know how to accept requests of any length. Make sure you do it only when needed.

    You may want to check other related values like:

      KALIVE_TMO       // time-out in ms for HTTP keep-alives
      REQUEST_TMO      // time-out in ms waiting for request
      MIN_SEND_SPEED   // send rate in bytes/sec (if < close)
      MIN_READ_SPEED   // read rate in bytes/sec (if < close)
    

    All of them can be setup from the gwan/init.c script - before any request can hit the server. This can also be done from G-WAN handlers and servlets, as shown in the examples cited above.