$100 to anyone who can resolve this download problem.

M

MARTIN LANNY

I am sorry about the heading of this thread, but I spent so much time
(over two weeks now) trying to figure out this problem, that I am
willing to pay for the answer.

Problem I am having:
Can someone tell me how to download the remote file (or it's content)
using POST method (passing username and password to authenticate the
download) ?


Currently I have this funtion:

Public Function GetContent(ByVal URL As String) As String
Dim web As New System.Net.WebClient
Dim d As Byte() =
System.Text.Encoding.UTF8.GetBytes("username=joedoe&password=123456")
Dim res As Byte() = web.UploadData(URL, "POST", d)
GetContent = System.Text.Encoding.UTF8.GetString(res)
End Function

This funtion works fine if Url leads to regular page. In that case it
retrieves the content just fine.

But doesn't return anything if URL points to download file.

Can someone amend this code or give me a code for authenticated
download of file using POST method?

Martin


Whoever answer this, I will send $100 by paypal or any other method
person prefers.
 
H

Herfried K. Wagner [MVP]

MARTIN LANNY said:
Can someone tell me how to download the remote file (or it's content)
using POST method (passing username and password to authenticate the
download) ?

Currently I have this funtion:

Public Function GetContent(ByVal URL As String) As String
Dim web As New System.Net.WebClient
Dim d As Byte() =
System.Text.Encoding.UTF8.GetBytes("username=joedoe&password=123456")
Dim res As Byte() = web.UploadData(URL, "POST", d)
GetContent = System.Text.Encoding.UTF8.GetString(res)
End Function

This funtion works fine if Url leads to regular page. In that case it
retrieves the content just fine.

But doesn't return anything if URL points to download file.

The problem in your code is not the 'POST' request. I am not sure about the
reason why you don't receive any data. First, check if the byte array 'res'
contains any data. To do this, either set a breakpoint and watch its data
or check its 'Length' property afterwards. Maybe the data contains null
bytes which are interpreted as null characters by 'GetString' and thus not
shown when displaying the data in a textbox or message box. I have tested
the code with a server which redirects this request. In this case an
exception is thrown, so this is likely not the reason.

What type of file are you attempting to download? Are you sure it makes
sense to convert the data read from the response to a string?
 
M

MARTIN LANNY

Url itself doesn't show the name of the file.
If you were to go to this url with your webbrowser it would ask you for
the name and password (regular form).
Example: https://www.google.com/adsense/

After you fill this info, it would show you the prompt to save the
file.
And I need some routine to grab the content of this file or save it on
my local machine.
So far I am out of luck and no one seems to know how to grab file using
POST authentication.
Martin
 
H

Herfried K. Wagner [MVP]

MARTIN LANNY said:
Url itself doesn't show the name of the file.
If you were to go to this url with your webbrowser it would ask you for
the name and password (regular form).
Example: https://www.google.com/adsense/

Sure, I know what you are referring to.
After you fill this info, it would show you the prompt to save the
file.
And I need some routine to grab the content of this file or save it on
my local machine.
So far I am out of luck and no one seems to know how to grab file using
POST authentication.

Check out <URL:http://dotnet.mvps.org/download/>. The ASP.NET script will
accept 'POST' authentication and return a small PDF file as
'application/pdf'. It only accepts the authentication data you provided in
your post:

User name: joedoe
Password: 123456

Test code:

\\\
Public Function GetContent(ByVal Url As String) As String
Dim web As New WebClient
Dim d As Byte() = _
Encoding.UTF8.GetBytes("username=joedoe&password=123456")
Dim res As Byte() = web.UploadData(URL, "POST", d)
Return Encoding.UTF8.GetString(res)
End Function
..
..
..
MsgBox(GetContent("http://dotnet.mvps.org/download/"))
///

The sample code above just works file, as does the 'POST' form-based
authentication.
 
H

Herfried K. Wagner [MVP]

MARTIN LANNY said:
I know, it works fine for pages, not for download files. And that is my
whole problem.
If you point GetContent to http://blah.com/page.html it is working
fine.
If you point GetContent to http://blah.com/page.csv it is not working.

I doubt that the CSV file allows authentication through 'POST'. You'll have
to authenticate on the login page and preserve the authentication in a
cookie. This can be done by using the 'CookieContainer' class to keep the
session alive until you have downloaded the protected file. The code below
demonstrates how to download AdSense's statistics overview page by using
this technique:

\\\
Dim Request As HttpWebRequest = _
DirectCast( _
HttpWebRequest.Create("https://www.google.com/adsense/login.do"), _
HttpWebRequest _
)
Dim Cookies As New CookieContainer()
With Request
.CookieContainer = Cookies
.Method = "POST"
.ContentType = "application/x-www-form-urlencoded"
End With
Dim Writer As New StreamWriter(Request.GetRequestStream())
Writer.Write("username=#####&password=#####")
Writer.Close()
Request.GetResponse().Close()
Request = _
DirectCast( _
WebRequest.Create("https://www.google.com/adsense/report/overview"),
_
HttpWebRequest _
)
Request.CookieContainer = Cookies
Dim Response As Stream = Request.GetResponse().GetResponseStream()
Dim Reader As New StreamReader(Response)
Writer = New StreamWriter("C:\report.html")
Writer.Write(Reader.ReadToEnd())
Reader.Close()
///

BTW: If this works and if you really want to send me a thank-you, please
contact me at the address referenced by the "Netzpost" link on
<URL:http://dotnet.mvps.org/meta/author/#Contact>. Thank you :).
 
J

John Veldthuis

User name: joedoe
Password: 123456

Test code:

\\\
Public Function GetContent(ByVal Url As String) As String
Dim web As New WebClient
Dim d As Byte() = _
Encoding.UTF8.GetBytes("username=joedoe&password=123456")
Dim res As Byte() = web.UploadData(URL, "POST", d)
Return Encoding.UTF8.GetString(res)
End Function
.
.
.
MsgBox(GetContent("http://dotnet.mvps.org/download/"))
///

The sample code above just works file, as does the 'POST' form-based
authentication.

Does not work for me!

Comes up with an error for the object.
I am trying to read in a https web page (no trouble reading the page
at all), then post back the user name and password, and then finally
get the redirected result page back into a string so that I can parse
it for the information I want.

No trouble with the first part of reading the page but in no way can I
get the rest to work. I have tried 4 different ways based on different
code I have found now.
 
H

Herfried K. Wagner [MVP]

John Veldthuis said:
I am trying to read in a https web page (no trouble reading the page
at all), then post back the user name and password, and then finally
get the redirected result page back into a string so that I can parse
it for the information I want.

No trouble with the first part of reading the page but in no way can I
get the rest to work. I have tried 4 different ways based on different
code I have found now.

Could you post some code? I tested the scenario you described and the
'WebClient' object's 'UploadData' method returns the data of the file which
the server redirected the request to.
 
J

John Veldthuis

Could you post some code? I tested the scenario you described and the
'WebClient' object's 'UploadData' method returns the data of the file which
the server redirected the request to.

Okay at the bottom is the first Webpage that is returned and is the login page for the web page.
This is the data returned by the first read.

The code I use to try and read this that I think should work is

Private Function GetHTML(ByVal URL As String, Optional ByVal TimeOut As Integer = 10) As String

Dim cookieJar As CookieContainer = New CookieContainer
Dim payload As String
Dim webReq As HttpWebRequest
Dim webReps As WebResponse
Dim sr As StreamReader
Dim sw As StreamWriter
Dim txt As String
Try
' Set up our web request

webReq = CType(WebRequest.Create(New Uri(URL)), HttpWebRequest)
webReq.CookieContainer = cookieJar
webReq.Credentials = CredentialCache.DefaultCredentials
webReq.UserAgent = "BGClient"
webReq.KeepAlive = True
webReq.Headers.Set("Pragma", "no-cache")
webReq.Timeout = TimeOut * 1000
webReq.Method = "GET"
webReps = webReq.GetResponse
sr = New StreamReader(webReps.GetResponseStream)
txt = sr.ReadToEnd
sr.Close()
webReps.Close()
webReq = CType(WebRequest.Create(New Uri(URL)), HttpWebRequest)
webReq.CookieContainer = cookieJar
webReq.Credentials = CredentialCache.DefaultCredentials
webReq.UserAgent = "BGClient"
webReq.KeepAlive = True
webReq.Headers.Set("Pragma", "no-cache")
webReq.Timeout = TimeOut * 1000
webReq.Method = "POST"
webReq.ContentType = "application/x-www-form-urlencoded"
payload = "[email protected]&pass=passw&c&usagelogin=Submit"
webReq.ContentLength = payload.Length
sw = New StreamWriter(webReq.GetRequestStream)
sw.write(payload)
sw.close()
webReps = webReq.GetResponse
sr = New StreamReader(webReps.GetResponseStream)
txt = sr.ReadToEnd.Trim
Debug.WriteLine(txt)
sr.Close()
webReps.Close()
GetHTML = txt
Catch
Return String.Empty
End Try
End Function

fquid is the username below and pass is the password. These are what I have seen passed thru IE
using IEHeaders to check. As I said I can read the first part but the second part of the sending the
username/password and getting the proper redirected page back fails.




<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<HEAD>
<TITLE>Login to TelstraClear HighSpeed Internet Usage
Meter</TITLE>
<META NAME="Keywords" CONTENT="login, authentication">
<META NAME="Description" CONTENT="Form to login to
TelstraClear HighSpeed Internet usage meter.">
<script>
function checkForm(theForm){
var err = "";
var u = trimString(theForm.fquid.value);
var p = trimString(theForm.pass.value);
if (u.length == 0){
err = err + "- Username cannot be empty!";
}
if (p.length == 0){
err = err + "\n- Password cannot be empty!";
}
if (err.length != 0)
{
alert(err);
return false;
}
else
{
return true;
}
}


function trimString(theString) {
while (theString.charAt(0) == " ") {
theString =
theString.substring(1,theString.length);
}
while (theString.charAt(theString.length - 1) == " ")
{
theString =
theString.substring(0,theString.length - 1);
}
return theString;
}
</script>
</head>


<body bgcolor="ffffff"
onLoad="document.forms.loginForm.fquid.focus();">

<form name="loginForm" method="POST" action="/usagemeter/index.cfm"
onSubmit="return checkForm(this)">

<img src="images/dot-clear.gif" width=1 height=1 vspace=2> <br>

<table align="center" cellpadding=2 cellspacing=0 border=0
bgcolor="#999999">
<tr>
<td>
<table cellpadding=5 cellspacing=0 border=0 bgcolor="#f0f0f0">
<tr><td><font face="Arial, Helvetica" size=2
color="#666666"><b>Welcome to TelstraClear HighSpeed Internet Usage
Meter. Please Login.</b></font> </td></tr>

<tr>
<td align="center">
<font face="Arial, Helvetica" size=2
color="#666666"><b>User
Name</b><br>([email protected])</font><br>
<input type="text" name="fquid" maxlength="50"
size="30" value=""><br>
<img src="images/dot-clear.gif" width=1
height=1 vspace=2><br>
<font face="Arial, Helvetica" size=2
color="#666666"><b>Password</b></font><br>
<input type="password" name="pass"
maxlength="30" size="30" value=""><br>
<img src="images/dot-clear.gif" width=1
height=1 vspace=2><br>
<INPUT type="Hidden" name="s" value="c">
<input type="submit" name="usagelogin"
value="Submit">
</td>
</tr>
</table>
</td>
</tr>
</table>

</form>


</body>
</html>
 
H

Herfried K. Wagner [MVP]

John Veldthuis said:
Could you post some code? I tested the scenario you described and the
'WebClient' object's 'UploadData' method returns the data of the file
which
the server redirected the request to.

Okay at the bottom is the first Webpage that is returned and is the login
page for the web page.
This is the data returned by the first read.

The code I use to try and read this that I think should work is

Private Function GetHTML(ByVal URL As String, Optional ByVal TimeOut As
Integer = 10) As String

Dim cookieJar As CookieContainer = New CookieContainer
Dim payload As String
Dim webReq As HttpWebRequest
Dim webReps As WebResponse
Dim sr As StreamReader
Dim sw As StreamWriter
Dim txt As String
Try
' Set up our web request

webReq = CType(WebRequest.Create(New Uri(URL)), HttpWebRequest)
webReq.CookieContainer = cookieJar
webReq.Credentials = CredentialCache.DefaultCredentials
webReq.UserAgent = "BGClient"
webReq.KeepAlive = True
webReq.Headers.Set("Pragma", "no-cache")
webReq.Timeout = TimeOut * 1000
webReq.Method = "GET"
webReps = webReq.GetResponse
sr = New StreamReader(webReps.GetResponseStream)
txt = sr.ReadToEnd
sr.Close()
webReps.Close()
webReq = CType(WebRequest.Create(New Uri(URL)), HttpWebRequest)
[...]
<form name="loginForm" method="POST" action="/usagemeter/index.cfm"

Are you sure you are directing the login request to <URL:http://<domain
name>/usagemeter/index.cfm>, which is the actual login script?
 
M

MARTIN LANNY

Herfried K. Wagner,
I want to kiss you man. :)
It seems to work. I am coding it in. Once done and it all works, I will
send you $100.
Please send your paypal email address to my email: newsbackup at gmail
dot com
Thanks a lot for everything...
Gosh... I am so happy, after so many days of trying this out...
jeeez...
Thanks
Martin
 
C

Cor Ligthert [MVP]

Martin,

In my personal opinion this is not a good situation if people start giving
money for solutions in this newsgroup. (My idea was that you were joking)

If somebody would write I donate $100 dollar to by instance the Katrina fund
and he does, than it would in my opinion be an even better stimulanse to
help you. Although I never have seen that it is needed when somebody is
really in trouble and tells that.

However just my personal opinion.

Cor
 
H

Herfried K. Wagner [MVP]

Martin,

MARTIN LANNY said:
It seems to work. I am coding it in. Once done and it all works, I will
send you $100.

Thank you :).

If you have any further questions related to this topic, feel free to post
them.
 
H

Herfried K. Wagner [MVP]

Cor,

Cor Ligthert said:
If somebody would write I donate $100 dollar to by instance the Katrina
fund and he does, than it would in my opinion be an even better stimulanse
to help you. Although I never have seen that it is needed when somebody is
really in trouble and tells that.

I agree with you that people should be encouraged to spend money for victims
of Katrina. However, this doesn't mean that all people should spend all the
money they earn for those people. Imagine how many people here get help for
free and thus have more money to spend for poor people. I don't think that
a single excuse is such a big problem. Don't forget that I am a poor
student who doesn't earn any money!

Just my 2 Euro cents...
 
M

MARTIN LANNY

Herfried K. Wagner,

thanks for all your help.
I just sent you $100 to your paypal address, as a gesture of
appreciation of the help you provided in .NET newsgroups.You really
helped me a lot and fixed the problem on which I spent countless hours.

Thanks once again.
Martin

To all others: I understand your concern and I know there is many
different ways person can thank for a good deed.
But Herfriend helped me in the past already and I promised I will send
the cash to person who will solve the problem.
Btw. I do support Canadian Red Cross already.
 
B

BeeF

Glad to see a soloution for you Martin
Not too sure though on the way that it went about, kind of side with Cor on
this.
Although Herfried "I am a poor
student who doesn't earn any money!" Good luck to you.
If it not in the guidelines of the newsgroup or code of conduct, which I am
sure you are all well aware of then I don't see the hassle. Perhaps though
it should be because I could not afford $100 per soloution. But I guess
there the incentive to learn more before asking for help.
 
H

Herfried K. Wagner [MVP]

BeeF said:
Perhaps though it should be because I could not afford $100 per
soloution.

This doesn't matter. If I have a solution to your question, I'll post it
:).
 
J

John Veldthuis

Are you sure you are directing the login request to <URL:http://<domain
name>/usagemeter/index.cfm>, which is the actual login script?

Okay, thanks for the hint. I checked again by single stepping all the why through the function and
found this time that the return page was an error page. I double checked what I was suppose to send
and I actually missed one of the parameters.

Added the parameter in and I get back what I expect. Thanks for your hint as it was driving me mad
knowing it should work and not working out why it did not.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top