发布新日志

  • Sikuli0.10.1试用

    2010-08-04 14:57:23

    在51testing 7月份的杂志上看到这个工具,下载了来(http://groups.casil.mit.edu/uid/sikuli/download.shtml)试用了下,此工具虽然和描述中那样的操作图形化,界面简单,但是回放出错率挺高的,必须将被回放的东西置于IDE之后,且精准的真是差强人意。试验了N多次,那工具就是找不到我IE的地址栏,后来N多找不到图片的情况发生,很是失望。

    参考:http://bugway.appspot.com/?p=324801

  • JBuilder2005单元测试之创建单元测试用例

    2009-07-16 16:03:20

    我们先为Subsection类创建测试用例

      1.在编辑器中打开Subsection.java文件,使其处理激活态。

      2.File->New...->Test->在Test页的对象库中双击Test Case图标,启动创建测试用例的向导,如下图所示:

    qq


    图 错误!文档
    中没有指定样式的文字。指定测试的方法

      ·Select class:测试的目标类,默认为当前编辑器中打开的类,也可以通过其后的…按钮选择工程中其他的类。

      ·Avaiable methods:列出了测试目标类的所有public、protected和默认可视域的方法,private方法不列出。只要你测试了前三者的方法,private也被间接测试到了。这里,我们选择getValue()和sign()方法。

      点击Next到下一步。

      3.设置测试用例类的类名。

    q

    JBuilder为测试用例类指定了一个默认的类名,即Test<业务类名>,包名和业务类包名一致。接受默认的值,直接按Finish创建TestSubsection测试用例类。

      实战经验:

      虽然在物理上,业务类和测试用例类被放在不同目录下,但在工程窗格的资源树中,业务类和测试用例还是挤在了一起。如果一个包下有多个业务类,加上它们相应的测试用例类,将显得更加拥挤不堪。所以最好将测试用例放到不同的包中,如com.super.bdbj包中的所有业务类的测试用例放到test.super.bdbj目录下,这样将彻底解决测试用例和业务类的物理和逻辑上的分离,使工程窗格中的资源树更加整洁明了。

      TestSubsection类的代码如下所示:

      代码清单 错误!文档中没有指定样式的文字。向导生成的TestSubsection类

    1. package chapter25;
    2.
    3. import junit.framework.*;
    4. public class TestSubsection extends TestCase {
    5.  private Subsection subsection = null;
    6.  protected void setUp() throws Exception {
    7.   super.setUp();
    8.   subsection = new Subsection();
    9.  }
    10.
    11. protected void tearDown() throws Exception {
    12.  subsection = null;
    13.  super.tearDown();
    14. }
    15.
    16. public void testGetValue() {
    17.   int d = 0;
    18.   int expectedReturn = 0;
    19.   int actualReturn = subsection.getValue(d);
    20.   assertEquals("return value", expectedReturn, actualReturn);
    21.   /**@todo fill in the test code*/
    22. }
    23.
    24. public void testSign() {
    25.  double d = 0.0;
    26.  int expectedReturn = 0;
    27.  int actualReturn = subsection.sign(d);
    28.  assertEquals("return value", expectedReturn, actualReturn);
    29.  /**@todo fill in the test code*/
    30. }
    31. }

      在第5行声明了一个Subsection的成员变量,并在setUp()中实例化这个变量(第7行),在tearDown()中释放这个变量(第12行),其实这三部分就构成了一个测试固件。当然,由于我们的getValue()、sign()方法都是静态方法,所以并不需要这个固件,在测试方法中直接调用方法就可以了,如Subsection.getValue(),但为了加强概念上的认识,我们特别予以保留。

      第16~22行的testGeValue()方法,和第24~30行的testSign(),就是在向导第1步所选择的需要测试的API方法对应的测试方法。JBuilder当然不可能知道我们API的逻辑规则,所以它仅提供了一个框架式的测试代码,需要我们发挥聪明才智通过assertXxx()定制覆盖性强的测试规则。

    文章来源于领测软件测试网 http://www.ltesting.net/

  • JWebUnit为Web应用程序创建测试用例的办法

    2009-07-16 14:29:05

    您是否正在寻找一种把自动测试技术应用到 Web 开发中的方法?那么不用再找了!JWebUnit 就是为 Web 应用程序创建测试用例的一个开源框架,它可以容易地插入到大多数 Java IDE 中。通过使用一个示例应用程序,描述了生成简洁测试用例的详细步骤,软件工程师 Amit Tuli 对 JWebUnit 进行了介绍。  

      自动测试可以节省重复执行相同测试步骤的时间和精力。本文将介绍 jWebUnit,这是一组 Java 类,用于为 Web 应用程序开发测试用例。jWebUnit 是一个开源项目,可以在 BSD 许可下免费获得。我将介绍如何下载 JWebUnit 库、配置 Eclipse 平台来开发 jWebUnit 测试用例,以及如何构建一个示例测试用例。  

      JWebUnit 简介  

      JWebUnit 以 HttpUnit(一个进行 Web 应用程序自动测试的 Java 库)和 JUnit 单元测试框架为基础(请参阅 参考资料)。jWebUnit 提供了导航 Web 应用程序的高级 API,并组合了一组断言,用它们来验证链接导航、表单输入项和提交、表格内容以及其他典型商务 Web 应用程序特性的正确性。 jWebUnit 以 JAR 文件形式提供的,可以很容易地将它插入大多数 IDE 中,jWebUnit 也包含其他必要的库。  

      用HttpUnit 进行测试  

      对 Web 应用程序自动进行测试意味着跳过 Web 浏览器,通过程序来处理 Web 站点。首先,我要介绍 HttpUnit(JWebUnit 的构建块之一)是如何简化这项工作的。HttpUnit 可以模拟帧、javascript、页面重定向 cookie,等等。在将 HttpUnit 用于 JUnit 时,它可以迅速地对 Web 站点的功能进行验证。  

      清单 1 显示了一个用 HttpUnit 编写的测试用例,它试图单击 HttpUnit 主页上的“Cookbook”链接:

      

      清单 1. 单击 HttpUnit 主页上 Cookbook 链接的 HttpUnit 代码

      1 public class HttpUnitTest {  2 public static void main(String[] args) {  3  try {  4   WebConversation wc = new WebConversation();  5   WebRequest request =        new GetMethodWebRequest("http://httpunit.   sourceforge.net/index.html");  6   wc.setProxyServer( "your.proxy.com", 80 );  7   WebResponse response = wc.getResponse(request);  8   WebLink httpunitLink =        response.getFirstMatchingLink(WebLink.   MATCH_CONTAINED_TEXT,"Cookbook");  9   response = httpunitLink.click();  10   System.out.println("Test successful !!");  11  } catch (Exception e) {  12   System.err.println("Exception: " + e);  13  }  14 }  15 }

      

      

      清单 1 中的代码用 your.proxy.com (第 6 行)连接 Internet。如果存在直接 Internet 连接,那么可以把这个语句注释掉。第 8 行的语句在页面中搜索包含文本 Cookbook 的 Web 链接。第 9 行的语句用于单击这个链接。如果找到链接,那么用户会看到 Test Successful !这条消息。

    用 JWebUnit 进行的测试更简单  

      清单 2 的测试用例用 JWebUnit API 执行和清单 1 相同的任务:  

      清单 2. 单击 HttpUnit 主页上 Cookbook 链接的 JWebUnit 代码  

      1 public class JWebUnitTest extends WebTestCase{  2 public static void main(String[] args){  3  junit.textui.TestRunner.run(new TestSuite(JWebUnitTest.class));  4 }  5 public void setUp(){  6  getTestContext().setBaseUrl("http://httpunit.sourceforge.net");  7  getTestContext().setProxyName("webproxy.watson.ibm.com");  8  getTestContext().setProxyPort(8080);  9 }  10 public void testSearch(){  11  beginAt("/index.html");  12  clickLinkWithText("Cookbook");  13 }  14 }

      

      如果没注意清单 2 中特定于 JUnit 的代码,那么您可以看到,测试用例现在变得相当整洁、简练。需要查看的重要的行是第 6 行、第 11 行和第 12 行。  

      在第 6 行,基本 URL 被设置到 HttpUnit 的主页中。第 11 行用相对路径 /index.html 连接站点。第 12 行用于单击页面上具有文本 Cookbook 的链接。如果链接有效,那么 JUnit 会报告成功;否则,JUnit 会报告异常。  

      JWebUnit API:进一步观察  

      每个 JWebUnit 测试的核心都是 net.sourceforge.jwebunit.WebTestCase 类,它代表测试用例。每个测试用例都必须是从这个类扩展而来。(net.sourceforge.jwebunit.WebTestCase 类本身则是从 junit.framework.TestCase 类扩展而来的,它在 JUnit 中代表测试用例。) 表 1 描述了这个类的一些常用方法:

    [点击图片可在新窗口打开]



      表 1. net.sourceforge.jwebunit.WebTestCase 类的重要方法

    另一个重要的类是 net.sourceforge.jwebunit.TestContext。它为测试创建上下文。可以用这个类来处理像 cookie、会话和授权之类的信息 

      下载 jWebUnit,在 Eclipse 中配置 jWebUnit  

      JWebUnit 是用纯 Java 代码实现的,所以可以以 JAR 文件的形式获得它 (请参阅 参考资料,从中获得下载链接)。在完成下载之后,请按以下步骤在 Eclipse 平台上配置 JWebUnit 库:  

      把下载的文件 jwebunit-1.2.zip 释放到临时目录中(假设是 C:\temp)。  

      在 Eclipse 中创建新 Java 项目,将其命名为 jWebUnit。  

      右击 Package Explorer 视图中的 jWebUnit 项目,然后选择 Properties。  

      单击 Java Build Path。单击 Libraries 标签中的 Add External JARs。  

      浏览到 C:\temp\jwebunit-1.2\lib 目录,选择这个目录中的所有 JAR 文件。  

      单击 OK。  

      现在可以在 Eclipse 中的 jWebUnit 项目下开发 jWebUnit 测试用例了。  

      构建示例应用程序  

      现在就可以查看 jWebUnit API 的实际应用了。我将带您研究一个示例应用程序,帮助您更好地理解 jWebUnit 的真正威力。这个应用程序是一个测试用例,用于打开一个 Google 搜索页面并搜索文本 HttpUnit。应用程序需要测试以下场景:  

      打开 Google 主页 http://www.google.com。  

      确定该页包含一个名为 q 的表单元素。(在 Google 的主页上,名为 q 的文本框是接受用户查询输入的文本框。)应用程序用这个元素输入搜索参数。  

      在搜索文本框中输入字符串 HttpUnit Home,并提交表单。  

      获得结果页,并确定该页面包含的链接中包含文本 HttpUnit Home。  

      单击包含文本 HttpUnit Home 的链接。  

      现在测试场景已经就绪,可以编写 Java 应用程序,用 jWebUnit 实现这些需求了。  

      第一步是声明一个从 WebTestCase 扩展而来的类,如清单 3 所示:  

      清单 3. 声明测试用例类

      public class GoogleTest extends WebTestCase {

      static String searchLink = "";

      }

      正如我在前面提到过的,jWebUnit 要求每个测试用例都是从 WebTestCase 中扩展而来的。searchLink 保存传入的搜索参数。这个值以命令行参数的形式传递给测试用例。  

      下一步是声明入口点 —— main() 方法,如清单 4 所示:  

      清单 4. main() 方法  

      public static void main(String[] args) {

      searchLink = args[0];

      junit.textui.TestRunner.run(new

      TestSuite(GoogleTest.class));

      }
    main() 方法调用 junit.textui.TestRunner.run() 执行 JTest 测试用例。因为需要运行 GoogleTest 测试用例,所以,作为参数传递给 run() 方法的测试套件采用 GoogleTest.class 作为参数。  

      接下来,JTest 调用 setUp() 方法来设置基本 URL 和代理,如清单 5 所示:  

      清单 5. 设置  

      public void setUp() {

      getTestContext().setBaseUrl("http://www.google.com");

      getTestContext().setProxyName("proxy.host.com");

      getTestContext().setProxyPort(80);

      }

        清单 5 把基本 URL 设置为 http://www.google.com。这意味着测试用例的启动是相对于这个 URL 的。下面两个语句设置连接到 Internet 的代理主机和代理端口。如果是直接连接到 Internet,那么可以忽略代理设置语句。  

      现在开始浏览站点并输入搜索参数。清单 6 显示了访问 Web 页面,然后测试所有场景的代码: 

      清单 6. 测试所有场景  

      public void testSearch() {

      beginAt("/");

      assertFormElementPresent("q");

      setFormElement("q", "HttpUnit");

      submit("btnG");

      assertLinkPresentWithText(searchLink);

      clickLinkWithText(searchLink);

      }

      清单 6 的代码连接到基本 URL,并相对于 / 开始浏览。然后它断定页面中包含一个名为 q 的表单元素 —— q 是 Google 主页上查询输入文本框的名称。下一条语句用值 HttpUnit 设置名为 q 的文本框。  

      再下一条语言提交表单上名为 btnG 的提交按钮。(在 Google 的主页上,名为 btnG 的按钮是标签为 Google Search 的按钮。)表单是在这个对话中提交的,下一页列出搜索结果。在结果页面上,代码首先检查是否有一个链接的文本是 HttpUnit Home。如果该链接不存在,那么测试就以 AssertionFailedError 失败。如果该链接存在,则测试执行的下一个操作是单击链接。  

      运行示例应用程序  

      现在把示例应用程序投入使用当中:  

    下载示例应用程序 j-webunitsample.jar 。  

      在一个目录中解压缩 j-webunitsample.jar。例如,如果把它释放到 C:\temp 中,那么就要把源文件和类文件放在 C:\temp\com\jweb\test 中,而 setclasspth.bat 则放在 C:\temp 中。  

      编辑 setclasspath.bat:设置 JAR_BASE 指向包含所有必需 JAR 文件的目录。例如,如果在 C:\temp 中释放 jwebunit-1.2.zip 文件,那么将 JAR_BASE 设置为 C:\temp\jwebunit-1.2\lib。 

      打开命令行提示符,切换到 C:\temp 目录。  

      执行 setclasspath.bat。这会设置执行测试用例所需的 CLASSPATH。  

      用命令 java com.jweb.test.GoogleTest "HttpUnit Home" 运行应用程序。

      示例输出  

      在执行了测试用例之后,会在命令行输出一个测试用例报告。如果测试失败,报告看起来如清单 7 中所示:  

      清单 7. 带有断言失败的输出

      C:\temp>java com.jweb.test.GoogleTest "HttpUnit Hwee"   .F   Time: 5.338   There was 1 failure:   1) testSearch(com.jweb.test.GoogleTest)junit.   framework.AssertionFailedError: Link    with text [HttpUnit Hwee] not found in response.   at net.sourceforge.jwebunit.WebTester.   assertLinkPresentWithText(WebTester.java:618)   at net.sourceforge.jwebunit.WebTestCase.   assertLinkPresentWithText(WebTestCase.java:244)   at com.jweb.test.GoogleTest.testSearch(GoogleTest.java:36)   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)   at com.jweb.test.GoogleTest.main(GoogleTest.java:19)     FAILURES!!!   Tests run: 1, Failures: 1, Errors: 0   

      正如在清单 7 中可以看到的,可以用 HttpUnit Hwee 作为参数来执行测试用例。这个测试用例遇到断言的地方会失败,因为结果页面中不包含带有这个文本的链接。由此也就产生了 junit.framework.AssertionFailedError。  

      清单 8 执行时用 HttpUnit Home 作为参数。测试用例找到一个带有这个文本的链接,所以测试通过了:  

      清单 8. 成功测试的输出  

      C:\temp>java com.jweb.test.GoogleTest "HttpUnit Home"

      Time: 6.991  

      OK (1 test)  

      结束语  

      本文通过讨论 jWebUnit 框架的一些突出特性和最重要的类,介绍如何用它创建简洁的测试用例,让您对 jWebUnit 框架有一个认识。jWebUnit 还有更多特性可以用在测试用例中。它支持测试 Web 页面中的链接行数。可以对字符串、表或者带有指定标签的表单输入元素是否存在于页面上进行断言。此外,jWebUnit 还可以处理 cookie (例如断言存在某个 cookie、删除 cookie 等。)测试可以对某个文本之后出现的特定文本的链接进行单击。 如果想为 Web 应用程序构建快而有效的测试用例,jWebUnit可能是您最好的朋友。
  • IETester中文免费版 - 最佳网页IE浏览器兼容性测试工具(IE6 IE7 IE8共存)

    2009-07-15 17:41:05

      对于很多拥有自己博客或者接触网页制作的朋友,肯定会遇到自己辛苦写好的页面在不同的浏览器下显示出来的效果截然不同吧,喜欢追求完美的朋友就肯定希望能尽量在不同浏览器下对页面进行测试并保证其正常显示了。当然,像FireFox、Safari、Opera等浏览器还可以随意地安装卸载,然而,最麻烦的莫过于微软的“IE”系列了。

        基本上你不能用常规的方法同时在一个系统中安装IE5、IE6、IE7甚至IE8!找多台电脑来测试对很多人来说也并不是很容易的事情。之前异次元の世界也曾给大家介绍过一款绿色版的IE6,但始终问题比较多,并不是十分好用。X-Force今天给大家介绍的IETester就可以完美地解决这个烦人的问题了!IETester可以让你同时测试网页在IE5~IE8下的兼容性和显示效果....


    IETester 主界面截图


         IETester可以在独立的标签页中开启IE5.5、IE6、IE7以及最新的IE8 beta2这4个不同版本的IE,而且在Windows Vista下也有着良好的稳定性。IETester的界面完全仿照了Office2007的风格,软件功能已经精简到仅仅与浏览页面相关。点击界面左上方的“新标签”后就会出现IE版本的选择菜单。注意:如果不选版本,软件将默认为IE 7。



      通过 IETester ,设计者们可以在一个窗口下轻松地打开支持不同版本IE的标签页,这里有一个细节:标签前面的蓝色数字则代表了所属IE的版本号。虽然数字的样式有点“丑”,但是便于使用者识别IE的版本号,为用户提供了方便。
  • QRe.一个开源的正则表达式测试工具

    2009-07-15 17:39:11

    QRe.一个开源的正则表达式测试工具

    项目主页:
    http://code.google.com/p/qre/

    下载:
    http://qre.googlecode.com/files/QRe-V0.2.jar

    用法java -jar QRe.jar
    运行环境:Windows jre1.5/1.6
    特点:
    1.支持匹配处高亮显示
    2.支持group
    3.支持多次匹配
    4.当点击表格中匹配到的项时,左边的文本框会定位到相应的上下文位置
    5.如果匹配到的文字过长,双击相应的项可以查看细节。




  • 用于调试CSS/JavaScript兼容性的工具

    2009-07-15 17:38:12

     一般做CSS或者js编写的都要调试两大浏览器的兼容性:Microsoft Inte.net Explorer 和 FireFox。

    给大家介绍两个工具:
    [1] Microsoft Internet Explorer Developer Toolbar
    [2] Firebug

    两个工具条分别安装于 IE 和 Firefox 中,前一个就是一个安装文件,怎么装就不说了。后面那个,是一个xpi文件,安装方法:
    1、先打开firefox,然后点文件->打开文件
    2、选择这个xpi文件,在弹出的提示选择安装即可。


    CSS方面:
    两个工具均可分析当前页面的DOM树并显示。还可以根据DOM树察看影响各个部分的样式表的信息。在firebug中,更是可以直接在firebug里面修改测试,而无需真正的去修改源文件。当然功能不仅仅于此,大家安装以后体验一下就可以了。

    JS方面:
    Ie 的自身一些内建方法迷惑了太多的人,致使很多人写的js在非ie中无法正常运行。微软的那个工具条,在调试css方面还算不错,但是在调试js方面,就比较逊色了。这里建议大家按照firebug的提示修改你的js,基本上ie都能运行。

    大家自己装上看看吧。

  • CURL详解(转载)

    2009-07-14 15:24:08

    • 目录
    1. 介绍
    2. curl扩展的安装
    3. curl_init
    4. curl_setopt
    5. curl_exec
    6. curl_close
    7. curl_version
    • 介绍

            PHP 支持libcurl(允许你用不同的协议连接和沟通不同的服务器)。, libcurl当前支持http, https, ftp, gopher, telnet, dict, file, 和ldap 协议。libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传(当然你也可以使用PHP的ftp扩展), HTTP基本表单上传,代理,cookies,和用户认证。

    为了使用CURL函数你需要安装CURL包。PHP 需要你使用CURL 7.0.2-beta或更高版。如果CURL的版本低于7.0.2-beta,PHP将不工作。

    要使用PHP的CURL支持,你必须用带有--with-curl[=DIR]参数重新编译PHP(DIR是包含库和头文件的目录)。

    这些函数是在PHP 4.0.2中新增得。

    一旦你编译了带有CURL支持的PHP,你可以使用curl函数。基本思路是:你使用curl_init()函数初始化CURL会话,而后你可以设置你的所有选项,通过curl_exec()函数执行,最后你可以作用curl_close()函数来结束你的会话。以下是一个例子:是把PHP的主页取回放到一个文件中。
    例 1. 使用PHP的CURL模块取回PHP主页

    $ch = curl_init ("http://www.php.net/");
    $fp = fopen ("php_homepage.txt", "w");

    curl_setopt ($ch, CURLOPT_FILE, $fp);
    curl_setopt ($ch, CURLOPT_HEADER, 0);

    curl_exec ($ch);
    curl_close ($ch);
    fclose ($fp);
    ?>
     


    目录列表
    curl_init — 初始化一个CURL会话
    curl_setopt — 为CURL调用设置一个选项
    curl_exec — 执行一个CURL会话
    curl_close — 关闭一个CURL会话
    curl_version — 返回当前CURL版本

     

    • curl扩展的安装

    PHP已经内置有php_curl.dll,在ext目录下,此DLL用于支持SSL和zlib.
    在php.ini中找到有extension=php_curl.dll, 去掉前面的注释.
    设置extension_dir=你的php的ext目录(例如c:\php\ext)
    把ext目录下的libeay32.dll, ssleay32.dll, php5ts.dll, php_curl.dll 都拷贝到system32目录下,重启apache即可。

    • curl_init

    curl_init -- 初始化一个CURL会话

    描述

     

    int curl_init ([string url])

     

    curl_init()函数将初始化一个新的会话,返回一个CURL句柄供curl_setopt(), curl_exec(),和 curl_close() 函数使用。如果可选参数被提供,那么CURLOPT_URL选项将被设置成这个参数的值。你可以使用curl_setopt()函数人工设置。
    例 1. 初始化一个新的CURL会话,且取回一个网页

    $ch = curl_init();

    curl_setopt ($ch, CURLOPT_URL, "http://www.zend.com/");
    curl_setopt ($ch, CURLOPT_HEADER, 0);

    curl_exec ($ch);

    curl_close ($ch);
    ?>
     


    参见:curl_close(), curl_setopt()

    • curl_setopt

    curl_setopt -- 为CURL调用设置一个选项

    描述

     

    bool curl_setopt (int ch, string option, mixed value)

     

    curl_setopt()函数将为一个CURL会话设置选项。option参数是你想要的设置,value是这个选项给定的值。

    下列选项的值将被作为长整形使用(在option参数中指定):

     

    CURLOPT_INFILESIZE: 当你上传一个文件到远程站点,这个选项告诉PHP你上传文件的大小。

    CURLOPT_VERBOSE: 如果你想CURL报告每一件意外的事情,设置这个选项为一个非零值。

    CURLOPT_HEADER: 如果你想把一个头包含在输出中,设置这个选项为一个非零值。

    CURLOPT_NOPROGRESS: 如果你不会PHP为CURL传输显示一个进程条,设置这个选项为一个非零值。

    注意:PHP自动设置这个选项为非零值,你应该仅仅为了调试的目的来改变这个选项。

    CURLOPT_NOBODY: 如果你不想在输出中包含body部分,设置这个选项为一个非零值。

    CURLOPT_FAILONERROR: 如果你想让PHP在发生错误(HTTP代码返回大于等于300)时,不显示,设置这个选项为一人非零值。默认行为是返回一个正常页,忽略代码。

    CURLOPT_UPLOAD: 如果你想让PHP为上传做准备,设置这个选项为一个非零值。

    CURLOPT_POST: 如果你想PHP去做一个正规的HTTP POST,设置这个选项为一个非零值。这个POST是普通的 application/x-www-from-urlencoded 类型,多数被HTML表单使用。

    CURLOPT_FTPLISTONLY: 设置这个选项为非零值,PHP将列出FTP的目录名列表。

    CURLOPT_FTPAPPEND: 设置这个选项为一个非零值,PHP将应用远程文件代替覆盖它。

    CURLOPT_NETRC: 设置这个选项为一个非零值,PHP将在你的 ~./netrc 文件中查找你要建立连接的远程站点的用户名及密码。

    CURLOPT_FOLLOWLOCATION: 设置这个选项为一个非零值(象 "Location: ")的头,服务器会把它当做HTTP头的一部分发送(注意这是递归的,PHP将发送形如 "Location: "的头)。

    CURLOPT_PUT: 设置这个选项为一个非零值去用HTTP上传一个文件。要上传这个文件必须设置CURLOPT_INFILE和CURLOPT_INFILESIZE选项.

    CURLOPT_MUTE: 设置这个选项为一个非零值,PHP对于CURL函数将完全沉默。

    CURLOPT_TIMEOUT: 设置一个长整形数,作为最大延续多少秒。

    CURLOPT_LOW_SPEED_LIMIT: 设置一个长整形数,控制传送多少字节。

    CURLOPT_LOW_SPEED_TIME: 设置一个长整形数,控制多少秒传送CURLOPT_LOW_SPEED_LIMIT规定的字节数。

    CURLOPT_RESUME_FROM: 传递一个包含字节偏移地址的长整形参数,(你想转移到的开始表单)。

    CURLOPT_SSLVERSION: 传递一个包含SSL版本的长参数。默认PHP将被它自己努力的确定,在更多的安全中你必须手工设置。

    CURLOPT_TIMECONDITION: 传递一个长参数,指定怎么处理CURLOPT_TIMEVALUE参数。你可以设置这个参数为TIMECOND_IFMODSINCE 或 TIMECOND_ISUNMODSINCE。这仅用于HTTP。

    CURLOPT_TIMEVALUE: 传递一个从1970-1-1开始到现在的秒数。这个时间将被CURLOPT_TIMEVALUE选项作为指定值使用,或被默认TIMECOND_IFMODSINCE使用。

    下列选项的值将被作为字符串:

     

    CURLOPT_URL: 这是你想用PHP取回的URL地址。你也可以在用curl_init()函数初始化时设置这个选项。

    CURLOPT_USERPWD: 传递一个形如[username]:[password]风格的字符串,作用PHP去连接。

    CURLOPT_PROXYUSERPWD: 传递一个形如[username]:[password] 格式的字符串去连接HTTP代理。

    CURLOPT_RANGE: 传递一个你想指定的范围。它应该是"X-Y"格式,X或Y是被除外的。HTTP传送同样支持几个间隔,用逗句来分隔(X-Y,N-M)。

    CURLOPT_POSTFIELDS: 传递一个作为HTTP “POST”操作的所有数据的字符串。

    CURLOPT_REFERER: 在HTTP请求中包含一个"referer"头的字符串。

    CURLOPT_USERAGENT: 在HTTP请求中包含一个"user-agent"头的字符串。

    CURLOPT_FTPPORT: 传递一个包含被ftp "POST"指令使用的IP地址。这个POST指令告诉远程服务器去连接我们指定的IP地址。 这个字符串可以是一个IP地址,一个主机名,一个网络界面名(在UNIX下),或是'-’(使用系统默认IP地址)。

    CURLOPT_COOKIE: 传递一个包含HTTP cookie的头连接。

    CURLOPT_SSLCERT: 传递一个包含PEM格式证书的字符串。

    CURLOPT_SSLCERTPASSWD: 传递一个包含使用CURLOPT_SSLCERT证书必需的密码。

    CURLOPT_COOKIEFILE: 传递一个包含cookie数据的文件的名字的字符串。这个cookie文件可以是Netscape格式,或是堆存在文件中的HTTP风格的头。

    CURLOPT_CUSTOMREQUEST: 当进行HTTP请求时,传递一个字符被GET或HEAD使用。为进行DELETE或其它操作是有益的,更Pass a string to be used instead of GET or HEAD when doing an HTTP request. This is useful for doing  or another, more obscure, HTTP request.

    注意: 在确认你的服务器支持命令先不要去这样做。

    下列的选项要求一个文件描述(通过使用fopen()函数获得):

     

    CURLOPT_FILE: 这个文件将是你放置传送的输出文件,默认是STDOUT.

    CURLOPT_INFILE: 这个文件是你传送过来的输入文件。

    CURLOPT_WRITEHEADER: 这个文件写有你输出的头部分。

    CURLOPT_STDERR: 这个文件写有错误而不是stderr。


     

    • curl_exec

    curl_exec -- 执行一个CURL会话

    描述

     

    bool curl_exec (int ch)

     

    在你初始化一个CURL会话,及为这个会话设置了所有的选项后,这个函数将被调用。它的目的仅仅是执行预先确定的CURL会话(通过给定的ch参数)。

    • curl_close

    curl_close -- 关闭一个CURL会话

    描述

     

    void curl_close (int ch)

     

    这个函数关闭一个CURL会话,并且释放所有的资源。CURL句柄(ch参数)也被删除。

    • curl_version

    curl_version -- 返回当前CURL版本

    描述

    string curl_version (void)

     

    curl_version()函数返回一个包含CURL版本的字符串。



     附CURL for PHP 官方网站:http://curl.haxx.se/libcurl/php/

  • CURL -命令行下载工具

    2009-07-13 12:23:16

    curl是一个利用URL语法在命令行方式下工作的文件传输工具。它支持很多协议:FTP, FTPS, HTTP, HTTPS, GOPHER,  TELNET, DICT, FILE 以及 LDAP。curl同样支持HTTPS认证,HTTP POST方法, HTTP PUT方法, FTP 上传, kerberos认证, HTTP上传, 代理服务器, cookies, 用户名/密码认证, 下载文件断点续传, 上载文件断点续传,  http代理服务器管道( proxy tunneling), 甚至它还支持IPv6, socks5代理服务器, 通过http代理服务器上传文件到FTP服务器等等,功能十分强大。Windows操作系统下的网络蚂蚁,网际快车(FlashGet)的功能它都可以做到。准确的说,curl支
    持文件的上传和下载,所以是一个综合传输工具,但是按照传统,用户习惯称curl为下载工具。
     
    curl是瑞典curl组织开发的,您可以访问http://curl.haxx.se/获取它的源代码和相关说明。鉴于curl在Linux上的广泛使用,IBM在AIX Linux Toolbox的光盘中包含了这个软件,并且您可以访问IBM网站http://www- 1.ibm.com/servers/aix/products/aixos/linux/altlic.html下载它。curl的最新版本是 7.10.8,IBM网站上提供的版本为7.9.3。在AIX下的安装很简单,IBM网站上下载的rpm格式的包。
     
    在http://curl.haxx.se/docs/,您可以下载到UNIX格式的man帮助,里面有详细的curl工具的使用说明。curl的用法为:curl [options] [URL...] 其中options是下载需要的参数,大约有80多个,curl的各个功能完全是依靠这些参数完成的。具体参数的使用,用户可以参考curl的man帮助。
     
    下面,本文就将结合具体的例子来说明怎样利用curl进行下载。
    1、获得一张页面
    使用命令:curl http://curl.haxx.se
    这是最简单的使用方法。用这个命令获得了http://curl.haxx.se指向的页面,同样,如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地。如果下载的是HTML文档,那么缺省的将不显示文件头部,即HTML 文档的header。要全部显示,请加参数 -i,要只显示头部,用参数 -I。任何时候,可以使用 -v 命令看curl是怎样工作的,它向服务器发送的所有命令都会显示出来。为了断点续传,可以使用-r参数来指定传输范围。
     
    2、表单(Form)的获取
    在WEB页面设计中,form是很重要的元素。Form通常用来收集并向网站提交信息。提交信息的方法有两种,GET方法和POST方法。先讨论GET方法,例如在页面中有这样一段:
    <form. method="GET" action="junk.cgi">
    <input type=text name="birthyear">
    <input type=submit name=press value="OK">
    </form>
    那么浏览器上会出现一个文本框和一个标为“OK”的按钮。按下这个按钮,表单就用GET方法向服务器提交文本框的数据。例如原始页面是在  www.hotmail.com/when/birth.html看到的,然后您在文本框中输入1905,然后按OK按钮,那么浏览器的URL现在应该 是:“www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK”
    对于这种网页,curl可以直接处理,例如想获取上面的网页,只要输入:
    curl "www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK"
    就可以了。
    表单用来提交信息的第二种方法叫做POST方法,POST方法和GET方法的区别在于GET方法使用的时候,浏览器中会产生目标URL,而POST不会。类似GET,这里有一个网页:
    <form. method="POST" action="junk.cgi">
    <input type=text name="birthyear">
    <input type=submit name=press value="OK">
    </form>
    浏览器上也会出现一个文本框和一个标为“OK”的按钮。按下这个按钮,表单用POST方法向服务器提交数据。这时的URL是看不到的,因此需要使用特殊的方法来抓取这个页面:
    curl -d "birthyear=1905&press=OK" www.hotmail.com/when/junk.cgi
    这个命令就可以做到。
    1995年年末,RFC 1867定义了一种新的POST方法,用来上传文件。主要用于把本地文件上传到服务器。此时页面是这样写的:
    <form. method="POST" enctype='multipart/form-data' action="upload.cgi">
    <input type=file name=upload>
    <input type=submit name=press value="OK">
    </form>
    对于这种页面,curl的用法不同:
    curl -F upload=@localfilename -F press=OK [URL]
    这个命令的实质是将本地的文件用POST上传到服务器。有关POST还有不少用法,用户可以自己摸索。
     
    3、使用PUT方法。
    HTTP协议文件上传的标准方法是使用PUT,此时curl命令使用-T参数:
    curl -T uploadfile www.uploadhttp.com/receive.cgi
     
    4、有关认证。
    curl可以处理各种情况的认证页面,例如下载用户名/密码认证方式的页面(在IE中通常是出现一个输入用户名和密码的输入框):
    curl -u name:password www.secrets.com
    如果网络是通过http代理服务器出去的,而代理服务器需要用户名和密码,那么输入:
    curl -U proxyuser:proxypassword http://curl.haxx.se
    任何需要输入用户名和密码的时候,只在参数中指定用户名而空着密码,curl可以交互式的让用户输入密码。
     
    5、引用。
    有些网络资源访问的时候必须经过另外一个网络地址跳转过去,这用术语来说是:referer,引用。对于这种地址的资源,curl也可以下载:
    curl -e http://curl.haxx.se daniel.haxx.se
     
    6、指定用户客户端。
    有些网络资源首先需要判断用户使用的是什么浏览器,符合标准了才能够下载或者浏览。此时curl可以把自己“伪装”成任何其他浏览器:
    curl -A "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL]
    这个指令表示curl伪装成了IE5.0,用户平台是Windows 2000。(对方服务器是根据这个字串来判断客户端的类型的,所以即使使用AIX也无所谓)。使用:
    curl -A "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL]
    此时curl变成了Netscape,运行在PIII平台的Linux上了。
     
    7、COOKIES
    Cookie是服务器经常使用的一种记忆客户信息的方法。如果cookie被记录在了文件中,那么使用命令:
    curl -b stored_cookies_in_file www.cookiesite.com
    curl可以根据旧的cookie写出新cookie并发送到网站:
    curl -b cookies.txt -c newcookies.txt www.cookiesite.com
     
    8、加密的HTTP——HTTPS。
    如果是通过OpenSSL加密的https协议传输的网页,curl可以直接访问:
    curl https://that.secure.server.com
     
    9、http认证。
    如果是采用证书认证的http地址,证书在本地,那么curl这样使用:
    curl -E mycert.pem https://that.secure.server.com
     
    参考读物和注意事项:curl非常博大,用户要想使用好这个工具,除了详细学习参数之外,还需要深刻理解http的各种协议与URL的各个语法。这里推荐几个读物:
    RFC 2616 HTTP协议语法的定义。
    RFC 2396 URL语法的定义。
    RFC 2109 Cookie是怎样工作的。
    RFC 1867 HTTP如何POST,以及POST的格式  


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dbigbear/archive/2006/11/21/1402580.aspx

  • curl

    2009-07-13 11:12:39

    cURL是一个利用URL语法在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。

    cURL支援的通訊協定有FTP、FTPS、HTTP、HTTPS、TFTP、Telnet、DICT、FILE和LDAP。

    -------------------------------------------------------------------------------------------

    Curl语言是一种编程语言被设计来编写网络程序。它的目标是以一种单一的语言来取代HTML,Cascading Style. Sheets(层叠样式表)and JavaScript,虽然它目前并未在世界范围内被广泛使用,但在日本有一定的普及。

    Curl不像HTML,它不是一种文本标记语言,但Curl语言既可以用于普通的文本显示,又可以用于实现大规模的客户端商业软件系统。Curl不利的一面是:需要向客户端安装运行环境。

    用Curl写的程序既可以运行于浏览器中,又可以像普通客户端程序那样独立于浏览器运行,运行前需要安装SurgeRTE。"SurgeRTE"是一种与JAVA类似的跨平台运行环境(runtime environment,RTE),其中包含浏览器的插件。它目前支持微软视窗(Microsoft Windows)操作系统 和 Linux操作系统,据传苹果机版将在不久的未来发布。

    Curl语言便于学习,编程效率高,是一种支持多重继承,范型等数据类型的面向对象编程语言。 1

    -----------------------------------------------------------------------------------------
    在Windows下使用curl命令
    curl 是一般linux发行版中都带有的小工具,利用这个工具可以很方便的下载文件,我一般使用这个工具来查看某个页面相应的HTTP头信息,例如: curl -I http://www.71way.com/

    在 Windows系统中我们也一样可以使用这个工具,如果不需要支持https的话,那直接下载一个可执行文件即可,下载页面是:http://curl.haxx.se/download.html,这个页面最底部有一个Windows下的下载链接,请选择不带SSL的版本,否则还需要安装SSL的支持包。我下载的地址是:

    http://curl.haxx.se/download/curl-7.17.0-win32-nossl.zip

    解压后直接执行 curl.exe 即可,使用方法跟linux下的完全相同。此命令功能非常强大,又兴趣自己研究一下。

    curl一下新浪新闻看看: curl -I http://news.sina.com.cn

    HTTP/1.0 200 OK
    Date: Fri, 26 Oct 2007 00:18:12 GMT
    Server: Apache/2.0.58 (Unix)
    Last-Modified: Fri, 26 Oct 2007 00:17:47 GMT
    ETag: "1fad23-81807-47c0a0c0"
    Accept-Ranges: bytes
    X-Powered-By: mod_xlayout_jh/0.0.1vhs.markII.remix
    Cache-Control: max-age=60
    Expires: Fri, 26 Oct 2007 00:19:12 GMT
    Vary: Accept-Encoding
    Content-Type: text/html
    Age: 28
    X-Cache: HIT from sh-40.sina.com.cn
    Connection: close

    用此工具来测试页面缓存的配置是很简单方便的。
    ------------------------------------------------------------------------------------------------------------------------------
    教你学用CURL --- 命令行浏览器
    CURL? 嗯,说来话长了~~~~

    这东西现在已经是苹果机上内置的命令行工具之一了,可见其魅力之一斑

    1)
    二话不说,先从这里开始吧!

    curl http://www.yahoo.com

    回车之后,www.yahoo.com 的html就稀里哗啦地显示在屏幕上了~~~~~

    2)
    嗯,要想把读过来页面存下来,是不是要这样呢?
    curl http://www.yahoo.com > page.html

    当然可以,但不用这么麻烦的!
    用curl的内置option就好,存下http的结果,用这个option: -o
    curl -o page.html http://www.yahoo.com

    这样,你就可以看到屏幕上出现一个下载页面进度指示。等进展到100%,自然就OK咯

    3)
    什么什么?!访问不到?肯定是你的proxy没有设定了。
    使用curl的时候,用这个option可以指定http访问所使用的proxy服务器及其端口: -x
    curl -x 123.45.67.89:1080 -o page.html http://www.yahoo.com


    4)
    访问有些网站的时候比较讨厌,他使用cookie来记录session信息。
    像IE/NN这样的浏览器,当然可以轻易处理cookie信息,但我们的curl呢?.....
    我们来学习这个option: -D <-- 这个是把http的response里面的cookie信息存到一个特别的文件中去
    curl -x 123.45.67.89:1080 -o page.html -D cookie0001.txt http://www.yahoo.com

    这样,当页面被存到page.html的同时,cookie信息也被存到了cookie0001.txt里面了


    5)
    那么,下一次访问的时候,如何继续使用上次留下的cookie信息呢?要知道,很多网站都是靠监视你的cookie信息,
    来判断你是不是不按规矩访问他们的网站的。
    这次我们使用这个option来把上次的cookie信息追加到http request里面去: -b
    curl -x 123.45.67.89:1080 -o page1.html -D cookie0002.txt -b cookie0001.txt http://www.yahoo.com

    这样,我们就可以几乎模拟所有的IE操作,去访问网页了!


    6)
    稍微等等~~~~~我好像忘记什么了~~~~~
    对了!是浏览器信息~~~~

    有些讨厌的网站总要我们使用某些特定的浏览器去访问他们,有时候更过分的是,还要使用某些特定的版本~~~~
    NND,哪里有时间为了它去找这些怪异的浏览器呢!?

    好在curl给我们提供了一个有用的option,可以让我们随意指定自己这次访问所宣称的自己的浏览器信息: -A
    curl -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -x 123.45.67.89:1080 -o page.html -D cookie0001.txt http://www.yahoo.com

    这样,服务器端接到访问的要求,会认为你是一个运行在Windows 2000上的IE6.0,嘿嘿嘿,其实也许你用的是苹果机呢!

    而"Mozilla/4.73 [en] (X11; U; Linux 2.2; 15 i686"则可以告诉对方你是一台PC上跑着的Linux,用的是Netscape 4.73,呵呵呵


    7)
    另外一个服务器端常用的限制方法,就是检查http访问的referer。比如你先访问首页,再访问里面所指定的下载页,这第二次访问的referer地址就是第一次访问成功后的页面地址。这样,服务器端只要发现对下载页面某次访问的referer地址不是首页的地址,就可以断定那是个盗连了~~~~~

    讨厌讨厌~~~我就是要盗连~~~~~!!
    幸好curl给我们提供了设定referer的option: -e
    curl -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -x 123.45.67.89:1080 -e "mail.yahoo.com" -o page.html -D cookie0001.txt http://www.yahoo.com

    这样,就可以骗对方的服务器,你是从mail.yahoo.com点击某个链接过来的了,呵呵呵


    8)
    写着写着发现漏掉什么重要的东西了!----- 利用curl 下载文件

    刚才讲过了,下载页面到一个文件里,可以使用 -o ,下载文件也是一样。
    比如, curl -o 1.jpg http://cgi2.tky.3web.ne.jp/~zzh/screen1.JPG
    这里教大家一个新的option: -O
    大写的O,这么用: curl -O http://cgi2.tky.3web.ne.jp/~zzh/screen1.JPG
    这样,就可以按照服务器上的文件名,自动存在本地了!

    再来一个更好用的。
    如果screen1.JPG以外还有screen2.JPG、screen3.JPG、....、screen10.JPG需要下载,难不成还要让我们写一个script来完成这些操作?
    不干!
    在curl里面,这么写就可以了:
    curl -O http://cgi2.tky.3web.ne.jp/~zzh/screen[1-10].JPG

    呵呵呵,厉害吧?!~~~

    9)
    再来,我们继续讲解下载!
    curl -O http://cgi2.tky.3web.ne.jp/~{zzh,nick}/[001-201].JPG

    这样产生的下载,就是
    ~zzh/001.JPG
    ~zzh/002.JPG
    ...
    ~zzh/201.JPG
    ~nick/001.JPG
    ~nick/002.JPG
    ...
    ~nick/201.JPG

    够方便的了吧?哈哈哈

    咦?高兴得太早了。
    由于zzh/nick下的文件名都是001,002...,201,下载下来的文件重名,后面的把前面的文件都给覆盖掉了~~~

    没关系,我们还有更狠的!
    curl -o #2_#1.jpg http://cgi2.tky.3web.ne.jp/~{zzh,nick}/[001-201].JPG

    --这是.....自定义文件名的下载?
    --对头,呵呵!

    #1是变量,指的是{zzh,nick}这部分,第一次取值zzh,第二次取值nick
    #2代表的变量,则是第二段可变部分---[001-201],取值从001逐一加到201
    这样,自定义出来下载下来的文件名,就变成了这样:
    原来: ~zzh/001.JPG ---> 下载后: 001-zzh.JPG
    原来: ~nick/001.JPG ---> 下载后: 001-nick.JPG

    这样一来,就不怕文件重名啦,呵呵


    9)
    继续讲下载
    我们平时在windows平台上,flashget这样的工具可以帮我们分块并行下载,还可以断线续传。
    curl在这些方面也不输给谁,嘿嘿

    比如我们下载screen1.JPG中,突然掉线了,我们就可以这样开始续传
    curl -c -O http://cgi2.tky.3wb.ne.jp/~zzh/screen1.JPG

    当然,你不要拿个flashget下载了一半的文件来糊弄我~~~~别的下载软件的半截文件可不一定能用哦~~~

    分块下载,我们使用这个option就可以了: -r
    举例说明
    比如我们有一个http://cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 要下载(赵老师的电话朗诵 :D )
    我们就可以用这样的命令:
    curl -r 0-10240 -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &\
    curl -r 10241-20480 -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &\
    curl -r 20481-40960 -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3 &\
    curl -r 40961- -o "zhao.part1" http:/cgi2.tky.3web.ne.jp/~zzh/zhao1.mp3

    这样就可以分块下载啦。
    不过你需要自己把这些破碎的文件合并起来
    如果你用UNIX或苹果,用 cat zhao.part* > zhao.mp3就可以
    如果用的是Windows,用copy /b 来解决吧,呵呵

    上面讲的都是http协议的下载,其实ftp也一样可以用。
    用法嘛,
    curl -u name:passwd ftp://ip:port/path/file
    或者大家熟悉的
    curl ftp://name:passwd@ip:port/path/file



    10)
    说完了下载,接下来自然该讲上传咯
    上传的option是 -T

    比如我们向ftp传一个文件: curl -T localfile -u name:passwd ftp://upload_site:port/path/

    当然,向http服务器上传文件也可以
    比如 curl -T localfile http://cgi2.tky.3web.ne.jp/~zzh/abc.cgi
    注意,这时候,使用的协议是HTTP的PUT method

    刚才说到PUT,嘿嘿,自然让老服想起来了其他几种methos还没讲呢!
    GET和POST都不能忘哦。

    http提交一个表单,比较常用的是POST模式和GET模式

    GET模式什么option都不用,只需要把变量写在url里面就可以了
    比如:
    curl http://www.yahoo.com/login.cgi?user=nickwolfe&password=12345

    而POST模式的option则是 -d

    比如,curl -d "user=nickwolfe&password=12345" http://www.yahoo.com/login.cgi
    就相当于向这个站点发出一次登陆申请~~~~~

    到底该用GET模式还是POST模式,要看对面服务器的程序设定。

    一点需要注意的是,POST模式下的文件上的文件上传,比如
    <form. method="POST" enctype="multipar/form-data" action="http://cgi2.tky.3web.ne.jp/~zzh/up_file.cgi">
    <input type=file name=upload>
    <input type=submit name=nick value="go">
    </form>
    这样一个HTTP表单,我们要用curl进行模拟,就该是这样的语法:
    curl -F upload=@localfile -F nick=go http://cgi2.tky.3web.ne.jp/~zzh/up_file.cgi

    罗罗嗦嗦讲了这么多,其实curl还有很多很多技巧和用法
    比如 https的时候使用本地证书,就可以这样
    curl -E localcert.pem https://remote_server

    再比如,你还可以用curl通过dict协议去查字典~~~~~
    curl dict://dict.org/d:computer

    今天就先讲到这里吧,呵呵。疯狂的curl功能,需要你---一起来发掘。

    copyright by nickwolfe@CCF
    2004.08.24 21:24应朋友之邀所作--初稿

Open Toolbar