请大家看看这个CGI(用CGI Expert做的)的奇怪现象(71分)

  • 主题发起人 主题发起人 DreamTiger
  • 开始时间 开始时间
D

DreamTiger

Unregistered / Unconfirmed
GUEST, unregistred user!
这是一个可以从IE的Favorite中把URL转换为HTML显示的。
我想用它输入用户和密码,校验正确后,显示转换结果。
当我输入正确的时候,转换结果正常显示,怪事出在如果
我输入了用户名和密码,但是密码不正确(用户名是选择
的,所以正确),这时候会跳出一个窗口,“
请输入用户名和密码。
站点: 111.111.111.111(机器IP)
领域: 111.111.111.111(同上)
用户名(U):
密码(P):
将密码存入密码表中(S)
确定 取消”

如果在别的机器上(用的是PWIN98,本机是NT)使用这个cgi,
输入密码不正确的时候,会跳出一个窗口“
请输入您的身份验证信息。
资源: 111.111.111.111
用户名(U):
密码(P):
将密码存入密码表中(S)
确定 取消”

好像是要连接网络邻居一样,这是怎么回事?
运行调试的时候,如果输入密码出错后,运行到了
HttpMemoFilter_Unauthorized.put;
然后就退出这个函数,也就是说运行次序没有问题。
F9继续后,出现上述输入窗口。
HttpMemoFilter_Unauthorized的Text就是很简单的
Access Denied一句话,这句话在上述窗口出现三次
后显示在浏览器窗口。

HttpMemoFilter_Init中语句是用于选择用户名,
输入密码,将参数返回给cgi自身的。

下面是主程序:

unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
HttpEng, HUtils, GenEng, IniFiles;

type
TForm1 = class(TForm)
GeneralHttpEngine1: TGeneralHttpEngine;
HttpMemoFilter_Unauthorized: THttpMemoFilter;
HttpMemoFilter_Result: THttpMemoFilter;
HttpMemoFilter_Init: THttpMemoFilter;
procedure GeneralHttpEngine1ExecRequest(Sender: TObject);
private
tslFavorite:TStringList;
procedure ConvertFavorite;
procedure ScanDir(Dir, { Directory name for Hdr }
Path : string; { Path to search }
Indent : integer); { Left Margin }
procedure AddHeader(Name : string);
procedure AddUrl(Name, URL : string);
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
const REC_FOUND = 0; { OK-Result of FindFirst }
ROOT_DIR = 'C:/WinNT/Profiles/sqh/Favorites'; { Where to start looking }
DIR_EXT = '/*.*'; { mask for Directories }
URL_EXT = '/*.URL'; { mask for URLs }

