Skip to content

Instantly share code, notes, and snippets.

@brnwdrng
Created August 9, 2016 22:59
Show Gist options
  • Save brnwdrng/442090c95b373aa82b593751c35c60eb to your computer and use it in GitHub Desktop.
Save brnwdrng/442090c95b373aa82b593751c35c60eb to your computer and use it in GitHub Desktop.
File upload via form post and ajax
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using Site.Production;
namespace Site.Production
{
/// <summary>
/// Handler example_upload for uploading .job files and relaying them to backend system
/// </summary>
public class example_upload : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
GenericResponse response = new GenericResponse();
GenericResponse.ResponsePackage package = new GenericResponse.ResponsePackage();
#region Processing code
string host_tld = context.Request.Url.Host.Replace("www.", "").ToLower();
string host_domain = host_tld.Substring(0, host_tld.LastIndexOf('.'));
bool IsValidHost = host_domain.Equals(Credentials.example_name.ToLower());
string service_vkey = Credentials.production_vkey;
string data_server = Credentials.production_server;
string ssl_username = Credentials.production_username;
string ssl_password = Credentials.production_password;
string target_page = "example.upload";
JavaScriptSerializer js_outbound = new JavaScriptSerializer();
try
{
#region Serialize incoming file
HttpPostedFile posted_file = context.Request.Files["file"];
FileUploadRequest file_upload = new FileUploadRequest();
file_upload.session_id = context.Request.Form["session_id"];
file_upload.project_name = context.Request.Form["project_name"];
file_upload.project_type = "abc";
file_upload.file_name = posted_file.FileName;
file_upload.file_size = posted_file.ContentLength;
file_upload.file_object = posted_file;
file_upload.file_data = file_upload.ConvertToByteArray(posted_file);
#endregion
#region Transfer file if valid
if (file_upload.file_data.Length > 0 && file_upload.file_data.Length < 10485761 && file_upload.CheckExtension() && IsValidHost)
{
#region Content
string form_dataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
string form_contentType = "multipart/form-data; boundary=" + form_dataBoundary;
string file_contentType = "application/octet-stream";
string form_useragent = "example_upload.ashx";
string form_method = "POST";
// compose as stream
Stream form_dataStream = new System.IO.MemoryStream();
string post_vkey = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}", form_dataBoundary, "vkey", service_vkey);
form_dataStream.Write(Encoding.UTF8.GetBytes(post_vkey), 0, Encoding.UTF8.GetByteCount(post_vkey));
string post_session = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}", form_dataBoundary, "web_session_id", file_upload.session_id);
form_dataStream.Write(Encoding.UTF8.GetBytes("\r\n"), 0, Encoding.UTF8.GetByteCount("\r\n"));
form_dataStream.Write(Encoding.UTF8.GetBytes(post_session), 0, Encoding.UTF8.GetByteCount(post_session));
string post_project = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}", form_dataBoundary, "project_name", file_upload.project_name);
form_dataStream.Write(Encoding.UTF8.GetBytes("\r\n"), 0, Encoding.UTF8.GetByteCount("\r\n"));
form_dataStream.Write(Encoding.UTF8.GetBytes(post_project), 0, Encoding.UTF8.GetByteCount(post_project));
string post_type = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}", form_dataBoundary, "project_type", file_upload.project_type);
form_dataStream.Write(Encoding.UTF8.GetBytes("\r\n"), 0, Encoding.UTF8.GetByteCount("\r\n"));
form_dataStream.Write(Encoding.UTF8.GetBytes(post_type), 0, Encoding.UTF8.GetByteCount(post_type));
string file_header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n", form_dataBoundary, "file", file_upload.file_name, file_contentType);
form_dataStream.Write(Encoding.UTF8.GetBytes(file_header), 0, Encoding.UTF8.GetByteCount(file_header));
form_dataStream.Write(file_upload.file_data, 0, file_upload.file_data.Length);
string form_footer = "\r\n--" + form_dataBoundary + "--\r\n";
form_dataStream.Write(Encoding.UTF8.GetBytes(form_footer), 0, Encoding.UTF8.GetByteCount(form_footer));
// convert to byte array
form_dataStream.Position = 0;
byte[] form_data = new byte[form_dataStream.Length];
form_dataStream.Read(form_data, 0, form_data.Length);
form_dataStream.Close();
#endregion
#region Request
Uri xfer_uri = new Uri(string.Format("https://{0}/{1}", data_server, target_page));
HttpWebRequest xfer_request = (HttpWebRequest)WebRequest.Create(xfer_uri);
xfer_request.PreAuthenticate = true;
xfer_request.Credentials = new NetworkCredential(ssl_username, ssl_password);
xfer_request.Method = form_method;
xfer_request.ContentType = form_contentType;
xfer_request.UserAgent = form_useragent;
xfer_request.Headers.Add("X-vkey", service_vkey);
xfer_request.Headers.Add("X-SessionID", file_upload.session_id);
xfer_request.Headers.Add("X-ProjectName", file_upload.project_name);
xfer_request.Headers.Add("X-ProjectType", file_upload.project_type);
xfer_request.Headers.Add("X-FileName", file_upload.file_name);
xfer_request.Headers.Add("X-FileSize", file_upload.file_size.ToString());
xfer_request.ContentLength = form_data.Length;
xfer_request.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
xfer_request.KeepAlive = false;
using (Stream xfer_stream = xfer_request.GetRequestStream())
{
xfer_stream.Write(form_data, 0, form_data.Length);
xfer_stream.Close();
}
#endregion
#region Response
HttpWebResponse xfer_response = (HttpWebResponse)xfer_request.GetResponse();
HttpStatusCode xfer_status = xfer_response.StatusCode;
string xfer_code = ((int)(xfer_response.StatusCode)).ToString();
string xfer_description = xfer_response.StatusDescription;
string status_string = String.Empty;
if (xfer_status == HttpStatusCode.OK)
{
StreamReader response_reader = new StreamReader(xfer_response.GetResponseStream());
string response_content = response_reader.ReadToEnd();
xfer_response.Close();
FileUploadResponse FileUpload_Response = js_outbound.Deserialize<FileUploadResponse>(response_content);
// validate vkey to ensure source of response
if (!FileUpload_Response.vkey.Equals(service_vkey))
{
package.status = 7;
status_string = String.Format("Failure [{0}] : ", xfer_code);
package.message = String.Concat(status_string, "Invalid service key");
}
else
{
switch (FileUpload_Response.status.ToLower())
{
case "good":
package.status = 1;
break;
case "bad_session_id":
package.status = 6;
break;
case "failure":
package.status = 0;
break;
default:
package.status = 0;
break;
}
package.message = String.IsNullOrEmpty(FileUpload_Response.description) ? "No explanation provided by server" : FileUpload_Response.description;
}
}
else
{
package.status = 0;
status_string = String.Format("Failure [{0}] : ", xfer_code);
package.message = String.Concat(status_string, "JSON reply unavailable");
}
#endregion
}
else
{
package.status = 0;
if (!IsValidHost)
{
package.message = "Abort: invalid host";
}
else
{
package.message = file_upload.CheckExtension() ? String.Format("Abort: file byte array length ({0}) invalid", file_upload.file_data.Length.ToString()) : "Abort: invalid file extension";
}
}
#endregion
}
catch (Exception ex)
{
package.status = 0;
package.message = ex.Message;
}
#endregion
context.Response.ContentType = "application/json";
context.Response.ContentEncoding = Encoding.UTF8;
context.Response.Write(response.Serialize(package));
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment