Home | Blog | Software | Reviews and Features | Forum | Help | Donate | About us
topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • February 14, 2016, 03:02:26 PM
  • Proudly celebrating 10 years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Last post Author Topic: functional C# class/component to upload to my DC space via explicit FTP over TLS  (Read 14525 times)

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
I have no problem doing this via Filezilla, but I need to figure out how to upload a file to my little corner of DC programmatically, from within my C# applications.  I've tried various things, from FTP classes I've both found and rolled myself, and using HttpWebRequest.  I also read about the winhttp.dll library, which some people say works whereas the internal C# stuff is not always robust (however, I have no experience with that library's functions).

The reason I need to be able to do this programmatically is that I've coded a game.  That game records the highscore, and updates that value whenever a player beats the previous high score.  I want the program to be able to upload the highscore.dat file (which contains not only the highscore, but also the name of the player who scored it) to a specific directory under http://kyrathaba.dcmembers.com

Does anyone have any working C# code that they've used successfully to upload a file to their DC webspace?  I know that DC uses explict FTP over TLS.  Perhaps the methods I've attempted aren't sophisticated enough to negotiate that.  At any rate, it'd be a real boon (not just to my current project, but also to future ones) if I could find a class or component that allows me this functionality.

I have used the code show here before successfully, on a non FTPES site, but can't get it to work here.
« Last Edit: May 13, 2011, 09:24:59 PM by kyrathaba »

Renegade

  • Charter Member
  • Joined in 2005
  • ***
  • Posts: 13,186
  • Tell me something you don't know...
    • View Profile
    • Renegade Minds
    • Donate to Member
Have you looked at the Indy Project? I think there are C# bindings for it.

EDIT:

Yes -- here -- http://www.indyproje...etsCLR/index.EN.aspx

Slow Down Music - Where I commit thought crimes...

Freedom is the right to be wrong, not the right to do wrong. - John Diefenbaker

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
Thanks for the possible help.  Looks like the project hasn't been updated since Feb. 2008, and that was has been done is mostly focused on SMTP/POP.  The only FTP related stuff I could find, so far, was:

Code: C# [Select]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace Indy.Sockets.Web {
  7.     class FTP {
  8.     }
  9. }

I'll keep looking through the download and documentation, though, just to be thorough.

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
I tried the following code in a console program, and received this error message:
Quote
The remote server returned an error: (530) Not logged in.

Code: C# [Select]
  1. static void Main(string[] args) {
  2.  
  3.             // Get the object used to communicate with the server.
  4.             FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://kyrathaba.dcmembers.com/testbed/test.txt");
  5.             request.Method = WebRequestMethods.Ftp.UploadFile;
  6.  
  7.             request.Credentials = new NetworkCredential("kyrathaba", "substitutedForActualPasswordInThisForumPost");
  8.  
  9.             // Copy the contents of the file to the request stream.
  10.             StreamReader sourceStream = new StreamReader("test.txt");
  11.             byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
  12.             sourceStream.Close();
  13.             request.ContentLength = fileContents.Length;
  14.  
  15.             Stream requestStream = request.GetRequestStream();
  16.             requestStream.Write(fileContents, 0, fileContents.Length);
  17.             requestStream.Close();
  18.  
  19.             FtpWebResponse response = (FtpWebResponse)request.GetResponse();
  20.  
  21.             Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
  22.  
  23.             response.Close();
  24.  
  25.             Console.WriteLine("Press a key to end program...");
  26.             Console.ReadKey();
  27.         }

hamradio

  • Charter Honorary Member
  • Joined in 2006
  • ***
  • Posts: 660
  • Amateur Radio Guy
    • View Profile
    • HamRadioUSA.net
    • Donate to Member
Only concern I got is how are you going to keep people from using a .net disassembler to see the password?
Carroll - HamRadioUSA.net

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 35,729
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Donate to Member
To follow up on ham's point -- you'd be insane to try to save high scores by embedding ftp login credentials in your public app and using ftp protocol to upload user high scores.  That's just not the way it's done.

