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.
245 lines
7.5 KiB
245 lines
7.5 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Web;
|
|
using Web.Core;
|
|
using FLocal.Common;
|
|
using FLocal.Common.dataobjects;
|
|
using FLocal.Common.actions;
|
|
using System.Xml.Linq;
|
|
using System.IO;
|
|
|
|
namespace FLocal.IISHandler {
|
|
class WebContext : FLocal.Common.UserContext {
|
|
|
|
private static readonly Encoding OutputEncoding = Encoding.UTF8;
|
|
|
|
public readonly HttpContext httpcontext;
|
|
|
|
public HttpRequest httprequest {
|
|
get {
|
|
return this.httpcontext.Request;
|
|
}
|
|
}
|
|
|
|
/*private object requestParts_Locker = new object();
|
|
private string[] requestParts_Data = null;
|
|
public string[] requestParts {
|
|
get {
|
|
if(this.requestParts_Data == null) {
|
|
lock(this.requestParts_Locker) {
|
|
if(this.requestParts_Data == null) {
|
|
this.requestParts_Data = this.httprequest.Path.Split("/", StringSplitOptions.RemoveEmptyEntries);
|
|
}
|
|
}
|
|
}
|
|
return this.requestParts_Data;
|
|
}
|
|
}*/
|
|
|
|
public XElement exportRequestParameters() {
|
|
return new XElement("get",
|
|
from i in Enumerable.Range(0, this.httprequest.QueryString.Count)
|
|
where this.httprequest.QueryString.GetKey(i) != null
|
|
select new XElement("param",
|
|
new XAttribute("name", this.httprequest.QueryString.GetKey(i)),
|
|
this.httprequest.QueryString[i]
|
|
)
|
|
);
|
|
}
|
|
|
|
public HttpResponse httpresponse {
|
|
get {
|
|
return this.httpcontext.Response;
|
|
}
|
|
}
|
|
|
|
public IUserSettings userSettings {
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public override FLocal.Common.IOutputParams outputParams {
|
|
get {
|
|
return this.design;
|
|
}
|
|
}
|
|
|
|
public readonly designs.IDesign design;
|
|
|
|
public override string formatDateTime(DateTime dateTime) {
|
|
return dateTime.ToString();
|
|
}
|
|
|
|
public override System.Xml.Linq.XElement formatTotalPosts(long posts) {
|
|
return PageOuter.create(this.userSettings.postsPerPage, posts).exportToXml(2, 0, 2);
|
|
}
|
|
|
|
public DateTime requestTime {
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public Session session;
|
|
|
|
public override Account account {
|
|
get {
|
|
if(this.session == null) {
|
|
return null;
|
|
}
|
|
return this.session.account;
|
|
}
|
|
}
|
|
|
|
public override PostVisibilityEnum isPostVisible(Post post) {
|
|
return this.userSettings.isPostVisible(post);
|
|
}
|
|
|
|
private designs.IDesign detectDesign() {
|
|
switch(this.httprequest.Url.Port % 1000) {
|
|
case 445:
|
|
return new designs.Raw();
|
|
case 447:
|
|
return new designs.Lite();
|
|
case 449:
|
|
return new designs.Rss();
|
|
case 451:
|
|
return new designs.Classic();
|
|
case 443:
|
|
default:
|
|
string[] parts = this.httprequest.Url.Host.Split('.');
|
|
switch(parts[0].ToLower()) {
|
|
case "raw":
|
|
return new designs.Raw();
|
|
case "lite":
|
|
return new designs.Lite();
|
|
case "rss":
|
|
return new designs.Rss();
|
|
case "classic":
|
|
return new designs.Classic();
|
|
case "modern":
|
|
default:
|
|
return new designs.Modern();
|
|
}
|
|
}
|
|
}
|
|
|
|
public WebContext(HttpContext httpcontext) {
|
|
this.httpcontext = httpcontext;
|
|
this.requestTime = DateTime.Now;
|
|
this.design = this.detectDesign();
|
|
|
|
HttpCookie sessionCookie = this.httprequest.Cookies[Config.instance.CookiesPrefix + "_session"];
|
|
if(sessionCookie != null && sessionCookie.Value != null && sessionCookie.Value != "") {
|
|
try {
|
|
var session = Session.LoadByKey(sessionCookie.Value);
|
|
var tmp = session.account;
|
|
string lastUrl = null;
|
|
if(this.httprequest.RequestType == "GET") {
|
|
if(this.design.IsHuman) {
|
|
lastUrl = this.httprequest.Path;
|
|
}
|
|
}
|
|
session.updateLastActivity(lastUrl);
|
|
HttpCookie newCookie = this.createCookie(Config.instance.CookiesPrefix + "_session");
|
|
newCookie.Value = session.sessionKey;
|
|
newCookie.Expires = DateTime.Now.AddSeconds(Config.instance.SessionLifetime);
|
|
this.httpresponse.AppendCookie(newCookie);
|
|
this.session = session;
|
|
} catch(NotFoundInDBException) {
|
|
sessionCookie.Value = "";
|
|
sessionCookie.Expires = DateTime.Now.AddDays(-1);
|
|
this.httpresponse.AppendCookie(sessionCookie);
|
|
//throw; //TODO: remove me!
|
|
}
|
|
}
|
|
if(this.session != null) {
|
|
this.userSettings = AccountSettings.LoadByAccount(this.session.account);
|
|
} else {
|
|
this.userSettings = new AnonymousUserSettings(null);
|
|
}
|
|
}
|
|
|
|
public void WriteTransformResult(string templateName, System.Xml.Linq.XDocument data) {
|
|
this.httpresponse.ContentType = this.design.ContentType;
|
|
this.httpresponse.ContentEncoding = OutputEncoding;
|
|
DateTime start = DateTime.Now;
|
|
TemplateEngine.WriteCompiled(this.design.GetFSName(templateName), data, this.httpresponse.Output);
|
|
Config.instance.Logger.Log(templateName + " transformation took " + (DateTime.Now-start).TotalSeconds + " seconds");
|
|
}
|
|
|
|
public XElement exportSession() {
|
|
if(this.session != null) {
|
|
return session.exportToXml(this);
|
|
} else {
|
|
return new XElement("session",
|
|
new XElement("notLoggedIn", true)
|
|
);
|
|
}
|
|
}
|
|
|
|
private void AddCommonData(HttpCookie cookie) {
|
|
cookie.HttpOnly = true;
|
|
cookie.Secure = Config.instance.forceHttps;
|
|
cookie.Domain = "." + String.Join(".", this.httprequest.Url.Host.Split(".", StringSplitOptions.RemoveEmptyEntries).Slice(1).ToArray());
|
|
cookie.Path = "/";
|
|
}
|
|
|
|
public HttpCookie createCookie(string name) {
|
|
HttpCookie result = new HttpCookie(name);
|
|
this.AddCommonData(result);
|
|
return result;
|
|
}
|
|
|
|
public Web.Core.Network.IPv4Address remoteHost {
|
|
get {
|
|
return new Web.Core.Network.IPv4Address(this.httprequest.UserHostAddress);
|
|
}
|
|
}
|
|
|
|
private static readonly Type BaseType = (new object()).GetType();
|
|
private string getFullTypeName(Type type, int allowedIterations) {
|
|
if(allowedIterations <= 0 || type.BaseType == null || type.BaseType.FullName == BaseType.FullName || type.BaseType.FullName == type.FullName) {
|
|
return type.FullName;
|
|
} else {
|
|
return type.FullName + " : " + getFullTypeName(type.BaseType, allowedIterations-1);
|
|
}
|
|
}
|
|
|
|
public void LogError(Exception e) {
|
|
string dir;
|
|
if(e is AccessDeniedException) {
|
|
dir = FLocal.Common.Config.instance.dataDir + "Logs\\AccessDenied\\";
|
|
} else {
|
|
dir = FLocal.Common.Config.instance.dataDir + "Logs\\";
|
|
}
|
|
using(StreamWriter writer = new StreamWriter(dir + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + "." + e.GetGuid().ToString() + ".txt")) {
|
|
writer.WriteLine("Requested url: " + this.httprequest.Url.ToString());
|
|
foreach(string key in this.httprequest.Form.Keys) {
|
|
writer.WriteLine(string.Format("Form[{0}]: {1}", key, this.httprequest.Form[key]));
|
|
}
|
|
writer.WriteLine("Remote ip: " + this.httprequest.UserHostAddress);
|
|
if(this.httprequest.UrlReferrer != null) {
|
|
writer.WriteLine("Referer: " + this.httprequest.UrlReferrer.ToString());
|
|
}
|
|
if(this.httprequest.Cookies[Config.instance.CookiesPrefix + "_session"] != null) {
|
|
writer.WriteLine("Session: " + this.httprequest.Cookies[Config.instance.CookiesPrefix + "_session"].Value);
|
|
}
|
|
writer.WriteLine();
|
|
|
|
writer.WriteLine("Exception: " + getFullTypeName(e.GetType(), 20));
|
|
writer.WriteLine("Guid: " + e.GetGuid().ToString());
|
|
writer.WriteLine(e.Message);
|
|
if(e is FLocalException) {
|
|
writer.WriteLine(((FLocalException)e).FullStackTrace);
|
|
} else {
|
|
writer.WriteLine(e.StackTrace);
|
|
}
|
|
writer.WriteLine("==============================");
|
|
writer.WriteLine(e.ToString());
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|