SimpleHttpRequest.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. namespace Nwc.XmlRpc
  2. {
  3. using System;
  4. using System.IO;
  5. using System.Net.Sockets;
  6. using System.Collections;
  7. ///<summary>Very basic HTTP request handler.</summary>
  8. ///<remarks>This class is designed to accept a TcpClient and treat it as an HTTP request.
  9. /// It will do some basic header parsing and manage the input and output streams associated
  10. /// with the request.</remarks>
  11. public class SimpleHttpRequest
  12. {
  13. private String _httpMethod = null;
  14. private String _protocol;
  15. private String _filePathFile = null;
  16. private String _filePathDir = null;
  17. private String __filePath;
  18. private TcpClient _client;
  19. private StreamReader _input;
  20. private StreamWriter _output;
  21. private Hashtable _headers;
  22. /// <summary>A constructor which accepts the TcpClient.</summary>
  23. /// <remarks>It creates the associated input and output streams, determines the request type,
  24. /// and parses the remaining HTTP header.</remarks>
  25. /// <param name="client">The <c>TcpClient</c> associated with the HTTP connection.</param>
  26. public SimpleHttpRequest(TcpClient client)
  27. {
  28. _client = client;
  29. _output = new StreamWriter(client.GetStream());
  30. _input = new StreamReader(client.GetStream());
  31. GetRequestMethod();
  32. GetRequestHeaders();
  33. }
  34. /// <summary>The output <c>StreamWriter</c> associated with the request.</summary>
  35. public StreamWriter Output
  36. {
  37. get { return _output; }
  38. }
  39. /// <summary>The input <c>StreamReader</c> associated with the request.</summary>
  40. public StreamReader Input
  41. {
  42. get { return _input; }
  43. }
  44. /// <summary>The <c>TcpClient</c> with the request.</summary>
  45. public TcpClient Client
  46. {
  47. get { return _client; }
  48. }
  49. private String _filePath
  50. {
  51. get { return __filePath; }
  52. set
  53. {
  54. __filePath = value;
  55. _filePathDir = null;
  56. _filePathFile = null;
  57. }
  58. }
  59. /// <summary>The type of HTTP request (i.e. PUT, GET, etc.).</summary>
  60. public String HttpMethod
  61. {
  62. get { return _httpMethod; }
  63. }
  64. /// <summary>The level of the HTTP protocol.</summary>
  65. public String Protocol
  66. {
  67. get { return _protocol; }
  68. }
  69. /// <summary>The "path" which is part of any HTTP request.</summary>
  70. public String FilePath
  71. {
  72. get { return _filePath; }
  73. }
  74. /// <summary>The file portion of the "path" which is part of any HTTP request.</summary>
  75. public String FilePathFile
  76. {
  77. get
  78. {
  79. if (_filePathFile != null)
  80. return _filePathFile;
  81. int i = FilePath.LastIndexOf("/");
  82. if (i == -1)
  83. return "";
  84. i++;
  85. _filePathFile = FilePath.Substring(i, FilePath.Length - i);
  86. return _filePathFile;
  87. }
  88. }
  89. /// <summary>The directory portion of the "path" which is part of any HTTP request.</summary>
  90. public String FilePathDir
  91. {
  92. get
  93. {
  94. if (_filePathDir != null)
  95. return _filePathDir;
  96. int i = FilePath.LastIndexOf("/");
  97. if (i == -1)
  98. return "";
  99. i++;
  100. _filePathDir = FilePath.Substring(0, i);
  101. return _filePathDir;
  102. }
  103. }
  104. private void GetRequestMethod()
  105. {
  106. string req = _input.ReadLine();
  107. if (req == null)
  108. throw new ApplicationException("Void request.");
  109. if (0 == String.Compare("GET ", req.Substring(0, 4), true))
  110. _httpMethod = "GET";
  111. else if (0 == String.Compare("POST ", req.Substring(0, 5), true))
  112. _httpMethod = "POST";
  113. else
  114. throw new InvalidOperationException("Unrecognized method in query: " + req);
  115. req = req.TrimEnd();
  116. int idx = req.IndexOf(' ') + 1;
  117. if (idx >= req.Length)
  118. throw new ApplicationException("What do you want?");
  119. string page_protocol = req.Substring(idx);
  120. int idx2 = page_protocol.IndexOf(' ');
  121. if (idx2 == -1)
  122. idx2 = page_protocol.Length;
  123. _filePath = page_protocol.Substring(0, idx2).Trim();
  124. _protocol = page_protocol.Substring(idx2).Trim();
  125. }
  126. private void GetRequestHeaders()
  127. {
  128. String line;
  129. int idx;
  130. _headers = new Hashtable();
  131. while ((line = _input.ReadLine()) != "")
  132. {
  133. if (line == null)
  134. {
  135. break;
  136. }
  137. idx = line.IndexOf(':');
  138. if (idx == -1 || idx == line.Length - 1)
  139. {
  140. Logger.WriteEntry("Malformed header line: " + line, LogLevel.Information);
  141. continue;
  142. }
  143. String key = line.Substring(0, idx);
  144. String value = line.Substring(idx + 1);
  145. try
  146. {
  147. _headers.Add(key, value);
  148. }
  149. catch (Exception)
  150. {
  151. Logger.WriteEntry("Duplicate header key in line: " + line, LogLevel.Information);
  152. }
  153. }
  154. }
  155. /// <summary>
  156. /// Format the object contents into a useful string representation.
  157. /// </summary>
  158. ///<returns><c>String</c> representation of the <c>SimpleHttpRequest</c> as the <i>HttpMethod FilePath Protocol</i>.</returns>
  159. override public String ToString()
  160. {
  161. return HttpMethod + " " + FilePath + " " + Protocol;
  162. }
  163. /// <summary>
  164. /// Close the <c>SimpleHttpRequest</c>. This flushes and closes all associated io streams.
  165. /// </summary>
  166. public void Close()
  167. {
  168. _output.Flush();
  169. _output.Close();
  170. _input.Close();
  171. _client.Close();
  172. }
  173. }
  174. }