Authenticating to Domino

I am writing a console client program in C++ to call and execute a Notes Java agent via HTTP and retrieve back a datastream.

My problem is that when I execute my program it first throws up an Internet Exploerer prompt for my Notes login information. Once I do this, the rest of the program woks fine.

I have embedded my username and password at the beginning of the URL, but I still get the prompt. If I use this same URL directly into an IE browser, it works fine with no prompt.

Does anyone know of VC++ trick to disable the login prompt?

Thanks, I appreciate the help.

///////////////////////////////////

           CODE 

///////////////////////////////////

#include <afx.h>

#include <afxwin.h>

#include <afxinet.h>

#include “grab.h”

#include <windows.h>

#include <iostream.h>

#include <fstream.h>

#include <stdlib.h>

/////////////////////////////////////////////////////////////////////////////

// Globals

LPCTSTR pszURL = NULL;

BOOL bStripMode = FALSE;

BOOL bProgressMode = FALSE;

CString strUser = “”;

CString strPasswd = “”;

CString strLocalFile = “”;

CString strWebFile = “”;

CString strURL=“”;

DWORD dwAccessType = PRE_CONFIG_INTERNET_ACCESS;

DWORD dwHttpRequestFlags =

INTERNET_FLAG_EXISTING_CONNECT | INTERNET_FLAG_NO_AUTO_REDIRECT;

const TCHAR szHeaders =

_T("Accept: text/*\r\nUser-Agent: MFC_File_Grabber\r\n");

/////////////////////////////////////////////////////////////////////////////

// CGrabSession object

// TEAR wants to use its own derivative of the CInternetSession class

// just so it can implement an OnStatusCallback() override.

CGrabSession::CGrabSession(LPCTSTR pszAppName, int nMethod)

: CInternetSession(pszAppName, 1, nMethod)

{

}

void CGrabSession::OnStatusCallback(DWORD /* dwContext */, DWORD dwInternetStatus,

LPVOID /* lpvStatusInfomration */, DWORD /* dwStatusInformationLen */)

{

if (!bProgressMode)

	return;



if (dwInternetStatus == INTERNET_STATUS_CONNECTED_TO_SERVER)

	cerr << _T("Connection made!") << endl;

}

/////////////////////////////////////////////////////////////////////////////

// CGrabException – used if something goes wrong for us

// GRAB will throw its own exception type to handle problems it might

// encounter while fulfilling the user’s request.

IMPLEMENT_DYNCREATE(CGrabException, CException)

CGrabException::CGrabException(int nCode)

: m_nErrorCode(nCode)

{

}

void ThrowGrabException(int nCode)

{

CGrabException* pEx = new CGrabException(nCode);

throw pEx;

}

/////////////////////////////////////////////////////////////////////////////

// Routines

void ShowBanner()

{

cerr << _T("TEAR - Tear a Page Off the Internet!") << endl;

cerr << _T("Version 4.2 - Copyright (C) Microsoft Corp 1998") << endl;

cerr << endl;

}

void ShowUsage()

{

cerr << _T("Usage:  TEAR [options] <URL> <FILE>") << endl << endl;

cerr << _T("\t<WEB FILE>  points at a HTTP resource") << endl;

cerr << _T("\t<LOCAL FILE> points at a local File resource") << endl;

cerr << _T("\t[options] are any of:") << endl;

cerr << _T("\t\t/U User Id") << endl;

cerr << _T("\t\t/P Password") << endl;

cerr << _T("\t\t/F Local File") << endl;

cerr << _T("\t\t/W Web File") << endl << endl;



cerr << endl;

exit(1);

}

// ParseOptions() looks for options on the command line and sets global

// flags so the rest of the program knows about them. ParseOptions()

// also initializes pszURL to point at the URL the user wanted.

BOOL ParseOptions(int argc, char* argv)

