MD5.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Net.FtpClient;
  4. namespace System.Net.FtpClient.Extensions {
  5. /// <summary>
  6. /// Implementation of the non-standard MD5 command
  7. /// </summary>
  8. public static class MD5 {
  9. delegate string AsyncGetMD5(string path);
  10. static Dictionary<IAsyncResult, AsyncGetMD5> m_asyncmethods = new Dictionary<IAsyncResult, AsyncGetMD5>();
  11. /// <summary>
  12. /// Gets the MD5 hash of the specified file using MD5. This is a non-standard extension
  13. /// to the protocol and may or may not work. A FtpCommandException will be
  14. /// thrown if the command fails.
  15. /// </summary>
  16. /// <param name="client">FtpClient Object</param>
  17. /// <param name="path">Full or relative path to remote file</param>
  18. /// <returns>Server response, presumably the MD5 hash.</returns>
  19. public static string GetMD5(this FtpClient client, string path) {
  20. // http://tools.ietf.org/html/draft-twine-ftpmd5-00#section-3.1
  21. FtpReply reply;
  22. string response;
  23. if (!(reply = client.Execute("MD5 {0}", path)).Success)
  24. throw new FtpCommandException(reply);
  25. response = reply.Message;
  26. if (response.StartsWith(path)) {
  27. response = response.Remove(0, path.Length).Trim();
  28. }
  29. return response;
  30. }
  31. /// <summary>
  32. /// Asynchronusly retrieve a MD5 hash. The MD5 command is non-standard
  33. /// and not guaranteed to work.
  34. /// </summary>
  35. /// <param name="client">FtpClient Object</param>
  36. /// <param name="path">Full or relative path to remote file</param>
  37. /// <param name="callback">AsyncCallback</param>
  38. /// <param name="state">State Object</param>
  39. /// <returns>IAsyncResult</returns>
  40. public static IAsyncResult BeginGetMD5(this FtpClient client, string path, AsyncCallback callback, object state) {
  41. AsyncGetMD5 func = new AsyncGetMD5(client.GetMD5);
  42. IAsyncResult ar = func.BeginInvoke(path, callback, state); ;
  43. lock (m_asyncmethods) {
  44. m_asyncmethods.Add(ar, func);
  45. }
  46. return ar;
  47. }
  48. /// <summary>
  49. /// Ends an asynchronous call to BeginGetMD5()
  50. /// </summary>
  51. /// <param name="ar">IAsyncResult returned from BeginGetMD5()</param>
  52. /// <returns>The MD5 hash of the specified file.</returns>
  53. public static string EndGetMD5(IAsyncResult ar) {
  54. AsyncGetMD5 func = null;
  55. lock (m_asyncmethods) {
  56. if (!m_asyncmethods.ContainsKey(ar))
  57. throw new InvalidOperationException("The specified IAsyncResult was not found in the collection.");
  58. func = m_asyncmethods[ar];
  59. m_asyncmethods.Remove(ar);
  60. }
  61. return func.EndInvoke(ar);
  62. }
  63. }
  64. }