If you want to save high scores the solution is to write a server based script (php, python, perl, dot net on the server, whatever), that responds to http queries from client application over the web, like any other web-based application, and updates the server database, etc.

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
I don't know how to write server-side scripts.  I guess I could just put up a submission form on a webpage and then have the program direct the user to that form to submit a file via by posting.

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
Or, the program could invoke the user's default email client to have them send their obfuscated highscore file to me.

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
Quote
Only concern I got is how are you going to keep people from using a .net disassembler to see the password?

To follow up on ham's point -- you'd be insane to try to save high scores by embedding ftp login credentials in your public app

Sorry guys, didn't realize.  That's one thing I value most highly about DC; gaining the benefit of others' expertise.

wraith808

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 7,868
  • "In my dreams, I always do it right."
    • View Profile
    • Donate to Member
You could also use encryption, and get it from a file if you want to use FTP.

Code: C# [Select]
  1. using System;
  2. using System.Security.Cryptography;
  3. using System.Text;
  4.  
  5. namespace Coderz808
  6. {
  7.     public static class EnDeCrypter
  8.     {
  9.         // Set this to some personalized crypto key
  10.         private const string cryptoKey = "someSortOfCryptoKey";
  11.  
  12.         // The Initialization Vector for the DES encryption routine (choose 8 personalized bytes)
  13.         private static readonly byte[] IV =
  14.             new byte[8] { 140, 103, 145, 2, 10, 176, 173, 9 };
  15.  
  16.         /// <summary>
  17.         /// Encrypts provided string parameter
  18.         /// </summary>
  19.         internal static string Encrypt(string s)
  20.         {
  21.             if (s == null || s.Length == 0) return string.Empty;
  22.  
  23.             string result = string.Empty;
  24.  
  25.             try
  26.             {
  27.                 byte[] buffer = Encoding.ASCII.GetBytes(s);
  28.  
  29.                 TripleDESCryptoServiceProvider des =
  30.                     new TripleDESCryptoServiceProvider();
  31.  
  32.                 MD5CryptoServiceProvider MD5 =
  33.                     new MD5CryptoServiceProvider();
  34.  
  35.                 des.Key =
  36.                     MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(cryptoKey));
  37.  
  38.                 des.IV = IV;
  39.                 result = Convert.ToBase64String(
  40.                     des.CreateEncryptor().TransformFinalBlock(
  41.                         buffer, 0, buffer.Length));
  42.             }
  43.             catch
  44.             {
  45.                 throw;
  46.             }
  47.  
  48.             return result;
  49.         }
  50.  
  51.         /// <summary>
  52.         /// Decrypts provided string parameter
  53.         /// </summary>
  54.         internal static string Decrypt(string s)
  55.         {
  56.             if (s == null || s.Length == 0) return string.Empty;
  57.  
  58.             string result = string.Empty;
  59.  
  60.             try
  61.             {
  62.                 byte[] buffer = Convert.FromBase64String(s);
  63.  
  64.                 TripleDESCryptoServiceProvider des =
  65.                     new TripleDESCryptoServiceProvider();
  66.  
  67.                 MD5CryptoServiceProvider MD5 =
  68.                     new MD5CryptoServiceProvider();
  69.  
  70.                 des.Key =
  71.                     MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(cryptoKey));
  72.  
  73.                 des.IV = IV;
  74.  
  75.                 result = Encoding.ASCII.GetString(
  76.                     des.CreateDecryptor().TransformFinalBlock(
  77.                     buffer, 0, buffer.Length));
  78.             }
  79.             catch
  80.             {
  81.                 throw;
  82.             }
  83.  
  84.             return result;
  85.         }
  86.     }    
  87. }

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
Thanks, wraith.  Yes, and I have the know-how to encrypt a password in my app.  I wouldn't put it in raw.  But I understand that it's better, probably to use some other file-submission method.

Let me ask this: does DC have a server-side script I could reference from the html code in a webpage, so that a user could upload a small (few bytes) binary file to a designated /incoming/ directory of my webspace?
« Last Edit: May 14, 2011, 09:48:30 AM by kyrathaba »

