VFPCGI Day8
出自VFP Wiki
VFPCGI的第八天
當你知道規則之後,很快就能寫出一個類似 Request 的物件了~ 所以我們的 cgilib.prg 又多了一個 Request 類別:
DEFINE CLASS REQUEST as Custom TotalBytes = 0 RequestMethod = "" ADD OBJECT QueryString AS collection ADD OBJECT FormField AS collection ADD OBJECT Cookies as collection PROCEDURE INIT DECLARE INTEGER GetStdHandle in Win32API integer nHandleType declare integer ReadFile in Win32API integer hFile, string @ cBuffer,; integer nBytes, integer @ nBytes2, integer @ nBytes3 LOCAL lcMethod LOCAL lcQueryString LOCAL lcContentLength, lnContentLength LOCAL lcInput LOCAL lnOverlappedIO LOCAL lnInHandle lcMethod = UPPER( GETENV( "REQUEST_METHOD" ) ) this.RequestMethod = lcMethod lcQueryString = "" DO CASE CASE INLIST( lcMethod , "GET" ) * get environment variable: QUERY_STRING lcQueryString = GETENV( "QUERY_STRING" ) this.ParseData( lcQueryString, this.QueryString ) CASE INLIST( lcMethod, "POST" ) &&lenght of input string in STDIN is in this environment variable lcContentLength = GETENV("CONTENT_LENGTH") IF LEN( lcContentLength ) > 0 THEN lnContentLength=VAL( lcContentLength ) ELSE lnContentLength = 0 ENDIF IF lnContentLength > 0 THEN &&get the input from STDIN lnInHandle=GetStdHandle(-10) lcInPut=REPLICATE(' ', lnContentLength ) lnOverlappedIO=0 ReadFile(lnInHandle, @lcInPut, lnContentLength, @lnContentLength, @lnOverlappedIO) ELSE lcInput='' ENDIF IF LEN( lcInput ) > 0 THEN this.ParseData( lcInput, this.FormField ) ENDIF OTHERWISE ENDCASE ENDPROC HIDDEN PROCEDURE ParseData LPARAMETERS cInput as String , oCollection as Collection LOCAL i, nStart, nPos, nEqualPos LOCAL lcStr, lcKey, lcValue * parse it. i = 1 nStart = 1 nPos=AT( "&", cInput, i ) IF nPos == 0 THEN nPos = LEN( cInput ) ENDIF DO WHILE nPos!=0 lcStr = SUBSTR( cInput, nStart, nPos-nStart ) nEqualPos = AT( "=", lcStr ) IF nEqualPos!=0 THEN lcKey = SUBSTR( lcStr, 1, nEqualPos-1 ) lcValue = SUBSTR( lcStr, nEqualPos+1 ) oCollection.Add( lcValue, lcKey ) ENDIF i=i+1 nStart = nPos + 1 nPos=AT( "&", cInput, i ) ENDDO IF nStart < LEN(cInput) THEN nPos = LEN( cInput ) lcStr = SUBSTR( cInput, nStart ) nEqualPos = AT( "=", lcStr ) IF nEqualPos!=0 THEN lcKey = SUBSTR( lcStr, 1, nEqualPos-1 ) lcValue = SUBSTR( lcStr, nEqualPos+1 ) oCollection.Add( lcValue, lcKey ) ENDIF ENDIF ENDPROC ENDDEFINE
Request 這部份是最容易有問題的地方了~因為安全的漏洞往往來自於此。 也正式因為如此,才會有人說,永遠不要相信使用者輸入的資料,無論如何都要作詳細的檢查。 早期多半用 C 語言來寫 CGI 的時候,這邊常會犯的錯誤是,沒有預留足夠的空間來放這些輸入的字串,這也導致了 hacker 可以用緩衝區溢位的方式來進行攻擊。
我們這邊做的比較簡單,都自己寫程式去 parse 字串,然後放到 collection 裡面去。 依照上個範例的輸出結果,我想你應該知道可以利用 aline() 之類的函數來解,這會更方便些~
這邊我們還沒處理 utf-8 與 % 的一些問題....同時也還沒補上 Request 的使用範例...