我接收到表单中<input type=file name=upfile>中的值为 c:\test.zip请问isapi 怎么实现上传?能否给出源代码?

解决方案 »

  1.   

    转:
    利用ISAPI开发CGI程序
    闻怡洋 http://www.vchelp.net/
    ----------------------------------------------------------------------------
    ----
    ISAPI(Internet Server API)最初是微软为IIS服务器所提供的一种CGI应用开发接口
    ,其主要的目的也是为CGI开发提供好的开发接口,如果不负责的讲ISAPI也可以认为是
    类似WinCGI的一种开发模式,只不过ISAPI通过映射宏来取得用户表单传送的参数。这一
    点上和MFC消息映射宏很相似。
    当然ISAPI的推出同时还具备了很多其他的特性:
    ISAPI以DLL动态连接库的方式实现,所以加载较普通的EXE运行程序快,而且系统不会在
    使用完后马上清除掉DLL在内存中的空间,所以再次使用时会获得更快的速度。
    ISAPI在调用者的内部以线程方式运行,所以和CGI进程相比较需要的运行空间也更小。在同一个DLL中可以集中多个处理函数,并且通过映射宏来指明不同的函数分别对什么样
    的请求来进行处理。
    由于与IIS的集成,所以可以利用ISAPI开发ISAPI过滤器。通过过滤器可以完成例如用户
    权限检测,数据加密,压缩,日志等功能,IIS服务器的功能也可以通过ISAPI过滤器来
    得到增强。
    到目前为止,很多非M$的WEB服务器也都添加了对ISAPI的支持。
    在同一个DLL中可以集中多个处理函数,所以执行ISAPI的请求和执行普通CGI的请求有一
    点区别,在URL中需要填写如下形式http://.../cgi-bin/test.dll?function_name&nam
    e=xxx&email=yyy,function_name表示的就是功能名称,为了能够正确处理你必须将其
    映射到DLL中的一个处理函数上。对与未映射的功能都将由一个默认函数处理。
    VC4.2以上版本为创建一个ISAPI程序提供了向导程序,在新建工程时选择ISAPI Extens
    ion Wizard并在以后的对话框中选择创建服务器扩展和输入相关的信息就可以了。
    一个最简单的ISAPI程序至少包含了一个由CHttpServer类所派生的新类,并且在该类中
    进行了基本的映射,重载了BOOL GetExtensionVersion(HSE_VERSION_INFO* pVer)函数
    和提供了形式如void Default(CHttpServerContext* pCtxt)的成员函数。幸运的是向导
    程序已经为我们做好了这一切并创建了最基本的代码。
    Default函数用于处理没有带参数首先我们修改Default函数中的代码,首先我们该写其
    中的相关代码成为如下:
    void CTestisaExtension::Default(CHttpServerContext* pCtxt)
    {
     //Print the <HTML> <BODY> tags.
     StartContent(pCtxt);
     //Print the title.
     WriteTitle(pCtxt);
     *pCtxt << _T("<p>演示</p>");
     *pCtxt << _T("<p>目前是Default成员函数其作用</p>");
     //Print </HTML> </BODY> tags.
     EndContent(pCtxt);
    }
    然后用以下方式调用:http://.../cgi-bin/test.dll?Default或http://.../cgi-bin/
    test.dll?。你就会看到输出的HTML页面了。
    <FORM ACTION="test.dll?Add" METHOD=POST>
    <INPUT NAME="name">
    <INPUT NAME="id">
    <INPUT TYPE=SUBMIT>
    </FORM>
    上面表单要求用户输入了用户名和ID号,所以传送的数据形式形式应该如同:http://.
    ../test.dll?Add&name=xxx&id=yyy,我们可以通过处理命令映射宏来指明处理命令的函
    数,然后通过参数映射宏对数据进行分解,分解后的数据将会存放入指定的变量。使用
    方法为:
    ON_PARSE_COMMAND(Add, CTestExtension, ITS_PSTR ITS_I4)
    ON_PARSE_COMMAND_PARAMS("name id")
    ON_PARSE_COMMAND宏中需要指明函数名,类名和参数类型列表,ON_PARSE_COMMAND_PAR
    AMS宏中需要根据前一个宏中所列出的参数列表来指明表单中的变量名称列表。最后一步
    就是定义一个名称与请求URL中?后命令名称相同的成员函数,参数的设置要与ON_PARSE
    _COMMAND宏中的参数列表定义相符合,在这个例子中为:
    void CTestExtension::Add(CHttpServerContext* pCtxt,LPTSTR pszName,int iID)。
    参数类型列表中可以使用下面的类型后面为该类型的说明:
    ITS_EMPTY 无数据
    ITS_PSTR 字符串LPCSTR
    ITS_I2 short
    ITS_I4 long
    ITS_R4 float
    ITS_R8 double
    下面我们看一个更复杂的表单,表单定义如下:
    <FORM ACTION="test.dll?Delete" METHOD=POST>
    <INPUT NAME="name">
    <INPUT NAME="month">
    <SELECT NAME="mode">
     <OPTION VALUE=1>All
     <OPTION VALUE=2>Before
     <OPTION VALUE=3>After
    <INPUT TYPE=HIDDEN NAME=pwd VALUE=xxx>
    <INPUT TYPE=SUBMIT>
    </FORM>
    定义映射和处理函数如下:
    ON_PARSE_COMMAND(Add, CTestExtension, ITS_PSTR ITS_I4 ITS_I4 ITS_PSTR)
    ON_PARSE_COMMAND_PARAMS("name month mode pwd")
    void CTestExtension::Add(CHttpServerContext* pCtxt,LPTSTR pszName,int iMonth
    ,int iMode,LPTSTR pszPwd)。
    ISAPI程序的输出:在所有的命令处理函数中第一个参数都是CHttpServerContext*指针
    ,我们所有的输出都要通过它进行,在CHttpServerContext类中定义了<<操作符,通过
    该操作符我们可以方便的输出字符串,数字,二进制数据。输出的方法为:
    *pCtxt<<"this is a string";
    *pCtxt<<'c';
    *pCtxt<<10;
    可以看得出输出是很简单的,一个完整的输出过程应该是如同下面的形式:
     StartContent(pCtxt);//开始输出
     WriteTitle(pCtxt);//输出头部信息,相当于输出<TITLE>
     *pCtxt << "your string";
     EndContent(pCtxt);//结束输出
    我们所使用的ISAPI扩展类是由CHttpServer所派生,可以调用CHttpServer::AddHeader
    来指明返回数据的类型,例如下面的代码演示了输出纯文本:
    void CTestisaExtension::Default(CHttpServerContext* pCtxt)
    {
     AddHeader(pCtxt, "Content-type = text/plain\r\n");
     (*pCtxt) << "Hello world!\r\n";
    }
    我们可以重载某些函数来达到加强控制的目的,可重载的函数有以下这些:
    virtual LPCTSTR CHttpServer::GetTitle( ) const;返回<TITLE>部分信息
    virtual BOOL CHttpServer::OnParseError( CHttpServerContext* pCtxt, int nCaus
    e );错误处理
    virtual void CHttpServer::StartContent( CHttpServerContext* pCtxt ) const;输
    出<HTML><BODY>部分信息
    virtual void CHttpServer::EndContent( CHttpServerContext* pCtxt ) const;输出
    </BODY></HTML>部分信息
    virtual void CHttpServer::WriteTitle( CHttpServerContext* pCtxt ) const;输出
    <TITLE></TITLE>部分信息
    此外我们可以在命令处理函数中利用CHttpServerContext指针来得到CGI中的相关环境变
    量,在CHttpServerContext中有一个成员变量m_pECB为下面的结构指针。
    typedef struct _EXTENSION_CONTROL_BLOCK {
        DWORD     cbSize;                              //IN 该结构长度
        DWORD     dwVersion                            //IN 版本
        HCONN     ConnID;                              //IN 连接上下文
        DWORD     dwHttpStatusCode;                   //OUT 状态码
        CHAR      lpszLogData[HSE_LOG_BUFFER_LEN];    //OUT
        LPSTR     lpszMethod;                          //IN 环境变量REQUEST_METH
    OD
        LPSTR     lpszQueryString;                     //IN QUERY_STRING
        LPSTR     lpszPathInfo;                        //IN PATH_INFO
        LPSTR     lpszPathTranslated;                  //IN PATH_TRANSLATED
        DWORD     cbTotalBytes;                        //IN CONTENT_LENGTH
        DWORD     cbAvailable;                         //IN
        LPBYTE    lpbData;                             //IN
        LPSTR     lpszContentType;                     //IN CONTENT_TYPE
    ...其他信息在此忽略
    } EXTENSION_CONTROL_BLOCK, *LPEXTENSION_CONTROL_BLOCK;
      

  2.   

    文件长度和内容不可以通过文件操作完成吗?ftell(fhandle);fread();