worstje

  • Honorary Member
  • Joined in 2009
  • **
  • Posts: 571
  • The Gent with the White Hat
    • View Profile
    • Donate to Member
I have an ugly C# function I cobbled together for JottiQ that supports both GET and POST methods, the latter of which supports filetransfers. The code is butt ugly, but it is functional. It returns a XMLDocument if I recall properly, but could be simplified to just return a stream I believe.

Let me know if it would be good enough for your needs, and I'll supply you after my shopping run has provided me with foodstuffs to last the weekend. It's probably an excellent example of how not to deal with webservices in .NET, but I don't care much. :)

Renegade

  • Charter Member
  • Joined in 2005
  • ***
  • Posts: 13,186
  • Tell me something you don't know...
    • View Profile
    • Renegade Minds
    • Donate to Member
I have an ugly C# function I cobbled together... It's probably an excellent example of how not to deal with webservices in .NET, but I don't care much. :)

Hip! Hip! Horray~!

Let's hear it for getting things done~! :)

I have so much code that's ugly, but works... I wouldn't show it to anyone.

Sure, I could clean it up and make it pretty and all that, but... Time...

+1 for getting things done. :)
Slow Down Music - Where I commit thought crimes...

Freedom is the right to be wrong, not the right to do wrong. - John Diefenbaker

worstje

  • Honorary Member
  • Joined in 2009
  • **
  • Posts: 571
  • The Gent with the White Hat
    • View Profile
    • Donate to Member
Good point. I hereby rescind my offer to share my code. :-[ The internet has far too long a memory for me to want to carry that blemish for the rest of my life. :mad:

Just kidding, I don't give a damn. Just let me know. 8)

Edit: On second thought, I re-read his request, and I think I've got the opposite. I have got client-side C# code that can upload to some http:// script, while I now think he wants a server-side script to receive file uploads and store them with. And with that, I am afraid I cannot help.
« Last Edit: May 14, 2011, 11:04:10 AM by worstje »

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 35,729
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Donate to Member
Quote
I don't know how to write server-side scripts.

kyrathaba, you're a fast learner and, while i'm not suggesting you learn how to write server scripts for this project, i would suggest that you might find it very enjoyable to learn a little bit of php, just as a change of pace from desktop application coding.  it would also give you a feel for what kinds of things you can do with server side coding.

why not get yourself a book and start the php programming school assignments here.

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
Mouser, I promise to look into PHP.  In the meantime, worstje, I'd be very grateful for your ugly code ;)  I promise never to share/re-post it anywhere. 

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
Here's my application in its current incarnation (screenshot).  I want to add a menu item "Share my highscore", or something to that effect.  It should allow the user to upload the small (20-50 byte) file containing their highscore to a designated /incoming/ directory on DC.  I would have another utility program that allows me to scan that particular online folder and download all such files currently residing their, opening each, retrieving username and highscore, and compiling an HTML file showing a listing of the game's users and their highscores in descending order.

Would something like this (modified slightly) work?  I realize there has be a complimentary PHP script residing on the server...

Quote
<form enctype="multipart/form-data" action="uploader.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
Choose a file to upload: <input name="uploadedfile" type="file" /><br />
<input type="submit" value="Upload File" />
</form>

postViaPHP.png
« Last Edit: May 14, 2011, 02:08:52 PM by kyrathaba »

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 35,729
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Donate to Member
Quote
It should allow the user to upload the small (20-50 byte) file containing their highscore to a designated /incoming/ directory on DC.  I would have another utility program that allows me to scan that particular online folder and download all such files currently residing their, opening each, retrieving username and highscore, and compiling an HTML file showing a listing of the game's users and their highscores in descending order.

:)

think about what you are saying.

You want client to be able to "upload a 20-50 byte FILE" and then you want them to be able to view other people's high scores by scanning a server folder, downloading all other highscore files, opening each, reading info, and then "compiling an HTML file" on the local pc and displaying it.

You need to shift your thinking.

You do not want this.

What you want is something 1000x simpler and more straightforward.

You want a server script that will accept two very simple http requests, the first will be submission of high score info, it could be as simple as accepting an http request of http:/kyrathaba.com/highscoresubmit?name=mouser&score=54  or you could use a post form method.

