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