根据微软支持:How To Handle Proxy Authorization with WinInet 和其他Delphi示例(http://forum.codecall.net/topic/51366-internetopen-tthreads-maxconnectionsperserver/,https://pastebin.com/f1ea3a752),我编写了以下测试代码,尝试通过经过身份验证的代理服务器访问https页面的正确方法:
program Project35;
{$APPTYPE CONSOLE}
uses
SysUtils, WinInet, Windows, Classes;
Function sslGet(Const AServer, AUrl : string): AnsiString;
var
aBuffer : Array[0..4096] of Char;
BufStream : TMemoryStream;
sMethod : AnsiString;
BytesRead : Cardinal;
pSession : HINTERNET;
pConnection : HINTERNET;
pRequest : HINTERNET;
LUsername: string;
LPassword: string;
LProxy, LBypass: string;
LAgent: string;
LStatusCode, LStatusLen, LIndex : DWORD;
begin
Result := '';
LUsername := 'User-002' ;
LPassword := 'test2';
LProxy := 'myproxyserver:808';//https=https://
LBypass := '<local>';
LAgent := 'Bo-Test';
//pSession := InternetOpen(PChar(LAgent), INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0);
pSession := InternetOpen(PChar(LAgent), INTERNET_OPEN_TYPE_PROXY , PChar(LProxy), PChar(LBypass), 0);
//pSession := InternetOpen(PChar(LAgent), INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY , nil, nil, 0);
if Assigned(pSession) then
try
// pConnection := InternetConnect(pSession, PChar(AServer), INTERNET_DEFAULT_HTTPS_PORT, PChar(LUsername), PChar(LPassword), INTERNET_SERVICE_HTTP, 0, 0);
pConnection := InternetConnect(pSession, PChar(AServer), INTERNET_DEFAULT_HTTPS_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
if Assigned(pConnection) then
try
sMethod := 'GET';
pRequest := HTTPOpenRequest(pConnection, PChar(sMethod), PChar(AURL), nil, nil, nil,
INTERNET_FLAG_SECURE or
INTERNET_FLAG_KEEP_CONNECTION or
INTERNET_FLAG_NO_CACHE_WRITE or
INTERNET_FLAG_PRAGMA_NOCACHE or
INTERNET_FLAG_NO_AUTH or
INTERNET_FLAG_IGNORE_CERT_CN_INVALID or
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID or
INTERNET_FLAG_NO_UI or
INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS or
SECURITY_FLAG_IGNORE_UNKNOWN_CA, 0); //or INTERNET_FLAG_NO_AUTH
if Assigned(pRequest) then
try
if HTTPSendRequest(pRequest, nil, 0, nil, 0) then
begin
LStatusLen := SizeOf(LStatusCode);
LIndex := 0;
// expecting a 407 returned
HttpQueryInfo(pRequest, HTTP_QUERY_STATUS_CODE or HTTP_QUERY_FLAG_NUMBER,
@LStatusCode, LStatusLen, LIndex);
Write('Status code=');
writeln(LStatusCode);
// resend after 407
InternetSetOption(pRequest, INTERNET_OPTION_PROXY_USERNAME, PChar(LUsername) , length(LUsername));
InternetSetOption(pRequest, INTERNET_OPTION_PROXY_PASSWORD, PChar(LPassword), length(LPassword));
HTTPSendRequest(pRequest, nil, 0, nil, 0);
HttpQueryInfo(pRequest, HTTP_QUERY_STATUS_CODE or HTTP_QUERY_FLAG_NUMBER,
@LStatusCode, LStatusLen, LIndex);
Write('Resend status code=');
writeln(LStatusCode);
BufStream := TMemoryStream.Create;
try
while InternetReadFile(pRequest, @aBuffer, SizeOf(aBuffer), BytesRead) do
begin
if (BytesRead = 0) then Break;
BufStream.Write(aBuffer, BytesRead);
end;
aBuffer[0] := #0;
BufStream.Write(aBuffer, 1);
Result := PChar(BufStream.Memory);
finally
FreeAndNil(BufStream);
end;
end
else begin
Writeln(GetLastError());
end;
finally
InternetCloseHandle(pRequest);
end;
finally
InternetCloseHandle(pConnection);
end;
finally
InternetCloseHandle(pSession);
end;
end;
var
StopEnter: string;
begin
try
// the wsdl is only available with ssl, i.e., https://services.staging.referralnet.com.au/services/Referral_Service_51?wsdl
// it is invalid for http://services.staging.referralnet.com.au/services/Referral_Service_51?wsdl
Writeln(sslGet('services.staging.referralnet.com.au', '/services/Referral_Service_51?wsdl'));
Write('Press Enter to stop ...');
Readln(StopEnter);
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
我使用CCProxy作为此测试的代理服务器。 我尝试使用两台机器,一台修改了hosts文件,以便wsdl页面的服务器指向127.0.0.1,另一台修改了防火墙,因此阻止了服务器的所有流量。
两次测试都返回了两个407代码,即原始和重发请求均以407失败。
可能有什么不对?或者有人能指出我一个有效的例子吗?
答案 0 :(得分:0)
看看THttpRIo组件如何处理这个问题。只需按照代码中的代理属性使用即可。