The server script will then simply ADD the users score to its high score database.

And then to VIEW high scores from the desktop application, you will simply make another web query to the server script of the form http://kyrathaba.com/highscores.php which will RETURN AN HTML FILE that the client can display to view high scores.  Users could even just view that web page directly.  (Or alternatively return a response with some raw data from the database for you to format and display).

You need to stop thinking about doing this purely from the desktop application using protocols like ftp.  That way lies madness.



You need to wrap your head around web coding so that you have a better taste for what things you should be doing server-side vs. desktop client side.  Go read a few pages about web coding (php, perl, whatever) and using database stuff on the server, etc.  You will find it is both easy, fun, and liberating.
« Last Edit: May 14, 2011, 02:03:03 PM by mouser »

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
Yeah, I'm very desktopApp-centric in my thinking, because that's all I've every done.  It would be better if the server did it all.  Is there some sort of free desktop app that I could use in conjunction with developing such a script, just to test the script and know that it will work once uploaded to a server?  Or can I just tinker with scripts, uploading them to one of my subdirectories and testing them directly?

worstje

  • Honorary Member
  • Joined in 2009
  • **
  • Posts: 571
  • The Gent with the White Hat
    • View Profile
    • Donate to Member
You can install a local webserver to develop on, or you can upload each time. For as far software goes, usually a simple webbrowser will do miracles (with or without a temporary html page that has a form that allows you to create the proper sort of request).

Either way, I am fully in agreement with mouser. You'll want some scripts on the webserver. Nothing more, nothing less. Forget all that crap about uploading files, scanning directories, etc etc. :)

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 35,729
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Donate to Member
Yeah, I'm very desktopApp-centric in my thinking, because that's all I've every done.  It would be better if the server did it all.  Is there some sort of free desktop app that I could use in conjunction with developing such a script, just to test the script and know that it will work once uploaded to a server?

What you should do is install a "LAMP" bundle on your local pc, and which will let you do and test all your web development initially on your desktop.

I don't know which package people currently recommend for windows, but one is XAMPP: http://www.apachefri...n/xampp-windows.html  which is probably a good option.

The most confusing part is actually getting setup and just getting started.  After that you will probably find web coding highly rewarding and invigorating.

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 35,729
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Donate to Member
Run don't walk to your nearest bookstore or online retailer and buy yourself a book on PHP/MYSQL.  One i like is http://www.amazon.co...t-4th/dp/0672329166/ but any one that grabs your attention will do.

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
Okay, I'm convinced. 

Unfortunately, this is going to mean delaying releasing this app.  What I really want to do is spend some time in the next few weeks working through the Stage 2 C# assignments in the Programming School.  But now it looks like I'll have to break away long enough to figure out how to do the PHP I need for Highscores submission, collating, and reporting in a webpage.

Shouldn't be that hard, once I understand the syntax of PHP.  Basically, each 'highscore.dat' file just contains a single line of text, such as these three examples, and the program splits them into 'highscore' and 'userWhoAchievedThisHighscore' using the semicolon character as a delimeter:

10500;mouser
8755;kyrathaba
12200;worstje

When it saves a 'highscore' on disk, it encrypts it first, so the user(s) of the game can't peek.

kyrathaba

  • N.A.N.Y. Organizer
  • Honorary Member
  • Joined in 2006
  • **
  • Posts: 3,105
    • View Profile
    • Read more about this member.
    • Donate to Member
So, how would this work, mouser?  I have to get some PHP working on XAMP, then submit it to you for proofing/approval, and then it goes in some special directory on the DC server?  Or can the script run within a subidrectory of my own DC webspace?

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 35,729
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Donate to Member
Quote
Or can the script run within a subidrectory of my own DC webspace?

You can just upload the php files and access and test them from the web, no special permissions or work needed behind the scenes for php.  you are going to be pleasantly surprised at how easy it is to start writing server scripts that do interesting things.

The only thing you WILL have to eventually have us do is create the initial database for you on the server.  after that you will be able to access it and modify it from your scripts.