Skip to content

Commit 98dbb93

Browse files
committed
Merge pull request #4 from ellemayo/master
Optimization
2 parents 59d51d2 + 06e4e72 commit 98dbb93

File tree

1 file changed

+206
-178
lines changed

1 file changed

+206
-178
lines changed

jQueryFileUpload/Upload.ashx.cs

+206-178
Original file line numberDiff line numberDiff line change
@@ -1,183 +1,211 @@
1-
using System;
21
using System.Collections.Generic;
32
using System.IO;
4-
using System.Security.AccessControl;
53
using System.Web;
64
using System.Web.Script.Serialization;
75

8-
namespace jQueryUploadTest {
9-
public class Upload : IHttpHandler {
10-
public class FilesStatus {
11-
public string thumbnail_url { get; set; }
12-
public string name { get; set; }
13-
public string url { get; set; }
14-
public int size { get; set; }
15-
public string type { get; set; }
16-
public string delete_url { get; set; }
17-
public string delete_type { get; set; }
18-
public string error { get; set; }
19-
public string progress { get; set; }
20-
}
21-
private readonly JavaScriptSerializer js = new JavaScriptSerializer();
22-
private string ingestPath;
23-
public bool IsReusable { get { return false; } }
24-
public void ProcessRequest (HttpContext context) {
25-
var r = context.Response;
26-
ingestPath = @"C:\temp\ingest\";
27-
28-
r.AddHeader("Pragma", "no-cache");
29-
r.AddHeader("Cache-Control", "private, no-cache");
30-
31-
HandleMethod(context);
32-
}
33-
34-
private void HandleMethod (HttpContext context) {
35-
switch (context.Request.HttpMethod) {
36-
case "HEAD":
37-
case "GET":
38-
ServeFile(context);
39-
break;
40-
41-
case "POST":
42-
UploadFile(context);
43-
break;
44-
45-
case "DELETE":
46-
DeleteFile(context);
47-
break;
48-
49-
default:
50-
context.Response.ClearHeaders();
51-
context.Response.StatusCode = 405;
52-
break;
53-
}
54-
}
55-
56-
private void DeleteFile (HttpContext context) {
57-
var filePath = ingestPath + context.Request["f"];
58-
if (File.Exists(filePath)) {
59-
File.Delete(filePath);
60-
}
61-
}
62-
63-
private void UploadFile (HttpContext context) {
64-
var statuses = new List<FilesStatus>();
65-
var headers = context.Request.Headers;
66-
67-
if (string.IsNullOrEmpty(headers["X-File-Name"])) {
68-
UploadWholeFile(context, statuses);
69-
} else {
70-
UploadPartialFile(headers["X-File-Name"], context, statuses);
71-
}
72-
73-
74-
WriteJsonIframeSafe(context, statuses);
75-
}
76-
77-
private void UploadPartialFile (string fileName, HttpContext context, List<FilesStatus> statuses) {
78-
if (context.Request.Files.Count != 1) throw new HttpRequestValidationException("Attempt to upload chunked file containing more than one fragment per request");
79-
var inputStream = context.Request.Files[0].InputStream;
80-
var fullName = ingestPath + Path.GetFileName(fileName);
81-
82-
using (var fs = new FileStream(fullName, FileMode.Append, FileAccess.Write)) {
83-
var buffer = new byte[1024];
84-
85-
var l = inputStream.Read(buffer, 0, 1024);
86-
while (l > 0) {
87-
fs.Write(buffer,0,l);
88-
l = inputStream.Read(buffer, 0, 1024);
89-
}
90-
fs.Flush();
91-
fs.Close();
92-
}
93-
94-
statuses.Add(new FilesStatus {
95-
thumbnail_url = "Thumbnail.ashx?f=" + fileName,
96-
url = "Upload.ashx?f=" + fileName,
97-
name = fileName,
98-
size = (int)(new FileInfo(fullName)).Length,
99-
type = "image/png",
100-
delete_url = "Upload.ashx?f=" + fileName,
101-
delete_type = "DELETE",
102-
progress = "1.0"
103-
});
104-
105-
}
106-
107-
private void UploadWholeFile(HttpContext context, List<FilesStatus> statuses) {
108-
for (int i = 0; i < context.Request.Files.Count; i++) {
109-
var file = context.Request.Files[i];
110-
file.SaveAs(ingestPath + Path.GetFileName(file.FileName));
111-
var fname = Path.GetFileName(file.FileName);
112-
statuses.Add(new FilesStatus
113-
{
114-
thumbnail_url = "Thumbnail.ashx?f=" + fname,
115-
url = "Upload.ashx?f=" + fname,
116-
name = fname,
117-
size = file.ContentLength,
118-
type = "image/png",
119-
delete_url = "Upload.ashx?f=" + fname,
120-
delete_type = "DELETE",
121-
progress = "1.0"
122-
});
123-
}
124-
}
125-
126-
private void WriteJsonIframeSafe(HttpContext context, List<FilesStatus> statuses) {
127-
context.Response.AddHeader("Vary", "Accept");
128-
try {
129-
if (context.Request["HTTP_ACCEPT"].Contains("application/json")) {
130-
context.Response.ContentType = "application/json";
131-
} else {
132-
context.Response.ContentType = "text/plain";
133-
}
134-
} catch {
135-
context.Response.ContentType = "text/plain";
136-
}
137-
138-
var jsonObj = js.Serialize(statuses.ToArray());
139-
context.Response.Write(jsonObj);
140-
}
141-
142-
private void ServeFile (HttpContext context) {
143-
if (string.IsNullOrEmpty(context.Request["f"])) ListCurrentFiles(context);
144-
else DeliverFile(context);
145-
}
146-
147-
private void DeliverFile (HttpContext context) {
148-
var filePath = ingestPath + context.Request["f"];
149-
if (File.Exists(filePath)) {
150-
context.Response.ContentType = "application/octet-stream";
151-
context.Response.WriteFile(filePath);
152-
context.Response.AddHeader("Content-Disposition", "attachment, filename=\"" + context.Request["f"] + "\"");
153-
} else {
154-
context.Response.StatusCode = 404;
155-
}
156-
}
157-
158-
private void ListCurrentFiles (HttpContext context) {
159-
var files = new List<FilesStatus>();
160-
161-
var names = Directory.GetFiles(@"C:\temp\ingest", "*", SearchOption.TopDirectoryOnly);
162-
163-
foreach (var name in names) {
164-
var f = new FileInfo(name);
165-
files.Add(new FilesStatus
166-
{
167-
thumbnail_url = "Thumbnail.ashx?f=" + f.Name,
168-
url = "Upload.ashx?f=" + f.Name,
169-
name = f.Name,
170-
size = (int)f.Length,
171-
type = "image/png",
172-
delete_url = "Upload.ashx?f=" + f.Name,
173-
delete_type = "DELETE"
174-
});
175-
}
176-
177-
context.Response.AddHeader("Content-Disposition", "inline, filename=\"files.json\"");
178-
var jsonObj = js.Serialize(files.ToArray());
179-
context.Response.Write(jsonObj);
180-
context.Response.ContentType = "application/json";
181-
}
182-
}
183-
}
6+
namespace WebInterface.General.Handlers
7+
{
8+
/// <summary>
9+
/// Summary description for ImageUpload
10+
/// </summary>
11+
public class ImageUpload : IHttpHandler
12+
{
13+
/// <summary>
14+
/// Uploaded Files
15+
/// </summary>
16+
public class FilesStatus
17+
{
18+
public string name { get; set; }
19+
public string type { get; set; }
20+
public int size { get; set; }
21+
public string progress { get; set; }
22+
public string url { get; set; }
23+
public string thumbnail_url { get; set; }
24+
public string delete_url { get; set; }
25+
public string delete_type { get; set; }
26+
public string error { get; set; }
27+
28+
public FilesStatus(){}
29+
30+
public FilesStatus(FileInfo fileInfo)
31+
{ this.SetValues(fileInfo.Name, (int)fileInfo.Length); }
32+
33+
public FilesStatus(string FileName, int FileLength)
34+
{ this.SetValues(FileName, FileLength); }
35+
36+
private void SetValues(string FileName, int FileLength)
37+
{
38+
name = FileName;
39+
type = "image/png";
40+
size = FileLength;
41+
progress = "1.0";
42+
url = HandlerPath + "Upload.ashx?f=" + FileName;
43+
thumbnail_url = HandlerPath + "Thumbnail.ashx?f=" + FileName;
44+
delete_url = HandlerPath + "Upload.ashx?f=" + FileName;
45+
delete_type = "DELETE";
46+
}
47+
}
48+
49+
private readonly JavaScriptSerializer js = new JavaScriptSerializer();
50+
private const string HandlerPath = "/";
51+
private string ImagePath;
52+
private string ThumbPath;
53+
54+
public bool IsReusable { get { return false; } }
55+
56+
// Process incoming request
57+
public void ProcessRequest(HttpContext context)
58+
{
59+
// Set the image paths
60+
ImagePath = context.Server.MapPath("~/images/");
61+
ThumbPath = context.Server.MapPath("~/images/");
62+
63+
context.Response.AddHeader("Pragma", "no-cache");
64+
context.Response.AddHeader("Cache-Control", "private, no-cache");
65+
66+
HandleMethod(context);
67+
}
68+
69+
// Handle request based on method
70+
private void HandleMethod(HttpContext context)
71+
{
72+
switch (context.Request.HttpMethod)
73+
{
74+
case "HEAD":
75+
case "GET":
76+
ServeFile(context);
77+
break;
78+
79+
case "POST":
80+
UploadFile(context);
81+
break;
82+
83+
case "DELETE":
84+
DeleteFile(context);
85+
break;
86+
87+
default:
88+
context.Response.ClearHeaders();
89+
context.Response.StatusCode = 405;
90+
break;
91+
}
92+
}
93+
94+
// Delete file from the server
95+
private void DeleteFile(HttpContext context)
96+
{
97+
var filePath = ImagePath + context.Request["f"];
98+
if (File.Exists(filePath))
99+
{
100+
File.Delete(filePath);
101+
}
102+
}
103+
104+
// Upload file to the server
105+
private void UploadFile(HttpContext context)
106+
{
107+
var statuses = new List<FilesStatus>();
108+
var headers = context.Request.Headers;
109+
110+
if (string.IsNullOrEmpty(headers["X-File-Name"]))
111+
{
112+
UploadWholeFile(context, statuses);
113+
}
114+
else
115+
{
116+
UploadPartialFile(headers["X-File-Name"], context, statuses);
117+
}
118+
119+
WriteJsonIframeSafe(context, statuses);
120+
}
121+
122+
// Upload partial file
123+
private void UploadPartialFile(string fileName, HttpContext context, List<FilesStatus> statuses)
124+
{
125+
if (context.Request.Files.Count != 1) throw new HttpRequestValidationException("Attempt to upload chunked file containing more than one fragment per request");
126+
var inputStream = context.Request.Files[0].InputStream;
127+
var fullName = ImagePath + Path.GetFileName(fileName);
128+
129+
using (var fs = new FileStream(fullName, FileMode.Append, FileAccess.Write))
130+
{
131+
var buffer = new byte[1024];
132+
133+
var l = inputStream.Read(buffer, 0, 1024);
134+
while (l > 0)
135+
{
136+
fs.Write(buffer, 0, l);
137+
l = inputStream.Read(buffer, 0, 1024);
138+
}
139+
fs.Flush();
140+
fs.Close();
141+
}
142+
statuses.Add(new FilesStatus(new FileInfo(fullName)));
143+
}
144+
145+
// Upload entire file
146+
private void UploadWholeFile(HttpContext context, List<FilesStatus> statuses)
147+
{
148+
for (int i = 0; i < context.Request.Files.Count; i++)
149+
{
150+
var file = context.Request.Files[i];
151+
file.SaveAs(ImagePath + Path.GetFileName(file.FileName));
152+
153+
string fullName = Path.GetFileName(file.FileName);
154+
statuses.Add(new FilesStatus(fullName, file.ContentLength));
155+
}
156+
}
157+
158+
private void WriteJsonIframeSafe(HttpContext context, List<FilesStatus> statuses)
159+
{
160+
context.Response.AddHeader("Vary", "Accept");
161+
try
162+
{
163+
if (context.Request["HTTP_ACCEPT"].Contains("application/json"))
164+
context.Response.ContentType = "application/json";
165+
else
166+
context.Response.ContentType = "text/plain";
167+
}
168+
catch
169+
{
170+
context.Response.ContentType = "text/plain";
171+
}
172+
173+
var jsonObj = js.Serialize(statuses.ToArray());
174+
context.Response.Write(jsonObj);
175+
}
176+
177+
private void ServeFile(HttpContext context)
178+
{
179+
if (string.IsNullOrEmpty(context.Request["f"])) ListCurrentFiles(context);
180+
else DeliverFile(context);
181+
}
182+
183+
private void DeliverFile(HttpContext context)
184+
{
185+
string filePath = ThumbPath + context.Request["f"];
186+
187+
if (File.Exists(filePath))
188+
{
189+
context.Response.ContentType = "application/octet-stream";
190+
context.Response.WriteFile(filePath);
191+
context.Response.AddHeader("Content-Disposition", "attachment, filename=\"" + context.Request["f"] + "\"");
192+
}
193+
else
194+
context.Response.StatusCode = 404;
195+
}
196+
197+
private void ListCurrentFiles(HttpContext context)
198+
{
199+
var FileList = new List<FilesStatus>();
200+
var names = Directory.GetFiles(ImagePath, "*", SearchOption.TopDirectoryOnly);
201+
202+
foreach (var name in names)
203+
FileList.Add(new FilesStatus(new FileInfo(name)));
204+
205+
string jsonObj = js.Serialize(FileList.ToArray());
206+
context.Response.AddHeader("Content-Disposition", "inline, filename=\"files.json\"");
207+
context.Response.Write(jsonObj);
208+
context.Response.ContentType = "application/json";
209+
}
210+
}
211+
}

0 commit comments

Comments
 (0)