tags:

views:

965

answers:

4

I am having a bit of trouble using strtok with strcmp.

//Handles the header sent by the browser
char* handleHeader(char *header){
        //Method given by browser (will only take GET, POST, and HEAD)
        char *method,*path, *httpVer;

        method = (char*)malloc(strlen(header)+1);
        strcpy(method,header);
        method = strtok(method," ");


        path = strtok(NULL," ");
        httpVer = strtok(NULL, " ");
        printf("\nMethod: %s\nPath: %s\nHTTP: %s\n",method,path,httpVer);


        printf("\nc1: %d\nc2: %d\n",strcmp(httpVer,"HTTP/1.0"),strcmp(httpVer,"HTTP/1.1"));

        if(!(!strcmp(httpVer,"HTTP/1.0") || (!strcmp(httpVer,"HTTP/1.1")))){
                printf("\ngive a 400 error\n");
                return "400 foo";
        }


        if(!strcmp(method,"GET")){
                //char *path = strtok(NULL," ");

                //If they request the root file, change the path to index.html
                if(!strcmp(path,"/")){
                        path = (char*)malloc(strlen(BASE_DIR) + strlen("/index.html")+1);
                        strcpy(path,"/index.html");
                }
                 return readPage(path,2);
        }
}

If I give it the following header

GET / HTTP/1.0

I get this output:

Method: GET
Path: /
HTTP: HTTP/1.0


c1: 1
c2: -1

give a 400 error

As you can see, strtok() parses the string properly, but the values c1, and c2 dont seem to make sense (c1 should return 0, but instead it returns 1).

Whats going on here?

+6  A: 

I'm guessing that you're not giving it this:

GET / HTTP/1.0

but rather this:

GET / HTTP/1.0\n

or possibly this:

GET / HTTP/1.0\r\n

Looking at your code, there should be one blank line between the "HTTP" output line and the "c1" line, but you have two, implying that the "HTTP" value itself contains a newline.

Output some quotes around the values - I bet you see this:

HTTP: "HTTP/1.0
"
RichieHindle
Just thought about this. @Steven1350, try strstr instead of strcmp to see if this happens.
Zed
Replacing strcmp with strstr, I got the following, c1: 163160734c2: 0
Steven1350
The fact that `c1` is non-zero means that the string `HTTP/1.0` does appear within `httpVer`.
RichieHindle
You are correct, there is a \n at the end of HTTP/1.0. Thanks, it seems to work.
Steven1350
Since strstr() returns the address at which the string ("HTTP/1.0") starts in the token, that's a success - and RichieHindle's diagnosis is correct.
Jonathan Leffler
A: 

Try using

strncmp(httpVer, "HTTP/1.0", 8)

so that you ignore trailing whitespace.

Karl Voigtland
both c1 and c2 returned 0 when I tried this
Steven1350
strncmp() will only compare up to the specified number of characters. So this should work as long as you are not interested in anything possibly being after the '1.0'.
Karl Voigtland
+1  A: 

From your output it looks like there may be a '/n' at the end of the HTTP/1.0 string? Richie is too fast for me ;)

Try trimming/removing any white space on the input string before you tokenize it.

simon
+1  A: 

As you can see from the blank lines in your output (and as several people have said already) there are control characters on the end of your HTTP/1.0. You could fix this.

But why are you writing a new HTTP request parser in C? It's 2009! There are loads of them already out there, some of which are even correct, many liberally licensed. And even if you do need to write your own for some reason, you should use a safe language (Python, Java, Lua, C#, Perl, something) so that if you make a trivial error counting characters, you don't end up with a big security hole in your program. (And even if you somehow have to use C, strtok is a particularly egregious C function.)

Kragen Javier Sitaker