{

int nIndex;



for (nIndex = 1; nIndex < argc; nIndex++)

{

	// an option or a URL?



	if (*argv[nIndex] == '-' || *argv[nIndex] == '/')

	{

		if (argv[nIndex][1] == 'W' || argv[nIndex][1] == 'w'){

            nIndex++;

		

            if(*argv[nIndex] != NULL || *argv[nIndex] != '-' || *argv[nIndex] != '/'){

				strWebFile = strWebFile + argv[nIndex];

				cerr << "WEB FILE: " << strWebFile << endl;

			}else{

				cerr << _T("Error: Must specify a web file. ") << endl;

			    return FALSE;

			}				

        }

		else if (argv[nIndex][1] == 'S' || argv[nIndex][1] == 's')

			bStripMode = TRUE;

		else if (argv[nIndex][1] == 'P' || argv[nIndex][1] == 'p'){			

			nIndex++;

		

            if(argv[nIndex][1] != NULL || argv[nIndex][1] != '-' || argv[nIndex][1] != '/'){

				strPasswd= strPasswd + argv[nIndex];

				cerr << "PASSWORD: " << strPasswd << endl;

			}else{

				cerr << _T("Error: Must give a password. ") << endl;

			    return FALSE;

			}								

		}else if (argv[nIndex][1] == 'U' || argv[nIndex][1] == 'u'){			

			nIndex++;

		

            if(argv[nIndex][1] != NULL || argv[nIndex][1] != '-' || argv[nIndex][1] != '/'){

				strUser += argv[nIndex];

				strUser += " ";

				nIndex++;



				if (argv[nIndex] != NULL){

				   strUser += argv[nIndex];

				}

														

				cerr << "USERNAME: " << strUser << endl;

			}else{

				cerr << _T("Error: Must give a username. ") << endl;

			    return FALSE;

			}

			            

		}else if (argv[nIndex][1] == 'F' || argv[nIndex][1] == 'f'){			

			nIndex++;

		

            if(argv[nIndex][1] != NULL || argv[nIndex][1] != '-' || argv[nIndex][1] != '/'){

				strLocalFile = strLocalFile + argv[nIndex];

				cerr << "File: " << strLocalFile << endl;

			}else{

				cerr << _T("Error: Must give a web filename. ") << endl;

			    return FALSE;

			}

			

        }			

		else

		{

			cerr << _T("Error: unrecognized option: ") << argv[nIndex] << endl;

			return FALSE;

		}

	}

	else

	{

	// can't have too many URLs



	if (pszURL != NULL)

	{

		cerr << _T("Error: can only specify one URL!") << endl;

		return FALSE;

	}

	else

		pszURL = argv[nIndex];

	}

}



return TRUE;

}

void ValidateFile(char buffer_1)

{

// Valid file path name (file is there).    

char *lpStr1;

lpStr1 = buffer_1;



// Return value from "PathFileExists".

int retval;



// Search for the presence of a file with a true result.

// retval = PathFileExists(lpStr1);

if(retval == 1)

{

    cout << "Search for the file path of : " << lpStr1 << endl;

    cout << "The file requested \"" << lpStr1 << "\" is a valid file" << endl;

    cout << "The return from function is : " << retval << endl;

}    

else

{

    cout << "\nThe file requested " << lpStr1 << " is not a valid file" << endl;

    cout << "The return from function is : " << retval << endl;

}

}

// StripTags() rips through a buffer and removes HTML tags from it.

// The function uses a static variable to remember its state in case

// a HTML tag spans a buffer boundary.

void StripTags(LPTSTR pszBuffer)

{

static BOOL bInTag = FALSE;

LPTSTR pszSource = pszBuffer;

LPTSTR pszDest = pszBuffer;



while (*pszSource != '\0')

{

	if (bInTag)

	{

		if (*pszSource == '>')

			bInTag = FALSE;

		pszSource++;

	}

	else

	{

		if (*pszSource == '<')

			bInTag = TRUE;

		else

		{

			*pszDest = *pszSource;

			pszDest++;

		}

		pszSource++;

	}

}

*pszDest = '\0';

}

/////////////////////////////////////////////////////////////////////////////

// The main() Thang

int main(int argc, char* argv)

{

ShowBanner();



/////////////////

// Initialize MFC

/////////////////

if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))

{

	cerr << _T("MFC Failed to initialize.\n");

	return 1;

}



///////////////// 

// GET ARGUMENTS

/////////////////

// Required:

//  + Web File Name

//  + Local File Name

//  + User ID (2)

//  + Password



if (argc < 2 || !ParseOptions(argc, argv) ) // || pszURL == NULL)

	ShowUsage();





int nRetCode = 0;



///////////////////////////////////////

// Initialize GrabSession Object Class

///////////////////////////////////////



CGrabSession session(_T("GRAB - MFC Sample App"), dwAccessType);

CHttpConnection* pServer = NULL;

CHttpFile* pFile = NULL;



            ofstream out(strLocalFile);



            strURL  = "http://" + strUser + ":" + strPasswd;

            strURL  +=  "@www.grocerssupply.com/web/webcust.nsf/ctest?f=" + strWebFile;

cout << "URL: " << strURL << endl;

pszURL = strURL;



try

