Discussion:
InternetCreateUrl, InternetCrackUrl, ERROR_INTERNET_INVALID_URL
(too old to reply)
Roman Ryl...
2006-01-11 17:28:16 UTC
Permalink
Hi,

This should be a simple issue however I did not find in newgroup
search. I have an FTP URL with embedded username, which in its turn
contains '@', something like:

'ftp://' <***@domain.com> ':' <password> '@' <server.com> </path...>

The problem is that InternetCreateUrl does not replace '@' character
with %40 and InternetCrackUrl subsequently fails. ICU_ENCODE flags does
not seem to make InternetCreateUrl convert the character, however if
the replacemed manually, InternetCrackUrl does decode correctly.

My question is whether there is a more correct solution than replace
'@' manually like I do now:

LPCTSTR pszUserName = ... ; // input
CString sUserNameEx;
if(_tcschr(pszUserName, _T('@')))
{
sUserNameEx = pszUserName;
sUserNameEx.Replace(_T("@"), _T("%40"));
pszUserName = sUserNameEx;
}

Roman
Scherbina Vladimir
2006-01-11 19:46:38 UTC
Permalink
Hello, Roman.

Can you publish here exact piece code that fails ?
--
Vladimir
Post by Roman Ryl...
Hi,
This should be a simple issue however I did not find in newgroup
search. I have an FTP URL with embedded username, which in its turn
with %40 and InternetCrackUrl subsequently fails. ICU_ENCODE flags does
not seem to make InternetCreateUrl convert the character, however if
the replacemed manually, InternetCrackUrl does decode correctly.
My question is whether there is a more correct solution than replace
LPCTSTR pszUserName = ... ; // input
CString sUserNameEx;
{
sUserNameEx = pszUserName;
pszUserName = sUserNameEx;
}
Roman
Roman Ryl...
2006-01-26 10:27:12 UTC
Permalink
Vladimir,

Here it goes, see below. The output is:

Location: ftp://***@bbb.net:***@aaa.com/path
Error: 12005 in line 33
Error: 12005 in line 59

Roman

===

#include "stdafx.h"
#include <windows.h>
#include <wininet.h>

#pragma comment(lib, "wininet.lib")

int _tmain(int argc, _TCHAR* argv[])
{
URL_COMPONENTS Components1;
ZeroMemory(&Components1, sizeof Components1);
Components1.dwStructSize = sizeof Components1;
Components1.lpszScheme = _T("ftp");
Components1.nScheme = INTERNET_SCHEME_FTP;
Components1.lpszHostName = _T("aaa.com");
Components1.nPort = INTERNET_DEFAULT_FTP_PORT;
Components1.lpszUserName = _T("***@bbb.net");
Components1.lpszPassword = _T("pass");
Components1.lpszUrlPath = _T("/path");
//Components1.lpszExtraInfo =
TCHAR pszLocation[INTERNET_MAX_URL_LENGTH];
DWORD nLocationLength = INTERNET_MAX_URL_LENGTH;
if(!InternetCreateUrl(&Components1, ICU_ESCAPE, pszLocation,
&nLocationLength))
{
printf("Error: %d in line %d\n", GetLastError(), __LINE__);
return 1;
}
printf("Location: %s\n", pszLocation);
URL_COMPONENTS Components2;
ZeroMemory(&Components2, sizeof Components2);
Components2.dwStructSize = sizeof Components2;
if(!InternetCrackUrl(pszLocation, 0, 0, &Components2))
{
printf("Error: %d in line %d\n", GetLastError(), __LINE__);
//return 2;
}
TCHAR pszScheme[INTERNET_MAX_SCHEME_LENGTH];
TCHAR pszHostName[INTERNET_MAX_HOST_NAME_LENGTH];
TCHAR pszUserName[INTERNET_MAX_USER_NAME_LENGTH];
TCHAR pszPassword[INTERNET_MAX_PASSWORD_LENGTH];
TCHAR pszUrlPath[INTERNET_MAX_PATH_LENGTH];
TCHAR pszExtraInfo[INTERNET_MAX_URL_LENGTH];
URL_COMPONENTS Components3;
ZeroMemory(&Components3, sizeof Components3);
Components3.dwStructSize = sizeof Components3;
Components3.lpszScheme = pszScheme;
Components3.dwSchemeLength = INTERNET_MAX_SCHEME_LENGTH;
Components3.lpszHostName = pszHostName;
Components3.dwHostNameLength = INTERNET_MAX_HOST_NAME_LENGTH;
Components3.lpszUserName = pszUserName;
Components3.dwUserNameLength = INTERNET_MAX_USER_NAME_LENGTH;
Components3.lpszPassword = pszPassword;
Components3.dwPasswordLength = INTERNET_MAX_PASSWORD_LENGTH;
Components3.lpszUrlPath = pszUrlPath;
Components3.dwUrlPathLength = INTERNET_MAX_PATH_LENGTH;
Components3.lpszExtraInfo = pszExtraInfo;
Components3.dwExtraInfoLength = INTERNET_MAX_URL_LENGTH;
if(!InternetCrackUrl(pszLocation, 0, ICU_DECODE | ICU_ESCAPE,
&Components3))
{
printf("Error: %d in line %d\n", GetLastError(), __LINE__);
return 2;
}
return 0;
}
Scherbina Vladimir
2006-01-26 11:34:50 UTC
Permalink
The problem in your code is that InternetCrackUrl failes when you specify
'@' in user name. Change:

