Para conseguir autentificar nuestro programa en un proxy, podemos dejar que el usuario lo haga a mano y automatizar el proceso y hacerlo transparente. Esto puede ahorrar los molestos diálogos que piden el usuario y contraseña.
La función que publico nos autentifica en un proxy dando una URL que tenga que salir por él, un nombre de usuario y una contraseña. El código origunal lo escribí en C++ pero lo muestro también migrado a delphi:
Versión C++:
#pragma link "$(BCB)\\lib\\PSDK\\Wininet.lib" //--------------------------------------------------------------------------- void Authenticate(char* _URL, char* Username, char* Password) { HINTERNET hInet, hConnect, hRequest; DWORD dwStatus, dwStatusSize = sizeof(DWORD); char *URL = strnewdup(_URL); if(!strnicmp(URL, "http://", 7)) URL += 7; char *C = strchr(URL, '//'); if(C) *C = 0; hInet = InternetOpen("agent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); hConnect = InternetConnect(hInet, URL, INTERNET_INVALID_PORT_NUMBER, NULL, NULL, INTERNET_SERVICE_HTTP, 0,0); hRequest = HttpOpenRequest(hConnect, "GET", "", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0); for(int n=0; n<2; n++){ HttpSendRequest(hRequest, NULL, 0, NULL, 0); HttpQueryInfo(hRequest, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusSize, NULL); // Se requiere autentificación en el Proxy o en el servidor if(dwStatus == HTTP_STATUS_PROXY_AUTH_REQ || dwStatus == HTTP_STATUS_DENIED){ // Introducimos UserName InternetSetOption(hRequest, INTERNET_OPTION_PROXY_USERNAME, (void*)Username, lstrlen(Username)+1); // Introducimos el Password InternetSetOption(hRequest, INTERNET_OPTION_PROXY_PASSWORD, (void*)Password, lstrlen(Password)+1); } } delete URL; InternetCloseHandle(hInet); InternetCloseHandle(hConnect); InternetCloseHandle(hRequest); }
Ejemplo de uso:
Authenticate(Edit1->Text.c_str(), "User", "Password"); CppWebBrowser1->Navigate(WideString(Edit1->Text).c_bstr());
La versión delphi es similar en su funcionamiento y uso:
uses Wininet; procedure Authenticate(URL, UserName, PassWord: String); var hInet, hConnect, hRequest: HINTERNET; dwStatus, StatusSize, i: DWORD; begin StatusSize:= sizeof(dwStatus); URL:= StrLower(PCHAR(URL)); i:= Pos('http://', URL); if i>0 then URL:= Copy(URL, 8, Length(URL)-7); i:= Pos('/', URL); if i>0 then SetLength(URL, i-1); hInet:= InternetOpen('agent', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0); hConnect:= InternetConnect(hInet, PCHAR(URL), INTERNET_INVALID_PORT_NUMBER, nil, nil, INTERNET_SERVICE_HTTP, 0,0); hRequest:= HttpOpenRequest(hConnect, 'GET', '', nil, nil, nil, INTERNET_FLAG_KEEP_CONNECTION, 0); for i:=0 to 1 do begin HttpSendRequest(hRequest, nil, 0, nil, 0); HttpQueryInfo(hRequest, HTTP_QUERY_FLAG_NUMBER or HTTP_QUERY_STATUS_CODE, @dwStatus, StatusSize, PCardinal(0)^); // Se requiere autentificación en el Proxy o en el servidor if (dwStatus = HTTP_STATUS_PROXY_AUTH_REQ) or (dwStatus = HTTP_STATUS_DENIED) then begin // Introducimos UserName InternetSetOption(hRequest, INTERNET_OPTION_PROXY_USERNAME, PCHAR(UserName), Length(UserName) + 1); // Introducimos el Password InternetSetOption(hRequest, INTERNET_OPTION_PROXY_PASSWORD, PCHAR(PassWord), Length(PassWord) + 1); end; end; InternetCloseHandle(hInet); InternetCloseHandle(hConnect); InternetCloseHandle(hRequest); end;
Ejemplo de uso:
Authenticate(PCHAR(Edit1.Text), 'User', 'Password'); WebBrowser1.Navigate(WideString(Edit1.Text));
Espero que sea de utilidad.
Saludos.
PD: Actualizo para admitir direcciones IP