2009-09-19 74 views
2

我在使用strcmp和strtok時遇到了一些麻煩。C - strtok和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); 
     } 
} 

如果我給它下面的頭

GET/HTTP/1.0 

我得到這樣的輸出:

Method: GET 
Path:/
HTTP: HTTP/1.0 


c1: 1 
c2: -1 

give a 400 error 

正如你所看到的,strtok()函數正確解析字符串,但值C1 ,和c2似乎沒有道理(c1應該返回0,但相反,它返回1)。

這是怎麼回事?

回答

6

我猜你不給它這樣的:

GET/HTTP/1.0 

而是這樣的:

GET/HTTP/1.0\n 

或可能這樣的:

GET/HTTP/1.0\r\n 

看你的代碼,「HTTP」輸出行和「c1」行之間應該有一條空白行,但你有兩個,這意味着「HTTP」值本身包含一個換行符。

輸出周圍的價值觀一些報價 - 我敢打賭,你看到這一點:

HTTP: "HTTP/1.0 
" 
+0

就想到這個問題。 @ Steven1350,請嘗試使用strstr而不是strcmp來查看是否發生這種情況。 – Zed 2009-09-19 20:11:00

+0

用strstr替換strcmp,我得到以下內容: c1:163160734 c2:0 – 2009-09-19 20:14:52

+0

c1不爲零意味着字符串'HTTP/1.0'出現在'httpVer'中。 – RichieHindle 2009-09-19 20:17:17

-1

嘗試使用

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

讓你忽略尾隨空白。

+0

當我試過時,c1和c2都返回0 – 2009-09-19 20:16:50

+0

strncmp()只會比較指定的字符數。所以只要你對'1.0'之後的任何東西都不感興趣,這應該可以工作。 – 2009-09-19 20:20:04

1

從你的輸出看起來有可能在HTTP/1.0字符串的結尾是「/ N」? Richie對我來說太快了;)

在標記它之前,嘗試修剪/刪除輸入字符串上的任何空格。

2

正如你可以在你的輸出空白線看(和幾個人已經說過)有你的HTTP/1.0結束控制字符。你可以解決這個問題。

但是你爲什麼要在C中寫一個新的HTTP請求解析器?這是2009年!其中有很多已經在那裏,其中一些甚至是正確的,許多已經獲得了許可。即使你確實需要編寫自己出於某種原因,你應該使用一個安全的語言(Python和Java的,Lua中,C#,Perl和東西),這樣,如果你犯了一個微不足道的錯誤計數的字符,你不最終在你的程序中出現一個很大的安全漏洞。 (即使你無論如何都必須使用C,strtok是一個特別嚴重的C函數)。