1 | using System; |
---|
2 | using System.Collections.Generic; |
---|
3 | using System.Text; |
---|
4 | using System.Net; |
---|
5 | using System.IO; |
---|
6 | |
---|
7 | using System.Web; |
---|
8 | using System.Xml.Serialization; |
---|
9 | using System.Xml; |
---|
10 | using System.Collections.Specialized; |
---|
11 | |
---|
12 | namespace Com.Piwigo.Lib.Proxy |
---|
13 | { |
---|
14 | |
---|
15 | static internal class PwgGenericProxy<T> |
---|
16 | { |
---|
17 | /// <summary> |
---|
18 | /// Send Get data request to piwigo |
---|
19 | /// </summary> |
---|
20 | /// <param name="address"></param> |
---|
21 | /// <param name="methodName"></param> |
---|
22 | /// <param name="methodParameter"></param> |
---|
23 | /// <returns></returns> |
---|
24 | internal static T Get(Uri address, String methodName, String methodParameter) |
---|
25 | { |
---|
26 | T ReturnValue = default(T); |
---|
27 | HttpWebRequest Request; |
---|
28 | HttpWebResponse Response = null; |
---|
29 | StreamReader Reader; |
---|
30 | |
---|
31 | if (address == null) { throw new PwgProxyException("The get address is null."); } |
---|
32 | |
---|
33 | try |
---|
34 | { |
---|
35 | UriBuilder completeUri = new UriBuilder(address); |
---|
36 | if (methodParameter == null) |
---|
37 | { |
---|
38 | completeUri.Query = String.Format("method={0}", methodName); |
---|
39 | } |
---|
40 | else |
---|
41 | { |
---|
42 | completeUri.Query = String.Format("method={0}&{1}", methodName, methodParameter); |
---|
43 | } |
---|
44 | // Create and initialize the web request |
---|
45 | Request = WebRequest.Create(completeUri.Uri) as HttpWebRequest; |
---|
46 | Request.UserAgent = PwgConfigProxy.PwgUserAgent; |
---|
47 | Request.KeepAlive = PwgConfigProxy.PwgKeepAlive; |
---|
48 | #if DEBUG |
---|
49 | Request.Timeout = PwgConfigProxy.PwgTimeOutInSecond * 1000 * 1000; |
---|
50 | #else |
---|
51 | Request.Timeout = PwgConfigProxy.PwgTimeOutInSecond * 1000; |
---|
52 | #endif |
---|
53 | |
---|
54 | Request.CookieContainer = PwgConfigProxy.cookieContainer; // get session cookie |
---|
55 | |
---|
56 | // Get response |
---|
57 | Response = Request.GetResponse() as HttpWebResponse; |
---|
58 | |
---|
59 | if (Request.HaveResponse == true && Response != null) |
---|
60 | { |
---|
61 | // Get the response stream |
---|
62 | Reader = new StreamReader(Response.GetResponseStream()); |
---|
63 | |
---|
64 | ReturnValue = DeserializeObject(Reader); |
---|
65 | } |
---|
66 | } |
---|
67 | catch (WebException wex) |
---|
68 | { |
---|
69 | // This exception will be raised if the server didn't return 200 - OK |
---|
70 | // Try to retrieve more information about the network error |
---|
71 | if (wex.Response != null) |
---|
72 | { |
---|
73 | using (HttpWebResponse errorResponse = (HttpWebResponse)wex.Response) |
---|
74 | { |
---|
75 | throw new PwgProxyException( |
---|
76 | String.Format( |
---|
77 | "The server returned '{0}' with the status code {1} ({2:d}).", |
---|
78 | errorResponse.StatusDescription, errorResponse.StatusCode, |
---|
79 | errorResponse.StatusCode), |
---|
80 | wex); |
---|
81 | } |
---|
82 | } |
---|
83 | } |
---|
84 | finally |
---|
85 | { |
---|
86 | if (Response != null) { Response.Close(); } |
---|
87 | } |
---|
88 | return ReturnValue; |
---|
89 | } |
---|
90 | |
---|
91 | /// <summary> |
---|
92 | /// Send Post data request to piwigo |
---|
93 | /// </summary> |
---|
94 | /// <param name="address"></param> |
---|
95 | /// <param name="data"></param> |
---|
96 | /// <returns></returns> |
---|
97 | internal static T Post(Uri address, String data) |
---|
98 | { |
---|
99 | T ReturnValue = default(T); |
---|
100 | //System.Net.ServicePointManager.Expect100Continue = false; |
---|
101 | |
---|
102 | HttpWebRequest Request; |
---|
103 | HttpWebResponse Response = null; |
---|
104 | |
---|
105 | if (address == null) { throw new PwgProxyException("The get address is null."); } |
---|
106 | |
---|
107 | try |
---|
108 | { |
---|
109 | // Create the web request |
---|
110 | Request = WebRequest.Create(address) as HttpWebRequest; |
---|
111 | Request.UserAgent = PwgConfigProxy.PwgUserAgent; |
---|
112 | Request.KeepAlive = PwgConfigProxy.PwgKeepAlive; |
---|
113 | #if DEBUG |
---|
114 | Request.Timeout = PwgConfigProxy.PwgTimeOutInSecond * 1000 * 1000; |
---|
115 | #else |
---|
116 | Request.Timeout = PwgConfigProxy.PwgTimeOutInSecond * 1000; |
---|
117 | #endif |
---|
118 | |
---|
119 | Request.CookieContainer = PwgConfigProxy.cookieContainer; // get session cookie |
---|
120 | |
---|
121 | // Set type to POST |
---|
122 | Request.Method = "POST"; |
---|
123 | Request.ContentType = "application/x-www-form-urlencoded"; |
---|
124 | |
---|
125 | // Create a byte array of the data we want to send |
---|
126 | byte[] byteData = UTF8Encoding.UTF8.GetBytes(data); |
---|
127 | |
---|
128 | // Set the content length in the request headers |
---|
129 | Request.ContentLength = byteData.Length; |
---|
130 | |
---|
131 | // Write data |
---|
132 | using (Stream PostStream = Request.GetRequestStream()) |
---|
133 | { |
---|
134 | PostStream.Write(byteData, 0, byteData.Length); |
---|
135 | } |
---|
136 | |
---|
137 | // Get response |
---|
138 | using (Response = Request.GetResponse() as HttpWebResponse) |
---|
139 | { |
---|
140 | // Get the response stream |
---|
141 | StreamReader reader = new StreamReader(Response.GetResponseStream()); |
---|
142 | |
---|
143 | ReturnValue = DeserializeObject(reader); |
---|
144 | } |
---|
145 | } |
---|
146 | catch (WebException wex) |
---|
147 | { |
---|
148 | // This exception will be raised if the server didn't return 200 - OK |
---|
149 | // Try to retrieve more information about the network error |
---|
150 | if (wex.Response != null) |
---|
151 | { |
---|
152 | using (HttpWebResponse ErrorResponse = (HttpWebResponse)wex.Response) |
---|
153 | { |
---|
154 | throw new PwgProxyException( |
---|
155 | String.Format( |
---|
156 | "The server returned '{0}' with the status code {1} ({2:d}).", |
---|
157 | ErrorResponse.StatusDescription, ErrorResponse.StatusCode, |
---|
158 | ErrorResponse.StatusCode), |
---|
159 | wex); |
---|
160 | } |
---|
161 | } |
---|
162 | } |
---|
163 | finally |
---|
164 | { |
---|
165 | if (Response != null) { Response.Close(); } |
---|
166 | } |
---|
167 | return ReturnValue; |
---|
168 | } |
---|
169 | |
---|
170 | private class MimePart |
---|
171 | { |
---|
172 | internal NameValueCollection Headers { get; set; } |
---|
173 | internal byte[] Header { get; set; } |
---|
174 | internal Stream Data { get; set; } |
---|
175 | |
---|
176 | internal MimePart() |
---|
177 | { |
---|
178 | Headers = new NameValueCollection(); |
---|
179 | } |
---|
180 | } |
---|
181 | /// <summary> |
---|
182 | /// |
---|
183 | /// </summary> |
---|
184 | /// <param name="address">URI of server</param> |
---|
185 | /// <param name="dcFiles">Dictionary(String NameOfFileFiel, String FilePath) FilePath must exist on hdd</param> |
---|
186 | /// <param name="dcFields">Dictionary(String NameOfFormField, String ValueForField) others form filed to submit</param> |
---|
187 | /// <returns></returns> |
---|
188 | internal static T PostAsMultiPartForm(Uri address, Dictionary<String, String> dcFiles, Dictionary<String, String> dcFields) |
---|
189 | { |
---|
190 | List<MimePart> lstMimeParts = new List<MimePart>(); |
---|
191 | T ReturnValue = default(T); |
---|
192 | |
---|
193 | HttpWebRequest Request; |
---|
194 | HttpWebResponse Response = null; |
---|
195 | |
---|
196 | if (address == null) { throw new PwgProxyException("The get address is null."); } |
---|
197 | |
---|
198 | try |
---|
199 | { |
---|
200 | // Create the web request |
---|
201 | Request = WebRequest.Create(address) as HttpWebRequest; |
---|
202 | Request.UserAgent = PwgConfigProxy.PwgUserAgent; |
---|
203 | Request.KeepAlive = PwgConfigProxy.PwgKeepAlive; |
---|
204 | #if DEBUG |
---|
205 | Request.Timeout = PwgConfigProxy.PwgTimeOutInSecond * 1000 * 1000; |
---|
206 | #else |
---|
207 | Request.Timeout = PwgConfigProxy.PwgTimeOutInSecond * 1000; |
---|
208 | #endif |
---|
209 | Request.SendChunked = true; |
---|
210 | Request.ProtocolVersion = System.Net.HttpVersion.Version11; |
---|
211 | Request.CookieContainer = PwgConfigProxy.cookieContainer; // get session cookie |
---|
212 | |
---|
213 | // MultiPart Post Request |
---|
214 | Request.ContentType = "multipart/form-data;"; |
---|
215 | Request.Method = "POST"; |
---|
216 | |
---|
217 | // Loading Mine Part data from others form fields |
---|
218 | foreach (string key in dcFields.Keys) |
---|
219 | { |
---|
220 | MimePart part = new MimePart(); |
---|
221 | part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\""; |
---|
222 | part.Data = new MemoryStream(Encoding.UTF8.GetBytes(dcFields[key])); |
---|
223 | lstMimeParts.Add(part); |
---|
224 | } |
---|
225 | |
---|
226 | // Loading MinePart data from form file fields |
---|
227 | foreach (String strFieldName in dcFiles.Keys) |
---|
228 | { |
---|
229 | MimePart part = new MimePart(); |
---|
230 | part.Headers["Content-Disposition"] = "form-data; name=\"" + strFieldName + "\"; filename=\"" + dcFiles[strFieldName] + "\""; |
---|
231 | part.Headers["Content-Type"] = "application/octet-stream"; |
---|
232 | part.Data = File.OpenRead(dcFiles[strFieldName]); // Open file for getting a stream reader on it. |
---|
233 | lstMimeParts.Add(part); |
---|
234 | } |
---|
235 | |
---|
236 | string strBound = "----------" + DateTime.Now.Ticks.ToString("x"); |
---|
237 | byte[] strFooter = Encoding.UTF8.GetBytes("--" + strBound + "--\r\n"); |
---|
238 | Request.ContentType += " boundary=" + strBound; |
---|
239 | |
---|
240 | long contentLength = 0; |
---|
241 | foreach (MimePart part in lstMimeParts) |
---|
242 | { |
---|
243 | StringBuilder sb = new StringBuilder(); |
---|
244 | |
---|
245 | sb.Append("--"); |
---|
246 | sb.Append(strBound); |
---|
247 | sb.AppendLine(); |
---|
248 | foreach (string key in part.Headers.AllKeys) |
---|
249 | { |
---|
250 | sb.Append(key); |
---|
251 | sb.Append(": "); |
---|
252 | sb.AppendLine(part.Headers[key]); |
---|
253 | } |
---|
254 | sb.AppendLine(); |
---|
255 | |
---|
256 | part.Header = Encoding.UTF8.GetBytes(sb.ToString()); |
---|
257 | |
---|
258 | contentLength += part.Header.Length + part.Data.Length + 2; |
---|
259 | |
---|
260 | } |
---|
261 | |
---|
262 | Request.ContentLength = contentLength + strFooter.Length; |
---|
263 | |
---|
264 | byte[] buffer = new byte[8192]; |
---|
265 | byte[] afterFile = Encoding.UTF8.GetBytes("\r\n"); |
---|
266 | int read; |
---|
267 | |
---|
268 | using (Stream s = Request.GetRequestStream()) |
---|
269 | { |
---|
270 | foreach (MimePart part in lstMimeParts) |
---|
271 | { |
---|
272 | s.Write(part.Header, 0, part.Header.Length); |
---|
273 | |
---|
274 | while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0) |
---|
275 | s.Write(buffer, 0, read); |
---|
276 | |
---|
277 | part.Data.Close(); |
---|
278 | part.Data.Dispose(); |
---|
279 | |
---|
280 | s.Write(afterFile, 0, afterFile.Length); |
---|
281 | } |
---|
282 | |
---|
283 | s.Write(strFooter, 0, strFooter.Length); |
---|
284 | } |
---|
285 | |
---|
286 | // Get response |
---|
287 | using (Response = Request.GetResponse() as HttpWebResponse) |
---|
288 | { |
---|
289 | // Get the response stream |
---|
290 | StreamReader reader = new StreamReader(Response.GetResponseStream()); |
---|
291 | |
---|
292 | ReturnValue = DeserializeObject(reader); |
---|
293 | } |
---|
294 | } |
---|
295 | catch (WebException wex) |
---|
296 | { |
---|
297 | // This exception will be raised if the server didn't return 200 - OK |
---|
298 | // Try to retrieve more information about the network error |
---|
299 | if (wex.Response != null) |
---|
300 | { |
---|
301 | using (HttpWebResponse ErrorResponse = (HttpWebResponse)wex.Response) |
---|
302 | { |
---|
303 | throw new PwgProxyException( |
---|
304 | String.Format( |
---|
305 | "The server returned '{0}' with the status code {1} ({2:d}).", |
---|
306 | ErrorResponse.StatusDescription, ErrorResponse.StatusCode, |
---|
307 | ErrorResponse.StatusCode), |
---|
308 | wex); |
---|
309 | } |
---|
310 | } |
---|
311 | } |
---|
312 | catch (IOException ioex) |
---|
313 | { |
---|
314 | // This exception will be raised if file aren't ok on client |
---|
315 | if (ioex!= null) |
---|
316 | { |
---|
317 | throw new PwgProxyException( |
---|
318 | String.Format( |
---|
319 | "A IO file exception stop the request building : {0}.", ioex.Message), |
---|
320 | ioex); |
---|
321 | } |
---|
322 | } |
---|
323 | finally |
---|
324 | { |
---|
325 | if (Response != null) { Response.Close(); } |
---|
326 | foreach (MimePart part in lstMimeParts) |
---|
327 | { |
---|
328 | if (part.Data != null) |
---|
329 | part.Data.Dispose(); |
---|
330 | } |
---|
331 | } |
---|
332 | return ReturnValue; |
---|
333 | } |
---|
334 | |
---|
335 | /// <summary> |
---|
336 | /// return object from xml retuned by piwigo |
---|
337 | /// </summary> |
---|
338 | /// <param name="xmlData"></param> |
---|
339 | /// <returns></returns> |
---|
340 | internal static T DeserializeObject(StreamReader xmlData) |
---|
341 | { |
---|
342 | T ReturnValue = default(T); |
---|
343 | String line = String.Empty; |
---|
344 | try |
---|
345 | { |
---|
346 | #if DEBUG |
---|
347 | line = xmlData.ReadToEnd(); |
---|
348 | System.Diagnostics.Debug.WriteLine(line); |
---|
349 | |
---|
350 | byte[] hexLine = System.Text.Encoding.UTF8.GetBytes(line); |
---|
351 | MemoryStream m = new System.IO.MemoryStream(hexLine); |
---|
352 | StreamReader xmlDat = new StreamReader(m); |
---|
353 | #else |
---|
354 | xmlDat = xmlData; |
---|
355 | #endif |
---|
356 | System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); |
---|
357 | ReturnValue = (T)xsSerializer.Deserialize(xmlDat); |
---|
358 | } |
---|
359 | catch (Exception ex) |
---|
360 | { |
---|
361 | throw new PwgProxyException( |
---|
362 | String.Format( |
---|
363 | "The value {0} can't be deserialized in {1}, the error is {2} .", |
---|
364 | line, typeof(T).Name, ex.Message), |
---|
365 | ex); |
---|
366 | } |
---|
367 | |
---|
368 | return ReturnValue; |
---|
369 | } |
---|
370 | |
---|
371 | internal static void SerializeToXML(String fileName, T obj) |
---|
372 | { |
---|
373 | try |
---|
374 | { |
---|
375 | XmlSerializer serializer = new XmlSerializer(typeof(T)); |
---|
376 | TextWriter textWriter = new StreamWriter(fileName); |
---|
377 | serializer.Serialize(textWriter, obj); |
---|
378 | textWriter.Close(); |
---|
379 | } |
---|
380 | catch (Exception ex) |
---|
381 | { |
---|
382 | throw new PwgProxyException( |
---|
383 | String.Format( |
---|
384 | "The value {0} can't be serialized in {1}, the error is {2} .", |
---|
385 | obj, fileName, ex.Message), |
---|
386 | ex); |
---|
387 | } |
---|
388 | } |
---|
389 | } |
---|
390 | } |
---|