2012-08-01 63 views
1

這不是真的與編程有關,但我在程序中使用它,所以我認爲最好在這裏問一下。本質上這是一個關於處理HTTP請求異常的問題。HTTP請求字段中的特殊字符

標準的請求可能是這樣的:

GET/HTTP/1.1 
Host: example.com 
User-Agent: Firefox 

我的問題是,應該如何HTTP在通常不被篡改HTTP請求的部分處理「特殊字符」。例如,如果方法是「POST ME」而不是「GET」(即包含空格),該怎麼辦?這會被編碼爲%20嗎?

另一個例子,假設我希望我的一個頭文件是「Class:Test:example」,並在頭文件名稱中添加了「:」(頭文件的值爲「example」)。這會被編碼爲%3A嗎?

注意:這不是關於是否有任何Web服務器接受這種編碼;這是關於如何完成的。我的程序是一個模糊測試器,所以它應該測試這種事情!

回答

2

這兩個問題必須回答爲「否」和「是的,但是......」

「百分比編碼」你的建議是爲內容,值定義,不是爲HTTP語言的語法。你混合協議和有效載荷。

您可能想看看定義HTTP的RFC。它清楚地定義了一種語法。如果你堅持這種語法,你可以創建有效的擴展(這是你正在嘗試做的)。如果你破壞了這個語法,你會創建無效的http請求。這可能是你可以在室內做的事情,但很可能這種請求在開放的互聯網中不起作用,例如代理服務器發揮作用。這些必須在語法層面上理解你的請求。

對於問題2,答案是「是,但是」,我寫道。所以對BUT幾句話:

如果您按照您的建議編碼第二個':',您可以指定這樣的標頭並且它們是有效的。但是,您應該瞭解您在那裏做了什麼:您沒有向頭名稱中引入層次結構。相反,您需要指定一個標題內容以包含':'。這很好。由您的服務器組件來理解,解釋並按預期對內容作出反應。

+0

沒錯,但我的問題不是它是否會在開放的互聯網上工作;它應該如何完成。如果我理解正確,沒有爲希望發送「POST ME」作爲HTTP方法的用戶定義任何編碼機制。 這不是第二個「:」我要編碼;這意味着當我希望頭*名*爲「Class:Test」時,頭值將是「Test:example」,值爲「example」。 是的,我知道我不是在這裏創建一個層次結構... – Rsaesha 2012-08-01 11:46:10

+0

我確實理解你的問題。我只是試圖通過提到互聯網來解釋事情是如何工作的。 AFAIK「POST ME」的確是一個無效的請求方法名稱。所以你可以指定它,但不確定會發生什麼。那麼測試它的重點在哪裏?除了你正在尋找諸如緩衝區溢出之類的東西。但是在那種情況下,考慮「如何完成」再次沒有意義。標題名稱「Class:Test」無效。與上述相同的說法適用。 – arkascha 2012-08-01 11:49:10

+0

他們沒有爲此定義編碼機制,因爲它根本沒有必要。他們已經有一種方法來創建多字頭名稱,並使用連字符作爲分隔符。爲什麼你需要在標題名稱中使用「:」?而不是「POST ME」,你可以使用「POSTME」或「POST-ME」。 – Barmar 2012-08-01 11:52:19

0

HTTP規範說這個方法是一個令牌,所以它不能包含任何分隔字符。所以「POST ME」不是一個有效的方法。

同樣,標題名稱也是標記,所以它們不能包含「:」。冒號總是作爲標題名稱和其內容之間的分隔符。

正如arkascha所說,您應該閱讀指定HTTP協議的RFC 2616。

+0

我已閱讀。我只是想知道是否還有其他的東西已經寫入了這些案例。 – Rsaesha 2012-08-01 11:47:51

0

對於你的含有空間的方法,這是不可能的,因爲請求線被定義爲這樣的:

Request-Line = Method SP Request-URI SP HTTP-Version CRLF 

Method被定義爲HTTP/1.1動詞或延伸法之一,是一個token(不能包含空格)。所以服務器遇到的第一個空間標誌着方法的結束。因此,一個方法不能包含空格。你可以對它進行百分比編碼,但服務器不會知道如何處理動詞GET%20ME

爲了您Class:Test: example,HTTP標頭是defined爲:

message-header = field-name ":" [ field-value ] 
field-name  = token 
field-value = *(field-content | LWS) 
field-content = <the OCTETs making up the field-value 
        and consisting of either *TEXT or combinations 
        of token, separators, and quoted-string> 

和文本被定義爲:

TEXT   = <any OCTET except CTLs, 
       but including LWS> 

和CTL被定義爲:

CTL   = <any US-ASCII control character 
       (octets 0 - 31) and DEL (127)> 

因此,沒有,你不必逃避更多的冒號(58),標題行中的第一個冒號是alwa ys被認爲是分隔符,因爲在token中不允許冒號。

因此在您的示例中,字段名稱是Class,而field-valueTest: example

+0

沒錯,但這不是我問的。爲了澄清,我希望標題名稱爲「Class:Test」,值爲「example」,而不是標題名稱爲「Class」,值爲「Test:example」。這種行爲顯然沒有在HTTP規範中定義; 「:」在標題名稱中是不允許的。 – Rsaesha 2012-08-01 11:57:05

+0

@Rsaesha是的,它被定義爲不被允許。您*不能*在HTTP頭名稱中包含冒號。 – CodeCaster 2012-08-01 11:57:52