boazsegev / facil.io

Your high performance web application C framework
http://facil.io
MIT License
2.16k stars 141 forks source link

Unexpected Numeral and String representation issue when parsing a query #84

Open immortalChensm opened 4 years ago

immortalChensm commented 4 years ago
int main(int argc, char const *argv[]) {

    http_listen("80", NULL,
                .on_request = on_http_request,
                .on_upgrade = on_http_upgrade,
                .max_clients=10240,
                .log = 1,
                .public_folder="../web"
    );
    fio_start(.threads = 1, .workers = 1);
    return 0;
} 
static void on_http_request(http_s *h) {
   if (fiobj_type_is(h->params,FIOBJ_T_HASH)){
        if (fiobj_hash_haskey(h->params,fiobj_str_new("name",4))){
            printf("ok=%s\n",fiobj_obj2cstr(fiobj_hash_get(h->params,fiobj_str_new("name",4))).data);
            printf("ok1=%s\n",fiobj_obj2cstr(h->query).data);
        }
    }
}

use postman send a request: http://ip:port/?name=xbbb&age=100 图片

print result : 图片

图片 图片

1、when name=b or name=x will display 0
2、when name value is 'b' and 'x' will display number value
3、when name value=0b001,value=0100 value=0x11 will display number value

boazsegev commented 4 years ago

@immortalChensm ,

Thank you for opening this issue.

These are very interesting results... but they seem to be the expected behavior.

The issue appears (on initial review) to result from the fact that xbbb is a valid hex representation of a number (you might recognize it as: 0x0BBB).

A number staring with b (short for binary) would be recognized as any binary string consisting of zero or more zeros and ones (you might recognize it as: 0b0).

The x is recognized as 0x0 where excess zeros might be truncated.

The 0## format is an octal numeral representation (i.e., 010 == 8).

The http_str2fiobj tests if the whole of the string matches a numeral format (0x, x, 0b, b, etc') and converts the string to a numeral if the value consists only of the number.

An easy solution is to add a trailing space or a quote.

Another approach is to manually parse the query or rewrite the http_str2fiobj function.

However, I do wonder - if this design is not what you expect, how would you recommend that the http_str2fiobj behave?

Kindly, Bo.

immortalChensm commented 4 years ago

Thank you so much! but other http server[such as nginx,apache] result is string,it is not number,I see it is binary /octal/hexadecimal

boazsegev commented 4 years ago

Hi @immortalChensm ,

Both Nginx and Apache are HTTP servers, not application servers.

To the best of my knowledge, they don't analyze the content of the request on the same level. For example, the information is always a "string".

For example, the name name[first]=Joe&name[last]=Smith in facil.io should be translated into a nested data object (equivalent to the JSON {"name": {"first":"Joe","last":"Smith"}})... this is very different than having the params hash contain a key named "name[first]"...

Another example is that the value 0xff and the value 255 are different values in these cases (whereas, for facil.io these two values are identical).

On one hand, it's quite easy to emulate the simplified (Nginx) behavior with facil.io by scanning the query string manually.

On the other hand, I understand there could be a reason to keep a String based values for numbers (the fiobj2i function should convert these string to numbers automatically)... the biggest issue I would have with this approach is that it could make it more difficult to translate data into JSON (numeral fields will need to be replaced manually before conversion).

Kindly, Bo.

immortalChensm commented 4 years ago

Thank you so much! I see it