[En-Nut-Discussion] httpd and forms: New method for POST evaluation

Bernard Fouché bernard.fouche at kuantic.com
Tue Sep 6 20:16:04 CEST 2005


Ole Reinhardt wrote:

>Hi,
>
>  
>
>>A few comments about that method:
>>    
>>
>
>These are always wellcome!
>  
>
I'm very new to NutOs/Ethernet so forgive me if there are things or uses 
I don't yet get right!

>  
>
>>- it uses fread() and fread() returns zero if EOF is reached (and this 
>>value is not tested anyway)
>>    
>>
>
>Can EOF be reached at all? As it is a stream communication there won't
>be a EOF, right? All other parts of httpd also use fread, dont't they?
>  
>
I just ran 'find . -name "*.c" -exec egrep fread /dev/null {} \;' from 
the root directory of ethernut 3.6.8
and found fread() to be used only in [unix_]eeprom code and rs232d.c. I 
don't like fread() much since
it works by 'item' and unless you want to process fixed size record, you 
endup performing multiplications
(it also takes time) or have one byte 'item'. And there is the EOF 
problem anyway.

>So what do you suggest? Better use fgetc? I have decided agains this
>approach as it is less overhead. Any better idea? I could also change
>this to use fgetc.
>  
>
Or have feof() test stream after each fread(). fgets() does not work 
well for binary data however
I dunno if one is allowed to send binary data with a POST method. (I 
send XML myself)

For a method used also as example on how to use NutOs, I think that 
fgetc() is less error-prone

>
>This is a quick and dirty method to obtain form values and only shall be
>used for this. So I think the chance to get invalid request is quite
>negligible. 
>
>For shure making the function more stable is prefarable.
>
>Any ideas how to change / enhance this function?
>
>
>  
>
Anyway I was very glad to have it to help me understand how things are 
going in httpd/httserv.c.

IMHO, the method should:

- be bullet-proof and survive malformated queries. Having a software 
and/or product crashed or
locked because of a buggy request is always a pain to debug.
- be split in two, if you want to provide a parser to extract names and 
values from the posted data.
One function that just gets the data from  the query, one function that 
process a 'req' where the application
designer knows that it must have name-value pairs.

Here comes my current version, very simplified:

int NutHttpProcessPostQuery(FILE *stream, REQUEST * req)
{
    uint16_t i;
    uint16_t c;
   
    if (req->req_query != NULL)
        return FALSE;
   
    if (!stream)
        return FALSE;

    if (req->req_method == METHOD_POST) {
      req->req_query = NutHeapAllocClear(req->req_length+1);
      if (req->req_query == NULL) {
    /* Out of memory */
    NutHeapFree(req->req_query);   
    return FALSE;
      }
      i = 0;
      while(i < req->req_length){
    c=fgetc(stream);
    if(c==EOF)
      break;
    req->req_query[i++]=c;
      }
    }
    return TRUE;
}

 Bernard



More information about the En-Nut-Discussion mailing list