Components1.lpszUserName = _T("***@bbb.net"); to
Components1.lpszUserName = _T("useratbbbnet");

and all will be okay.

--
Vladimir
Post by Roman Ryl...
Vladimir,
Error: 12005 in line 33
Error: 12005 in line 59
Roman
===
#include "stdafx.h"
#include <windows.h>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")
int _tmain(int argc, _TCHAR* argv[])
{
URL_COMPONENTS Components1;
ZeroMemory(&Components1, sizeof Components1);
Components1.dwStructSize = sizeof Components1;
Components1.lpszScheme = _T("ftp");
Components1.nScheme = INTERNET_SCHEME_FTP;
Components1.lpszHostName = _T("aaa.com");
Components1.nPort = INTERNET_DEFAULT_FTP_PORT;
Components1.lpszPassword = _T("pass");
Components1.lpszUrlPath = _T("/path");
//Components1.lpszExtraInfo =
TCHAR pszLocation[INTERNET_MAX_URL_LENGTH];
DWORD nLocationLength = INTERNET_MAX_URL_LENGTH;
if(!InternetCreateUrl(&Components1, ICU_ESCAPE, pszLocation,
&nLocationLength))
{
printf("Error: %d in line %d\n", GetLastError(), __LINE__);
return 1;
}
printf("Location: %s\n", pszLocation);
URL_COMPONENTS Components2;
ZeroMemory(&Components2, sizeof Components2);
Components2.dwStructSize = sizeof Components2;
if(!InternetCrackUrl(pszLocation, 0, 0, &Components2))
{
printf("Error: %d in line %d\n", GetLastError(), __LINE__);
//return 2;
}
TCHAR pszScheme[INTERNET_MAX_SCHEME_LENGTH];
TCHAR pszHostName[INTERNET_MAX_HOST_NAME_LENGTH];
TCHAR pszUserName[INTERNET_MAX_USER_NAME_LENGTH];
TCHAR pszPassword[INTERNET_MAX_PASSWORD_LENGTH];
TCHAR pszUrlPath[INTERNET_MAX_PATH_LENGTH];
TCHAR pszExtraInfo[INTERNET_MAX_URL_LENGTH];
URL_COMPONENTS Components3;
ZeroMemory(&Components3, sizeof Components3);
Components3.dwStructSize = sizeof Components3;
Components3.lpszScheme = pszScheme;
Components3.dwSchemeLength = INTERNET_MAX_SCHEME_LENGTH;
Components3.lpszHostName = pszHostName;
Components3.dwHostNameLength = INTERNET_MAX_HOST_NAME_LENGTH;
Components3.lpszUserName = pszUserName;
Components3.dwUserNameLength = INTERNET_MAX_USER_NAME_LENGTH;
Components3.lpszPassword = pszPassword;
Components3.dwPasswordLength = INTERNET_MAX_PASSWORD_LENGTH;
Components3.lpszUrlPath = pszUrlPath;
Components3.dwUrlPathLength = INTERNET_MAX_PATH_LENGTH;
Components3.lpszExtraInfo = pszExtraInfo;
Components3.dwExtraInfoLength = INTERNET_MAX_URL_LENGTH;
if(!InternetCrackUrl(pszLocation, 0, ICU_DECODE | ICU_ESCAPE,
&Components3))
{
printf("Error: %d in line %d\n", GetLastError(), __LINE__);
return 2;
}
return 0;
}
Roman Ryl...
2006-01-26 12:19:19 UTC
Permalink
Vladimir,

The problem was reported by our customer who uses our software (and we
work through WinInet API) and specified username with @, so we studied
the issue.

The actual problem is that FTP servers (and FTP server of this
particular customer) do accept user names with @ and so does even IE (I
believe through WinInet) if the @ character is escaped via %40. So I
expected InternetCreateUrl implementing proper escapement.

Roman
Scherbina Vladimir
2006-01-26 13:35:12 UTC
Permalink
Post by Roman Ryl...
The actual problem is that FTP servers (and FTP server of this
expected InternetCreateUrl implementing proper escapement.
Most likely InternetCreateUrl uses UrlEscape, that does not contain '@' in
it's list of escaped characters.

--
Vladimir
Roman Ryl...
2006-01-26 14:01:32 UTC
Permalink
Any suggestion how to properly embed username with @ into location
string?
Scherbina Vladimir
2006-01-26 15:53:48 UTC
Permalink
I guess, the only one way is left - to escape '@' manually...

--
Vladimir
Post by Roman Ryl...
string?
Loading...