Created
April 2, 2013 16:47
-
-
Save wizzard0/5293837 to your computer and use it in GitHub Desktop.
Multipart form+file upload
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Net; | |
using System.IO; | |
using System.Collections.Specialized; | |
using System.Diagnostics; | |
namespace Util | |
{ | |
using Newtonsoft.Json; | |
/// <summary> | |
/// misc network utils | |
/// </summary> | |
public class NetworkUtil | |
{ | |
/// <summary> | |
/// The http upload file. | |
/// </summary> | |
/// <param name="url"> The url. </param> | |
/// <param name="file"> The file. </param> | |
/// <param name="fileStream"> The file stream. </param> | |
/// <param name="paramName"> The file param name. </param> | |
/// <param name="contentType"> The content type. </param> | |
/// <param name="nvc"> The nvc. </param> | |
/// <returns> The <see cref="Stream"/>. </returns> | |
public static T HttpUploadFile<T, TError>(string url, string file, Stream fileStream, string paramName, string contentType, NameValueCollection nvc, IServerConnector connector) where T : JsonBaseResult | |
{ | |
Stream stm = null; | |
while (true) | |
{ | |
try | |
{ | |
stm = PerformUpload(url, file, fileStream, paramName, contentType, nvc, connector); | |
break; | |
} | |
catch (WebException we) | |
{ | |
if ((we.Response as HttpWebResponse).StatusCode == HttpStatusCode.Unauthorized) | |
{ | |
connector.ResetSession(); | |
continue; // retry | |
} | |
else | |
{ | |
throw; | |
} | |
} | |
catch (Exception) | |
{ | |
throw; | |
} | |
} | |
JsonSerializer js = new JsonSerializer(); | |
var gcr = js.Deserialize<T>(new JsonTextReader(new StreamReader(stm))); | |
if (!gcr.success) | |
{ | |
stm.Seek(0, SeekOrigin.Begin); | |
var err = js.Deserialize<TError>(new JsonTextReader(new StreamReader(stm))); | |
throw ExceptionFactory.Error(err); | |
} | |
return gcr; | |
} | |
private static Stream PerformUpload(string url, string file, Stream fileStream, string paramName, string contentType, NameValueCollection nvc, IServerConnector connector) | |
{ | |
// log.Debug(string.Format("Uploading {0} to {1}", file, url)); | |
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); | |
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); | |
var wr = (HttpWebRequest)WebRequest.Create(url); | |
wr.ContentType = "multipart/form-data; boundary=" + boundary; | |
wr.Method = "POST"; | |
wr.KeepAlive = true; | |
wr.CookieContainer = connector.CookieContainer; | |
var credential = connector.Credentials; | |
if (credential is UsernamePasswordCredential) | |
{ | |
var upc = credential as UsernamePasswordCredential; | |
wr.Headers.Add( | |
"Authorization", | |
"Basic " | |
+ | |
Convert.ToBase64String(Encoding.UTF8.GetBytes(upc.Username + ":" + upc.Password.ToUnsecureString()))); | |
} | |
else if (credential is CurrentWindowsIdentityCredential) | |
{ | |
wr.UseDefaultCredentials = true; | |
} | |
else | |
{ | |
throw new ArgumentException(String.Format("Unknow credential type {0}", credential)); | |
} | |
wr.Credentials = System.Net.CredentialCache.DefaultCredentials; | |
Stream rs = wr.GetRequestStream(); | |
string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; | |
foreach (string key in nvc.Keys) | |
{ | |
rs.Write(boundarybytes, 0, boundarybytes.Length); | |
string formitem = string.Format(formdataTemplate, key, nvc[key]); | |
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); | |
rs.Write(formitembytes, 0, formitembytes.Length); | |
} | |
byte[] buffer = new byte[4096]; | |
int bytesRead = 0; | |
if (fileStream != null) | |
{ | |
rs.Write(boundarybytes, 0, boundarybytes.Length); | |
string headerTemplate = | |
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n"; | |
string header = string.Format(headerTemplate, paramName, file, contentType); | |
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); | |
rs.Write(headerbytes, 0, headerbytes.Length); | |
//FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read); | |
fileStream.Seek(0, SeekOrigin.Begin); | |
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) | |
{ | |
rs.Write(buffer, 0, bytesRead); | |
} | |
fileStream.Close(); | |
} | |
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); | |
rs.Write(trailer, 0, trailer.Length); | |
rs.Close(); | |
WebResponse wresp = null; | |
try | |
{ | |
wresp = wr.GetResponse(); | |
Stream stream2 = wresp.GetResponseStream(); | |
MemoryStream resp = new MemoryStream(); | |
while ((bytesRead = stream2.Read(buffer, 0, buffer.Length)) != 0) | |
{ | |
resp.Write(buffer, 0, bytesRead); | |
} | |
if (wresp.ContentLength != -1) | |
{ | |
Debug.Assert(resp.Length == wresp.ContentLength); | |
} | |
resp.Seek(0, SeekOrigin.Begin); | |
return resp; | |
//log.Debug(string.Format("File uploaded, server response is: {0}", reader2.ReadToEnd())); | |
} | |
catch (Exception ex) | |
{ | |
log.Error("Error uploading file", ex); | |
} | |
finally | |
{ | |
if (wresp != null) | |
{ | |
wresp.Close(); | |
wresp = null; | |
} | |
wr = null; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment