An alternative to UBB.threads
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
FLocal/Web.IISUploadHandler/UploadHandler.cs

83 lines
3.0 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using Web.Core;
namespace Web.IISUploadHandler {
class UploadHandler : IHttpHandler {
public bool IsReusable {
get {
return true;
}
}
public void ProcessRequest(HttpContext httpcontext) {
if(httpcontext.Request.Path.ToLower() == "/upload/") {
this.ProcessUpload(httpcontext);
} else if(httpcontext.Request.Path.ToLower().StartsWith("/data/")) {
this.ProcessRetrieve(httpcontext);
} else {
throw new HttpException(403, "wrong url");
}
}
private static string getFilePath(string md5, string extension) {
foreach(char chr in (md5 + extension)) {
if(!Char.IsLetterOrDigit(chr)) throw new HttpException(403, "wrong md5 or extension");
}
return Config.instance.storageDir + md5.PHPSubstring(0, 2) + Path.DirectorySeparatorChar + md5.PHPSubstring(2, 2) + Path.DirectorySeparatorChar + md5.PHPSubstring(4) + "." + extension;
}
private static void CreateDirectoryIfNotExists(DirectoryInfo directoryInfo) {
if(!directoryInfo.Exists) {
CreateDirectoryIfNotExists(directoryInfo.Parent);
directoryInfo.Create();
}
}
private void ProcessUpload(HttpContext context) {
byte[] data = new byte[context.Request.InputStream.Length];
if(context.Request.InputStream.Read(data, 0, (int)context.Request.InputStream.Length) != context.Request.InputStream.Length) {
throw new FLocalException("File is not uploaded correctly");
}
string file_md5 = Util.md5(context.Request.InputStream);
string md5 = Util.md5(file_md5 + " " + Config.instance.salt);
if(md5 != context.Request.QueryString["signature"]) {
throw new HttpException(403, "signature mismatch");
}
string filePath = getFilePath(file_md5, context.Request.QueryString["extension"]);
CreateDirectoryIfNotExists((new FileInfo(filePath)).Directory);
using(FileStream stream = new FileStream(filePath, FileMode.CreateNew)) {
stream.Write(data, 0, data.Length);
}
context.Response.Write("OK");
}
private void ProcessRetrieve(HttpContext context) {
string[] requestParts = context.Request.Path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
if(requestParts.Length != 2) throw new HttpException(403, "wrong url");
string[] fileParts = requestParts[1].Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
if(fileParts.Length != 2) throw new HttpException(403, "wrong url");
string mime = Util.getMimeByExtension(fileParts[1]);
if(mime == null) throw new FLocalException("unknown extension '" + fileParts[1] + "'");
context.Response.ContentType = mime;
context.Response.Cache.SetExpires(DateTime.Now.AddDays(10));
context.Response.Cache.SetLastModified(DateTime.Now.AddYears(-1));
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.TransmitFile(getFilePath(fileParts[0], fileParts[1]));
}
}
}