Tommy 碎碎念
https://blog.teatime.com.tw/
Tommy Wu's blog
tommy
2024-03-19T14:02:15Z
-
Delphi 中使用 WebBrowser 元件時對按鍵的處理
https://blog.teatime.com.tw/1/post/483
<p>我們某些系統是使用古老的 Delphi3 開發的, 所以.... 不支援 unicode 也是正常的. 就算在資料庫中加上了 nchar/nvarchar 的欄位, 還是無法正常的顯示 (其實連存取都有點麻煩, 因為 BDE 不支援 unicode, 要動些手腳才可以).由於 web 上頭對於 unicode 的處理十分容易, 所以... 打算把兩者混在一起使用.</p><p>Microsoft 有提供一個 IE 的 ActiveX 元件, 所以, 在 Delphi3 可以簡單的把它加進來 (會多 WebBrowser 與 WebBrowser_V1 兩個元件可以用, V1 據說是 IE3 的版本, 所以... 我們通常直接用 WebBrowser 那個).</p><p>為了安全起見, 我們是透過 database 來處理 Delphi 與 WebBrowser 之間的 session, 在開啟 WebBrowser 的 form 之前, 會把相關的參數與登入的帳號寫到資料庫, 用一個 hash 當 key, 然後在 WebBrowser form 開啟時, 用 post 的方式把那個 hash 傳過去, 在 web server 端依據那個 key 去查資料庫取得登入的帳號與參數, 如果不正確或 hash 不存在就拒絕存取.</p><p>透過這種方式, 使用者不需要離開原本的系統, 也不會知道那個 form 打開來實際上是個瀏覽器, 又能正確處理 unicode 的字元.</p><p>不過, 在 Delphi 中使用 WebBrowser 元件會有個問題就是某些按鍵會沒作用, 例如: 無法用 tab 切換輸入的欄位, 也沒辦法用 ctrl-c/ctrl-v 之類的按鍵複製與貼上.</p><p>這些可以透過下面的方法來處理 (在 WebBrowser 元件放的那個 form 的 .pas):</p><ul><li>uses 加上 ActiveX (才能用 OleInitialize 與 OleUninitialize 函式)</li><li>end. 之前加上這幾行 (可以讓滑鼠操作的複製貼上有作用) </li></ul><pre class="pascal"><div class="insertcode"><span>initialization</span><br /> OleInitialize<span>(</span><span>nil</span><span>)</span><span>;</span><br /> <br /><span>finalization</span><br /> OleUninitialize<span>;</span><br /> <br /> <br /><span>end</span><span>.</span></div></pre><ul><li>寫一個 message 處理的函式來處理</li></ul><br /><pre class="pascal"><div class="insertcode"><span class="kw1">var</span><br /> FOleInPlaceActiveObject<span class="sy1">:</span> IOleInPlaceActiveObject<span class="sy1">;</span><br /> SaveMessageHandler<span class="sy1">:</span> TMessageEvent<span class="sy1">;</span><br /> <br /><span class="kw1">procedure</span> TForm_webbrowser<span class="sy1">.</span><span class="me1">MyMessageHandler</span><span class="br0">(</span><span class="kw1">var</span> Msg<span class="sy1">:</span> TMsg<span class="sy1">;</span> <span class="kw1">var</span> Handled<span class="sy1">:</span> <span class="kw4">Boolean</span><span class="br0">)</span><span class="sy1">;</span><br /><span class="kw1">var</span> iOIPAO<span class="sy1">:</span> IOleInPlaceActiveObject<span class="sy1">;</span><br /> Dispatch<span class="sy1">:</span> IDispatch<span class="sy1">;</span><br /><span class="kw1">begin</span><br /><span class="kw1">if</span> WebBrowser1 <span class="sy3">=</span> <span class="kw2">nil</span> <span class="kw1">then</span><br /> <span class="kw1">begin</span><br /> Handled <span class="sy1">:</span><span class="sy3">=</span> <span class="kw2">False</span><span class="sy1">;</span><br /> Exit<span class="sy1">;</span><br /> <span class="kw1">end</span><span class="sy1">;</span><br /> <br />Handled<span class="sy1">:</span><span class="sy3">=</span><span class="br0">(</span>IsDialogMessage<span class="br0">(</span>WebBrowser1<span class="sy1">.</span><span class="me1">Handle</span><span class="sy1">,</span> Msg<span class="br0">)</span> <span class="sy3">=</span> <span class="kw2">True</span><span class="br0">)</span><span class="sy1">;</span><br /> <br /><span class="kw1">if</span> <span class="br0">(</span>Handled<span class="br0">)</span> <span class="kw3">and</span> <span class="br0">(</span><span class="kw1">not</span> WebBrowser1<span class="sy1">.</span><span class="me1">Busy</span><span class="br0">)</span> <span class="kw1">then</span><br /> <span class="kw1">begin</span><br /> <span class="kw1">if</span> FOleInPlaceActiveObject <span class="sy3">=</span> <span class="kw2">nil</span> <span class="kw1">then</span><br /> <span class="kw1">begin</span><br /> Dispatch <span class="sy1">:</span><span class="sy3">=</span> WebBrowser1<span class="sy1">.</span><span class="me1">Application</span><span class="sy1">;</span><br /> <span class="kw1">if</span> Dispatch <> <span class="kw2">nil</span> <span class="kw1">then</span><br /> <span class="kw1">begin</span><br /> Dispatch<span class="sy1">.</span><span class="me1">QueryInterface</span><span class="br0">(</span>IOleInPlaceActiveObject<span class="sy1">,</span> iOIPAO<span class="br0">)</span><span class="sy1">;</span><br /> <span class="kw1">if</span> iOIPAO <> <span class="kw2">nil</span> <span class="kw1">then</span><br /> FOleInPlaceActiveObject <span class="sy1">:</span><span class="sy3">=</span> iOIPAO<span class="sy1">;</span><br /> <span class="kw1">end</span><span class="sy1">;</span><br /> <span class="kw1">end</span><span class="sy1">;</span><br /> <br /> <span class="kw1">if</span> FOleInPlaceActiveObject <> <span class="kw2">nil</span> <span class="kw1">then</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="br0">(</span>Msg<span class="sy1">.</span><span class="me1">message</span> <span class="sy3">=</span> WM_KEYDOWN<span class="br0">)</span> <span class="kw1">or</span> <span class="br0">(</span>Msg<span class="sy1">.</span><span class="me1">message</span> <span class="sy3">=</span> WM_KEYUP<span class="br0">)</span><span class="br0">)</span> <span class="kw3">and</span><br /> <span class="br0">(</span><span class="br0">(</span>Msg<span class="sy1">.</span><span class="me1">wParam</span> <span class="sy3">=</span> VK_BACK<span class="br0">)</span> <span class="kw1">or</span> <span class="br0">(</span>Msg<span class="sy1">.</span><span class="me1">wParam</span> <span class="sy3">=</span> VK_LEFT<span class="br0">)</span> <span class="kw1">or</span> <span class="br0">(</span>Msg<span class="sy1">.</span><span class="me1">wParam</span> <span class="sy3">=</span> VK_RIGHT<span class="br0">)</span><span class="br0">)</span> <span class="kw1">then</span><br /> <span class="co1">//nothing - do not pass on Backspace, Left or Right arrows</span><br /> <span class="kw1">else</span><br /> FOleInPlaceActiveObject<span class="sy1">.</span><span class="me1">TranslateAccelerator</span><span class="br0">(</span>Msg<span class="br0">)</span><span class="sy1">;</span><br /> <span class="kw1">end</span><span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span><br /> <br /><span class="kw1">procedure</span> TForm_webbrowser<span class="sy1">.</span><span class="me1">FormActivate</span><span class="br0">(</span>Sender<span class="sy1">:</span> TObject<span class="br0">)</span><span class="sy1">;</span><br /><span class="kw1">begin</span><br />SaveMessageHandler <span class="sy1">:</span><span class="sy3">=</span> Application<span class="sy1">.</span><span class="me1">OnMessage</span><span class="sy1">;</span><br />Application<span class="sy1">.</span><span class="me1">OnMessage</span> <span class="sy1">:</span><span class="sy3">=</span> MyMessageHandler<span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span><br /> <br /><span class="kw1">procedure</span> TForm_webbrowser<span class="sy1">.</span><span class="me1">FormClose</span><span class="br0">(</span>Sender<span class="sy1">:</span> TObject<span class="sy1">;</span><br /> <span class="kw1">var</span> Action<span class="sy1">:</span> TCloseAction<span class="br0">)</span><span class="sy1">;</span><br /><span class="kw1">begin</span><br />Application<span class="sy1">.</span><span class="me1">OnMessage</span> <span class="sy1">:</span><span class="sy3">=</span> SaveMessageHandler<span class="sy1">;</span><br />FOleInPlaceActiveObject <span class="sy1">:</span><span class="sy3">=</span> <span class="kw2">nil</span><span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span><br /> <br /><span class="kw1">procedure</span> TForm_webbrowser<span class="sy1">.</span><span class="me1">FormDeactivate</span><span class="br0">(</span>Sender<span class="sy1">:</span> TObject<span class="br0">)</span><span class="sy1">;</span><br /><span class="kw1">begin</span><br />Application<span class="sy1">.</span><span class="me1">OnMessage</span> <span class="sy1">:</span><span class="sy3">=</span> SaveMessageHandler<span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span></div></pre><p>透過這樣子的處理, 就能使用 tab, ctrl-c/ctrl-v 等按鍵了.</p>
程式設計
2016-08-25T12:13:01Z
tommy
-
MyEzBuilder
https://blog.teatime.com.tw/1/post/447
<p>這是一個以 <a href="http://dl.dropboxusercontent.com/u/61164954/homepage/ezbuilder/index.htm" target="_blank">EzBuilder</a> 為範本改寫的軟體. 主要是為了支援 unicode 的檔案名稱.</p><p>不過由於多數的轉檔軟體都不支援 unicode 的檔名, 所以必須將檔名轉成非 unicode 的檔名, 才能正常的轉換. 這個程式裡頭會使用 hardlink 的方式來處理相關的檔案 (也就表示只能在 NTFS 格式的檔案系統裡頭運作).</p><p>與 EzBuilder 的差異如下:</p><ul><li>支援 unicode 的檔名.</li><li>不支援 setup.ini 裡頭 textsub_direct=0 時的處理 (把 ass/ssa 轉成 srt 格式), 也就是這參數對本程式無作用.</li><li>同上, 所以 setup.ini 裡頭的 language 參數也無作用.</li><li>setup.ini 新增 utf8_comment 參數, 設定為 1 表示在 comment.txt 會使用 utf-8 的編碼. 預設為 0.</li><li>setup.ini 新增 change_codepage 參數, 設定為 1 表示會在 build.bat 一開始執行 chcp 65001, 結束時轉回原本的 codepage. 預設為 0.</li><li>使用 -rename 參數, 可以用來更改 unicode 檔案名稱. (轉檔後用來改檔案名稱)</li><li>MediaFile 目錄下的影像/字幕檔會用 hardlink 產生一個檔名為 temp_media_N.xxx 的附本以方便轉檔程式處理. (轉檔後刪除)</li><li>在 avisynth 設定檔中插入字幕的處理會使用 temp_media_N.xxx 的檔案名稱.</li></ul>在 bat_work.txt 與 avs_deal.txt 可以轉換的字串: (與 EzBuilder 可能有些地方不一樣)<br /><ul><li>AvsNumberLoad => 檔案序號</li><li>File_To_Load => 未含目錄的影像檔名</li><li>MainFileLoad => 未含目錄的影像檔名 (無副檔名)</li><li>ExtFileLoad => 影像檔副檔名</li><li>MediaFileDir => MediaFile 目錄</li><li>DoneFileDir => DoneFile 目錄</li></ul><p>因為有些定義可能不同, 所以如果拿原本 EzBuilder 的 profile 來用時, bat_work.txt 與 avs_deal.txt 的內容請自行更改. (壓縮檔內有兩個範例)</p><p>如果要搭配 EzBuilder GUI 使用的話, 應該是將 MyEzBuilder.exe 改成 EzBuilder.exe 就可以 (支援相同的參數, 不過我沒試過).</p><p>檔案放這兒: <a href="http://www.teatime.com.tw/~tommy/files/MyEzBuilder_20130605.7z" target="_blank">http://www.teatime.com.tw/~tommy/files/MyEzBuilder_20130605.7z</a></p><p>檔案內含兩個 profile 範例與 C# 原始碼, 本程式採用 GPL2 的授權方式. </p>
程式設計
Software
2013-06-05T16:16:29Z
tommy
-
Windows console 模式的程式顯示 unicode 的方式
https://blog.teatime.com.tw/1/post/445
<p>原本有些小程式是使用 <a href="http://php.net/" target="_blank">php</a> 寫的 script 來跑, 不過... 由於 php 一直沒有支援 unicode (Windows wide string, 官方是說要等 PHP 6, 不過看起來不知道還要多久), 在處理 unicode 的檔案名稱時就會有問題, 所以... 還是需要自己寫些小程式來處理.</p><p>不過, 剛用 Visual C++ 寫的時候, 發現處理 unicode 時沒有什麼問題, 不過... 用 _tprintf (實際上應該就是 wprintf) 印出資料的時候, 都無法顯示出 unicode 的字.</p><p>找了相關的資料, 發現只要先去設定 stdout 的輸出模式, 就可以正常顯示 unicode 了. </p><pre class="c"><div class="insertcode"><pre class="c" style="font-family: monospace">_setmode<span class="br0">(</span>_fileno<span class="br0">(</span>stdout<span class="br0">)</span><span class="sy0">,</span> _O_U16TEXT<span class="br0">)</span><span class="sy0">;</span></pre></div></pre><p>只要程式先執行過上述的指令, 就可以正常的顯示 wide string (UTF16-LE) 的字串了. </p>
程式設計
VS2012
2013-05-05T10:27:31Z
tommy
-
讓你的 php socket 程式支援 SOCKS5 與 HTTP CONNECT Proxy
https://blog.teatime.com.tw/1/post/438
<p>最近因為有些程式所在的環境, 對外連線有些麻煩, 所以... 就想加上 proxy 的支援, 而目前最常用的 proxy, 大概就是 <a href="http://en.wikipedia.org/wiki/SOCKS" target="_blank">SOCKS5</a> 或 HTTP Proxy 了.</p><p>一般 <a href="http://php.net/" target="_blank">php</a> 的程式, 對於 socket 的處理, 通常都是使用 <a href="http://php.net/manual/en/function.fsockopen.php" target="_blank">fsockopen()</a> 來處理. 而上頭兩類的 proxy, 都是在一開始連線時, 處理一些 handshake 的動作之後, 就不用再做任何處理了, 後續的動作與你直接連線都一樣. 所以... 我們只要寫一個 function, 用來取代 fsockopen(), 就可以簡單的加上 proxy 的支援了.</p><p>首先, 是對於 SOCKS 的部份:</p><pre class="php"><div class="insertcode"><pre class="php" style="font-family: monospace"> <span class="kw2">private</span> <span class="kw2">function</span> _proxy_socks5_open<span class="br0">(</span><span class="re0">$host</span><span class="sy0">,</span> <span class="re0">$port</span><span class="sy0">,</span> <span class="re0">$errno</span><span class="sy0">,</span> <span class="re0">$errstr</span><span class="sy0">,</span> <span class="re0">$timeout</span><span class="br0">)</span><br /> <span class="br0">{</span><br /> <span class="co1">// already define proxy host and port</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_host</span> <span class="sy0">===</span> <span class="kw4">false</span> <span class="sy0">||</span> <span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_port</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <br /> <span class="co1">// connect to proxy server</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"SOCKS: Trying to "</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_port</span><span class="sy0">.</span><span class="st0">" ...<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$sock</span> <span class="sy0">=</span> <span class="sy0">@</span><a href="http://www.php.net/fsockopen"><span class="kw3">fsockopen</span></a><span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_host</span><span class="sy0">,</span> <span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_port</span><span class="sy0">,</span> <span class="re0">$errno</span><span class="sy0">,</span> <span class="re0">$errstr</span><span class="sy0">,</span> <span class="re0">$timeout</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$sock</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"SOCKS: fsockopen() "</span><span class="sy0">.</span><span class="re0">$errstr</span><span class="sy0">.</span><span class="st0">" ("</span><span class="sy0">.</span><span class="re0">$errno</span><span class="sy0">.</span><span class="st0">")<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"SOCKS: Connected<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <br /> <span class="co1">// we have the proxy user and password or not</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_user</span> <span class="sy0">!==</span> <span class="kw4">false</span> <span class="sy0">&&</span> <span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_pass</span> <span class="sy0">!==</span> <span class="kw4">false</span><span class="br0">)</span><br /> <span class="re0">$method</span> <span class="sy0">=</span> <span class="nu12">0x02</span><span class="sy0">;</span><br /> <span class="kw1">else</span><br /> <span class="re0">$method</span> <span class="sy0">=</span> <span class="nu12">0x00</span><span class="sy0">;</span><br /> <span class="co1">// sending version/method to proxy server</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/fwrite"><span class="kw3">fwrite</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> <a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">(</span><span class="st0">"C3"</span><span class="sy0">,</span> 0x05<span class="sy0">,</span> 0x01<span class="sy0">,</span> <span class="re0">$method</span><span class="br0">)</span><span class="br0">)</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span> <span class="br0">{</span><br /> <a href="http://www.php.net/fclose"><span class="kw3">fclose</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"SOCKS: fwrite() error for version/method<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="co1">// get response from proxy server</span><br /> <span class="re0">$buffer</span> <span class="sy0">=</span> <a href="http://www.php.net/fread"><span class="kw3">fread</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> 1024<span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$response</span> <span class="sy0">=</span> <a href="http://www.php.net/unpack"><span class="kw3">unpack</span></a><span class="br0">(</span><span class="st0">"Cversion/Cmethod"</span><span class="sy0">,</span> <span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="sy0">!</span><span class="br0">(</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">(</span><span class="re0">$response</span><span class="br0">[</span><span class="st_h">'version'</span><span class="br0">]</span><span class="br0">)</span> <span class="sy0">&&</span> <a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">(</span><span class="re0">$response</span><span class="br0">[</span><span class="st_h">'method'</span><span class="br0">]</span><span class="br0">)</span> <span class="sy0">&&</span> <span class="re0">$response</span><span class="br0">[</span><span class="st_h">'version'</span><span class="br0">]</span> <span class="sy0">==</span> 0x05 <span class="sy0">&&</span> <span class="re0">$response</span><span class="br0">[</span><span class="st_h">'method'</span><span class="br0">]</span> <span class="sy0">==</span> <span class="re0">$method</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><br /> <a href="http://www.php.net/fclose"><span class="kw3">fclose</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"SOCKS: unknown response (version/method): "</span><span class="sy0">.</span><a href="http://www.php.net/var_export"><span class="kw3">var_export</span></a><span class="br0">(</span><span class="re0">$response</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">)</span><span class="sy0">.</span><span class="st0">"<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$method</span> <span class="sy0">==</span> <span class="nu12">0x02</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="co1">// proxy server request username and password</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/fwrite"><span class="kw3">fwrite</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> <a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">(</span><span class="st0">"CC"</span><span class="sy0">,</span> 0x01<span class="sy0">,</span> <a href="http://www.php.net/strlen"><span class="kw3">strlen</span></a><span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_user</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_user</span><span class="sy0">.</span><br /> <a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">(</span><span class="st0">"C"</span><span class="sy0">,</span> <a href="http://www.php.net/strlen"><span class="kw3">strlen</span></a><span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_pass</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_pass</span><span class="br0">)</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span> <span class="br0">{</span><br /> <a href="http://www.php.net/fclose"><span class="kw3">fclose</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"SOCKS: fwrite() error for username/password<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$buffer</span> <span class="sy0">=</span> <a href="http://www.php.net/fread"><span class="kw3">fread</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> 1024<span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$response</span> <span class="sy0">=</span> <a href="http://www.php.net/unpack"><span class="kw3">unpack</span></a><span class="br0">(</span><span class="st0">"Cversion/Cstatus"</span><span class="sy0">,</span> <span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="sy0">!</span><span class="br0">(</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">(</span><span class="re0">$response</span><span class="br0">[</span><span class="st_h">'status'</span><span class="br0">]</span><span class="br0">)</span> <span class="sy0">&&</span> <span class="re0">$response</span><span class="br0">[</span><span class="st_h">'status'</span><span class="br0">]</span> <span class="sy0">==</span> 0x00<span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><br /> <a href="http://www.php.net/fclose"><span class="kw3">fclose</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"SOCKS: auth failed<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="co1">// pass the username/password check</span><br /> <span class="br0">}</span><br /> <span class="co1">// DNS perform in proxy or not</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_dns</span><span class="br0">)</span><br /> <span class="re0">$conn_str</span> <span class="sy0">=</span> <a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">(</span><span class="st0">"C5"</span><span class="sy0">,</span> 0x05<span class="sy0">,</span> 0x01<span class="sy0">,</span> 0x00<span class="sy0">,</span> 0x03<span class="sy0">,</span> <a href="http://www.php.net/strlen"><span class="kw3">strlen</span></a><span class="br0">(</span><span class="re0">$host</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">.</span><span class="re0">$host</span><span class="sy0">.</span><a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">(</span><span class="st0">"n"</span><span class="sy0">,</span> <span class="re0">$port</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">else</span><br /> <span class="re0">$conn_str</span> <span class="sy0">=</span> <a href="http://www.php.net/pack"><span class="kw3">pack</span></a><span class="br0">(</span><span class="st0">"C4Nn"</span><span class="sy0">,</span> 0x05<span class="sy0">,</span> 0x01<span class="sy0">,</span> 0x00<span class="sy0">,</span> 0x01<span class="sy0">,</span> <a href="http://www.php.net/ip2long"><span class="kw3">ip2long</span></a><span class="br0">(</span><a href="http://www.php.net/gethostbyname"><span class="kw3">gethostbyname</span></a><span class="br0">(</span><span class="re0">$host</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">,</span> <span class="re0">$port</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="co1">// connect it</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/fwrite"><span class="kw3">fwrite</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> <span class="re0">$conn_str</span><span class="br0">)</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span> <span class="br0">{</span><br /> <a href="http://www.php.net/fclose"><span class="kw3">fclose</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"SOCKS: fwrite() error<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$buffer</span> <span class="sy0">=</span> <a href="http://www.php.net/fread"><span class="kw3">fread</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> 1024<span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$response</span> <span class="sy0">=</span> <a href="http://www.php.net/unpack"><span class="kw3">unpack</span></a><span class="br0">(</span><span class="st0">"Cversion/Cresult/Creg/Ctype/Lip/Sport"</span><span class="sy0">,</span> <span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">(</span><span class="re0">$response</span><span class="br0">[</span><span class="st_h">'version'</span><span class="br0">]</span><span class="br0">)</span> <span class="sy0">&&</span> <a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">(</span><span class="re0">$response</span><span class="br0">[</span><span class="st_h">'result'</span><span class="br0">]</span><span class="br0">)</span> <span class="sy0">&&</span> <span class="re0">$response</span><span class="br0">[</span><span class="st_h">'version'</span><span class="br0">]</span> <span class="sy0">==</span> 0x05 <span class="sy0">&&</span> <span class="re0">$response</span><span class="br0">[</span><span class="st_h">'result'</span><span class="br0">]</span> <span class="sy0">==</span> <span class="nu12">0x00</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="co1">// yes, we already connect it via proxy</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"SOCKS: OK<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="re0">$sock</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <a href="http://www.php.net/fclose"><span class="kw3">fclose</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"SOCKS: error<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span></pre></div></pre><p>在這個函式中, 連線到 proxy server, 再依據需求送出登入的帳號密碼, 成功後就把 socket handle 回傳, 若失敗就傳回 false.</p><p>接著是 http proxy 的部份:</p><pre class="php"><div class="insertcode"><pre class="php" style="font-family: monospace"> <span class="kw2">private</span> <span class="kw2">function</span> _proxy_http_open<span class="br0">(</span><span class="re0">$host</span><span class="sy0">,</span> <span class="re0">$port</span><span class="sy0">,</span> <span class="re0">$errno</span><span class="sy0">,</span> <span class="re0">$errstr</span><span class="sy0">,</span> <span class="re0">$timeout</span><span class="br0">)</span><br /> <span class="br0">{</span><br /> <span class="co1">// already define proxy host and port</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_host</span> <span class="sy0">===</span> <span class="kw4">false</span> <span class="sy0">||</span> <span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_port</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <br /> <span class="co1">// connect to proxy server</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: Trying to "</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_port</span><span class="sy0">.</span><span class="st0">" ...<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$sock</span> <span class="sy0">=</span> <span class="sy0">@</span><a href="http://www.php.net/fsockopen"><span class="kw3">fsockopen</span></a><span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_host</span><span class="sy0">,</span> <span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_port</span><span class="sy0">,</span> <span class="re0">$errno</span><span class="sy0">,</span> <span class="re0">$errstr</span><span class="sy0">,</span> <span class="re0">$timeout</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$sock</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: fsockopen() "</span><span class="sy0">.</span><span class="re0">$errstr</span><span class="sy0">.</span><span class="st0">" ("</span><span class="sy0">.</span><span class="re0">$errno</span><span class="sy0">.</span><span class="st0">")<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: Connected<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$conn_str</span> <span class="sy0">=</span> <span class="st0">"CONNECT "</span><span class="sy0">.</span><span class="re0">$host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$port</span><span class="sy0">.</span><span class="st0">" HTTP/1.1<span class="es1">\r</span><span class="es1">\n</span>Host: "</span><span class="sy0">.</span><span class="re0">$host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$port</span><span class="sy0">.</span><span class="st0">"<span class="es1">\r</span><span class="es1">\n</span>User-Agent: ftp.cls.php<span class="es1">\r</span><span class="es1">\n</span><span class="es1">\r</span><span class="es1">\n</span>"</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: send => '<span class="es4">$conn_str</span>'<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/fwrite"><span class="kw3">fwrite</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> <span class="re0">$conn_str</span><span class="br0">)</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span> <span class="br0">{</span><br /> <a href="http://www.php.net/fclose"><span class="kw3">fclose</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: fwrite() error<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$buffer</span> <span class="sy0">=</span> <a href="http://www.php.net/fgets"><span class="kw3">fgets</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> 1024<span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$response</span> <span class="sy0">=</span> <a href="http://www.php.net/rtrim"><span class="kw3">rtrim</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: data => '"</span><span class="sy0">.</span><a href="http://www.php.net/rtrim"><span class="kw3">rtrim</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">.</span><span class="st0">"'<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="co1">// read following header/body</span><br /> <span class="re0">$auth_array</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$auth_header</span> <span class="sy0">=</span> <span class="st_h">''</span><span class="sy0">;</span><br /> <span class="re0">$content_length</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br /> <span class="kw1">while</span> <span class="br0">(</span><span class="sy0">!</span><a href="http://www.php.net/feof"><span class="kw3">feof</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$buffer</span> <span class="sy0">=</span> <a href="http://www.php.net/fgets"><span class="kw3">fgets</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> 1024<span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: header => '"</span><span class="sy0">.</span><a href="http://www.php.net/rtrim"><span class="kw3">rtrim</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">.</span><span class="st0">"'<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">1</span><span class="br0">)</span> <span class="sy0">==</span> <span class="st_h">' '</span> <span class="sy0">&&</span> <span class="re0">$auth_header</span> <span class="sy0">!==</span> <span class="st_h">''</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$auth_header</span> <span class="sy0">.=</span> <a href="http://www.php.net/rtrim"><span class="kw3">rtrim</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">continue</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="co1">// end of header</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$buffer</span> <span class="sy0">===</span> <span class="st0">"<span class="es1">\r</span><span class="es1">\n</span>"</span><span class="br0">)</span><br /> <span class="kw1">break</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/strncasecmp"><span class="kw3">strncasecmp</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="sy0">,</span> <span class="st_h">'Proxy-Authenticate:'</span><span class="sy0">,</span> <span class="nu0">19</span><span class="br0">)</span> <span class="sy0">==</span> <span class="nu0">0</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="co1">// Proxy-Authenticate: Digest realm="TeaTime Squid Proxy Server", nonce="Cjz/UAAAAADQEPuX/H8AAGmnlR0AAAAA", qop="auth", stale=false</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$auth_header</span> <span class="sy0">!==</span> <span class="st_h">''</span><span class="br0">)</span><br /> <span class="re0">$auth_array</span><span class="br0">[</span><span class="br0">]</span> <span class="sy0">=</span> <span class="re0">$auth_header</span><span class="sy0">;</span><br /> <span class="re0">$auth_header</span> <span class="sy0">=</span> <a href="http://www.php.net/rtrim"><span class="kw3">rtrim</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/strncasecmp"><span class="kw3">strncasecmp</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="sy0">,</span> <span class="st_h">'Content-Length:'</span><span class="sy0">,</span> <span class="nu0">15</span><span class="br0">)</span> <span class="sy0">==</span> <span class="nu0">0</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="co1">// Content-Length: 3123</span><br /> <span class="re0">$content_length</span> <span class="sy0">=</span> <a href="http://www.php.net/trim"><span class="kw3">trim</span></a><span class="br0">(</span><a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="sy0">,</span> 15<span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="br0">}</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$auth_header</span> <span class="sy0">!==</span> <span class="st_h">''</span><span class="br0">)</span><br /> <span class="re0">$auth_array</span><span class="br0">[</span><span class="br0">]</span> <span class="sy0">=</span> <span class="re0">$auth_header</span><span class="sy0">;</span><br /> <span class="re0">$body</span> <span class="sy0">=</span> <span class="st_h">''</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$content_length</span> <span class="sy0">!=</span> 0<span class="br0">)</span> <span class="br0">{</span><br /> <span class="kw1">while</span> <span class="br0">(</span><span class="re0">$content_length</span> <span class="sy0">></span> 0<span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$data</span> <span class="sy0">=</span> <a href="http://www.php.net/fread"><span class="kw3">fread</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> <span class="re0">$content_length</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$body</span> <span class="sy0">.=</span> <span class="re0">$data</span><span class="sy0">;</span><br /> <span class="re0">$content_length</span> <span class="sy0">=</span> <span class="re0">$content_length</span> <span class="sy0">-</span> <a href="http://www.php.net/strlen"><span class="kw3">strlen</span></a><span class="br0">(</span><span class="re0">$data</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: body => '"</span><span class="sy0">.</span><span class="re0">$body</span><span class="sy0">.</span><span class="st0">"'<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <a href="http://www.php.net/fclose"><span class="kw3">fclose</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/strtolower"><span class="kw3">strtolower</span></a><span class="br0">(</span><a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">(</span><span class="re0">$response</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">7</span><span class="br0">)</span><span class="br0">)</span> <span class="sy0">!=</span> <span class="st_h">'http/1.'</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: error<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$code</span> <span class="sy0">=</span> <a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">(</span><span class="re0">$response</span><span class="sy0">,</span> 9<span class="sy0">,</span> 3<span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$code</span><span class="br0">[</span><span class="nu0">0</span><span class="br0">]</span> <span class="sy0">==</span> <span class="st_h">'2'</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="co1">// yes, we already connect it via proxy</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: OK<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="re0">$sock</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$code</span> <span class="sy0">!=</span> <span class="st0">"407"</span> <span class="sy0">&&</span> <span class="re0">$code</span> <span class="sy0">!=</span> <span class="st0">"401"</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: error<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="co1">// need auth here</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_user</span> <span class="sy0">===</span> <span class="kw4">false</span> <span class="sy0">||</span> <span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_pass</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: error<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">(</span><span class="re0">$auth_array</span><span class="br0">)</span> <span class="sy0">==</span> <span class="nu0">0</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="co1">// no Proxy-Authenticate:</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: error<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="kw1">foreach</span> <span class="br0">(</span><span class="re0">$auth_array</span> <span class="kw1">as</span> <span class="re0">$auth_header</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: auth_header => '<span class="es4">$auth_header</span>'<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$auth_data</span> <span class="sy0">=</span> <a href="http://www.php.net/trim"><span class="kw3">trim</span></a><span class="br0">(</span><a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">(</span><span class="re0">$auth_header</span><span class="sy0">,</span> 19<span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/strncasecmp"><span class="kw3">strncasecmp</span></a><span class="br0">(</span><span class="re0">$auth_data</span><span class="sy0">,</span> <span class="st_h">'Digest '</span><span class="sy0">,</span> <span class="nu0">7</span><span class="br0">)</span> <span class="sy0">==</span> <span class="nu0">0</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="co1">// method Digest</span><br /> <span class="re0">$token</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$data</span> <span class="sy0">=</span> <a href="http://www.php.net/explode"><span class="kw3">explode</span></a><span class="br0">(</span><span class="st0">","</span><span class="sy0">,</span> <a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">(</span><span class="re0">$auth_data</span><span class="sy0">,</span> 7<span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">foreach</span> <span class="br0">(</span><span class="re0">$data</span> <span class="kw1">as</span> <span class="re0">$v</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$item</span> <span class="sy0">=</span> <a href="http://www.php.net/explode"><span class="kw3">explode</span></a><span class="br0">(</span><span class="st0">"="</span><span class="sy0">,</span> <span class="re0">$v</span><span class="sy0">,</span> 2<span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$name</span> <span class="sy0">=</span> <a href="http://www.php.net/trim"><span class="kw3">trim</span></a><span class="br0">(</span><span class="re0">$item</span><span class="br0">[</span>0<span class="br0">]</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$value</span> <span class="sy0">=</span> <a href="http://www.php.net/trim"><span class="kw3">trim</span></a><span class="br0">(</span><span class="re0">$item</span><span class="br0">[</span>1<span class="br0">]</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$value</span><span class="br0">[</span><span class="nu0">0</span><span class="br0">]</span> <span class="sy0">==</span> <span class="st_h">'"'</span><span class="br0">)</span><br /> <span class="re0">$value</span> <span class="sy0">=</span> <a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">(</span><span class="re0">$value</span><span class="sy0">,</span> 1<span class="sy0">,</span> <a href="http://www.php.net/strlen"><span class="kw3">strlen</span></a><span class="br0">(</span><span class="re0">$value</span><span class="br0">)</span> <span class="sy0">-</span> 2<span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$token</span><span class="br0">[</span><span class="re0">$name</span><span class="br0">]</span> <span class="sy0">=</span> <span class="re0">$value</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="sy0">!</span><a href="http://www.php.net/array_key_exists"><span class="kw3">array_key_exists</span></a><span class="br0">(</span><span class="st0">"nonce"</span><span class="sy0">,</span> <span class="re0">$token</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="co1">// nonce not found</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: error (nonce not found)<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">continue</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="sy0">!</span><a href="http://www.php.net/array_key_exists"><span class="kw3">array_key_exists</span></a><span class="br0">(</span><span class="st0">"realm"</span><span class="sy0">,</span> <span class="re0">$token</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="co1">// realm not found</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: error (realm not found)<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">continue</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="co1">// HA1 = md5(username:realm:password)</span><br /> <span class="co1">// if qop = auth or no qop</span><br /> <span class="co1">// HA2 = md5(method:digestURI)</span><br /> <span class="co1">// if qop = auth-int</span><br /> <span class="co1">// HA2 = md5(method:digestURI:md5(body))</span><br /> <span class="co1">// if qop = auth or auth-int</span><br /> <span class="co1">// response = md5(HA1:nonce:nonceCount:clientNonce:qop:HA2)</span><br /> <span class="co1">// if no qop</span><br /> <span class="co1">// response = md5(HA1:nonce:HA2)</span><br /> <span class="re0">$clientNonce</span> <span class="sy0">=</span> <span class="st_h">''</span><span class="sy0">;</span><br /> <span class="re0">$ha1</span> <span class="sy0">=</span> <a href="http://www.php.net/md5"><span class="kw3">md5</span></a><span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_user</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$token</span><span class="br0">[</span><span class="st0">"realm"</span><span class="br0">]</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_pass</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="sy0">!</span><a href="http://www.php.net/array_key_exists"><span class="kw3">array_key_exists</span></a><span class="br0">(</span><span class="st0">"qop"</span><span class="sy0">,</span> <span class="re0">$token</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$ha2</span> <span class="sy0">=</span> <a href="http://www.php.net/md5"><span class="kw3">md5</span></a><span class="br0">(</span><span class="st0">"CONNECT:"</span><span class="sy0">.</span><span class="re0">$host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$port</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$response</span> <span class="sy0">=</span> <a href="http://www.php.net/md5"><span class="kw3">md5</span></a><span class="br0">(</span><span class="re0">$ha1</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$token</span><span class="br0">[</span><span class="st0">"nonce"</span><span class="br0">]</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$ha2</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="kw1">else</span> <span class="br0">{</span><br /> <span class="re0">$qop_array</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">foreach</span> <span class="br0">(</span><a href="http://www.php.net/explode"><span class="kw3">explode</span></a><span class="br0">(</span><span class="st0">","</span><span class="sy0">,</span> <span class="re0">$token</span><span class="br0">[</span><span class="st0">"qop"</span><span class="br0">]</span><span class="br0">)</span> <span class="kw1">as</span> <span class="re0">$v</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$qop_array</span><span class="br0">[</span><span class="br0">]</span> <span class="sy0">=</span> <a href="http://www.php.net/strtolower"><span class="kw3">strtolower</span></a><span class="br0">(</span><a href="http://www.php.net/trim"><span class="kw3">trim</span></a><span class="br0">(</span><span class="re0">$v</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/in_array"><span class="kw3">in_array</span></a><span class="br0">(</span><span class="st0">"auth"</span><span class="sy0">,</span> <span class="re0">$qop_array</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$qop</span> <span class="sy0">=</span> <span class="st0">"auth"</span><span class="sy0">;</span><br /> <span class="re0">$ha2</span> <span class="sy0">=</span> <a href="http://www.php.net/md5"><span class="kw3">md5</span></a><span class="br0">(</span><span class="st0">"CONNECT:"</span><span class="sy0">.</span><span class="re0">$host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$port</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/in_array"><span class="kw3">in_array</span></a><span class="br0">(</span><span class="st0">"auth-int"</span><span class="sy0">,</span> <span class="re0">$qop_array</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$qop</span> <span class="sy0">=</span> <span class="st0">"auth-int"</span><span class="sy0">;</span><br /> <span class="re0">$ha2</span> <span class="sy0">=</span> <a href="http://www.php.net/md5"><span class="kw3">md5</span></a><span class="br0">(</span><span class="st0">"CONNECT:"</span><span class="sy0">.</span><span class="re0">$host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$port</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$body</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="kw1">else</span> <span class="br0">{</span><br /> <span class="co1">// noknown qop</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: error (unknown qop: "</span><span class="sy0">.</span><span class="re0">$token</span><span class="br0">[</span><span class="st0">"qop"</span><span class="br0">]</span><span class="sy0">.</span><span class="st0">")<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">continue</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$clientNonce</span> <span class="sy0">=</span> <a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">(</span><span class="st0">"<span class="es6">%08x</span>"</span><span class="sy0">,</span> <a href="http://www.php.net/time"><span class="kw3">time</span></a><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$response</span> <span class="sy0">=</span> <a href="http://www.php.net/md5"><span class="kw3">md5</span></a><span class="br0">(</span><span class="re0">$ha1</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$token</span><span class="br0">[</span><span class="st0">"nonce"</span><span class="br0">]</span><span class="sy0">.</span><span class="st0">":00000001:"</span><span class="sy0">.</span><span class="re0">$clientNonce</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$qop</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$ha2</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$proxy_header</span> <span class="sy0">=</span> <span class="st0">"Digest username=<span class="es1">\"</span>"</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_user</span><span class="sy0">.</span><span class="st0">"<span class="es1">\"</span>, realm=<span class="es1">\"</span>"</span><span class="sy0">.</span><span class="re0">$token</span><span class="br0">[</span><span class="st0">"realm"</span><span class="br0">]</span><span class="sy0">.</span><span class="st0">"<span class="es1">\"</span>, nonce=<span class="es1">\"</span>"</span><span class="sy0">.</span><span class="re0">$token</span><span class="br0">[</span><span class="st0">"nonce"</span><span class="br0">]</span><span class="sy0">.</span><span class="st0">"<span class="es1">\"</span>, uri=<span class="es1">\"</span>"</span><span class="sy0">.</span><span class="re0">$host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$port</span><span class="sy0">.</span><span class="st0">"<span class="es1">\"</span>, response=<span class="es1">\"</span>"</span><span class="sy0">.</span><span class="re0">$response</span><span class="sy0">.</span><span class="st0">"<span class="es1">\"</span>"</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$clientNonce</span> <span class="sy0">!==</span> <span class="st_h">''</span><span class="br0">)</span><br /> <span class="re0">$proxy_header</span> <span class="sy0">.=</span> <span class="st0">", qop="</span><span class="sy0">.</span><span class="re0">$qop</span><span class="sy0">.</span><span class="st0">", nc=00000001, cnonce=<span class="es1">\"</span>"</span><span class="sy0">.</span><span class="re0">$clientNonce</span><span class="sy0">.</span><span class="st0">"<span class="es1">\"</span>"</span><span class="sy0">;</span><br /> <span class="co1">// Proxy-Authorization: Digest username="tommy", realm="TeaTime Squid Proxy Server", nonce="h0n/UAAAAABQTgaY/H8AAFj8wDEAAAAA", uri="/phpsysinfo/index.php?disp=dynamic", response="e63732269c77d70b344f8dd650d6f753", qop=auth, nc=00000001, cnonce="557152171b138196"</span><br /> <br /> <span class="co1">// connect to proxy server</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: Trying to "</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_port</span><span class="sy0">.</span><span class="st0">" ...<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$sock</span> <span class="sy0">=</span> <span class="sy0">@</span><a href="http://www.php.net/fsockopen"><span class="kw3">fsockopen</span></a><span class="br0">(</span><span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_host</span><span class="sy0">,</span> <span class="re0">$this</span><span class="sy0">-></span><span class="me1">proxy_port</span><span class="sy0">,</span> <span class="re0">$errno</span><span class="sy0">,</span> <span class="re0">$errstr</span><span class="sy0">,</span> <span class="re0">$timeout</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$sock</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: fsockopen() "</span><span class="sy0">.</span><span class="re0">$errstr</span><span class="sy0">.</span><span class="st0">" ("</span><span class="sy0">.</span><span class="re0">$errno</span><span class="sy0">.</span><span class="st0">")<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">continue</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: Connected<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$conn_str</span> <span class="sy0">=</span> <span class="st0">"CONNECT "</span><span class="sy0">.</span><span class="re0">$host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$port</span><span class="sy0">.</span><span class="st0">" HTTP/1.1<span class="es1">\r</span><span class="es1">\n</span>Host: "</span><span class="sy0">.</span><span class="re0">$host</span><span class="sy0">.</span><span class="st0">":"</span><span class="sy0">.</span><span class="re0">$port</span><span class="sy0">.</span><span class="st0">"<span class="es1">\r</span><span class="es1">\n</span>Proxy-Authorization: "</span><span class="sy0">.</span><span class="re0">$proxy_header</span><span class="sy0">.</span><span class="st0">"<span class="es1">\r</span><span class="es1">\n</span>User-Agent: ftp.cls.php<span class="es1">\r</span><span class="es1">\n</span><span class="es1">\r</span><span class="es1">\n</span>"</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: send => '<span class="es4">$conn_str</span>'<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/fwrite"><span class="kw3">fwrite</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> <span class="re0">$conn_str</span><span class="br0">)</span> <span class="sy0">===</span> <span class="kw4">false</span><span class="br0">)</span> <span class="br0">{</span><br /> <a href="http://www.php.net/fclose"><span class="kw3">fclose</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: fwrite() error<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="kw1">continue</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="re0">$buffer</span> <span class="sy0">=</span> <a href="http://www.php.net/fgets"><span class="kw3">fgets</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> 1024<span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$response</span> <span class="sy0">=</span> <a href="http://www.php.net/rtrim"><span class="kw3">rtrim</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: data => '"</span><span class="sy0">.</span><a href="http://www.php.net/rtrim"><span class="kw3">rtrim</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">.</span><span class="st0">"'<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="co1">// read following header/body</span><br /> <span class="re0">$content_length</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span><br /> <span class="kw1">while</span> <span class="br0">(</span><span class="sy0">!</span><a href="http://www.php.net/feof"><span class="kw3">feof</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$buffer</span> <span class="sy0">=</span> <a href="http://www.php.net/fgets"><span class="kw3">fgets</span></a><span class="br0">(</span><span class="re0">$sock</span><span class="sy0">,</span> 1024<span class="br0">)</span><span class="sy0">;</span><br /> <span class="re0">$this</span><span class="sy0">-></span>_debug_print<span class="br0">(</span><span class="st0">"HTTP: header => '"</span><span class="sy0">.</span><a href="http://www.php.net/rtrim"><span class="kw3">rtrim</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="br0">)</span><span class="sy0">.</span><span class="st0">"'<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="co1">// end of header</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$buffer</span> <span class="sy0">===</span> <span class="st0">"<span class="es1">\r</span><span class="es1">\n</span>"</span><span class="br0">)</span><br /> <span class="kw1">break</span><span class="sy0">;</span><br /> <span class="kw1">if</span> <span class="br0">(</span><a href="http://www.php.net/strncasecmp"><span class="kw3">strncasecmp</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="sy0">,</span> <span class="st_h">'Content-Length:'</span><span class="sy0">,</span> <span class="nu0">15</span><span class="br0">)</span> <span class="sy0">==</span> <span class="nu0">0</span><span class="br0">)</span> <span class="br0">{</span><br /> <span class="co1">// Content-Length: 3123</span><br /> <span class="re0">$content_length</span> <span class="sy0">=</span> <a href="http://www.php.net/trim"><span class="kw3">trim</span></a><span class="br0">(</span><a href="http://www.php.net/substr"><span class="kw3">substr</span></a><span class="br0">(</span><span class="re0">$buffer</span><span class="sy0">,</span> 15<span class="br0">)</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="br0">}</span><br /> <span class="kw1">if</span> <span class="br0">(</span><span class="re0">$content_length</span> <span class="sy0">!=</span> 0<span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$xbody</span> <span class="sy0">=</span> <span class="st_h">''</span><span class="sy0">;</span><br /> <span class="kw1">while</span> <span class="br0">(</span><span class="re0">$content_length</span> <span class="sy0">></span> 0<span class="br0">)</span> <span class="br0">{</span><br /> <span class="re0">$data</span> <span class="sy0">=</span> <a href="http://www.php.net/fread"><span class="kw3">fread</span></a><span class="br0">(</spa</span></pre></div></pre>
程式設計
PHP
2013-01-29T10:47:42Z
tommy
-
使用 cygwin 取代 msys 來搭配 mingw 使用
https://blog.teatime.com.tw/1/post/432
<p>由於在 <a href="http://www.mingw.org/wiki/MSYS" target="_blank">msys</a> 中碰到的 <a href="http://blog.teatime.com.tw/1/post/431" target="_blank">make freeze</a> 問題, 所以就將開發的環境由 msys 轉到 <a href="http://www.cygwin.com/" target="_blank">cygwin</a> 來使用了.</p><p>其實 msys 是當初 cygwin 1.3 的一個子集, 現在換到 cygwin, 其實就是裝上了一個完整的 cygwin 環境, 而不是之前使用 msys 一樣, 只取所需要的部份來使用.</p><p>因為不想用裡頭的 cross compiler, 所以打算用與之前 msys 的方式來直接使用 mingw. 原本以為只要像是在 msys 中一樣, mount /mingw 進來, 在 PATH 裡頭, 把 /mingw/bin 放到 /bin 之前就可以用了. 結果.... 執行 gcc 是沒什麼問題, 不過... 由於 Windows 的換行字元是 CRLF, 而 cygwin 是用 LF, 所以.... 跑 configure 時, 會去讀取一些程式的執行結果來判斷時, 就會多出一個 ^M (就是 CR 這個字元), 結果.... 執行的結果就會有問題了. 看來... 原本 msys 還會把這個 CR 處理掉.</p><p>找了一下, 發現 bash 本身就有個 igncr 的選項可以用, 試著執行 set -o igncr, 會發現是把 igncr 設為 on 了, 不過並沒有作用. 所以看起來... 這選項並不會影響到已經執行的 shell. 所以改試著去設定 SHELLOPTS 這個環境變數. 不過.... 去設定這變數時會說這是一個唯讀的變數, 無法變更. 所以.... 我們要在執行 bash 之前就去設定這個變數就可以了.</p>
程式設計
2012-11-23T21:11:13Z
tommy
-
奇怪的 MSYS Make freeze 問題
https://blog.teatime.com.tw/1/post/431
<p>最近因為要更新所用的 <a href="http://tdm-gcc.tdragon.net/" target="_blank">TDM64-GCC</a> 中的 <a href="http://mingw-w64.svn.sourceforge.net/viewvc/mingw-w64/trunk/" target="_blank">mingw64-runtime-crt</a> (有些 function 在最近的版本才有), 結果, 玩著玩著就自己 build 起 <a href="http://mingw-w64.sourceforge.net/" target="_blank">mingw64</a> 用的 <a href="http://gcc.gnu.org/" target="_blank">gcc</a> 4.7.2 來了 (這中間也有些心得, 有空再說) .</p><p>結果, 在 build gcc 的過程 (使用 <a href="http://www.mingw.org/wiki/MSYS" target="_blank">MSYS</a> 環境), 使用 <a href="http://www.gnu.org/software/make/" target="_blank">make</a> -jN 來加速編譯的速度時, 發現常常跑到一半, make 就停住了 (不過仍佔用不少 CPU 時間), 每次都要 kill 之後再重跑.</p><p>上網找了一下, 發現 <a href="http://sourceforge.net/projects/mingwbuilds/" target="_blank">mingwbuilds</a> 這個專案的維護者之一, 最近也反應了這個問題, 不過似乎沒有什麼解決的方法. 再往久一點的時間找資料, 發現有這問題的人並不算少, 有人說用 <a href="http://sourceforge.net/projects/mingw/files/MinGW/Extension/make/" target="_blank">mingw32-make</a> 就可以解決 (不過我試了一下, 一樣會隨機停下來).... 看來並沒有什麼可以的解決方案.</p><p>由於 msys 的 make 停在 3.81 版本, 而 make 3.82 也出來一陣子了, 所以就試著自己編一個新的版本來用看看. 先抓回 msys 的 make 3.81 的 source, 解開來之後, 有 4 個 patch, 就打算套用到 3.82 上頭.... 結果... 相差太大, 無法直接套用... 手動慢慢處理時, 發現前兩個 patch 似乎可以不用了 (<a href="http://www.cygwin.com/" target="_blank">cygwin</a> 用的, 不過 3.82 好像本身就支援 cygwin, 應該可以不用自己 patch), 就直接處理後面兩個小 patch (有些不同, 不過一個是不管大小寫, 一個是 configure 的設定, 我改了一下, 好像沒什麼問題).... </p><p><a href="http://www.teatime.com.tw/~tommy/mypatch/make-3.82-msys.patch" target="_blank">patch</a> 如下:</p><pre class="diff"><div class="insertcode"><pre class="diff" style="font-family: monospace">diff -Nur make-3.82/Makefile.am make-3.82.patched/Makefile.am<br /><span class="re3">--- make-<span class="nu0">3.82</span>/Makefile.am <span class="nu0">2010</span>-07-<span class="nu0">13</span> 09:<span class="nu0">20</span>:<span class="nu0">30</span> +0800</span><br /><span class="re4">+++ make-3.82.patched/Makefile.am <span class="nu0">2012</span>-<span class="nu0">11</span>-07 <span class="nu0">14</span>:<span class="nu0">15</span>:<span class="nu0">44</span> +0800</span><br /><span class="re6">@@ -<span class="nu0">173</span>,<span class="nu0">10</span> +<span class="nu0">173</span>,<span class="nu0">17</span> @@</span><br /> case `cd $<span class="br0">(</span>srcdir<span class="br0">)</span>; pwd` in `pwd`<span class="br0">)</span> : ;; \<br /> *<span class="br0">)</span> test -d tests || mkdir tests; \<br /> rm -f srctests; \<br /><span class="re7">- if ln -s "$<span class="br0">(</span>srcdir<span class="br0">)</span>/tests" srctests; then \</span><br /><span class="re8">+ if /bin/false && ln -s "$<span class="br0">(</span>srcdir<span class="br0">)</span>/tests" srctests; then \</span><br /> for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \<br /> rm -f tests/$$f; ln -s ../srctests/$$f tests; \<br /><span class="re7">- done; fi ;; \</span><br /><span class="re8">+ done; \</span><br /><span class="re8">+ else \</span><br /><span class="re8">+ mkdir srctests ;\</span><br /><span class="re8">+ lndir $<span class="br0">(</span>srcdir<span class="br0">)</span>/tests/ srctests ;\</span><br /><span class="re8">+ for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \</span><br /><span class="re8">+ rm -f tests/$$f; <span class="br0">(</span>cd tests && ln -s ../srctests/$$f .<span class="br0">)</span>; \</span><br /><span class="re8">+ done; \</span><br /><span class="re8">+ fi ;; \</span><br /> esac; \<br /> echo "cd tests && $<span class="br0">(</span>PERL<span class="br0">)</span> ./run_make_tests.pl -make ../make$<span class="br0">(</span>EXEEXT<span class="br0">)</span> $<span class="br0">(</span>MAKETESTFLAGS<span class="br0">)</span>"; \<br /> cd tests && $<span class="br0">(</span>PERL<span class="br0">)</span> ./run_make_tests.pl -make ../make$<span class="br0">(</span>EXEEXT<span class="br0">)</span> $<span class="br0">(</span>MAKETESTFLAGS<span class="br0">)</span>; \<br />diff -Nur make-3.82/configure.in make-3.82.patched/configure.in<br /><span class="re3">--- make-<span class="nu0">3.82</span>/configure.in <span class="nu0">2010</span>-07-<span class="nu0">28</span> <span class="nu0">13</span>:<span class="nu0">39</span>:<span class="nu0">50</span> +0800</span><br /><span class="re4">+++ make-3.82.patched/configure.in <span class="nu0">2012</span>-<span class="nu0">11</span>-07 <span class="nu0">14</span>:<span class="nu0">16</span>:<span class="nu0">49</span> +0800</span><br /><span class="re6">@@ -<span class="nu0">41</span>,<span class="nu0">9</span> +<span class="nu0">41</span>,<span class="nu0">8</span> @@</span><br /> <br /> # Specialized system macros<br /> AC_CANONICAL_HOST<br /><span class="re7">-AC_AIX</span><br /><span class="re8">+AC_USE_SYSTEM_EXTENSIONS</span><br /> AC_ISC_POSIX<br /><span class="re7">-AC_MINIX</span><br /> <br /> # Enable gettext, in "external" mode.<br /> <br />diff -Nur make-3.82/implicit.c make-3.82.patched/implicit.c<br /><span class="re3">--- make-<span class="nu0">3.82</span>/implicit.c <span class="nu0">2010</span>-07-<span class="nu0">13</span> 09:<span class="nu0">20</span>:<span class="nu0">40</span> +0800</span><br /><span class="re4">+++ make-3.82.patched/implicit.c <span class="nu0">2012</span>-<span class="nu0">11</span>-07 <span class="nu0">14</span>:<span class="nu0">22</span>:<span class="nu0">25</span> +0800</span><br /><span class="re6">@@ -<span class="nu0">711</span>,<span class="nu0">7</span> +<span class="nu0">711</span>,<span class="nu0">7</span> @@</span><br /> /* @@ dep->changed check is disabled. */<br /> if <span class="br0">(</span>lookup_file <span class="br0">(</span>d->name<span class="br0">)</span> != 0<br /> /*|| <span class="br0">(</span><span class="br0">(</span>!dep->changed || check_lastslash<span class="br0">)</span> && */<br /><span class="re7">- || file_exists_p <span class="br0">(</span>d->name<span class="br0">)</span><span class="br0">)</span></span><br /><span class="re8">+ || file_exists_p <span class="br0">(</span>d->name<span class="br0">)</span> || <span class="br0">(</span>access <span class="br0">(</span>d->name, F_OK<span class="br0">)</span> == <span class="nu0">0</span><span class="br0">)</span><span class="br0">)</span></span><br /> <span class="br0">{</span><br /> <span class="br0">(</span>pat++<span class="br0">)</span>->name = d->name;<br /> continue;<br />diff -Nur make-3.82/vpath.c make-3.82.patched/vpath.c<br /><span class="re3">--- make-<span class="nu0">3.82</span>/vpath.c <span class="nu0">2010</span>-07-<span class="nu0">19</span> <span class="nu0">15</span>:<span class="nu0">10</span>:<span class="nu0">54</span> +0800</span><br /><span class="re4">+++ make-3.82.patched/vpath.c <span class="nu0">2012</span>-<span class="nu0">11</span>-07 <span class="nu0">14</span>:<span class="nu0">14</span>:04 +0800</span><br /><span class="re6">@@ -<span class="nu0">461</span>,<span class="nu0">7</span> +<span class="nu0">461</span>,<span class="nu0">8</span> @@</span><br /> /* We know the directory is in the hash table now because either<br /> construct_vpath_list or the code just above put it there.<br /> Does the file we seek exist in it? */<br /><span class="re7">- exists_in_cache = exists = dir_file_exists_p <span class="br0">(</span>name, filename<span class="br0">)</span>;</span><br /><span class="re8">+ //exists_in_cache = exists = dir_file_exists_p <span class="br0">(</span>name, filename<span class="br0">)</span>;</span><br /><span class="re8">+ exists_in_cache = exists = <span class="nu0">1</span>;</span><br /> #endif<br /> <span class="br0">}</span></pre></div></pre><p>如果不打算自己 build, 也不怕我加料的話, 可以抓我自己做的這個版本:<br /><a href="http://www.teatime.com.tw/~tommy/files/make-3.82-1-msys-1.0.17-bin.tar.lzma" target="_blank">http://www.teatime.com.tw/~tommy/files/make-3.82-1-msys-1.0.17-bin.tar.lzma</a> </p><p>換用這個版本之後, 我試著 build gcc 幾次, 目前都很正常, 沒有再碰到 freeze 的情形了. </p><hr />2012/11/12:<p>看來上頭的解決方法是錯的... 在另一台機器上, 一樣很頻繁的出現同樣的問題.</p><p>這兩天試著加上一些訊息在 make 上頭, 結果.... 發現錯誤似乎不是在 make 上面, 因為我在 make 一開始執行與結束時都把訊息寫到檔案上, 當出現 make freeze 的時候, 那個 pid 並沒有出現在這些檔案中, 表示系統在執行某個 make 時, 在執行到 main() 之前就已經造成該行程 freeze 了. 所以... 問題應該是出在 msys 本身.</p><p>往下追要看的東西似乎有點多, 暫時先放棄了.... 目前這個 freeze 的情形似乎只會出現在比較複雜的 make 上頭. 所以.... 只好在這類的程式上, 不要用 -j 來處理了.</p><p>PS. 另外.... 轉到 cygwin 上頭, 似乎就沒有這個問題了. </p>
程式設計
Patch
2012-11-07T21:59:41Z
tommy
-
Visual Studio 2012 在 Windows 8 底下無法使用 Shell32.Shell 的問題?
https://blog.teatime.com.tw/1/post/427
<p>最近開始用 C# 寫 .Net 的程式, 發現就寫程式的方便性來說, 比起直接用 C/C++ 寫要方便許多. 所以... 原本有些為了方便, 使用 php 來寫的 script, 也都順便改用 C# 來寫.</p><p>因為 Windows 8 與 Visual Studio 2012 出來後, 就由 MSDN 中抓回來用, 其實算很好用. 不過... 碰到一個原本在 Windows 7 搭配 Visual Studio 2010 時可以正常運作的程式, 改用 Windows 8 搭配 Visual Studio 2012 就會出現錯誤.</p><p>出錯的地方很簡單, 就類似這樣:</p><pre class="csharp"><div class="insertcode"><pre class="csharp" style="font-family: monospace"><span class="kw1">namespace</span> Shell32Test<br /><span class="br0">{</span><br /> <span class="kw4">class</span> Program<br /> <span class="br0">{</span><br /> <span class="kw1">static</span> <span class="kw1">void</span> Main<span class="br0">(</span><span class="kw4">string</span><span class="br0">[</span><span class="br0">]</span> args<span class="br0">)</span><br /> <span class="br0">{</span><br /> <span class="kw4">object</span> shell <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Shell32.<span class="me1">Shell</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="br0">}</span><br /><span class="br0">}</span></pre></div></pre><p>會出現下面的錯誤:</p><pre class="csharp"><div class="insertcode"><pre class="csharp" style="font-family: monospace">Unable to cast COM <span class="kw4">object</span> of type <span class="st0">'System.__ComObject'</span> to <span class="kw4">interface</span> type <span class="st0">'Shell32.Shell'</span>. <span class="kw1">This</span> operation failed because the QueryInterface call on the COM component <span class="kw1">for</span> the <span class="kw4">interface</span> with IID <span class="st0">'{286E6F1B-7113-4355-9562-96B7E9D64C54}'</span> failed due to the following error<span class="sy0">:</span> No such <span class="kw4">interface</span> supported <span class="br0">(</span>Exception from HRESULT<span class="sy0">:</span> 0x80004002 <span class="br0">(</span>E_NOINTERFACE<span class="br0">)</span><span class="br0">)</span>.</pre></div></pre><p>不過, 同一個程式, 在 Windows 7 下, 不管用 Visual Studio 2010 或 2012 都可以運作. 而且, 把那個可以運作的執行檔, 複製到 Windows 8 也一樣可以正常運作.</p><p>後來, 發現在 Windows 8 底下用 Visual Studio 2012 寫 Windows Form 的程式時, 也可以正常運作. 似乎只有在 console 程式會無法運作.</p><p>比較一下兩者的程式碼, 發現 Windows Form 的程式會在 Main 前面加上<span class="pln">一行:</span></p><pre class="csharp"><div class="insertcode"><pre class="csharp" style="font-family: monospace"><span class="br0">[</span>STAThread<span class="br0">]</span></pre></div></pre><p>試著加上變成:</p><pre class="csharp"><div class="insertcode"><pre class="csharp" style="font-family: monospace"><span class="kw1">namespace</span> Shell32Test<br /><span class="br0">{<br /> [STAThread]<br /></span> <span class="kw4">class</span> Program<br /> <span class="br0">{</span><br /> <span class="kw1">static</span> <span class="kw1">void</span> Main<span class="br0">(</span><span class="kw4">string</span><span class="br0">[</span><span class="br0">]</span> args<span class="br0">)</span><br /> <span class="br0">{</span><br /> <span class="kw4">object</span> shell <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a> Shell32.<span class="me1">Shell</span><span class="br0">(</span><span class="br0">)</span><span class="sy0">;</span><br /> <span class="br0">}</span><br /> <span class="br0">}</span><br /><span class="br0">}</span></pre></div></pre><p>這樣子居然可以正常執行了. 真是個奇怪的 bug. </p>
程式設計
C#
VS2012
Windows 8
.Net
2012-09-19T17:32:58Z
tommy
-
Delphi 的 utf-8 轉換
https://blog.teatime.com.tw/1/post/419
<p>新版的 Delphi 應該不用這麼麻煩, 據說只要直接在 AnsiString, WideString, UTF8String 之間 assign 時就會自動幫你做轉換 (沒用過, 不知道是不是真的這樣就可以).</p><p>不過... 還在用 Delphi 3/5, 所以... 只好自己來轉:</p><pre class="delphi"><div class="insertcode"><pre class="delphi" style="font-family: monospace"><span class="kw1">unit</span> util_utf8<span class="sy1">;</span><br /> <br /><span class="kw1">interface</span><br /> <br /><span class="kw1">uses</span> Windows<span class="sy1">;</span><br /> <br /><span class="kw1">type</span><br /> UTF8String <span class="sy3">=</span> <span class="kw4">AnsiString</span><span class="sy1">;</span><br /> <br /> <span class="kw1">function</span> AnsiToWide<span class="br0">(</span><span class="kw1">const</span> S<span class="sy1">:</span> <span class="kw4">AnsiString</span><span class="br0">)</span><span class="sy1">:</span> <span class="kw4">WideString</span><span class="sy1">;</span><br /> <span class="kw1">function</span> WideToUTF8<span class="br0">(</span><span class="kw1">const</span> WS<span class="sy1">:</span> <span class="kw4">WideString</span><span class="br0">)</span><span class="sy1">:</span> UTF8String<span class="sy1">;</span><br /> <span class="kw1">function</span> <span class="kw3">AnsiToUTF8</span><span class="br0">(</span><span class="kw1">const</span> S<span class="sy1">:</span> <span class="kw4">AnsiString</span><span class="br0">)</span><span class="sy1">:</span> UTF8String<span class="sy1">;</span><br /> <span class="kw1">function</span> UTF8ToWide<span class="br0">(</span><span class="kw1">const</span> US<span class="sy1">:</span> UTF8String<span class="br0">)</span><span class="sy1">:</span> <span class="kw4">WideString</span><span class="sy1">;</span><br /> <span class="kw1">function</span> WideToAnsi<span class="br0">(</span><span class="kw1">const</span> WS<span class="sy1">:</span> <span class="kw4">WideString</span><span class="br0">)</span><span class="sy1">:</span> <span class="kw4">AnsiString</span><span class="sy1">;</span><br /> <span class="kw1">function</span> <span class="kw3">UTF8ToAnsi</span><span class="br0">(</span><span class="kw1">const</span> S<span class="sy1">:</span> UTF8String<span class="br0">)</span><span class="sy1">:</span> <span class="kw4">AnsiString</span><span class="sy1">;</span><br /> <br /><span class="kw1">implementation</span><br /> <br /><span class="kw1">function</span> AnsiToWide<span class="br0">(</span><span class="kw1">const</span> S<span class="sy1">:</span> <span class="kw4">AnsiString</span><span class="br0">)</span><span class="sy1">:</span> <span class="kw4">WideString</span><span class="sy1">;</span><br /><span class="kw1">var</span> len<span class="sy1">:</span> <span class="kw4">integer</span><span class="sy1">;</span><br /> ws<span class="sy1">:</span> <span class="kw4">WideString</span><span class="sy1">;</span><br /><span class="kw1">begin</span><br />Result<span class="sy1">:</span><span class="sy3">=</span><span class="st0">''</span><span class="sy1">;</span><br /><span class="kw1">if</span> <span class="br0">(</span><span class="kw3">Length</span><span class="br0">(</span>S<span class="br0">)</span> <span class="sy3">=</span> 0<span class="br0">)</span> <span class="kw1">then</span><br /> <span class="kw3">exit</span><span class="sy1">;</span><br />len<span class="sy1">:</span><span class="sy3">=</span>MultiByteToWideChar<span class="br0">(</span>CP_ACP<span class="sy1">,</span> 0<span class="sy1">,</span> <span class="kw4">PChar</span><span class="br0">(</span>s<span class="br0">)</span><span class="sy1">,</span> <span class="sy3">-</span>1<span class="sy1">,</span> <span class="kw2">nil</span><span class="sy1">,</span> 0<span class="br0">)</span><span class="sy1">;</span><br /><span class="kw3">SetLength</span><span class="br0">(</span>ws<span class="sy1">,</span> len<span class="br0">)</span><span class="sy1">;</span><br />MultiByteToWideChar<span class="br0">(</span>CP_ACP<span class="sy1">,</span> 0<span class="sy1">,</span> <span class="kw4">PChar</span><span class="br0">(</span>s<span class="br0">)</span><span class="sy1">,</span> <span class="sy3">-</span>1<span class="sy1">,</span> <span class="kw4">PWideChar</span><span class="br0">(</span>ws<span class="br0">)</span><span class="sy1">,</span> len<span class="br0">)</span><span class="sy1">;</span><br />Result<span class="sy1">:</span><span class="sy3">=</span>ws<span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span><br /> <br /><span class="kw1">function</span> WideToUTF8<span class="br0">(</span><span class="kw1">const</span> WS<span class="sy1">:</span> <span class="kw4">WideString</span><span class="br0">)</span><span class="sy1">:</span> UTF8String<span class="sy1">;</span><br /><span class="kw1">var</span> len<span class="sy1">:</span> <span class="kw4">integer</span><span class="sy1">;</span><br /> us<span class="sy1">:</span> UTF8String<span class="sy1">;</span><br /><span class="kw1">begin</span><br />Result<span class="sy1">:</span><span class="sy3">=</span><span class="st0">''</span><span class="sy1">;</span><br /><span class="kw1">if</span> <span class="br0">(</span><span class="kw3">Length</span><span class="br0">(</span>WS<span class="br0">)</span> <span class="sy3">=</span> 0<span class="br0">)</span> <span class="kw1">then</span><br /> <span class="kw3">exit</span><span class="sy1">;</span><br />len<span class="sy1">:</span><span class="sy3">=</span>WideCharToMultiByte<span class="br0">(</span>CP_UTF8<span class="sy1">,</span> 0<span class="sy1">,</span> <span class="kw4">PWideChar</span><span class="br0">(</span>WS<span class="br0">)</span><span class="sy1">,</span> <span class="sy3">-</span>1<span class="sy1">,</span> <span class="kw2">nil</span><span class="sy1">,</span> 0<span class="sy1">,</span> <span class="kw2">nil</span><span class="sy1">,</span> <span class="kw2">nil</span><span class="br0">)</span><span class="sy1">;</span><br /><span class="kw3">SetLength</span><span class="br0">(</span>us<span class="sy1">,</span> len<span class="br0">)</span><span class="sy1">;</span><br />WideCharToMultiByte<span class="br0">(</span>CP_UTF8<span class="sy1">,</span> 0<span class="sy1">,</span> <span class="kw4">PWideChar</span><span class="br0">(</span>WS<span class="br0">)</span><span class="sy1">,</span> <span class="sy3">-</span>1<span class="sy1">,</span> <span class="kw4">PChar</span><span class="br0">(</span>us<span class="br0">)</span><span class="sy1">,</span> len<span class="sy1">,</span> <span class="kw2">nil</span><span class="sy1">,</span> <span class="kw2">nil</span><span class="br0">)</span><span class="sy1">;</span><br />Result<span class="sy1">:</span><span class="sy3">=</span>us<span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span><br /> <br /><span class="kw1">function</span> <span class="kw3">AnsiToUTF8</span><span class="br0">(</span><span class="kw1">const</span> S<span class="sy1">:</span> <span class="kw4">AnsiString</span><span class="br0">)</span><span class="sy1">:</span> UTF8String<span class="sy1">;</span><br /><span class="kw1">begin</span><br />Result<span class="sy1">:</span><span class="sy3">=</span>WideToUTF8<span class="br0">(</span>AnsiToWide<span class="br0">(</span>S<span class="br0">)</span><span class="br0">)</span><span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span><br /> <br /><span class="kw1">function</span> UTF8ToWide<span class="br0">(</span><span class="kw1">const</span> US<span class="sy1">:</span> UTF8String<span class="br0">)</span><span class="sy1">:</span> <span class="kw4">WideString</span><span class="sy1">;</span><br /><span class="kw1">var</span> len<span class="sy1">:</span> <span class="kw4">integer</span><span class="sy1">;</span><br /> ws<span class="sy1">:</span> <span class="kw4">WideString</span><span class="sy1">;</span><br /><span class="kw1">begin</span><br />Result<span class="sy1">:</span><span class="sy3">=</span><span class="st0">''</span><span class="sy1">;</span><br /><span class="kw1">if</span> <span class="br0">(</span><span class="kw3">Length</span><span class="br0">(</span>US<span class="br0">)</span> <span class="sy3">=</span> 0<span class="br0">)</span> <span class="kw1">then</span><br /> <span class="kw3">exit</span><span class="sy1">;</span><br />len<span class="sy1">:</span><span class="sy3">=</span>MultiByteToWideChar<span class="br0">(</span>CP_UTF8<span class="sy1">,</span> 0<span class="sy1">,</span> <span class="kw4">PChar</span><span class="br0">(</span>US<span class="br0">)</span><span class="sy1">,</span> <span class="sy3">-</span>1<span class="sy1">,</span> <span class="kw2">nil</span><span class="sy1">,</span> 0<span class="br0">)</span><span class="sy1">;</span><br /><span class="kw3">SetLength</span><span class="br0">(</span>ws<span class="sy1">,</span> len<span class="br0">)</span><span class="sy1">;</span><br />MultiByteToWideChar<span class="br0">(</span>CP_UTF8<span class="sy1">,</span> 0<span class="sy1">,</span> <span class="kw4">PChar</span><span class="br0">(</span>US<span class="br0">)</span><span class="sy1">,</span> <span class="sy3">-</span>1<span class="sy1">,</span> <span class="kw4">PWideChar</span><span class="br0">(</span>ws<span class="br0">)</span><span class="sy1">,</span> len<span class="br0">)</span><span class="sy1">;</span><br />Result<span class="sy1">:</span><span class="sy3">=</span>ws<span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span><br /> <br /><span class="kw1">function</span> WideToAnsi<span class="br0">(</span><span class="kw1">const</span> WS<span class="sy1">:</span> <span class="kw4">WideString</span><span class="br0">)</span><span class="sy1">:</span> <span class="kw4">AnsiString</span><span class="sy1">;</span><br /><span class="kw1">var</span> len<span class="sy1">:</span> <span class="kw4">integer</span><span class="sy1">;</span><br /> s<span class="sy1">:</span> <span class="kw4">AnsiString</span><span class="sy1">;</span><br /><span class="kw1">begin</span><br />Result<span class="sy1">:</span><span class="sy3">=</span><span class="st0">''</span><span class="sy1">;</span><br /><span class="kw1">if</span> <span class="br0">(</span><span class="kw3">Length</span><span class="br0">(</span>WS<span class="br0">)</span> <span class="sy3">=</span> 0<span class="br0">)</span> <span class="kw1">then</span><br /> <span class="kw3">exit</span><span class="sy1">;</span><br />len<span class="sy1">:</span><span class="sy3">=</span>WideCharToMultiByte<span class="br0">(</span>CP_ACP<span class="sy1">,</span> 0<span class="sy1">,</span> <span class="kw4">PWideChar</span><span class="br0">(</span>WS<span class="br0">)</span><span class="sy1">,</span> <span class="sy3">-</span>1<span class="sy1">,</span> <span class="kw2">nil</span><span class="sy1">,</span> 0<span class="sy1">,</span> <span class="kw2">nil</span><span class="sy1">,</span> <span class="kw2">nil</span><span class="br0">)</span><span class="sy1">;</span><br /><span class="kw3">SetLength</span><span class="br0">(</span>s<span class="sy1">,</span> len<span class="br0">)</span><span class="sy1">;</span><br />WideCharToMultiByte<span class="br0">(</span>CP_ACP<span class="sy1">,</span> 0<span class="sy1">,</span> <span class="kw4">PWideChar</span><span class="br0">(</span>WS<span class="br0">)</span><span class="sy1">,</span> <span class="sy3">-</span>1<span class="sy1">,</span> <span class="kw4">PChar</span><span class="br0">(</span>s<span class="br0">)</span><span class="sy1">,</span> len<span class="sy1">,</span> <span class="kw2">nil</span><span class="sy1">,</span> <span class="kw2">nil</span><span class="br0">)</span><span class="sy1">;</span><br />Result<span class="sy1">:</span><span class="sy3">=</span>s<span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span><br /> <br /><span class="kw1">function</span> <span class="kw3">UTF8ToAnsi</span><span class="br0">(</span><span class="kw1">const</span> S<span class="sy1">:</span> UTF8String<span class="br0">)</span><span class="sy1">:</span> <span class="kw4">AnsiString</span><span class="sy1">;</span><br /><span class="kw1">begin</span><br />Result<span class="sy1">:</span><span class="sy3">=</span>WideToAnsi<span class="br0">(</span>UTF8ToWide<span class="br0">(</span>S<span class="br0">)</span><span class="br0">)</span><span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span><br /> <br /><span class="kw1">end</span><span class="sy1">.</span></pre></div></pre><p>就是直接使用 win32 的 API 來處理.</p><p>PS. 舊的 VCL 只支援 Ansi, 所以... WideString 與 UTF8String (定義與 AnsiString 相同) 並沒有辦法正確的在 VCL 中顯示. </p>
程式設計
2012-03-02T12:39:06Z
tommy
-
Zint Barcode Generator
https://blog.teatime.com.tw/1/post/418
<p>最近試著在 Delphi 中產生 QR-Code, 找到了 <a href="http://sourceforge.net/projects/zint/" target="_blank">zint</a> 這東西, 也找到有人<a href="http://theunknownones.googlecode.com/svn/trunk/Components/ZintBarcode/" target="_blank">針對 zint.dll 做的 Delphi 模組</a>. 不過... 適用的 Delphi 版本是在 D10 之後, 我們用的 D3 與 D5 (沒錯了, 很老了) 都無法直接用.由於我們的需求很簡單, 所以放棄那個 uZintBarcode.pas 模組, 直接改 uZintInterface.pas 來用 (這個 DLL 的 import 用法, 在 Delphi 的版本之間差異不大, 改幾個地方就能用了.</p><pre class="delphi"><div class="insertcode"><pre class="delphi" style="font-family: monospace"><span class="kw1">unit</span> ZintInterface<span class="sy1">;</span><br /> <br /><span class="kw1">interface</span><br /> <br /><span class="co2">{$M+}</span><br /> <br /><span class="kw1">uses</span> Windows<span class="sy1">,</span> Classes<span class="sy1">,</span> SysUtils<span class="sy1">,</span> Graphics<span class="sy1">,</span> Dialogs<span class="sy1">;</span><br /> <br /><span class="kw1">type</span><br /> TZSymbol <span class="sy3">=</span> <span class="kw1">record</span><br /> symbology<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> height<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> whitespace_width<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> border_width<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> output_options<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> fgcolour<span class="sy1">:</span> <span class="kw1">array</span><span class="br0">[</span>0<span class="sy1">..</span>9<span class="br0">]</span> <span class="kw1">of</span> <span class="kw4">AnsiChar</span><span class="sy1">;</span><br /> bgcolour<span class="sy1">:</span> <span class="kw1">array</span><span class="br0">[</span>0<span class="sy1">..</span>9<span class="br0">]</span> <span class="kw1">of</span> <span class="kw4">AnsiChar</span><span class="sy1">;</span><br /> outfile<span class="sy1">:</span> <span class="kw1">array</span> <span class="br0">[</span>0<span class="sy1">..</span>255<span class="br0">]</span> <span class="kw1">of</span> <span class="kw4">AnsiChar</span><span class="sy1">;</span><br /> scale<span class="sy1">:</span> <span class="kw4">double</span><span class="sy1">;</span><br /> option_1<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> option_2<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> option_3<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> show_human_readable_text<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> input_mode<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> text<span class="sy1">:</span> <span class="kw1">array</span><span class="br0">[</span>0<span class="sy1">..</span>127<span class="br0">]</span> <span class="kw1">of</span> <span class="kw4">AnsiChar</span><span class="sy1">;</span><br /> rows<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> width<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> primary<span class="sy1">:</span> <span class="kw1">array</span> <span class="br0">[</span>0<span class="sy1">..</span>127<span class="br0">]</span> <span class="kw1">of</span> <span class="kw4">AnsiChar</span><span class="sy1">;</span><br /> encoded_data<span class="sy1">:</span> <span class="kw1">array</span><span class="br0">[</span>0<span class="sy1">..</span>177<span class="br0">]</span> <span class="kw1">of</span> <span class="kw1">array</span><span class="br0">[</span>0<span class="sy1">..</span>177<span class="br0">]</span> <span class="kw1">of</span> <span class="kw4">AnsiChar</span><span class="sy1">;</span><br /> row_height<span class="sy1">:</span> <span class="kw1">array</span><span class="br0">[</span>0<span class="sy1">..</span>177<span class="br0">]</span> <span class="kw1">of</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> errtxt<span class="sy1">:</span> <span class="kw1">array</span><span class="br0">[</span>0<span class="sy1">..</span>99<span class="br0">]</span> <span class="kw1">of</span> <span class="kw4">AnsiChar</span><span class="sy1">;</span><br /> bitmap<span class="sy1">:</span> <span class="kw4">PAnsiChar</span><span class="sy1">;</span><br /> bitmap_width<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> bitmap_height<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> rendered<span class="sy1">:</span> <span class="kw4">Pointer</span><span class="sy1">;</span><br /> <span class="kw1">end</span><span class="sy1">;</span><br /> PZSymbol <span class="sy3">=</span> <span class="sy2">^</span>TZSymbol<span class="sy1">;</span><br /> <br /><span class="kw1">const</span><br /> LibName <span class="sy3">=</span> <span class="st0">'zint.dll'</span><span class="sy1">;</span><br /> <br /> <span class="kw1">function</span> ZBarcode_Create<span class="sy1">:</span> PZSymbol<span class="sy1">;</span> <span class="kw1">cdecl</span><span class="sy1">;</span> <span class="kw1">external</span> LibName<span class="sy1">;</span><br /> <span class="kw1">procedure</span> ZBarcode_Delete<span class="br0">(</span>symbol<span class="sy1">:</span> PZSymbol<span class="br0">)</span><span class="sy1">;</span> <span class="kw1">cdecl</span><span class="sy1">;</span> <span class="kw1">external</span> LibName<span class="sy1">;</span><br /> <span class="kw1">procedure</span> ZBarcode_Clear<span class="br0">(</span>symbol<span class="sy1">:</span> PZSymbol<span class="br0">)</span><span class="sy1">;</span> <span class="kw1">cdecl</span><span class="sy1">;</span> <span class="kw1">external</span> LibName<span class="sy1">;</span><br /> <span class="kw1">function</span> ZBarcode_Buffer<span class="br0">(</span>symbol<span class="sy1">:</span> PZSymbol<span class="sy1">;</span> rotate_angle<span class="sy1">:</span> <span class="kw4">Integer</span><span class="br0">)</span><span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span> <span class="kw1">cdecl</span><span class="sy1">;</span> <span class="kw1">external</span> LibName<span class="sy1">;</span><br /> <span class="kw1">function</span> ZBarcode_Encode_and_Buffer<span class="br0">(</span>symbol<span class="sy1">:</span> PZSymbol<span class="sy1">;</span> input<span class="sy1">:</span> <span class="kw4">PAnsiChar</span><span class="sy1">;</span> <span class="kw3">length</span><span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span> rotate_angle<span class="sy1">:</span> <span class="kw4">Integer</span><span class="br0">)</span><span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span> <span class="kw1">cdecl</span><span class="sy1">;</span> <span class="kw1">external</span> LibName<span class="sy1">;</span><br /> <br /> <span class="kw1">procedure</span> ZBarcodeToBitmap<span class="br0">(</span>ASymbol<span class="sy1">:</span> PZSymbol<span class="sy1">;</span> <span class="kw1">const</span> ABitmap<span class="sy1">:</span> TBitmap<span class="br0">)</span><span class="sy1">;</span><br /> <br /><span class="kw1">implementation</span><br /> <br /><span class="kw1">procedure</span> ZBarcodeToBitmap<span class="br0">(</span>ASymbol<span class="sy1">:</span> PZSymbol<span class="sy1">;</span> <span class="kw1">const</span> ABitmap<span class="sy1">:</span> TBitmap<span class="br0">)</span><span class="sy1">;</span><br /><span class="kw1">var</span> myp<span class="sy1">:</span> PRGBTriple<span class="sy1">;</span><br /> row<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /> rowwidth<span class="sy1">:</span> <span class="kw4">Integer</span><span class="sy1">;</span><br /><span class="kw1">begin</span><br />ABitmap<span class="sy1">.</span><span class="me1">PixelFormat</span> <span class="sy1">:</span><span class="sy3">=</span> pf24bit<span class="sy1">;</span><br />ABitmap<span class="sy1">.</span><span class="me1">Width</span> <span class="sy1">:</span><span class="sy3">=</span> ASymbol<span class="sy1">.</span><span class="me1">bitmap_width</span><span class="sy1">;</span><br />ABitmap<span class="sy1">.</span><span class="me1">Height</span> <span class="sy1">:</span><span class="sy3">=</span> ASymbol<span class="sy1">.</span><span class="me1">bitmap_height</span><span class="sy1">;</span><br /> <br />myp <span class="sy1">:</span><span class="sy3">=</span> <span class="kw4">Pointer</span><span class="br0">(</span>ASymbol<span class="sy1">.</span><span class="me1">bitmap</span><span class="br0">)</span><span class="sy1">;</span><br />rowwidth <span class="sy1">:</span><span class="sy3">=</span> Asymbol<span class="sy1">.</span><span class="me1">bitmap_width</span> <span class="sy3">*</span> <span class="nu0">3</span><span class="sy1">;</span><br /> <br /><span class="kw1">for</span> row <span class="sy1">:</span><span class="sy3">=</span> 0 <span class="kw1">to</span> ASymbol<span class="sy1">.</span><span class="me1">bitmap_height</span> <span class="sy3">-</span> 1 <span class="kw1">do</span><br /> <span class="kw1">begin</span><br /> CopyMemory<span class="br0">(</span>ABitmap<span class="sy1">.</span><span class="me1">ScanLine</span><span class="br0">[</span>row<span class="br0">]</span><span class="sy1">,</span> myp<span class="sy1">,</span> rowwidth<span class="br0">)</span><span class="sy1">;</span><br /> <span class="kw3">Inc</span><span class="br0">(</span>myp<span class="sy1">,</span> Asymbol<span class="sy1">.</span><span class="me1">bitmap_width</span><span class="br0">)</span><span class="sy1">;</span><br /> <span class="kw1">end</span><span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span><br /> <br /><span class="kw1">end</span><span class="sy1">.</span></pre></div></pre><p>使用上也很簡單:</p><pre class="delphi"><div class="insertcode"><pre class="delphi" style="font-family: monospace"><span class="kw1">procedure</span> TForm1<span class="sy1">.</span><span class="me1">Button1Click</span><span class="br0">(</span>Sender<span class="sy1">:</span> <span class="kw4">TObject</span><span class="br0">)</span><span class="sy1">;</span><br /><span class="kw1">var</span> FSymbol<span class="sy1">:</span> PZSymbol<span class="sy1">;</span><br /> s<span class="sy1">:</span> <span class="kw4">string</span><span class="sy1">;</span><br /><span class="kw1">begin</span><br />Image1<span class="sy1">.</span><span class="me1">Picture</span><span class="sy1">.</span><span class="me1">Bitmap</span> <span class="sy1">:</span><span class="sy3">=</span> <span class="kw2">nil</span><span class="sy1">;</span><br />s <span class="sy1">:</span><span class="sy3">=</span> Memo1<span class="sy1">.</span><span class="me1">Text</span><span class="sy1">;</span><br />FSymbol <span class="sy1">:</span><span class="sy3">=</span> ZBarcode_Create<span class="sy1">;</span><br /><span class="kw1">try</span><br /> FSymbol<span class="sy1">.</span><span class="me1">symbology</span> <span class="sy1">:</span><span class="sy3">=</span> BARCODE_QRCODE<span class="sy1">;</span><br /> ZBarcode_Encode_and_Buffer<span class="br0">(</span>FSymbol<span class="sy1">,</span> <span class="kw4">PChar</span><span class="br0">(</span>s<span class="br0">)</span><span class="sy1">,</span> <span class="kw3">Length</span><span class="br0">(</span>s<span class="br0">)</span><span class="sy1">,</span> 0<span class="br0">)</span><span class="sy1">;</span><br /> ZBarcodeToBitmap<span class="br0">(</span>FSymbol<span class="sy1">,</span> Image1<span class="sy1">.</span><span class="me1">Picture</span><span class="sy1">.</span><span class="me1">Bitmap</span><span class="br0">)</span><span class="sy1">;</span><br /><span class="kw1">finally</span><br /> ZBarcode_Delete<span class="br0">(</span>FSymbol<span class="br0">)</span><span class="sy1">;</span><br /> FSymbol <span class="sy1">:</span><span class="sy3">=</span> <span class="kw2">nil</span><span class="sy1">;</span><br /> <span class="kw1">end</span><span class="sy1">;</span><br /><span class="kw1">end</span><span class="sy1">;</span></pre></div></pre><p>對於中文 (Big5 或 UTF-8) 也能正常的處理.</p><p>PS. 如果你是使用比較高的 Delphi 版本, 可以直接使用那個 uZintBarcode.pas 模組... 不過要注意的是, 裡頭會把 input_mode 設為 UNICODE_MODE (1), 這個名稱看起來是要能處理 Unicode,不過... 用了這一個 mode, 反而會造成中文變成亂碼 (不管 Big5 或 UTF-8 都一樣), 害我測了很久都找不出為什麼不能用中文. 後來看了 source code, 發現這個處理, 只是用來把 latin 的符號轉成 unicode (基本上, 與非英文語系的 unicode 完全沒關係), 改成 DATA_MODE (0) 之後, 就可以正常處理中文了. </p>
程式設計
2012-03-02T09:57:52Z
tommy
-
修正 phpmsnclass 在 big-endian 機器上無法正常登入的問題
https://blog.teatime.com.tw/1/post/410
<p>看來以前沒有人用 <a href="http://code.google.com/p/phpmsnclass" target="_blank">phpmsnclass</a> 這東西在 big-endian 的機器上頭.... 直到昨天有人問我他在登入時一直出現 <a href="http://msnpiki.msnfanatic.com/index.php/Reference:Error_List#911" target="_blank">911</a> 的錯誤, 加了一些除錯訊息之後, 終於發現 <a href="http://php.net/manual/en/function.pack.php" target="_blank">pack()</a> 的結果與在 x86/x64 上的結果不一樣. 造成 login 所需要的 BLOB 資料運算錯誤.</p><p>因為我只有 x86 的機器, 所以... 自然都用 little-endian 的方式來處理, 所以 pack() 傳入的參數是 'L' (依據 machine 來決定 unsigned long 的儲存方式)... 不過, 在 big-endian 結果就不同了.</p><p>所以我們應該在這地方使用 'V' (用 little-endian 的方式處理 unsigned long) 才處理, 這樣不管在 little-endian 或 big-endian 的機器都可以正常使用.</p><p>有需要的, 請自行到 Google code 去抓 r61 或之後的版本. </p>
程式設計
PHP
2012-01-17T10:18:27Z
tommy