{ The .URL files used by IE have the same format that was used in }
{ Windows 3.x's .INI files. Thus, we can use the TIniFile class and }
{ TIniFile.Readstring method to extract the information. }
{ Methinks it should be possible to store additional information in }
{ the .URL files for managing shortcuts, etc. Play with it if you }
{ have time. Maybe set it to *not* export some shortcuts, or to }
{ include pictures (IMG=), or set different fonts for HTML generation }

INI_SECTION = 'InternetShortcut'; { Section in the URL file }
INI_ITEM = 'URL'; { Item in the section }
INI_DEFAULT = 'N/A'; { ...if URL not found }

STARTINDENT = 0; { Left Margin in Memo }
ADD_INDENT = 4; { Indent for each level }
DIR_INDENT = 2; { back up two for dir. }

MISCELLANEOUS = 'Miscellaneous'; { Header for Root Dir }

procedure TForm1.ConvertFavorite;
begin
ScanDir('',ROOT_DIR,0);
end;

procedure TForm1.ScanDir(Dir, { Directory name for Hdr }
Path : string; { Path to search }
Indent : integer); { Left Margin }
var SearchRec : TSearchRec;
Err : integer;
URL : string;
begin { of ScanDir }
{ Scan for Directories first }
Err:=FindFirst(Path+DIR_EXT, faDirectory, SearchRec);
while (Err = REC_FOUND) do with SearchRec do begin
if Name[1] <> '.' then begin { Avoid Directories '.' and '..' }
ScanDir(Name, Path+'/'+Name, Indent+ADD_INDENT) { Recurse down }
end;
Err:=FindNext(SearchRec) { Find Next Directory name }
end;
FindClose(SearchRec); { We're done here }

{ Scan for URLs }
Err:=FindFirst(Path+URL_EXT, faAnyFile, SearchRec);
{ if a URL was found in this directory, output the directory name or
generate and HTML Header with the directory name. This assures that
a the header will not be generated for empty directories, or non-URL
directories. }
if (Err = REC_FOUND) then begin
if Dir>'' then AddHeader(Dir) { Generate HTML }
else AddHeader(MISCELLANEOUS)
end;
{ now begin scanning the dir }
while (Err = REC_FOUND) do with SearchRec do begin
{ Get the URL information from the current URL file }
with TIniFile.Create(Path+'/'+Name) do begin
URL:=ReadString(INI_SECTION, INI_ITEM, INI_DEFAULT);
Free;
end;
{ output or generate html for the name and URL }
AddURL(Copy(Name, 1,Length(Name)-4), URL); { Copy deletes the extension ".URL" }
Err:=FindNext(SearchRec);
end;
FindClose(SearchRec)
{ OK, all done }
end;

procedure TForm1.AddHeader(Name : string);
begin
{ Write a header (i.e. Directory name ) }
tslFavorite.Add('<p><font size=5><strong>'+Name+'</strong></font></p>');
end;

procedure TForm1.AddUrl(Name, URL : string);
begin
{ Write a URL }
tslFavorite.Add(Format('<p><a href="%s"><strong>%s</strong></a></p>',[URL,Name]));
end;

procedure TForm1.GeneralHttpEngine1ExecRequest(Sender: TObject);
var
sUsername: string;
sPassword: string;
begin
sUsername:=FormVar('Username','');
sPassword:=FormVar('Password','');

if (Length(sUsername)>0) and (Length(sPassword)>0) then // Here you should do some check
begin
if(sUserName = 'sqh') and (sPassword = '1234567') then
begin
HttpMemoFilter_Result.Text.Clear;
tslFavorite := TStringList.Create;
try
ConvertFavorite;
HttpMemoFilter_Result.Text.Assign(tslFavorite);
finally
tslFavorite.Free;
end;

PutLine('<html><head><title>Favorites</title></head><body>');
HttpMemoFilter_Result.Put;
PutLine('</body></html>')
end
else
begin
PutHttpHeader('HTTP/1.0 401 Unauthorized to access the document','');
PutHttpHeader('Content-Type','text/html');
PutHttpHeader('WWW-Authenticate','Basic realm="' + RemoteAddress + '"');
PutLine('<HTML><TITLE>' + sUsername + ':' + sPassword + '</TITLE></HTML>');
HttpMemoFilter_Unauthorized.put;
end;
end
else
begin
HttpMemoFilter_Init.put;
end;
end;

end.
 
虽然你说了这么多,但我还是没看明白你的问题到底是什么??
仔细看看你说的话,似乎有些混乱.

况且,网页授权好像不是这么用的.
 
呵呵,代码也够乱的
 
呵呵,代码么,我只是简单移植了一下,下次注意,应该把没必要的
代码去掉。

问题是很奇怪的,我在程序中什么也没干,他怎么会跳出一个要我输
入用户名和密码的窗口?
 
你能不能把你的问题简单的描述一下?

这是我第一次要求别人"简化"问题描述.... :-)

1.你想干什么?
2.你怎么做的?(用言语描述吧)
3.出现了什么问题?
 
1、我想通过检验输入的用户名和用户密码,决定是否运行一个
procedure,把用户的Favorite转换成html,显示。

2、用CGI Expert做的。如果传过来的Username或Password为空,
显示选择用户名和输入密码的窗口(HttpMemoFilter_Init.put)
如果传过来的Username或者Password不为空,检查是否符合要求,
符合则进行Favorite到html的转换,显示,不符合,就显示出错
信息。(HttpMemoFilter_Result.Put)

3、问题是:当检查不符合要求时,会跳出一个窗口,询问用户名
和密码。这个窗口不是我写的代码中的,我不知道他是怎么出现
的,也很想知道怎么才能让他出现。

因为这个问题我觉得太奇怪了,觉得很难表述,所以写的罗里罗
唆了,不好意思,各位大侠多多包涵。




 
我想你将IE的安全级设的太高了,所以动不动它就给你验证了。
还有Netscape也是如此。
 
1.你怎么能得到用户的Favorite ? (题外话)

2.网页授权和NT的账户有关,好像不是你这样用的.
建议你做简单的form来验证就可以了;
 
to cAKK:
1、因为我的NT装在C盘,用的是Fat16表(原装机,没能转换成NTFS),所以
对Favorite可以读写。
2、我是希望能用NT的账户来验证,但不知道该怎么做。请举个例子,我对于
这方面很不熟悉,正想多多请教。

to Jams:
IE的安全级我设的是“中”。
 
1.你不是想把<font color=red>用户自己</font>的Favorite转换成html吗? 可是你怎么能读取浏览器
客户端的东西呢?
这个问题如果你自信可以解决,就不用再讨论了,毕竟和本问题关系不大;
2.强烈建议你不要用NT账户来管理验证,因为这样你需要为每个注册用户设一个
帐号,你的服务器受得了吗?
参考一下本论坛的身份验证方式.
 
1、我读取的是服务器上的Favorite,不是浏览器客户端的。我也没想弄
得那么复杂,只是为了自己的方便,可以在别人的机子上读出自己的
Favorite而已。

2、如果我希望用NT账号来管理验证,怎么做?

3、本论坛的身份验证方式是怎么做的?

如果觉得分数不够的话,我可以再加分。多谢。
 
2.如果通过NT账户验证,你需要给每个注册的用户开一个NT帐号,
然后将你的网页的目录设置访问权限,只有正式账户的用户才可以访问;
这样,当用户访问该网页时,会自动弹出口令对话框,要求输入口令,并
自动进行验证,这一切不需要你自己来做.
缺点是如果你的注册用户太多,你的NT可能吃不消.
3.本论坛是通过Cookie管理的,登陆时将username,password保存到Cookie
里面,每一页面访问前先检查Cookie,如果存在username,password则
继续,否则redircet到登陆页面.
 
呵呵, 可以肯定是你的下面语句出问题:-)
PutHttpHeader('HTTP/1.0 401 Unauthorized to access the document','');
PutHttpHeader('Content-Type','text/html');
PutHttpHeader('WWW-Authenticate','Basic realm="' + RemoteAddress + '"');
PutLine('');
HttpMemoFilter_Unauthorized.put;
把www-authenti...这句去掉, 另外, HTTP/1.0...这句好象不是这么用吧???(不太
清楚)
还有putline('')还是用terminateheader来代替吧:-)

