I'm trying to connect to a sftp server and I don't get any exception or timeout, only increasing memory usage.
I am using the library EnterpriseDT.Net.Ftp
My code is like this:
XmlConfigurator.Configure();
Module1.Logger = LogManager.GetLogger("SftpTester");
try
{
Module1.Logger.Info((object) "[EnterpriseDT] - Start");
Uri uri1 = new Uri("ftp://*****");
// ISSUE: explicit reference operation
// ISSUE: variable of a reference type
Uri& uri2 = #uri1;
int port = ****;
string str1 = "******";
// ISSUE: explicit reference operation
// ISSUE: variable of a reference type
string& UserName = #str1;
string str2 = "*******";
// ISSUE: explicit reference operation
// ISSUE: variable of a reference type
string& Password = #str2;
SecureFTPConnection secureFtpConnection = Module1.InitConnection(uri2, port, UserName, Password);
Module1.Logger.Info((object) "Connecting to ftp...");
secureFtpConnection.Connect();
Module1.Logger.Info((object) "Connection Successful!!!");
try
{
Module1.Logger.Info((object) "Disposing connection...");
secureFtpConnection.Dispose();
}
catch (Exception ex)
{
ProjectData.SetProjectError(ex);
ProjectData.ClearProjectError();
}
Module1.Logger.Info((object) "Connection Disposed.");
}
catch (Exception ex)
{
ProjectData.SetProjectError(ex);
Exception exception = ex;
Module1.Logger.Error((object) ("Main() - " + exception.Message));
Module1.Logger.Error((object) ("StackTrace: " + exception.StackTrace));
if (exception.InnerException != null)
Module1.Logger.Error((object) ("InnerException: " + exception.InnerException.Message));
ProjectData.ClearProjectError();
}
finally
{
Module1.Logger.Info((object) "[EnterpriseDT] - End");
}
private static SecureFTPConnection InitConnection(ref Uri uri, int port, ref string UserName = "", ref string Password = "")
{
Module1.Logger.Info((object) "InitConnection() - Setting Up Connection");
SecureFTPConnection secureFtpConnection = new SecureFTPConnection();
secureFtpConnection.LicenseOwner = "*******";
secureFtpConnection.LicenseKey = "***********";
secureFtpConnection.ServerAddress = uri.Host;
Module1.Logger.Info((object) ("\tHost: " + uri.Host));
secureFtpConnection.UserName = UserName;
Module1.Logger.Info((object) ("\tUsername: " + UserName));
secureFtpConnection.Protocol = FileTransferProtocol.SFTP;
Module1.Logger.Info((object) ("\tProtocol: " + FileTransferProtocol.SFTP.ToString()));
secureFtpConnection.ServerValidation = SecureFTPServerValidationType.None;
Module1.Logger.Info((object) ("\tServerValidation: " + SecureFTPServerValidationType.None.ToString()));
secureFtpConnection.AuthenticationMethod = AuthenticationType.Password;
Module1.Logger.Info((object) ("\tAuthenticationMethod: " + AuthenticationType.Password.ToString()));
if (port > 0)
{
secureFtpConnection.ServerPort = port;
Module1.Logger.Info((object) ("\tServerPort: " + port.ToString()));
}
secureFtpConnection.Password = Password;
Module1.Logger.Info((object) ("\tPassword: " + Password));
return secureFtpConnection;
}
Log message:
2014-09-27 04:50:22,783 [1] - [SftpTester] [EnterpriseDT] - Start
2014-09-27 04:50:22,799 [1] - [SftpTester] InitConnection() - Setting Up Connection
2014-09-27 04:50:22,971 [1] - [SftpTester] Host: *******
2014-09-27 04:50:22,971 [1] - [SftpTester] Username: *****
2014-09-27 04:50:22,971 [1] - [SftpTester] Protocol: SFTP
2014-09-27 04:50:22,971 [1] - [SftpTester] ServerValidation: None
2014-09-27 04:50:22,971 [1] - [SftpTester] AuthenticationMethod: Password
2014-09-27 04:50:22,971 [1] - [SftpTester] ServerPort: ****
2014-09-27 04:50:22,971 [1] - [SftpTester] Password: ******
2014-09-27 04:50:22,971 [1] - [SftpTester] Connecting to ftp...
Any idea if this is a timeout error or if I am in a blacklist?
Update 07/10/2014
Sequence for server:
Password authentication
Waiting for packet
Packet arrived
Auth partial success. Try: password, publickey, keyboard-interactive
Keyboard interactive authentication
Waiting for packet
Packet arrived
Prompt: Password:
Waiting for packet
Packet arrived
Auth partial success. Try: password, publickey, keyboard-interactive
Waiting for packet
Packet arrived
Prompt: Password:
Loop (9 to 15)
update
Updating the library solve the problem, was a bug.
Version 8.6.1
(23 Sep 2014)
Fixed kbi re-entrant bug that causes a loop of authentication attempts.
Fixed SFTP bug where an exception wasn't thrown when uploading a file to a non-existent directory.
Fixed SFTP problem where an OpenVMS SFTP server wasn't being recognized as SSH.
Fixed retry download problem where only one reconnect was made.
Fixed "Attempted to read or write protected memory" issue on some 2012 R2 machines using FTPS.
Your code looks ok. There is nothing special about it. The first thing you should do is enable Debug logging in the library, since you don't have enough information about the execution of your FTP code.
You can enable Debug with the following statement:
EnterpriseDT.Util.Debug.Logger.CurrentLevel = EnterpriseDT.Util.Debug.Level.DEBUG;
By default it will print debug info in the Console. you can use a custom appender (file, db etc.) if you like. The Debug info will give you much more information about the issue.
Any idea about if is a timeout error?
I don't think so. There is a client timeout set to 120000ms in the library by default. The Server timeouts are probably much higher. I don't think it is a timeout issue.
Am in a blacklist?
Maybe, but again that shouldn't hang an FTP client.
Why there is No message or timeout then?
Hangs could be caused by improper FTP Server or Firewall config. EnterpriseDT.Net.Ftp uses FTP Passive mode by default like most FTP clients. I would suggest checking your FTP server and firewall configuration and check everything is configured properly for Passive mode.
If your FTP Server is configured properly, you should be able to connect to it from any FTP client. You can try FileZilla or any other client, just to make sure your server is setup correctly. That way you will rule out any firewall or FTP server issues.
Update:
From what we see so far in the log it is an Auth issue. Looks like the SSH server supports password, publickey and keyboard-interactive auth.
My interpretation of your log above is that your SFTP client is trying to authenticate with the following methods in this exact order:
Try: password, publickey, keyboard-interactive
Password authentication (the default in your code) doesn't go through (wrong password?) and then the client switches to Keyboard authentication and that's why you are getting a password prompt in SSH, and the SFTP library is not able to handle that scenario, since you are not including a prompt response.
To fix that you should check out the SSHAuthPrompt class in the library, and include the prompt answer with the password in your code using the KBIPrompts property on the SecureFTPConnection class:
http://www.enterprisedt.com/products/edtftpnetpro/doc/manual/api/html/T_EnterpriseDT_Net_Ftp_Ssh_SSHAuthPrompt.htm
This class has two params in the constructor. The prompt should match what you are getting from KBI, and that should be 'Password:', the response value should be the password.
You should also try configuring the AuthenticationMode to KeyboardInteractive.
Related
I am using Windows authentication in a Webforms application, and I want to get the user's email address, but I think I hit the error when connecting to the server. Anything wrong with my code?
I had tried the strAccountId with/without domain name, (sAMAccountName=john).
The server is not operational.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.COMException: The server is not operational
Code:
string path = "LDAP://XYZ.LOCAL/CN=XYZ.LOCAL,OU=XXX,DC=XYZ,DC=LOCAL";
// The value of User.Identity.Name is XYZ\john
string strAccountId = "XYZ\\john";
string strPassword = "xxxxx";
bool bSucceeded;
string strError;
DirectoryEntry adsEntry = new DirectoryEntry(path, strAccountId, strPassword);
DirectorySearcher adsSearcher = new DirectorySearcher(adsEntry);
adsSearcher.Filter = "(sAMAccountName=" + strAccountId + ")";
try
{
SearchResult adsSearchResult = adsSearcher.FindOne();
bSucceeded = true;
strError = "User has been authenticated by Active Directory.";
EmailMsg.Text = strError;
adsEntry.Close();
}
catch (Exception ex)
{
bSucceeded = false;
strError = ex.Message;
EmailMsg.Text = strError;
adsEntry.Close();
}
In path you cannot put OUs, you need to do that after with adsEntry.Path.
string path = "LDAP://XYZ.LOCAL";
string strAccountId = "XYZ.LOCAL\\john";
string strPassword = "xxxxx";
DirectoryEntry adsEntry = new DirectoryEntry(path, strAccountId, strPassword);
adsEntry.Path = "LDAP://CN=XYZ.LOCAL,OU=XXX,DC=XYZ,DC=LOCAL";
Your path has three parts:
LDAP:// is the protocol
XYZ.LOCAL is the server to connect to. This is optional and can be excluded if the computer you run this from is joined to the same domain you're trying to connect to, or to a trusted domain.
CN=XYZ.LOCAL,OU=XXX,DC=XYZ,DC=LOCAL is the object on the domain to bind to. This is also optional. If excluded, it will bind to the root of the domain that the server in part 2 is part of. You must include either part 2 or 3, or both.
Since you have included the optional server name, it will try to connect to XYZ.LOCAL on the default LDAP port 389. "The server is not operational" means that it could not open a connection to XYZ.LOCAL on port 389. This is a network error and you need to figure out why the domain is not accessible from the computer you are running this from.
You can test the connection in PowerShell using:
Test-NetConnection XYZ.LOCAL -Port 389
Im trying to make a TLS/SSL websocket connection using Fleck lib.
https://github.com/statianzo/Fleck (0.9.8.25)
now i got the server startet .
but when a client connects i get the following message.
28-02-2014 19:16:15 [Info] Server started at wss://localhost:8081
28-02-2014 19:18:51 [Debug] Client connected from 127.0.0.1:62543
28-02-2014 19:18:51 [Debug] Authenticating Secure Connection
28-02-2014 19:18:52 [Debug] 0 bytes read. Closing.
anybody got an idea of what im doing wrong ?
Browser: Chrome, version : 33.0.1750.117
// sample code.
FleckLog.Level = LogLevel.Debug;
var allSockets = new List<IWebSocketConnection>();
var server = new WebSocketServer("wss://localhost:8081");
server.Certificate = new X509Certificate2(#"CRT.pfx", "Pwd");
server.Start(socket =>
{
socket.OnOpen = () =>
{
Console.WriteLine("Open!");
allSockets.Add(socket);
};
socket.OnClose = () =>
{
Console.WriteLine("Close!");
allSockets.Remove(socket);
};
socket.OnMessage = message =>
{
foreach (var user in allSockets.ToList())
{
if(user.ConnectionInfo.Id != socket.ConnectionInfo.Id){
user.Send(message);
}
}
};
});
var input = Console.ReadLine();
while (input != "exit")
{
foreach (var socket in allSockets.ToList())
{
socket.Send(input);
}
input = Console.ReadLine();
}
Is certificate signed by a browser trusted CA? If not, the web page you are opening with Chrome has to be under HTTPS so you can be prompted to accept the certificate, otherwise the connection will fail.
If even doing that does not work, please try with WebSocketListener and tell me which error you get if any.
Some issues I found debugging WSS:
Remember to change the port number to a one different to the one you used for not secure connections. Some browsers get confused if suddenly a port becomes secure or viceversa.
Remember to use the hostname indicated in the certificate to connect and not the IP.
If you are using a self-signed certificate, use it for HTTPS so you can see the dialog for accepting that certificate. When accessing via WSS:// there is not certificate acceptance dialog, it will just fail to connect.
Try with a self-signed certificate as well and see if it works.
I am trying to set up apple push notifications, i am writing my own code for the server and as far as i know i have set up the app correctly. How ever i keep getting the following error come back from the log:
Payload queue received. Connecting to apple server. Creating SSL
connection. Conected. Payload generated for
"Token goes here i deleted it :
{"aps":{"alert":"test","badge":1,"sound":"default"}} Notification
successfully sent to APNS server for Device Toekn :
"Token here I've deleted it" An
error occurred while reading Apple response for token
"Token here I've deleted it" -
Input string was not in a correct format. Disconnected
This is my code.
var push = new PushNotification(true, #"C:\wwwroot\UltraNet\PushService\bin\Debug\206dist.p12", "ultrait");
var payload = new NotificationPayload("devicetoken here ive deleted it", "test", 1, "default");
var p = new List<NotificationPayload> { payload };
var result = push.SendToApple(p);
Console.ReadLine();
I have made sure that the certificates etc are set up correctly.
I am testing it as a adhoc app at the moment because it takes so long for a new version to be able to go live.
I really don't know where I'm going wrong if any one could help it would be brilliant thank you.
I also don't know what i need to do with the PEM files that i have created.
Edit***
I have the correct token this is another error that i receive
Payload generated for
df99286a1cb993cecba86b2e21f3fc4c04d214fcf7e0cf35a668fc822bdaa053 :
{"aps":{"alert":"test","badge":1,"sound":"default"}} Notification
successfully sent to APNS server for Device Toekn :
df99286a1cb993cecba86b2e21f3fc4c04d214fcf7e0cf35a668fc822bdaa053
Disconnected. An error occurred while reading Apple response for token
df99286a1cb993cecba86b2e21f3fc4c04d214fcf7e0cf35a668fc822bdaa053 -
Safe handle has been closed
Based on the code of ReadResponse (see below), the Input string was not in a correct format error message refers to the response received from Apple, and not to the notification you sent.
The code failed to properly read the error response from Apple.
Had it succeeded in reading the response, you would have known what the exact failure was and which message failed. Since you don't have the error response, it's a safe bet to assume the problem is your device token. That's the most common failure. If you can isolate the device token for which the error occurs, you should simply delete that token from your DB. Invalid Device Token error often occurs when you try to use sandbox tokens when pushing to production environment or vica versa.
private void ReadResponse(IAsyncResult ar)
{
if (!_conected)
return;
string payLoadId = "";
int payLoadIndex = 0;
try
{
var info = ar.AsyncState as MyAsyncInfo;
info.MyStream.ReadTimeout = 100;
if (_apnsStream.CanRead)
{
var command = Convert.ToInt16(info.ByteArray[0]);
var status = Convert.ToInt16(info.ByteArray[1]);
var ID = new byte[4];
Array.Copy(info.ByteArray, 2, ID, 0, 4);
payLoadId = Encoding.Default.GetString(ID);
payLoadIndex = ((int.Parse(payLoadId)) - 1000);
Logger.Error("Apple rejected palyload for device token : " + _notifications[payLoadIndex].DeviceToken);
Logger.Error("Apple Error code : " + _errorList[status]);
Logger.Error("Connection terminated by Apple.");
_rejected.Add(_notifications[payLoadIndex].DeviceToken);
_conected = false;
}
}
catch (Exception ex)
{
Logger.Error("An error occurred while reading Apple response for token {0} - {1}", _notifications[payLoadIndex].DeviceToken, ex.Message);
}
}
It was all to do with my certificates.
Because i hadn't turnt my combined PEM certificate back to a p12 file.
I'm trying to connect to an LDAP server which requires StartTLS, but having no luck - whenever I use either the SessionOptions.StartTransportLayerSecurity(..) or set SessionOptions.SecureSocketLayer to true, I get exceptions.
Here's the code I'm using:
using (var connection = new LdapConnection(new LdapDirectoryIdentifier(config.LdapServer, config.Port, false, false)))
{
connection.SessionOptions.ProtocolVersion = 3;
connection.Credential = new NetworkCredential(config.BindDN, config.BindPassword);
connection.SessionOptions.VerifyServerCertificate += (conn, cert) => {return true;};
connection.AuthType = AuthType.Basic;
//connection.SessionOptions.SecureSocketLayer = true;
connection.SessionOptions.StartTransportLayerSecurity(null); // throws here, same if done after bind.
connection.Bind();
... do stuff with connection
}
The resulting exception is "TlsOperationException: An unspecified error occurred", which happens when invoking the StartTransportLayerSecurity method.
I've tested the code against both and OpenLDAP server and Active Directory, but neither works.
Does anyone know how to get StartTLS working with System.DirectoryServices?
There used to be a fair amount of subtle LDAP stack incompatibilities in the wild, which could still apply to the potentially legacy scenario your customer might be using.
The following are the most commonly encountered issues regarding incompatibilities between OpenLDAP and Microsoft's LDAP stack (I'll amend and/or replace these links once more info is available):
The OpenLDAP StartTLS issues (ITS#3037) (summarized in On getting OpenLDAP and Windows LDAP to interop) have triggered a respective hotfix:
You cannot send Start TLS requests from a computer that is running Windows Server 2003 or Windows XP or Windows Vista to a server that is running OpenLDAP Software
An extended operation that is sent to an LDAP server by API over the LDAP service causes a protocol error
Obviously, updating either OpenLDAP and/or Windows (ideally both of course) should remedy these issues, if they turn out to be the culprit here.
Good luck!
Please read this topic:
Binding over a TLS/SSL Encrypted Connection
Example 19. Binding to an ADAM instance on secure port 50001 using Basic authentication and SSL/TLS
string hostNameAndSSLPort = "sea-dc-02.fabrikam.com:50001";
string userName = "cn=User1,cn=AdamUsers,cn=ap1,dc=fabrikam,dc=com";
string password = "adamPassword01!";
// establish a connection
LdapConnection connection = new LdapConnection(hostNameAndSSLPort);
// create an LdapSessionOptions object to configure session
// settings on the connection.
LdapSessionOptions options = connection.SessionOptions;
options.ProtocolVersion = 3;
options.SecureSocketLayer = true;
connection.AuthType = AuthType.Basic;
NetworkCredential credential =
new NetworkCredential(userName, password);
connection.Credential = credential;
try
{
connection.Bind();
Console.WriteLine("\nUser account {0} validated using " +
"ssl.", userName);
if (options.SecureSocketLayer == true)
{
Console.WriteLine("SSL for encryption is enabled\nSSL information:\n" +
"\tcipher strength: {0}\n" +
"\texchange strength: {1}\n" +
"\tprotocol: {2}\n" +
"\thash strength: {3}\n" +
"\talgorithm: {4}\n",
options.SslInformation.CipherStrength,
options.SslInformation.ExchangeStrength,
options.SslInformation.Protocol,
options.SslInformation.HashStrength,
options.SslInformation.AlgorithmIdentifier);
}
}
catch (LdapException e)
{
Console.WriteLine("\nCredential validation for User " +
"account {0} using ssl failed\n" +
"LdapException: {1}", userName, e.Message);
}
catch (DirectoryOperationException e)
{
Console.WriteLine("\nCredential validation for User " +
"account {0} using ssl failed\n" +
"DirectoryOperationException: {1}", userName, e.Message);
}
And the next example show "How to use TLS to authenticate and perform a task"
string hostOrDomainName = "fabrikam.com";
string userName = "user1";
string password = "password1";
// establish a connection to the directory
LdapConnection connection = new LdapConnection(hostOrDomainName);
NetworkCredential credential =
new NetworkCredential(userName, password, domainName);
connection.Credential = credential;
connection.AuthType = AuthType.Basic;
LdapSessionOptions options = connection.SessionOptions;
options.ProtocolVersion = 3;
try
{
options.StartTransportLayerSecurity(null);
Console.WriteLine("TLS started.\n");
}
catch (Exception e)
{
Console.WriteLine("Start TLS failed with {0}",
e.Message);
return;
}
try
{
connection.Bind();
Console.WriteLine("Bind succeeded using basic " +
"authentication and SSL.\n");
Console.WriteLine("Complete another task over " +
"this SSL connection");
TestTask(hostName);
}
catch (LdapException e)
{
Console.WriteLine(e.Message);
}
try
{
options.StopTransportLayerSecurity();
Console.WriteLine("Stop TLS succeeded\n");
}
catch (Exception e)
{
Console.WriteLine("Stop TLS failed with {0}", e.Message);
}
Console.WriteLine("Switching to negotiate auth type");
connection.AuthType = AuthType.Negotiate;
Console.WriteLine("\nRe-binding to the directory");
connection.Bind();
// complete some action over this non-SSL connection
// note, because Negotiate was used, the bind request
// is secure.
// run a task using this new binding
TestTask(hostName);
After a bit more work on this issue I found that I was running up against a couple of issues:
There was a bug in the code where the port number was being incorrectly changed to the SSL port (636) when connecting to AD in our test suite (doh!).
The OpenLDAP test server (that was a replica of our customers) was using openldap-2.4.18 - which has known issues with StartTLS.
After applying a patch to OpenLDAP (as discussed here - http://www.openldap.org/lists/openldap-bugs/200405/msg00096.html) we were able to fix #2 - at which point we started getting a different error "A local error occurred".
Though originally we had this code:
connection.SessionOptions.VerifyServerCertificate
+= (conn, cert) => {return true;};
We had removed it while testing, and because the OpenLDAP server was using a self-signed cert, that was not in a trusted store. Re-introducing that callback resolved this issue, though we now make it a configurable option i.e. "Verify Server Certificate Y/N" so customers need to opt into skipping the check (mostly for our QA team to use).
Thanks Steffen for pointing me in the direction of OpenLDAP versions which lead me to this solution.
I have the following code running in a windows service:
WebClient webClient = new WebClient();
webClient.Credentials = new NetworkCredential("me", "12345", "evilcorp.com");
webClient.DownloadFile(downloadUrl, filePath);
Each time, I get the following exception
{"The remote server returned an error: (401) Unauthorized."}
With the following inner exception:
{"The function requested is not supported"}
I know for sure the credentials are valid, in fact, if I go to downloadUrl in my web browser and put in my credentials as evilcorp.com\me with password 12345, it downloads fine.
What is weird though is that if I specify my credentials as me#evilcorp.com with 12345, it appears to fail.
Is there a way to format credentials?
webClient.UseDefaultCredentials = true; resolved my issue.
Apparently the OS you are running on matters, as the default encryption has changed between OSes.
This blog has more details: http://ferozedaud.blogspot.com/2009/10/ntlm-auth-fails-with.html
This has apparently also been discussed on stackoverflow here: 407 Authentication required - no challenge sent
I would suggest read the blog first as the distilled knowledge is there.
According to the msdn docs the exception could be because the method has been called simultaneously on multiple threads. The DownloadFile method also requires a completely qualified URL such as http://evilcorp.com/.
For me, 'webClient.UseDefaultCredentials = true;' solves it only on local, not in the web app on the server connecting to another server. I couldn't add the needed credential into Windows as a user, but I found later some programming way - I won't test it as I already made own solution. And also I don't want to mangle with the web server's registry, even if I have the needed admin rights. All these problems are because of the Windows internal handling of the NTLM authentication ("Windows Domain") and all of libraries and frameworks built over that (e.g. .NET).
So the solution for me was quite simple in idea - create a proxy app in a multiplatform technology with a multiplatform NTLM library where the NTLM communication is created by hand according to the public specs, not by running the built-in code in Windows. I myself chose Node.js and the httpntlm library, because it's about only one single source file with few lines and calling it from .NET as a program returning the downloaded file (also I prefer transferring it through the standard output instead of creating a temporary file).
Node.js program as a proxy to download a file behind the NTLM authentication:
var httpntlm = require('httpntlm'); // https://github.com/SamDecrock/node-http-ntlm
//var fs = require('fs');
var login = 'User';
var password = 'Password';
var domain = 'Domain';
var file = process.argv.slice(2); // file to download as a parameter
httpntlm.get({
url: 'https://server/folder/proxypage.aspx?filename=' + file,
username: login,
password: password,
workstation: '',
domain: domain,
binary: true // don't forget for binary files
}, function (err, res/*ponse*/) {
if (err) {
console.log(err);
} else {
if (res.headers.location) { // in my case, the server redirects to a similar URL,
httpntlm.get({ // now containing the session ID
url: 'https://server' + res.headers.location,
username: login,
password: password,
workstation: '',
domain: domain,
binary: true // don't forget for binary files
}, function (err, res) {
if (err) {
console.log(err);
} else {
//console.log(res.headers);
/*fs.writeFile("434980.png", res.body, function (err) { // test write
if (err) // to binary file
return console.log("Error writing file");
console.log("434980.png saved");
});*/
console.log(res.body.toString('base64')); // didn't find a way to output
} // binary file, toString('binary')
}); // is not enough (docs say it's
// just 'latin1')...
} else { // if there's no redirect
//console.log(res.headers); // ...so I output base64 and
console.log(res.body.toString('base64')); // convert it back in the caller
} // code
}
});
.NET caller code (the web app downloading files from a web app on another server)
public static string ReadAllText(string path)
{
if (path.StartsWith("http"))
return System.Text.Encoding.Default.GetString(ReadAllBytes(path));
else
return System.IO.File.ReadAllText(path);
}
public static byte[] ReadAllBytes(string path)
{
if (path.StartsWith("http"))
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "node.exe"; // Node.js installs into the PATH
psi.Arguments = "MyProxyDownladProgram.js " +
path.Replace("the base URL before the file name", "");
psi.WorkingDirectory = "C:\\Folder\\With My\\Proxy Download Program";
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
Process p = Process.Start(psi);
byte[] output;
try
{
byte[] buffer = new byte[65536];
using (var ms = new MemoryStream())
{
while (true)
{
int read = p.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
break;
ms.Write(buffer, 0, read);
}
output = ms.ToArray();
}
p.StandardOutput.Close();
p.WaitForExit(60 * 60 * 1000); // wait up to 60 minutes
if (p.ExitCode != 0)
throw new Exception("Exit code: " + p.ExitCode);
}
finally
{
p.Close();
p.Dispose();
}
// convert the outputted base64-encoded string to binary data
return System.Convert.FromBase64String(System.Text.Encoding.Default.GetString(output));
}
else
{
return System.IO.File.ReadAllBytes(path);
}
}
Hmm. Lots of answers, but I wonder if answering your last question would have solved everything. "me" is not an authorization type (unless your server has added support for it, of course!). You probably want "Basic".
Also keep in mind that some webservices require you to send the authorization header on the initial request, and this won't do that. Rather it responds with it after getting an authorization required response from the server. If you need this, you need to create your own Authorization header.
String basicToken = Base64Encoding.EncodeStringToBase64(String.Format("{0}:{1}", clientId.Trim(), clientSecret.Trim()));
webClient.Headers.Add("Authorization", String.Format("Basic {0}", basicToken));
And of course as people have pointed out, setting UseDefaultCredentials to true works if you are using IIS (or other windows security aware http server) in a windows environment.