让 cytown 快点超过 CJ——谈谈 ISAPI filter(200分)

  • 主题发起人 主题发起人 CJ
  • 开始时间 开始时间
C

CJ

Unregistered / Unconfirmed
GUEST, unregistred user!
上次哪道题里讲起来的,我满有兴趣,知道 cytown
这方面的高手,所以请您谈谈,其他诸位也可发表意
见,分数照给

1、什么是 ISAPI Filter?
2、ISAPI Filter 相对于 ISAPI 的优点和缺点;
3、在 Delphi 中 ISAPI Filter 的实现;
4、其它...

分数分配:1/2:30,3:150,4、20(酌情另送)

200 分!
 
真大度。
不过,我不懂。
 
啊?我以为那么快就有答案...:(
 
我不懂,想来看看,也给几分吧?嘻嘻
 
啊?又是一个:(
 
这个问题大家赞助点如何?:-)
 
CJ,英文不错吧,我就不翻成中文再卖给你了。
(主要是翻不好怕大家看不懂;)

The two branches of the ISAPI, Internet Server Applications (ISAs)
and ISAPI Filters, comprise two different schools of thought on how
programmers can approach additional functionality. ISAs are the more
traditional of the two, leading programmers to develop something
that's more of an external component with special links back into the
server's workings. ISAPI Filters are closer to building blocks, which
can be attached directly to the server, providing a seamless
component that carefully monitors the HTTP requests being directed at
the server. Since each has its own particular way of being dealt with
by the server, I'll look at them as separate entities, and tie
together the common points where they conveniently overlap.

Internet Server API Filter
ISAPI filters are quite different from a traditional CGI program. If
ISAPI DLLs make a server more flexible, ISAPI filters turn a server
into a true contortionist, able to flex whatever way they need to.
They're not just resident with the server, they're part of the server
itself, having been loaded into memory and the server's configuration
ahead of time. They're direct extensions of the server, allowing them
to do tasks that no CGI program could think of doing, such as
enhancing the local logging of file transfers, building in pre-
defined methods of handling forms or searches, and even doing
customized local authentication for requests. You're making the
server evolve into something more powerful, instead of adding pieces
that the server can call for help.

When you create an ISAPI filter, you're creating a linked DLL that's
being examined every time the server processes an HTTP request. The
goal is to filter out specific notifications that you're interested
in, and remove the duties of handling that particular process from
the core functionality of the server. You're essentially saying, "Oh,
don't worry about that when you see it; that's what this filter is
for." This scalability allows you to take a basic server and
customize it to meet whatever needs you might have. You're adding
scalability to the server so that it meets your needs, even if the
original manufacturer didn't anticipate them.

Like an ISAPI DLL, an ISAPI filter has two entry points that must be
present in order to verify that the function meets the current
specification, and that it has a place to receive information from
the server. Unlike an ISAPI DLL, though, an ISAPI filter isn't
something that's spur-of-the-moment in its use-any filters you define
have to be entered in the system registry so that they are literally
part of the server's configuration. Since they're intercepting things
as they happen, the server needs to know about them. In this case,
it's convinced that it always had the ability to do these functions,
it just never used them before.





 
hi cytown?
where'r u?
help me pls,thanx
 
不好意思, 刚刚看到:-)
ISAPI(Internet Server Application Programming Interface) 实际是在IIS上
运行的IIS的扩展或过滤器的接口. 这两者都是用dll的形式存在, 都是为了扩展iis
的功能.

关于ISAPI扩展(extension, 以下简称e)和过滤器(filter, 以下简称f)的区别, 主
要在于以下不同:
1. 调用方式不同:
e的调用如cgi的调用一样, 如http://localhost/scripts/isapie.dll?xxx=yyy
f的调用是类似plug-in的方式, 方法是iis管理器(iis4)中选择webproperties
然后在isapi筛选器中添加修改删除. 它载入后只有关闭iis4才能卸载. 而且,
它不需要用传统的方式调用, 自动在每次web请求时生效.
iis2/3中要把filter dll添加到HKEY_LOCAL_MACHINES/SYSTEM/CurrentControlSet/Services/W3SVC/Parameters,
然后启动webserver才行.
2. 生效的方式不同:
e在调用时生效, 而f在启动webserver时就生效.
3. 使用的领域不同:
e如同cgi一样, 只不过是dll方式, 常驻内存, 而使用都是为了处理用户提交的
请求. 而f则完全不同, 虽然它可以处理返回用户的请求, 如cgi和e一样, 但它
更强大的功能是根据用户的请求来筛选需要的处理手段. 例如, 如果用户请求中
是/admin/的请求, 那末, 判断用户是否有此admin权限, 如果允许, 就转入/admin
目录中正常功能, 否则调入登录页面....

以上是我个人总结出来的异同.

关于isapi filter的编制, 其实很多书都可以看, 如果要例子, borland的demo里
可能没有, 建议你可以看cgiexpert的sample, 有很多isapi filter的例子.
 
谢谢cytown:
不过你晚了呀:-)
delphi自己的构件能写吗?谢谢
 
一个demo, 不过是d2的:-(

(***************************************************************************


Name:

Delphi unit HttpFilt.PAS

Abstract:

This module contains the types, constants, and functions needed to
create ISAPI Filter .DLLs with Delphi 2.0.

For more information on ISAPI, The Microsoft Internet Information FAQ is
located at http://rampages.onramp.net/~steveg/iis.html


Changes, fixes, and modifications; in reverse chronological order:

By Date Description
----- ---------- -----------------------------------------------------------
JRT 05/05/96 Jonathan R. Taylor <jtaylor@irdg.com>
Fixed forward reference problem with the
THTTP_FILTER_CONTEXT structure

SVG 05/05/96 Translated From C to Delphi 2.0
by Stephen Genusa (steveg@onramp.net).


**************************************************************************** )


Library httpfilt;

Uses
SysUtils,
Windows;

const

HTTP_FILTER_MAJOR = 1; { major version of this spec }
HTTP_FILTER_MINOR = 0; { minor version of this spec }
SF_MAX_USERNAME = 256;
SF_MAX_PASSWORD = 256;
SF_MAX_FILTER_DESC_LEN = 256;

{ SF_STATUS_TYPE }
SF_STATUS_TYPE = $8000000; { base value }
SF_STATUS_REQ_FINISHED = SF_STATUS_TYPE;
SF_STATUS_REQ_FINISHED_KEEP_CONN = SF_STATUS_TYPE + 1;
SF_STATUS_REQ_NEXT_NOTIFICATION = SF_STATUS_TYPE + 2;
SF_STATUS_REQ_HANDLED_NOTIFICATION = SF_STATUS_TYPE + 3;
SF_STATUS_REQ_ERROR = SF_STATUS_TYPE + 4;
SF_STATUS_REQ_READ_NEXT = SF_STATUS_TYPE + 5;

SF_NOTIFY_SECURE_PORT = $00000001;
SF_NOTIFY_NONSECURE_PORT = $00000002;
SF_NOTIFY_READ_RAW_DATA = $00008000;
SF_NOTIFY_PREPROC_HEADERS = $00004000;
SF_NOTIFY_AUTHENTICATION = $00002000;
SF_NOTIFY_URL_MAP = $00001000;
SF_NOTIFY_SEND_RAW_DATA = $00000400;
SF_NOTIFY_LOG = $00000200;
SF_NOTIFY_END_OF_NET_SESSION = $00000100;

SF_NOTIFY_ORDER_HIGH = $00080000;
SF_NOTIFY_ORDER_MEDIUM = $00040000;
SF_NOTIFY_ORDER_LOW = $00020000;
SF_NOTIFY_ORDER_DEFAULT = SF_NOTIFY_ORDER_LOW;
SF_NOTIFY_ORDER_MASK = (SF_NOTIFY_ORDER_HIGH or SF_NOTIFY_ORDER_MEDIUM or SF_NOTIFY_ORDER_LOW);

type
PVOID = Pointer;
LPVOID = Pointer;
PCardinal = ^Cardinal;

SF_REQ_TYPE = (SF_REQ_SEND_RESPONSE_HEADER, SF_REQ_ADD_HEADERS_ON_DENIAL,
SF_REQ_SET_NEXT_READ_SIZE, SF_REQ_SET_PROXY_INFO);

Type
TFuncPlaceHolder = POINTER;

THTTP_FILTER_CONTEXT = record
cbSize : DWORD;
Revision : DWORD;
ServerContext : PVOID;
ulReserved : DWORD;
fIsSecurePort : BOOL;
pFilterContext : PVOID;
GetServerVariable : TFuncPlaceHolder; {TGetServerVariable;}
AddResponseHeaders : TFuncPlaceHolder; {TAddResponseHeaders;}
WriteClient : TFuncPlaceHolder; {TWriteClient;}
AllocMen : TFuncPlaceHolder; {TAllocMem;}
ServerSupportFunc : TFuncPlaceHolder; {TServerSupportFunc;}
end;
HTTP_FILTER_CONTEXT = THTTP_FILTER_CONTEXT;
PHTTP_FILTER_CONTEXT = ^HTTP_FILTER_CONTEXT;


TGetServerVariable = Function(var pfc : THTTP_FILTER_CONTEXT;
VariableName : PChar;
Buffer : LPVOID;
BuffSize : PCardinal) : BOOL;
StdCall;

TAddResponseHeaders = Function(var pfc : THTTP_FILTER_CONTEXT;
Headers : PChar;
Reserved : DWORD) : BOOL;
StdCall;

TWriteClient = Function(var pfc : THTTP_FILTER_CONTEXT;
Buffer : LPVOID;
dwBytes : LPDWORD;
Reserved : DWORD) : BOOL;
StdCall;

TAllocMem = Procedure(var pfc : THTTP_FILTER_CONTEXT;
cbSize : DWORD;
dwReserved : DWORD);

TServerSupportFunc = Function(var pfc : THTTP_FILTER_CONTEXT;
sfReq : SF_REQ_TYPE;
pData : PVOID;
ul1 : DWORD;
ul2 : DWORD) : BOOL;
StdCall;



THTTP_FILTER_RAW_DATA = record
pvInData : PVOID;
cbInData : DWORD;
cbInBuffer : DWORD;
dwReserved : DWORD;
end;
HTTP_FILTER_RAW_DATA = THTTP_FILTER_RAW_DATA;
PHTTP_FILTER_RAW_DATA = ^HTTP_FILTER_RAW_DATA;

TGetHeader = Function(var pfc : THTTP_FILTER_CONTEXT;
lpszName : PChar;
lpvBuffer : LPVOID;
lpdwSize : LPDWORD) : BOOL; StdCall;

TSetHeader = Function(var pfc : THTTP_FILTER_CONTEXT;
lpszName : PChar;
lpszValue : PChar) : BOOL; StdCall;

TAddHeader = Function(var pfc : THTTP_FILTER_CONTEXT;
lpszName : PChar;
lpszValue : PChar) : BOOL; StdCall;




THTTP_FILTER_PREPROC_HEADERS = record
GetHeader : TGetHeader;
SetHeader : TSetHeader;
AddHeader : TAddHeader;
dwReserved : DWORD;
end;
HTTP_FILTER_PREPROC_HEADERS = THTTP_FILTER_PREPROC_HEADERS;
PHTTP_FILTER_PREPROC_HEADERS = ^HTTP_FILTER_PREPROC_HEADERS;


THTTP_FILTER_AUTHENT = record
pszUser : PChar;
cbUserBuff : DWORD;
pszPassword : PChar;
cbPasswordBuff : DWORD;
end;
HTTP_FILTER_AUTHENT = THTTP_FILTER_AUTHENT;
PHTTP_FILTER_AUTHENT = ^HTTP_FILTER_AUTHENT;


THTTP_FILTER_URL_MAP = record
pszURL : PChar;
pszPhysicalPath : PChar;
cbPathBuff : DWORD;
end;
HTTP_FILTER_URL_MAP = THTTP_FILTER_URL_MAP;
PHTTP_FILTER_URL_MAP = ^HTTP_FILTER_URL_MAP;


THTTP_FILTER_LOG = record
pszClientHostName : PChar;
pszClientUserName : PChar;
pszServerName : PChar;
pszOperation : PChar;
pszTarget : PChar;
pszParameters : PChar;
dwHttpStatus : DWORD;
dwWin32Status : DWORD;
end;
HTTP_FILTER_LOG = THTTP_FILTER_LOG;
PHTTP_FILTER_LOG = ^HTTP_FILTER_LOG;


THTTP_FILTER_VERSION = record
dwServerFilterVersion : DWORD;
dwFilterVersion : DWORD;
lpszFilterDesc : array [0..(SF_MAX_FILTER_DESC_LEN-1)] of Char;
dwFlags : DWORD;
end;
HTTP_FILTER_VERSION = THTTP_FILTER_VERSION;
PHTTP_FILTER_VERSION = ^HTTP_FILTER_VERSION;



Function HttpFilterProc(var pfc : HTTP_FILTER_CONTEXT;
NotificationType : DWORD;
pvNotification : LPVOID) : DWORD; export;
stdcall;

Var
S : Array[ 0..255 ] of char;
SLen : Cardinal;

begin
S := 'Hello, world!';
SLen := Length( S );
TWriteClient( pfc.WriteClient ) ( pfc, @S, @Slen, 0 );
end;

Function GetFilterVersion(var pVer : HTTP_FILTER_VERSION) : BOOL; export; stdcall;
begin
end;


begin
end.
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
461
import
I
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部