btw, 绝对不要用nt帐户来验证, 会出大问题的.
 
putline('')其实里面是有内容的,被解释掉了,呵呵。
去掉
PutHttpHeader('WWW-Authenticate','Basic realm="' + RemoteAddress + '"');
后,ie不再跳出要求填写用户名和密码的框了,但netscape仍然会弹出,
再去掉
PutHttpHeader('HTTP/1.0 401 Unauthorized to access the document','');
以后,netscape也正常了。

这两行代码到底是干什么的?
 
呵呵, 你不知道干什么用的??? 我倒!@@@%$$^$&%
那你还用:-(
http/1.0...那行是关于使用http的版本和返回码的.
401表示access denied.. 200表示ok!
用putline代替puthttpheader, 因为puthttpheader生成如下:
putline(param1 + '='+ param2);
就是HTTP/1.0 401 Unauthorized to access the document=
当然错了,
putline('HTTP/1.0 401');
就可以了.
关于httpheader里的内容, 很多, 去www.w3c.org查查吧.
 
DreamTiger肯定是把"HTTP/1.0 401 "当成普通的字符串了. :-)
 
//shy
以前一直就在用C++编程,别的没怎么学,这不,出笑话了。
那两行东东是从CGIExpert例子中扒下来的,呵呵。得好好
看看这方面的书了。不过,有一个问题我还是不太明白,
弹出来的这个窗口,输入了用户名和密码以后,在我的cgi
中怎么获取这两个新输入的值?
 
大概是AUTHORIZED_USER这个环境变量,可能拼写不准,不过差不多.
查查资料吧!
 
如果成功, 应该是REMOTE_USER 或 REMOTE_IDENT, 密码得不到:-)
 

Similar threads

I
回复
0
查看
612
import
I
I
回复
0
查看
714
import
I
I
回复
0
查看
682
import
I
后退
顶部