{

	// check to see if this is a reasonable URL



	CString strServerName;

	CString strObject;

	INTERNET_PORT nPort;

	DWORD dwServiceType;



	if (!AfxParseURL(pszURL, dwServiceType, strServerName, strObject, nPort) ||

		dwServiceType != INTERNET_SERVICE_HTTP)

	{

		cerr << _T("Error: can only use URLs beginning with http://") << endl;

		ThrowGrabException(1);

	}



	if (bProgressMode)

	{

		cerr << _T("Opening Internet...");

		VERIFY(session.EnableStatusCallback(TRUE));

	}



    // Connect to URL



	pServer = session.GetHttpConnection(strServerName, nPort);

	

	pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,

		strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);



	pFile->AddRequestHeaders(szHeaders);

	pFile->SendRequest();



	DWORD dwRet;

	pFile->QueryInfoStatusCode(dwRet);



	// if access was denied, prompt the user for the password



	if (dwRet == HTTP_STATUS_DENIED)

	{

		DWORD dwPrompt;

		dwPrompt = pFile->ErrorDlg(NULL, ERROR_INTERNET_INCORRECT_PASSWORD,

			FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL);



		// if the user cancelled the dialog, bail out



		if (dwPrompt != ERROR_INTERNET_FORCE_RETRY)

		{

			cerr << _T("Access denied: Invalid password\n");

			ThrowGrabException(1);

		}



		pFile->SendRequest();

		pFile->QueryInfoStatusCode(dwRet);

	}



	CString strNewLocation;

	pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);



	// were we redirected?

	// these response status codes come from WININET.H



	if (dwRet == HTTP_STATUS_MOVED ||

		dwRet == HTTP_STATUS_REDIRECT ||

		dwRet == HTTP_STATUS_REDIRECT_METHOD)

	{

		CString strNewLocation;

		pFile->QueryInfo(HTTP_QUERY_RAW_HEADERS_CRLF, strNewLocation);



		int nPlace = strNewLocation.Find(_T("Location: "));

		if (nPlace == -1)

		{

			cerr << _T("Error: Site redirects with no new location") << endl;

			ThrowGrabException(2);

		}



		strNewLocation = strNewLocation.Mid(nPlace + 10);

		nPlace = strNewLocation.Find('\n');



		if (nPlace > 0)

			strNewLocation = strNewLocation.Left(nPlace);



		// close up the redirected site



		pFile->Close();

		delete pFile;

		pServer->Close();

		delete pServer;



		if (bProgressMode)

		{

			cerr << _T("Caution: redirected to ");

			cerr << (LPCTSTR) strNewLocation << endl;

		}



		// figure out what the old place was

		if (!AfxParseURL(strNewLocation, dwServiceType, strServerName, strObject, nPort))

		{

			cerr << _T("Error: the redirected URL could not be parsed.") << endl;

			ThrowGrabException(2);

		}



		if (dwServiceType != INTERNET_SERVICE_HTTP)

		{

			cerr << _T("Error: the redirected URL does not reference a HTTP resource.") << endl;

			ThrowGrabException(2);

		}



		// try again at the new location

		pServer = session.GetHttpConnection(strServerName, nPort);



		pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET,

			strObject, NULL, 1, NULL, NULL, dwHttpRequestFlags);



		pFile->AddRequestHeaders(szHeaders);



		pFile->SendRequest();



		pFile->QueryInfoStatusCode(dwRet);



		if (dwRet != HTTP_STATUS_OK)

		{

			cerr << _T("Error: Got status code ") << dwRet << endl;

			ThrowGrabException(2);

		}

	}



	cerr << _T("Status Code is ") << dwRet << endl;



	TCHAR sz[1024];

	while (pFile->ReadString(sz, 1023))

	{



		out << sz << endl;

		if (bStripMode)

			StripTags(sz);

		cout << sz;

	



	}



// NOTE: Since HTTP servers normally spit back plain text, the

// above code (which reads line by line) is just fine.  However,

// other data sources (eg, FTP servers) might provide binary data

// which should be handled a buffer at a time, like this:

#if 0

	while (nRead > 0)

	{

		sz[nRead] = '\0';

	//	out << sz << endl;

		if (bStripMode)

			StripTags(sz);

		cout << sz;

	

		nRead = pFile->Read(sz, 1023);

	}

#endif

	pFile->Close();

	pServer->Close();

	out.close();

}

catch (CInternetException* pEx)

{

	// catch errors from WinINet



	TCHAR szErr[1024];

	pEx->GetErrorMessage(szErr, 1024);



	cerr << _T("Error: (") << pEx->m_dwError << _T(") ");

	cerr << szErr << endl;



	nRetCode = 2;

	pEx->Delete();

}

catch (CGrabException* pEx)

{

	// catch things wrong with parameters, etc



	nRetCode = pEx->m_nErrorCode;

	TRACE1("Error: Exiting with CGrabException(%d)\n", nRetCode);

	pEx->Delete();

}



if (pFile != NULL)

	delete pFile;

if (pServer != NULL)

	delete pServer;

session.Close();



return nRetCode;

}

Subject: Authenticating to Domino

I found my answer:

After I establish the HTTP connection I need to use the SetOption() function like so:

pFile->SetOption(INTERNET_OPTION_USERNAME,“Bruce McDougald”,sizeof(“Bruce McDougald”));

pFile->SetOption(INTERNET_OPTION_PASSWORD,“mypasswd”,sizeof(“mypasswd”));