URLs processing refactored

main
Inga 🏳‍🌈 14 years ago
parent 52352ecadd
commit 6fd2df43f2
  1. 2
      Builder/IISMainHandler/build.txt
  2. 43
      Common/Common.csproj
  3. 44
      Common/URL/AbstractUrl.cs
  4. 28
      Common/URL/QuickLink.cs
  5. 24
      Common/URL/Robots.cs
  6. 24
      Common/URL/Static.cs
  7. 327
      Common/URL/UrlManager.cs
  8. 25
      Common/URL/forum/AllPosts.cs
  9. 25
      Common/URL/forum/AllThreads.cs
  10. 24
      Common/URL/forum/Boards.cs
  11. 28
      Common/URL/forum/board/Headlines.cs
  12. 28
      Common/URL/forum/board/NewThread.cs
  13. 28
      Common/URL/forum/board/Threads.cs
  14. 28
      Common/URL/forum/board/thread/Posts.cs
  15. 30
      Common/URL/forum/board/thread/post/Edit.cs
  16. 30
      Common/URL/forum/board/thread/post/PMReply.cs
  17. 30
      Common/URL/forum/board/thread/post/Punish.cs
  18. 30
      Common/URL/forum/board/thread/post/Reply.cs
  19. 30
      Common/URL/forum/board/thread/post/Show.cs
  20. 25
      Common/URL/maintenance/CleanCache.cs
  21. 24
      Common/URL/maintenance/LocalNetworks.cs
  22. 24
      Common/URL/my/Avatars.cs
  23. 24
      Common/URL/my/Settings.cs
  24. 24
      Common/URL/my/UserData.cs
  25. 28
      Common/URL/my/conversations/Conversation.cs
  26. 24
      Common/URL/my/conversations/List.cs
  27. 24
      Common/URL/my/conversations/NewPM.cs
  28. 28
      Common/URL/my/conversations/Reply.cs
  29. 24
      Common/URL/my/login/Login.cs
  30. 24
      Common/URL/my/login/Migrate.cs
  31. 24
      Common/URL/my/login/RegisterByInvite.cs
  32. 28
      Common/URL/polls/Info.cs
  33. 24
      Common/URL/polls/NewPoll.cs
  34. 49
      Common/URL/upload/Item.cs
  35. 24
      Common/URL/upload/List.cs
  36. 24
      Common/URL/upload/New.cs
  37. 25
      Common/URL/users/Active.cs
  38. 25
      Common/URL/users/All.cs
  39. 25
      Common/URL/users/Online.cs
  40. 28
      Common/URL/users/user/Abstract.cs
  41. 18
      Common/URL/users/user/Info.cs
  42. 18
      Common/URL/users/user/PollsParticipated.cs
  43. 18
      Common/URL/users/user/Posts.cs
  44. 18
      Common/URL/users/user/Replies.cs
  45. 18
      Common/URL/users/user/Threads.cs
  46. 295
      IISMainHandler/HandlersFactory.cs
  47. 3
      IISMainHandler/IISMainHandler.csproj
  48. 10
      IISMainHandler/PageOuter.cs
  49. 4
      IISMainHandler/WebContext.cs
  50. 22
      IISMainHandler/handlers/AbstractGetHandler.cs
  51. 6
      IISMainHandler/handlers/BoardHandler.cs
  52. 2
      IISMainHandler/handlers/BoardsHandler.cs
  53. 4
      IISMainHandler/handlers/PostHandler.cs
  54. 26
      IISMainHandler/handlers/StaticHandler.cs
  55. 17
      IISMainHandler/handlers/ThreadHandler.cs
  56. 9
      IISMainHandler/handlers/request/MarkThreadAsReadHandler.cs
  57. 4
      IISMainHandler/handlers/response/AbstractNewMessageHandler.cs
  58. 14
      IISMainHandler/handlers/response/AbstractUserGetHandler.cs
  59. 3
      IISMainHandler/handlers/response/ActiveAccountListHandler.cs
  60. 8
      IISMainHandler/handlers/response/AllPostsHandler.cs
  61. 8
      IISMainHandler/handlers/response/AllThreadsHandler.cs
  62. 2
      IISMainHandler/handlers/response/AvatarsSettingsHandler.cs
  63. 6
      IISMainHandler/handlers/response/BoardAsThread.cs
  64. 17
      IISMainHandler/handlers/response/ConversationHandler.cs
  65. 4
      IISMainHandler/handlers/response/ConversationsHandler.cs
  66. 2
      IISMainHandler/handlers/response/CreatePollHandler.cs
  67. 4
      IISMainHandler/handlers/response/CreateThreadHandler.cs
  68. 4
      IISMainHandler/handlers/response/EditHandler.cs
  69. 42
      IISMainHandler/handlers/response/LegacyPHPHandler.cs
  70. 36
      IISMainHandler/handlers/response/LegacyUploadHandler.cs
  71. 2
      IISMainHandler/handlers/response/LocalNetworksListHandler.cs
  72. 2
      IISMainHandler/handlers/response/LoginHandler.cs
  73. 6
      IISMainHandler/handlers/response/MigrateAccountHandler.cs
  74. 4
      IISMainHandler/handlers/response/PMReplyHandler.cs
  75. 4
      IISMainHandler/handlers/response/PMReplyToPostHandler.cs
  76. 6
      IISMainHandler/handlers/response/PMSendHandler.cs
  77. 4
      IISMainHandler/handlers/response/PollHandler.cs
  78. 4
      IISMainHandler/handlers/response/PunishHandler.cs
  79. 4
      IISMainHandler/handlers/response/QuickLinkHandler.cs
  80. 2
      IISMainHandler/handlers/response/RedirectGetHandler.cs
  81. 7
      IISMainHandler/handlers/response/RegisterByInviteHandler.cs
  82. 4
      IISMainHandler/handlers/response/ReplyHandler.cs
  83. 10
      IISMainHandler/handlers/response/RobotsHandler.cs
  84. 2
      IISMainHandler/handlers/response/SettingsHandler.cs
  85. 9
      IISMainHandler/handlers/response/SkipXsltTransformException.cs
  86. 7
      IISMainHandler/handlers/response/UploadHandler.cs
  87. 4
      IISMainHandler/handlers/response/UploadListHandler.cs
  88. 2
      IISMainHandler/handlers/response/UploadNewHandler.cs
  89. 2
      IISMainHandler/handlers/response/UserDataHandler.cs
  90. 2
      IISMainHandler/handlers/response/UserInfoHandler.cs
  91. 4
      IISMainHandler/handlers/response/UserListHandler.cs
  92. 8
      IISMainHandler/handlers/response/UserPollsParticipatedHandler.cs
  93. 8
      IISMainHandler/handlers/response/UserPostsHandler.cs
  94. 8
      IISMainHandler/handlers/response/UserRepliesHandler.cs
  95. 8
      IISMainHandler/handlers/response/UserThreadsHandler.cs
  96. 2
      IISMainHandler/handlers/response/WhoIsOnlineHandler.cs
  97. 2
      IISMainHandler/handlers/response/maintenance/CleanCacheHandler.cs
  98. 2
      templates/Full/Login.xslt
  99. 2
      templates/Lite/Login.xslt

@ -128,6 +128,49 @@
<Compile Include="UBBParser.cs" />
<Compile Include="BBCodes\I.cs" />
<Compile Include="UploadManager.cs" />
<Compile Include="URL\AbstractUrl.cs" />
<Compile Include="URL\forum\AllPosts.cs" />
<Compile Include="URL\forum\AllThreads.cs" />
<Compile Include="URL\forum\Boards.cs" />
<Compile Include="URL\forum\board\Headlines.cs" />
<Compile Include="URL\forum\board\NewThread.cs" />
<Compile Include="URL\forum\board\Threads.cs" />
<Compile Include="URL\forum\board\thread\post\Edit.cs" />
<Compile Include="URL\forum\board\thread\post\PMReply.cs" />
<Compile Include="URL\forum\board\thread\post\Punish.cs" />
<Compile Include="URL\forum\board\thread\post\Reply.cs" />
<Compile Include="URL\forum\board\thread\post\Show.cs" />
<Compile Include="URL\forum\board\thread\Posts.cs" />
<Compile Include="URL\maintenance\CleanCache.cs" />
<Compile Include="URL\maintenance\LocalNetworks.cs" />
<Compile Include="URL\my\Avatars.cs" />
<Compile Include="URL\my\conversations\Conversation.cs" />
<Compile Include="URL\my\conversations\List.cs" />
<Compile Include="URL\my\conversations\NewPM.cs" />
<Compile Include="URL\my\conversations\Reply.cs" />
<Compile Include="URL\my\UserData.cs" />
<Compile Include="URL\my\login\Login.cs" />
<Compile Include="URL\my\login\Migrate.cs" />
<Compile Include="URL\my\login\RegisterByInvite.cs" />
<Compile Include="URL\my\Settings.cs" />
<Compile Include="URL\polls\Info.cs" />
<Compile Include="URL\polls\NewPoll.cs" />
<Compile Include="URL\QuickLink.cs" />
<Compile Include="URL\Robots.cs" />
<Compile Include="URL\Static.cs" />
<Compile Include="URL\upload\Item.cs" />
<Compile Include="URL\upload\List.cs" />
<Compile Include="URL\upload\New.cs" />
<Compile Include="URL\UrlManager.cs" />
<Compile Include="URL\users\Active.cs" />
<Compile Include="URL\users\All.cs" />
<Compile Include="URL\users\Online.cs" />
<Compile Include="URL\users\user\Abstract.cs" />
<Compile Include="URL\users\user\Info.cs" />
<Compile Include="URL\users\user\PollsParticipated.cs" />
<Compile Include="URL\users\user\Posts.cs" />
<Compile Include="URL\users\user\Replies.cs" />
<Compile Include="URL\users\user\Threads.cs" />
<Compile Include="UserContext.cs" />
<Compile Include="UserSettingsGateway.cs" />
</ItemGroup>

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Core;
namespace FLocal.Common.URL {
public abstract class AbstractUrl {
protected AbstractUrl(string remainder) {
this.remainder = remainder;
}
public string remainder {
get;
private set;
}
abstract public string title {
get;
}
abstract protected string _canonical {
get;
}
public string canonical {
get {
string result = this._canonical;
//if(!result.StartsWith("/")) result = "/" + result;
//if(!result.EndsWith("/")) result = result + "/";
return result;
}
}
public string canonicalFull {
get {
if(this.remainder == null) throw new CriticalException("Remainder is null");
return this.canonical + this.remainder;
}
}
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL {
public class QuickLink : AbstractUrl {
public readonly dataobjects.QuickLink link;
public QuickLink(string quickLinkId, string remainder) : base(remainder) {
this.link = dataobjects.QuickLink.LoadByName(quickLinkId);
}
public override string title {
get {
return this.link.name;
}
}
protected override string _canonical {
get {
return "/q/" + this.link.name;
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL {
public class Robots : AbstractUrl {
public Robots() : base("") {
}
public override string title {
get {
return "robots.txt";
}
}
protected override string _canonical {
get {
return "/robots.txt";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL {
public class Static : AbstractUrl {
public Static(string remainder) : base(remainder) {
}
public override string title {
get {
return this.remainder;
}
}
protected override string _canonical {
get {
return "/static/";
}
}
}
}

@ -0,0 +1,327 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
namespace FLocal.Common.URL {
public static class UrlManager {
private static string GetRemainder(string[] requestParts, int start) {
return string.Join("/", (from i in Enumerable.Range(start, requestParts.Length - start) select requestParts[i]).ToArray());
}
public static AbstractUrl Parse(string Path, NameValueCollection Query, bool isLoggedIn) {
string[] requestParts = Path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
if(requestParts.Length < 1) {
return new forum.Boards(GetRemainder(requestParts, 0));
}
#region legacy
if(Path.ToLower().StartsWith("/user/upload/")) {
return new upload.Item(requestParts[2], GetRemainder(requestParts, 3));
}
if(Path.EndsWith(".php")) {
string[] scriptParts = Path.Split('.');
if(scriptParts.Length != 2) {
return null;
}
switch(scriptParts[0].ToLower()) {
case "showflat":
case "ashowflat":
dataobjects.Post post = dataobjects.Post.LoadById(int.Parse(Query["Number"]));
return new forum.board.thread.Posts(post.threadId.ToString(), "p" + post.id.ToString());
case "showthreaded":
case "ashowthreaded":
return new forum.board.thread.post.Show(Query["Number"], "");
case "postlist":
return new forum.board.Threads(dataobjects.Board.LoadByLegacyName(Query["Board"]).id.ToString(), "");
case "showprofile":
return new users.user.Info(Query["User"], "");
default:
return null;
}
}
if(Path.ToLower().StartsWith("/images/graemlins/")) {
return new Static("smileys/" + GetRemainder(requestParts, 2));
}
#endregion
#region robots
if(Path.ToLower().StartsWith("/robots.txt")) {
return new Robots();
}
#endregion
switch(requestParts[0].ToLower()) {
#region newlegacy
case "allposts":
return new forum.AllPosts(GetRemainder(requestParts, 1));
case "allthreads":
return new forum.AllThreads(GetRemainder(requestParts, 1));
case "boards":
return new forum.Boards(GetRemainder(requestParts, 1));
case "board":
if(requestParts.Length < 2) {
return null;
}
if(requestParts.Length == 2) {
return new forum.board.Threads(requestParts[1], "");
}
switch(requestParts[2].ToLower()) {
case "threads":
return new forum.board.Threads(requestParts[1], GetRemainder(requestParts, 3));
case "headlines":
return new forum.board.Headlines(requestParts[1], GetRemainder(requestParts, 3));
case "newthread":
return new forum.board.NewThread(requestParts[1], GetRemainder(requestParts, 3));
default:
return new forum.board.Threads(requestParts[1], GetRemainder(requestParts, 2));
}
case "boardasthread":
return new forum.board.Headlines(requestParts[1], GetRemainder(requestParts, 2));
case "thread":
return new forum.board.thread.Posts(requestParts[1], GetRemainder(requestParts, 2));
case "post":
if(requestParts.Length < 2) {
return null;
}
if(requestParts.Length == 2) {
return new forum.board.thread.post.Show(requestParts[1], "");
}
switch(requestParts[2].ToLower()) {
case "edit":
return new forum.board.thread.post.Edit(requestParts[1], "");
case "reply":
return new forum.board.thread.post.Reply(requestParts[1], "");
case "pmreply":
return new forum.board.thread.post.PMReply(requestParts[1], "");
case "punish":
return new forum.board.thread.post.Punish(requestParts[1], "");
default:
return null;
}
case "registerbyinvite":
return new my.login.RegisterByInvite(GetRemainder(requestParts, 1));
case "user":
return new users.user.Info(requestParts[1], GetRemainder(requestParts, 2));
#endregion newlegacy
#region forum
case "forum":
if(requestParts.Length == 1) {
return new forum.Boards("");
}
switch(requestParts[1].ToLower()) {
case "board":
if(requestParts.Length == 2) {
return null;
}
if(requestParts.Length == 3) {
return new forum.board.Threads(requestParts[2], "");
}
switch(requestParts[3].ToLower()) {
case "headlines":
return new forum.board.Headlines(requestParts[2], GetRemainder(requestParts, 4));
case "newthread":
return new forum.board.NewThread(requestParts[2], GetRemainder(requestParts, 4));
case "thread":
if(requestParts.Length == 4) {
return null;
}
if(requestParts.Length == 5) {
return new forum.board.thread.Posts(requestParts[4], "");
}
switch(requestParts[5].ToLower()) {
case "post":
if(requestParts.Length == 6) {
return null;
}
if(requestParts.Length == 7) {
return new forum.board.thread.post.Show(requestParts[6], "");
}
switch(requestParts[7].ToLower()) {
case "edit":
return new forum.board.thread.post.Edit(requestParts[6], GetRemainder(requestParts, 8));
case "pmreply":
return new forum.board.thread.post.PMReply(requestParts[6], GetRemainder(requestParts, 8));
case "punish":
return new forum.board.thread.post.Punish(requestParts[6], GetRemainder(requestParts, 8));
case "reply":
return new forum.board.thread.post.Reply(requestParts[6], GetRemainder(requestParts, 8));
case "show":
return new forum.board.thread.post.Show(requestParts[6], GetRemainder(requestParts, 8));
default:
return null;
}
case "posts":
return new forum.board.thread.Posts(requestParts[4], GetRemainder(requestParts, 6));
default:
return null;
}
case "threads":
return new forum.board.Threads(requestParts[2], GetRemainder(requestParts, 4));
default:
return null;
}
case "allposts":
return new forum.AllPosts(GetRemainder(requestParts, 2));
case "allthreads":
return new forum.AllThreads(GetRemainder(requestParts, 2));
case "boards":
return new forum.Boards(GetRemainder(requestParts, 2));
default:
return null;
}
#endregion forum
#region maintenance
case "maintenance":
if(requestParts.Length < 2) {
return null;
}
switch(requestParts[1].ToLower()) {
case "cleancache":
return new maintenance.CleanCache(GetRemainder(requestParts, 2));
case "localnetworks":
return new maintenance.LocalNetworks(GetRemainder(requestParts, 1));
default:
return null;
}
#endregion maintenance
#region my;
case "my":
if(requestParts.Length == 1) {
if(isLoggedIn) {
return new my.conversations.List("");
} else {
return new my.login.Login("");
}
}
switch(requestParts[1].ToLower()) {
case "conversations":
if(requestParts.Length == 2) {
return new my.conversations.List("");
}
switch(requestParts[2].ToLower()) {
case "conversation":
return new my.conversations.Conversation(requestParts[3], GetRemainder(requestParts, 4));
case "list":
return new my.conversations.List(GetRemainder(requestParts, 3));
case "newpm":
case "pmsend":
return new my.conversations.NewPM(GetRemainder(requestParts, 3));
case "reply":
case "pmreply":
return new my.conversations.Reply(requestParts[3], GetRemainder(requestParts, 4));
default:
return null;
}
case "login":
if(requestParts.Length == 2) {
return new my.login.Login("");
}
switch(requestParts[2].ToLower()) {
case "login":
return new my.login.Login(GetRemainder(requestParts, 3));
case "migrate":
case "migrateaccount":
return new my.login.Migrate(GetRemainder(requestParts, 3));
case "registerbyinvite":
return new my.login.RegisterByInvite(GetRemainder(requestParts, 3));
default:
return null;
}
case "avatars":
return new my.Avatars(GetRemainder(requestParts, 2));
case "settings":
return new my.Settings(GetRemainder(requestParts, 2));
case "userdata":
return new my.UserData(GetRemainder(requestParts, 2));
default:
return null;
}
#endregion my;
#region polls
case "poll":
case "polls":
if(requestParts.Length < 2) {
return null;
}
switch(requestParts[1].ToLower()) {
case "info":
return new polls.Info(requestParts[2], GetRemainder(requestParts, 3));
case "newpoll":
case "create":
return new polls.NewPoll(GetRemainder(requestParts, 2));
default:
return new polls.Info(requestParts[1], GetRemainder(requestParts, 2));
}
#endregion polls
#region upload;
case "upload":
if(requestParts.Length < 2) {
return new upload.List("");
}
switch(requestParts[1].ToLower()) {
case "item":
return new upload.Item(requestParts[2], GetRemainder(requestParts, 3));
case "list":
return new upload.List(GetRemainder(requestParts, 2));
case "new":
return new upload.New(GetRemainder(requestParts, 2));
default:
return null;
}
#endregion upload;
#region users;
case "users":
if(requestParts.Length == 1) {
return new users.All("");
}
switch(requestParts[1].ToLower()) {
case "user":
if(requestParts.Length < 3) {
return null;
}
if(requestParts.Length == 3) {
return new users.user.Info(requestParts[2], "");
}
switch(requestParts[3].ToLower()) {
case "info":
return new users.user.Info(requestParts[2], GetRemainder(requestParts, 4));
case "pollsparticipated":
return new users.user.PollsParticipated(requestParts[2], GetRemainder(requestParts, 4));
case "posts":
return new users.user.Posts(requestParts[2], GetRemainder(requestParts, 4));
case "replies":
return new users.user.Replies(requestParts[2], GetRemainder(requestParts, 4));
case "threads":
return new users.user.Threads(requestParts[2], GetRemainder(requestParts, 4));
default:
return null;
}
case "active":
return new users.Active(GetRemainder(requestParts, 2));
case "all":
return new users.All(GetRemainder(requestParts, 2));
case "online":
return new users.Online(GetRemainder(requestParts, 2));
default:
return null;
}
#endregion users;
case "q":
return new QuickLink(requestParts[1], GetRemainder(requestParts, 2));
case "robots.txt":
return new Robots();
case "static":
return new Static(GetRemainder(requestParts, 1));
default:
return null;
}
}
}
}

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.forum {
public class AllPosts : AbstractUrl {
public AllPosts(string remainder) : base(remainder) {
}
public override string title {
get {
return "All posts";
}
}
protected override string _canonical {
get {
return "/Forum/AllPosts/";
}
}
}
}

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.forum {
public class AllThreads : AbstractUrl {
public AllThreads(string remainder) : base(remainder) {
}
public override string title {
get {
return "All threads";
}
}
protected override string _canonical {
get {
return "/Forum/AllThreads/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.forum {
public class Boards : AbstractUrl {
public Boards(string remainder) : base(remainder) {
}
public override string title {
get {
return "Boards";
}
}
protected override string _canonical {
get {
return "/Forum/Boards/";
}
}
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.forum.board {
public class Headlines : AbstractUrl {
public readonly Board board;
public Headlines(string boardId, string remainder) : base(remainder) {
this.board = Board.LoadById(int.Parse(boardId));
}
public override string title {
get {
return this.board.name;
}
}
protected override string _canonical {
get {
return "/Forum/Board/" + this.board.id + "/Headlines/";
}
}
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.forum.board {
public class NewThread : AbstractUrl {
public readonly Board board;
public NewThread(string boardId, string remainder) : base(remainder) {
this.board = Board.LoadById(int.Parse(boardId));
}
public override string title {
get {
return this.board.name;
}
}
protected override string _canonical {
get {
return "/Forum/Board/" + this.board.id + "/NewThread/";
}
}
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.forum.board {
public class Threads : AbstractUrl {
public readonly Board board;
public Threads(string boardId, string remainder) : base(remainder) {
this.board = Board.LoadById(int.Parse(boardId));
}
public override string title {
get {
return this.board.name;
}
}
protected override string _canonical {
get {
return "/Forum/Board/" + this.board.id + "/Threads/";
}
}
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.forum.board.thread {
public class Posts : AbstractUrl {
public readonly dataobjects.Thread thread;
public Posts(string threadId, string remainder) : base(remainder) {
this.thread = dataobjects.Thread.LoadById(int.Parse(threadId));
}
public override string title {
get {
return this.thread.title;
}
}
protected override string _canonical {
get {
return "/Forum/Board/" + this.thread.boardId + "/Thread/" + this.thread.id + "/Posts/";
}
}
}
}

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.forum.board.thread.post {
public class Edit : AbstractUrl {
public Post post;
public Edit(string postId, string remainder) : base(remainder) {
this.post = Post.LoadById(int.Parse(postId));
}
public override string title {
get {
return post.title;
}
}
protected override string _canonical {
get {
return "/Forum/Board/" + this.post.thread.boardId + "/Thread/" + this.post.threadId + "/Post/" + post.id + "/Edit/";
}
}
}
}

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.forum.board.thread.post {
public class PMReply : AbstractUrl {
public Post post;
public PMReply(string postId, string remainder) : base(remainder) {
this.post = Post.LoadById(int.Parse(postId));
}
public override string title {
get {
return post.title;
}
}
protected override string _canonical {
get {
return "/Forum/Board/" + this.post.thread.boardId + "/Thread/" + this.post.threadId + "/Post/" + post.id + "/PMReply/";
}
}
}
}

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.forum.board.thread.post {
public class Punish : AbstractUrl {
public Post post;
public Punish(string postId, string remainder) : base(remainder) {
this.post = Post.LoadById(int.Parse(postId));
}
public override string title {
get {
return post.title;
}
}
protected override string _canonical {
get {
return "/Forum/Board/" + this.post.thread.boardId + "/Thread/" + this.post.threadId + "/Post/" + post.id + "/Punish/";
}
}
}
}

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.forum.board.thread.post {
public class Reply : AbstractUrl {
public Post post;
public Reply(string postId, string remainder) : base(remainder) {
this.post = Post.LoadById(int.Parse(postId));
}
public override string title {
get {
return post.title;
}
}
protected override string _canonical {
get {
return "/Forum/Board/" + this.post.thread.boardId + "/Thread/" + this.post.threadId + "/Post/" + post.id + "/Reply/";
}
}
}
}

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.forum.board.thread.post {
public class Show : AbstractUrl {
public Post post;
public Show(string postId, string remainder) : base(remainder) {
this.post = Post.LoadById(int.Parse(postId));
}
public override string title {
get {
return post.title;
}
}
protected override string _canonical {
get {
return "/Forum/Board/" + this.post.thread.boardId + "/Thread/" + this.post.threadId + "/Post/" + post.id + "/Show/";
}
}
}
}

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.maintenance {
public class CleanCache : AbstractUrl {
public CleanCache(string remainder) : base(remainder) {
}
public override string title {
get {
return "Maintenance :: Clean cache";
}
}
protected override string _canonical {
get {
return "/Maintenance/CleanCache/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.maintenance {
public class LocalNetworks : AbstractUrl {
public LocalNetworks(string remainder) : base(remainder) {
}
public override string title {
get {
return "Local networks";
}
}
protected override string _canonical {
get {
return "/Maintenance/LocalNetworks/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.my {
public class Avatars : AbstractUrl {
public Avatars(string remainder) : base(remainder) {
}
public override string title {
get {
return "Avatars settings";
}
}
protected override string _canonical {
get {
return "/My/Avatars/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.my {
public class Settings : AbstractUrl {
public Settings(string remainder) : base(remainder) {
}
public override string title {
get {
return "Settings";
}
}
protected override string _canonical {
get {
return "/My/Settings/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.my {
public class UserData : AbstractUrl {
public UserData(string remainder) : base(remainder) {
}
public override string title {
get {
return "Change user data";
}
}
protected override string _canonical {
get {
return "/My/UserData/";
}
}
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.my.conversations {
public class Conversation : AbstractUrl {
public Account interlocutor;
public Conversation(string interlocutorId, string remainder) : base(remainder) {
this.interlocutor = Account.LoadById(int.Parse(interlocutorId));
}
public override string title {
get {
return this.interlocutor.user.name;
}
}
protected override string _canonical {
get {
return "/My/Conversations/Conversation/" + this.interlocutor.id + "/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.my.conversations {
public class List : AbstractUrl {
public List(string remainder) : base(remainder) {
}
public override string title {
get {
return "Conversations";
}
}
protected override string _canonical {
get {
return "/My/Conversations/List/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.my.conversations {
public class NewPM : AbstractUrl {
public NewPM(string remainder) : base(remainder) {
}
public override string title {
get {
return "New PM";
}
}
protected override string _canonical {
get {
return "/My/Conversations/NewPM/";
}
}
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.my.conversations {
public class Reply : AbstractUrl {
public PMMessage pm;
public Reply(string pmId, string remainder) : base(remainder) {
this.pm = PMMessage.LoadById(int.Parse(pmId));
}
public override string title {
get {
return this.pm.title;
}
}
protected override string _canonical {
get {
return "/My/Conversations/Reply/" + this.pm.id + "/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.my.login {
public class Login : AbstractUrl {
public Login(string remainder) : base(remainder) {
}
public override string title {
get {
return "Login";
}
}
protected override string _canonical {
get {
return "/My/Login/Login/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.my.login {
public class Migrate : AbstractUrl {
public Migrate(string remainder) : base(remainder) {
}
public override string title {
get {
return "Migrate";
}
}
protected override string _canonical {
get {
return "/My/Login/Migrate/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.my.login {
public class RegisterByInvite : AbstractUrl {
public RegisterByInvite(string remainder) : base(remainder) {
}
public override string title {
get {
return "Register by invite";
}
}
protected override string _canonical {
get {
return "/My/Login/RegisterByInvite/";
}
}
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.polls {
public class Info : AbstractUrl {
public readonly Poll poll;
public Info(string pollId, string remainder) : base(remainder) {
this.poll = Poll.LoadById(int.Parse(pollId));
}
public override string title {
get {
return this.poll.title;
}
}
protected override string _canonical {
get {
return "/Polls/Info/" + this.poll.id + "/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.polls {
public class NewPoll : AbstractUrl {
public NewPoll(string remainder) : base(remainder) {
}
public override string title {
get {
return "New poll";
}
}
protected override string _canonical {
get {
return "/Polls/NewPoll/";
}
}
}
}

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Core;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.upload {
public class Item : AbstractUrl {
public readonly Upload upload;
public Item(string uploadId, string remainder) : base(remainder) {
int iUploadId;
if(!int.TryParse(uploadId, out iUploadId)) {
string[] parts = uploadId.Split('.');
if(parts.Length != 2) throw new FLocalException("wrong url");
if(parts[0].Substring(0, 4).ToLower() != "file") throw new FLocalException("wrong url");
int rawFileNum = int.Parse(parts[0].Substring(4));
switch(parts[1].ToLower()) {
case "jpg":
iUploadId = rawFileNum;
break;
case "gif":
iUploadId = 500000 + rawFileNum;
break;
case "png":
iUploadId = 600000 + rawFileNum;
break;
default:
throw new FLocalException("wrong url");
}
}
this.upload = Upload.LoadById(iUploadId);
}
public override string title {
get {
return this.upload.filename;
}
}
protected override string _canonical {
get {
return "/Upload/Item/" + this.upload.id + "/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.upload {
public class List : AbstractUrl {
public List(string remainder) : base(remainder) {
}
public override string title {
get {
return "Uploads list";
}
}
protected override string _canonical {
get {
return "/Upload/List/";
}
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.upload {
public class New : AbstractUrl {
public New(string remainder) : base(remainder) {
}
public override string title {
get {
return "Upload new file";
}
}
protected override string _canonical {
get {
return "/Upload/New/";
}
}
}
}

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.users {
public class Active : AbstractUrl {
public Active(string remainder) : base(remainder) {
}
public override string title {
get {
return "Active users";
}
}
protected override string _canonical {
get {
return "/Users/Active/";
}
}
}
}

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.users {
public class All : AbstractUrl {
public All(string remainder) : base(remainder) {
}
public override string title {
get {
return "All users";
}
}
protected override string _canonical {
get {
return "/Users/All/";
}
}
}
}

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.users {
public class Online : AbstractUrl {
public Online(string remainder) : base(remainder) {
}
public override string title {
get {
return "Who is online";
}
}
protected override string _canonical {
get {
return "/Users/Online/";
}
}
}
}

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Common.dataobjects;
namespace FLocal.Common.URL.users.user {
public abstract class Abstract : AbstractUrl {
public readonly User user;
public Abstract(string userId, string remainder) : base(remainder) {
int iUserId;
if(int.TryParse(userId, out iUserId)) {
this.user = User.LoadById(iUserId);
} else {
this.user = User.LoadByName(userId);
}
}
public override string title {
get {
return this.user.name;
}
}
}
}

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.users.user {
public class Info : Abstract {
public Info(string userId, string remainder) : base(userId, remainder) {
}
protected override string _canonical {
get {
return "/Users/User/" + this.user.id + "/Info/";
}
}
}
}

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.users.user {
public class PollsParticipated : Abstract {
public PollsParticipated(string userId, string remainder) : base(userId, remainder) {
}
protected override string _canonical {
get {
return "/Users/User/" + this.user.id + "/PollsParticipated/";
}
}
}
}

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.users.user {
public class Posts : Abstract {
public Posts(string userId, string remainder) : base(userId, remainder) {
}
protected override string _canonical {
get {
return "/Users/User/" + this.user.id + "/Posts/";
}
}
}
}

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.users.user {
public class Replies : Abstract {
public Replies(string userId, string remainder) : base(userId, remainder) {
}
protected override string _canonical {
get {
return "/Users/User/" + this.user.id + "/Replies/";
}
}
}
}

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.URL.users.user {
public class Threads : Abstract {
public Threads(string userId, string remainder) : base(userId, remainder) {
}
protected override string _canonical {
get {
return "/Users/User/" + this.user.id + "/Threads/";
}
}
}
}

@ -4,215 +4,71 @@ using System.Linq;
using System.Text;
using System.Web;
using FLocal.Core;
using FLocal.Common.URL;
using URL = FLocal.Common.URL;
namespace FLocal.IISHandler {
class HandlersFactory {
public static ISpecificHandler getHandler(WebContext context) {
// if(!context.httprequest.Path.EndsWith("/")) {
// return new handlers.WrongUrlHandler();
// throw new FLocalException("Malformed url");
// }
if(context.requestParts.Length < 1) {
//return new handlers.RootHandler();
throw new RedirectException("/Boards/");
}
#region legacy
if(context.httprequest.Path.ToLower().StartsWith("/user/upload/")) {
return new handlers.response.LegacyUploadHandler();
}
if(context.httprequest.Path.EndsWith(".php")) {
return new handlers.response.LegacyPHPHandler();
}
if(context.httprequest.Path.ToLower().StartsWith("/images/graemlins/")) {
throw new RedirectException("/static/smileys/" + context.requestParts[2]);
}
#endregion
private static readonly Dictionary<Type, Func<AbstractUrl, ISpecificHandler>> handlersDictionary = new Dictionary<Type,Func<AbstractUrl,ISpecificHandler>> {
{ typeof(URL.forum.AllPosts),CreateHandler<URL.forum.AllPosts, handlers.response.AllPostsHandler> },
{ typeof(URL.forum.AllThreads), CreateHandler<URL.forum.AllThreads, handlers.response.AllThreadsHandler> },
{ typeof(URL.forum.board.Headlines), CreateHandler<URL.forum.board.Headlines, handlers.response.BoardAsThreadHandler> },
{ typeof(URL.forum.board.NewThread), CreateHandler<URL.forum.board.NewThread, handlers.response.CreateThreadHandler> },
{ typeof(URL.forum.board.thread.post.Edit), CreateHandler<URL.forum.board.thread.post.Edit, handlers.response.EditHandler> },
{ typeof(URL.forum.board.thread.post.PMReply), CreateHandler<URL.forum.board.thread.post.PMReply, handlers.response.PMReplyToPostHandler> },
{ typeof(URL.forum.board.thread.post.Punish), CreateHandler<URL.forum.board.thread.post.Punish, handlers.response.PunishHandler> },
{ typeof(URL.forum.board.thread.post.Reply), CreateHandler<URL.forum.board.thread.post.Reply, handlers.response.ReplyHandler> },
{ typeof(URL.forum.board.thread.post.Show), CreateHandler<URL.forum.board.thread.post.Show, handlers.PostHandler> },
{ typeof(URL.forum.board.thread.Posts), CreateHandler<URL.forum.board.thread.Posts, handlers.ThreadHandler> },
{ typeof(URL.forum.board.Threads), CreateHandler<URL.forum.board.Threads, handlers.BoardHandler> },
{ typeof(URL.forum.Boards), CreateHandler<URL.forum.Boards, handlers.BoardsHandler> },
{ typeof(URL.maintenance.CleanCache), CreateHandler<URL.maintenance.CleanCache, handlers.response.maintenance.CleanCacheHandler> },
{ typeof(URL.maintenance.LocalNetworks), CreateHandler<URL.maintenance.LocalNetworks, handlers.response.LocalNetworksListHandler> },
{ typeof(URL.my.Avatars), CreateHandler<URL.my.Avatars, handlers.response.AvatarsSettingsHandler> },
{ typeof(URL.my.conversations.Conversation), CreateHandler<URL.my.conversations.Conversation, handlers.response.ConversationHandler> },
{ typeof(URL.my.conversations.List), CreateHandler<URL.my.conversations.List, handlers.response.ConversationsHandler> },
{ typeof(URL.my.conversations.NewPM), CreateHandler<URL.my.conversations.NewPM, handlers.response.PMSendHandler> },
{ typeof(URL.my.conversations.Reply), CreateHandler<URL.my.conversations.Reply, handlers.response.PMReplyHandler> },
{ typeof(URL.my.login.Login), CreateHandler<URL.my.login.Login, handlers.response.LoginHandler> },
{ typeof(URL.my.login.Migrate), CreateHandler<URL.my.login.Migrate, handlers.response.MigrateAccountHandler> },
{ typeof(URL.my.login.RegisterByInvite), CreateHandler<URL.my.login.RegisterByInvite, handlers.response.RegisterByInviteHandler> },
{ typeof(URL.my.Settings), CreateHandler<URL.my.Settings, handlers.response.SettingsHandler> },
{ typeof(URL.my.UserData), CreateHandler<URL.my.UserData, handlers.response.UserDataHandler> },
{ typeof(URL.polls.Info), CreateHandler<URL.polls.Info, handlers.response.PollHandler> },
{ typeof(URL.polls.NewPoll), CreateHandler<URL.polls.NewPoll, handlers.response.CreatePollHandler> },
{ typeof(URL.QuickLink), CreateHandler<URL.QuickLink, handlers.response.QuickLinkHandler> },
{ typeof(URL.Robots), CreateHandler<URL.Robots, handlers.response.RobotsHandler> },
{ typeof(URL.Static), CreateHandler<URL.Static, handlers.StaticHandler> },
{ typeof(URL.upload.Item), CreateHandler<URL.upload.Item, handlers.response.UploadHandler> },
{ typeof(URL.upload.List), CreateHandler<URL.upload.List, handlers.response.UploadListHandler> },
{ typeof(URL.upload.New), CreateHandler<URL.upload.New, handlers.response.UploadNewHandler> },
{ typeof(URL.users.Active), CreateHandler<URL.users.Active, handlers.response.ActiveAccountListHandler> },
{ typeof(URL.users.All), CreateHandler<URL.users.All, handlers.response.UserListHandler> },
{ typeof(URL.users.Online), CreateHandler<URL.users.Online, handlers.response.WhoIsOnlineHandler> },
{ typeof(URL.users.user.Info), CreateHandler<URL.users.user.Info, handlers.response.UserInfoHandler> },
{ typeof(URL.users.user.PollsParticipated), CreateHandler<URL.users.user.PollsParticipated, handlers.response.UserPollsParticipatedHandler> },
{ typeof(URL.users.user.Posts), CreateHandler<URL.users.user.Posts, handlers.response.UserPostsHandler> },
{ typeof(URL.users.user.Replies), CreateHandler<URL.users.user.Replies, handlers.response.UserRepliesHandler> },
{ typeof(URL.users.user.Threads), CreateHandler<URL.users.user.Threads, handlers.response.UserThreadsHandler> },
};
#region robots
if(context.httprequest.Path.ToLower().StartsWith("/robots.txt")) {
return new handlers.response.RobotsHandler();
private static ISpecificHandler CreateHandler<TUrl, THandler>(AbstractUrl url)
where TUrl : AbstractUrl
where THandler : handlers.AbstractGetHandler<TUrl>, new()
{
return new THandler() {
url = (TUrl)url
};
}
#endregion
switch(context.requestParts[0].ToLower()) {
case "q":
return new handlers.response.QuickLinkHandler();
case "allposts":
return new handlers.response.AllPostsHandler();
case "allthreads":
return new handlers.response.AllThreadsHandler();
case "boards":
return new handlers.BoardsHandler();
case "board":
if(context.requestParts.Length < 2) {
return new handlers.WrongUrlHandler();
}
if(context.requestParts.Length == 2) {
return new handlers.BoardHandler();
}
switch(context.requestParts[2].ToLower()) {
case "newthread":
return new handlers.response.CreateThreadHandler();
default:
return new handlers.BoardHandler();
}
case "boardasthread":
return new handlers.response.BoardAsThreadHandler();
case "thread":
return new handlers.ThreadHandler();
case "post":
if(context.requestParts.Length < 2) {
return new handlers.WrongUrlHandler();
}
if(context.requestParts.Length == 2) {
return new handlers.PostHandler();
}
switch(context.requestParts[2].ToLower()) {
case "edit":
return new handlers.response.EditHandler();
case "reply":
return new handlers.response.ReplyHandler();
case "pmreply":
return new handlers.response.PMReplyToPostHandler();
case "punish":
return new handlers.response.PunishHandler();
default:
return new handlers.WrongUrlHandler();
}
case "my":
if(context.requestParts.Length == 1) {
if(context.account != null) {
throw new RedirectException("/My/Conversations/");
} else {
throw new RedirectException("/My/Login/");
}
}
switch(context.requestParts[1].ToLower()) {
case "login":
if(context.requestParts.Length == 2) {
return new handlers.response.LoginHandler();
} else {
switch(context.requestParts[2].ToLower()) {
case "migrateaccount":
return new handlers.response.MigrateAccountHandler();
case "registerbyinvite":
return new handlers.response.RegisterByInviteHandler();
default:
return new handlers.WrongUrlHandler();
}
}
case "settings":
return new handlers.response.SettingsHandler();
case "userdata":
return new handlers.response.UserDataHandler();
case "avatars":
return new handlers.response.AvatarsSettingsHandler();
case "conversations":
if(context.requestParts.Length == 2) {
return new handlers.response.ConversationsHandler();
} else {
switch(context.requestParts[2].ToLower()) {
case "conversation":
return new handlers.response.ConversationHandler();
case "pmsend":
return new handlers.response.PMSendHandler();
case "pmreply":
return new handlers.response.PMReplyHandler();
default:
return new handlers.response.ConversationsHandler();
}
}
default:
return new handlers.WrongUrlHandler();
}
case "users":
if(context.requestParts.Length == 1) {
throw new RedirectException("/Users/All/");
}
switch(context.requestParts[1].ToLower()) {
case "all":
return new handlers.response.UserListHandler();
case "active":
return new handlers.response.ActiveAccountListHandler();
case "online":
return new handlers.response.WhoIsOnlineHandler();
case "user":
if(context.requestParts.Length < 3) {
return new handlers.WrongUrlHandler();
}
if(context.requestParts.Length == 3) {
throw new RedirectException("/Users/User/" + context.requestParts[2] + "/Info/");
}
switch(context.requestParts[3].ToLower()) {
case "info":
return new handlers.response.UserInfoHandler();
case "threads":
return new handlers.response.UserThreadsHandler();
case "posts":
return new handlers.response.UserPostsHandler();
case "replies":
return new handlers.response.UserRepliesHandler();
case "pollsparticipated":
return new handlers.response.UserPollsParticipatedHandler();
default:
return new handlers.WrongUrlHandler();
}
default:
return new handlers.WrongUrlHandler();
}
case "upload":
if(context.requestParts.Length < 2) {
throw new RedirectException("/Upload/List/");
}
switch(context.requestParts[1].ToLower()) {
case "item":
return new handlers.response.UploadHandler();
case "new":
return new handlers.response.UploadNewHandler();
case "list":
return new handlers.response.UploadListHandler();
default:
return new handlers.WrongUrlHandler();
}
case "maintenance":
if(context.requestParts.Length < 2) {
return new handlers.WrongUrlHandler();
}
switch(context.requestParts[1].ToLower()) {
case "cleancache":
return new handlers.response.maintenance.CleanCacheHandler();
default:
return new handlers.WrongUrlHandler();
}
case "poll":
if(context.requestParts.Length < 2) {
return new handlers.WrongUrlHandler();
}
switch(context.requestParts[1].ToLower()) {
case "create":
return new handlers.response.CreatePollHandler();
default:
return new handlers.response.PollHandler();
public static ISpecificHandler getHandler(WebContext context) {
if(context.httprequest.Path.ToLower().StartsWith("/do/")) {
string action = context.httprequest.Path.ToLower().Substring(4).Trim('/');
if(action.StartsWith("markthreadasread")) {
return new handlers.request.MarkThreadAsReadHandler();
}
case "localnetworks":
return new handlers.response.LocalNetworksListHandler();
case "static":
return new handlers.StaticHandler(context.requestParts);
case "registerbyinvite":
string[] rbi_parts = context.requestParts;
rbi_parts[0] = "My/Login/RegisterByInvite";
throw new RedirectException("/" + string.Join("/", rbi_parts));
case "user":
string[] u_parts = context.requestParts;
u_parts[0] = "Users/User";
throw new RedirectException("/" + string.Join("/", u_parts));
case "do":
if(context.requestParts.Length < 2) {
return new handlers.WrongUrlHandler();
} else {
switch(context.requestParts[1].ToLower()) {
switch(action) {
case "login":
return new handlers.request.LoginHandler();
case "logout":
@ -237,45 +93,36 @@ namespace FLocal.IISHandler {
return new handlers.request.UserDataHandler();
case "sendpm":
return new handlers.request.SendPMHandler();
case "markthreadasread":
return new handlers.request.MarkThreadAsReadHandler();
case "upload":
return new handlers.request.UploadHandler();
case "newpoll":
return new handlers.request.CreatePollHandler();
case "vote":
return new handlers.request.VoteHandler();
case "avatars":
if(context.requestParts.Length < 3) {
return new handlers.WrongUrlHandler();
}
switch(context.requestParts[2].ToLower()) {
case "add":
case "avatars/add":
return new handlers.request.avatars.AddHandler();
case "remove":
case "avatars/remove":
return new handlers.request.avatars.RemoveHandler();
case "setasdefault":
case "avatars/setasdefault":
return new handlers.request.avatars.SetAsDefaultHandler();
default:
return new handlers.WrongUrlHandler();
}
case "maintenance":
if(context.requestParts.Length < 3) {
return new handlers.WrongUrlHandler();
}
switch(context.requestParts[2].ToLower()) {
case "cleancache":
case "maintenance/cleancache":
return new handlers.request.maintenance.CleanCacheHandler();
default:
return new handlers.WrongUrlHandler();
}
default:
return new handlers.WrongUrlHandler();
}
}
default:
AbstractUrl url = UrlManager.Parse(context.httprequest.Path, context.httprequest.QueryString, context.account != null);
if(url == null) {
return new handlers.WrongUrlHandler();
}
if(!context.httprequest.Path.StartsWith(url.canonical)) {
throw new RedirectException(url.canonicalFull);
}
return handlersDictionary[url.GetType()](url);
}
}

@ -89,8 +89,6 @@
<Compile Include="handlers\response\CreatePollHandler.cs" />
<Compile Include="handlers\response\CreateThreadHandler.cs" />
<Compile Include="handlers\response\EditHandler.cs" />
<Compile Include="handlers\response\LegacyPHPHandler.cs" />
<Compile Include="handlers\response\LegacyUploadHandler.cs" />
<Compile Include="handlers\response\LocalNetworksListHandler.cs" />
<Compile Include="handlers\response\LoginHandler.cs" />
<Compile Include="handlers\response\maintenance\CleanCacheHandler.cs" />
@ -152,6 +150,7 @@
<Compile Include="handlers\response\AbstractUserGetHandler.cs" />
<Compile Include="handlers\response\AllThreadsHandler.cs" />
<Compile Include="handlers\response\AvatarsSettingsHandler.cs" />
<Compile Include="handlers\response\SkipXsltTransformException.cs" />
<Compile Include="handlers\response\UserDataHandler.cs" />
<Compile Include="handlers\response\UserThreadsHandler.cs" />
</ItemGroup>

@ -47,7 +47,9 @@ namespace FLocal.IISHandler {
return result;
}
public static PageOuter createFromGet(string[] requestParts, long perPage, Dictionary<char, Func<long>> customAction, int offset) {
public static PageOuter createFromUrl(FLocal.Common.URL.AbstractUrl url, long perPage, Dictionary<char, Func<string, long>> customAction) {
string[] requestParts = url.remainder.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
int offset = 0;
bool reversed = (requestParts.Length > (offset+1)) && (requestParts[offset+1].ToLower() == "reversed");
if(requestParts.Length > offset) {
if(requestParts[offset].ToLower() == "all") {
@ -55,15 +57,15 @@ namespace FLocal.IISHandler {
} else if(Char.IsDigit(requestParts[offset][0])) {
return new PageOuter(long.Parse(requestParts[offset]), perPage, perPage, reversed);
} else {
return new PageOuter(customAction[requestParts[offset][0]](), perPage, perPage, reversed);
return new PageOuter(customAction[requestParts[offset][0]](requestParts[offset].Substring(1)), perPage, perPage, reversed);
}
} else {
return new PageOuter(0, perPage, perPage, reversed);
}
}
public static PageOuter createFromGet(string[] requestParts, long perPage, int offset) {
return createFromGet(requestParts, perPage, new Dictionary<char, Func<long>>(), offset);
public static PageOuter createFromUrl(FLocal.Common.URL.AbstractUrl url, long perPage) {
return createFromUrl(url, perPage, new Dictionary<char, Func<string, long>>());
}
public XElement exportToXml(int left, int current, int right) {

@ -23,7 +23,7 @@ namespace FLocal.IISHandler {
}
}
private object requestParts_Locker = new object();
/*private object requestParts_Locker = new object();
private string[] requestParts_Data = null;
public string[] requestParts {
get {
@ -36,7 +36,7 @@ namespace FLocal.IISHandler {
}
return this.requestParts_Data;
}
}
}*/
public XElement exportRequestParameters() {
return new XElement("get",

@ -4,8 +4,10 @@ using System.Linq;
using System.Text;
using System.Xml.Linq;
using FLocal.Common;
using FLocal.Common.URL;
namespace FLocal.IISHandler.handlers {
abstract class AbstractGetHandler : ISpecificHandler {
abstract protected string templateName {
@ -14,7 +16,7 @@ namespace FLocal.IISHandler.handlers {
abstract protected IEnumerable<XElement> getSpecificData(WebContext context);
protected IEnumerable<XElement> getCommonData(WebContext context) {
virtual protected IEnumerable<XElement> getCommonData(WebContext context) {
return new XElement[] {
new XElement(
"url",
@ -27,7 +29,6 @@ namespace FLocal.IISHandler.handlers {
context.exportSession(),
context.userSettings.skin.exportToXml(),
context.userSettings.machichara.exportToXml(),
new XElement("currentUrl", "/" + String.Join("/", context.requestParts) + "/"),
context.exportRequestParameters(),
};
}
@ -44,6 +45,7 @@ namespace FLocal.IISHandler.handlers {
public void Handle(WebContext context) {
try {
context.WriteTransformResult(this.templateName, this.getData(context));
} catch(response.SkipXsltTransformException) {
} catch(RedirectException) {
throw;
} catch(WrongUrlException) {
@ -55,4 +57,20 @@ namespace FLocal.IISHandler.handlers {
}
}
abstract class AbstractGetHandler<TUrl> : AbstractGetHandler where TUrl : AbstractUrl {
public TUrl url;
protected override IEnumerable<XElement> getCommonData(WebContext context) {
return base.getCommonData(context).Concat(
new XElement[] {
new XElement("currentUrl", this.url.canonicalFull),
new XElement("currentBaseUrl", this.url.canonical),
}
);
}
}
}

@ -11,7 +11,7 @@ using FLocal.Core.DB;
namespace FLocal.IISHandler.handlers {
class BoardHandler : AbstractGetHandler {
class BoardHandler : AbstractGetHandler<FLocal.Common.URL.forum.board.Threads> {
override protected string templateName {
get {
@ -20,8 +20,8 @@ namespace FLocal.IISHandler.handlers {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
Board board = Board.LoadById(int.Parse(context.requestParts[1]));
PageOuter pageOuter = PageOuter.createFromGet(context.requestParts, context.userSettings.threadsPerPage, 2);
Board board = this.url.board;
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.threadsPerPage);
IEnumerable<Thread> threads = board.getThreads(pageOuter, pageOuter.descendingDirection);
XElement[] result = new XElement[] {
new XElement("currentLocation", board.exportToXmlSimpleWithParent(context)),

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers {
class BoardsHandler : AbstractGetHandler {
class BoardsHandler : AbstractGetHandler<FLocal.Common.URL.forum.Boards> {
override protected string templateName {
get {

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers {
class PostHandler : AbstractGetHandler {
class PostHandler : AbstractGetHandler<FLocal.Common.URL.forum.board.thread.post.Show> {
override protected string templateName {
get {
@ -19,7 +19,7 @@ namespace FLocal.IISHandler.handlers {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
Post post = Post.LoadById(int.Parse(context.requestParts[1]));
Post post = this.url.post;
int lastReadId = 0;
if(context.session != null) {

@ -8,28 +8,26 @@ using System.IO;
using FLocal.Core;
namespace FLocal.IISHandler.handlers {
class StaticHandler : ISpecificHandler {
class StaticHandler : AbstractGetHandler<FLocal.Common.URL.Static> {
private string[] requestParts;
public StaticHandler(string[] requestParts) {
this.requestParts = requestParts;
protected override string templateName {
get {
return null;
}
public void Handle(WebContext context) {
if(this.requestParts.Length < 2) {
//throw new HttpException(403, "listing not allowed");
throw new WrongUrlException();
}
protected override IEnumerable<System.Xml.Linq.XElement> getSpecificData(WebContext context) {
string[] requestParts = this.url.remainder.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
Regex checker = new Regex("^[a-z][0-9a-z\\-_]*(\\.[a-zA-Z]+)?$", RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Singleline);
string path = "";
for(int i=1; i<this.requestParts.Length; i++) {
if(!checker.IsMatch(this.requestParts[i])) {
for(int i=0; i<requestParts.Length; i++) {
if(!checker.IsMatch(requestParts[i])) {
//throw new HttpException(400, "wrong url (checker='" + checker.ToString() + "'; string='" + this.requestParts[i] + "'");
throw new WrongUrlException();
}
path += FLocal.Common.Config.instance.DirSeparator + this.requestParts[i];
path += FLocal.Common.Config.instance.DirSeparator + requestParts[i];
}
string fullPath = FLocal.Common.Config.instance.dataDir + "Static" + path;
@ -56,6 +54,8 @@ namespace FLocal.IISHandler.handlers {
context.httpresponse.Cache.SetCacheability(HttpCacheability.Public);
context.httpresponse.TransmitFile(fileinfo.FullName);
throw new response.SkipXsltTransformException();
}
}

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers {
class ThreadHandler : AbstractGetHandler {
class ThreadHandler : AbstractGetHandler<FLocal.Common.URL.forum.board.thread.Posts> {
override protected string templateName {
get {
@ -21,14 +21,14 @@ namespace FLocal.IISHandler.handlers {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
Thread thread = Thread.LoadById(int.Parse(context.requestParts[1]));
PageOuter pageOuter = PageOuter.createFromGet(
context.requestParts,
Thread thread = this.url.thread;
PageOuter pageOuter = PageOuter.createFromUrl(
this.url,
context.userSettings.postsPerPage,
new Dictionary<char,Func<long>> {
new Dictionary<char,Func<string, long>> {
{
'p',
() => Config.instance.mainConnection.GetCountByConditions(
s => Config.instance.mainConnection.GetCountByConditions(
Post.TableSpec.instance,
new ComplexCondition(
ConditionsJoinType.AND,
@ -40,13 +40,12 @@ namespace FLocal.IISHandler.handlers {
new ComparisonCondition(
Post.TableSpec.instance.getIdSpec(),
ComparisonType.LESSTHAN,
int.Parse(context.requestParts[2].PHPSubstring(1)).ToString()
int.Parse(s).ToString()
)
)
)
}
},
2
}
);
IEnumerable<Post> posts = thread.getPosts(pageOuter, pageOuter.ascendingDirection);

@ -15,10 +15,13 @@ namespace FLocal.IISHandler.handlers.request {
class MarkThreadAsReadHandler : ReturnPostHandler {
protected override void _Do(WebContext context) {
string[] requestParts = context.httprequest.Path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
Account account = context.session.account;
Thread thread = Thread.LoadById(int.Parse(context.requestParts[2]));
if(!context.requestParts[3].StartsWith("p")) throw new WrongUrlException(); //throw new CriticalException("wrong url");
Post post = Post.LoadById(int.Parse(context.requestParts[3].PHPSubstring(1)));
Thread thread = Thread.LoadById(int.Parse(requestParts[2]));
if(!requestParts[3].StartsWith("p")) throw new WrongUrlException(); //throw new CriticalException("wrong url");
Post post = Post.LoadById(int.Parse(requestParts[3].PHPSubstring(1)));
if(post.thread.id != thread.id) throw new CriticalException("id mismatch");

@ -7,7 +7,7 @@ using FLocal.Core;
using FLocal.Common;
namespace FLocal.IISHandler.handlers.response {
abstract class AbstractNewMessageHandler : AbstractGetHandler {
abstract class AbstractNewMessageHandler<TUrl> : AbstractGetHandler<TUrl> where TUrl : FLocal.Common.URL.AbstractUrl {
abstract protected IEnumerable<XElement> getSpecificNewMessageData(WebContext context);
@ -20,7 +20,7 @@ namespace FLocal.IISHandler.handlers.response {
result.Add(new XElement("bodyUBB", context.httprequest.Form["Body"]));
result.Add(new XElement("bodyIntermediate", context.outputParams.preprocessBodyIntermediate(UBBParser.UBBToIntermediate(context.httprequest.Form["Body"]))));
}
return result.Union(this.getSpecificNewMessageData(context));
return result.Concat(this.getSpecificNewMessageData(context));
}
}

@ -12,20 +12,12 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
abstract class AbstractUserGetHandler : AbstractGetHandler {
abstract class AbstractUserGetHandler<TUrl> : AbstractGetHandler<TUrl> where TUrl : FLocal.Common.URL.users.user.Abstract {
abstract protected IEnumerable<XElement> getUserSpecificData(WebContext context, User user);
sealed override protected IEnumerable<XElement> getSpecificData(WebContext context) {
User user;
{
int userId;
if(int.TryParse(context.requestParts[2], out userId)) {
user = User.LoadById(userId);
} else {
user = User.LoadByName(context.requestParts[2]);
}
}
User user = this.url.user;
Account account = null;
if(context.session != null) {
try {
@ -44,7 +36,7 @@ namespace FLocal.IISHandler.handlers.response {
user.exportToXmlForViewing(context),
(account == null) ? null : new XElement("accountId", account.id.ToString()), //for PM history, PM send etc
(lastSession == null) ? null : new XElement("lastActivity", lastSession.lastHumanActivity.ToXml()),
}.Union(this.getUserSpecificData(context, user));
}.Concat(this.getUserSpecificData(context, user));
}
}

@ -11,7 +11,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class ActiveAccountListHandler : AbstractGetHandler {
class ActiveAccountListHandler : AbstractGetHandler<FLocal.Common.URL.users.Active> {
override protected string templateName {
get {
@ -20,7 +20,6 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
//PageOuter pageOuter = PageOuter.createFromGet(context.requestParts, context.userSettings.usersPerPage, 1);
PageOuter pageOuter = PageOuter.createUnlimited(context.userSettings.usersPerPage);
IEnumerable<Account> accounts = Account.LoadByIds(
from stringId in Config.instance.mainConnection.LoadIdsByConditions(

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class AllPostsHandler : AbstractGetHandler {
class AllPostsHandler : AbstractGetHandler<FLocal.Common.URL.forum.AllPosts> {
override protected string templateName {
get {
@ -21,11 +21,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
PageOuter pageOuter = PageOuter.createFromGet(
context.requestParts,
context.userSettings.postsPerPage,
1
);
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.postsPerPage);
IEnumerable<Post> posts = Post.LoadByIds(
from stringId
in Config.instance.mainConnection.LoadIdsByConditions(

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class AllThreadsHandler : AbstractGetHandler {
class AllThreadsHandler : AbstractGetHandler<FLocal.Common.URL.forum.AllThreads> {
override protected string templateName {
get {
@ -21,11 +21,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
PageOuter pageOuter = PageOuter.createFromGet(
context.requestParts,
context.userSettings.threadsPerPage,
1
);
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.threadsPerPage);
IEnumerable<Thread> threads = Thread.LoadByIds(
from stringId
in Config.instance.mainConnection.LoadIdsByConditions(

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class AvatarsSettingsHandler : AbstractGetHandler {
class AvatarsSettingsHandler : AbstractGetHandler<FLocal.Common.URL.my.Avatars> {
override protected string templateName {
get {

@ -10,7 +10,7 @@ using FLocal.Core.DB;
namespace FLocal.IISHandler.handlers.response {
class BoardAsThreadHandler : AbstractGetHandler {
class BoardAsThreadHandler : AbstractGetHandler<FLocal.Common.URL.forum.board.Headlines> {
override protected string templateName {
get {
@ -19,8 +19,8 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
Board board = Board.LoadById(int.Parse(context.requestParts[1]));
PageOuter pageOuter = PageOuter.createFromGet(context.requestParts, context.userSettings.postsPerPage, 2);
Board board = this.url.board;
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.postsPerPage);
IEnumerable<Thread> threads = board.getThreads(
pageOuter,
new SortSpec[] {

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class ConversationHandler : AbstractGetHandler {
class ConversationHandler : AbstractGetHandler<FLocal.Common.URL.my.conversations.Conversation> {
override protected string templateName {
get {
@ -21,15 +21,15 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
Account interlocutor = Account.LoadById(int.Parse(context.requestParts[3]));
Account interlocutor = this.url.interlocutor;
PMConversation conversation = PMConversation.LoadByAccounts(context.session.account, interlocutor);
PageOuter pageOuter = PageOuter.createFromGet(
context.requestParts,
PageOuter pageOuter = PageOuter.createFromUrl(
this.url,
context.userSettings.postsPerPage,
new Dictionary<char,Func<long>> {
new Dictionary<char, Func<string, long>> {
{
'p',
() => Config.instance.mainConnection.GetCountByConditions(
s => Config.instance.mainConnection.GetCountByConditions(
PMMessage.TableSpec.instance,
new ComplexCondition(
ConditionsJoinType.AND,
@ -46,13 +46,12 @@ namespace FLocal.IISHandler.handlers.response {
new ComparisonCondition(
PMMessage.TableSpec.instance.getIdSpec(),
ComparisonType.LESSTHAN,
int.Parse(context.requestParts[4].PHPSubstring(1)).ToString()
int.Parse(s).ToString()
)
)
)
}
},
4
}
);
IEnumerable<PMMessage> messages = conversation.getMessages(pageOuter, context, pageOuter.ascendingDirection);

@ -11,7 +11,7 @@ using FLocal.Core.DB;
namespace FLocal.IISHandler.handlers.response {
class ConversationsHandler : AbstractGetHandler {
class ConversationsHandler : AbstractGetHandler<FLocal.Common.URL.my.conversations.List> {
override protected string templateName {
get {
@ -20,7 +20,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
PageOuter pageOuter = PageOuter.createFromGet(context.requestParts, context.userSettings.threadsPerPage, 2);
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.threadsPerPage);
IEnumerable<PMConversation> conversations = PMConversation.getConversations(context.session.account, pageOuter, pageOuter.descendingDirection);
XElement[] result = new XElement[] {
new XElement("conversations",

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class CreatePollHandler : AbstractGetHandler {
class CreatePollHandler : AbstractGetHandler<FLocal.Common.URL.polls.NewPoll> {
override protected string templateName {
get {

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class CreateThreadHandler : AbstractNewMessageHandler {
class CreateThreadHandler : AbstractNewMessageHandler<FLocal.Common.URL.forum.board.NewThread> {
override protected string templateName {
get {
@ -19,7 +19,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificNewMessageData(WebContext context) {
Board board = Board.LoadById(int.Parse(context.requestParts[1]));
Board board = this.url.board;
return new XElement[] {
board.exportToXml(context, Board.SubboardsOptions.None),

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class EditHandler : AbstractNewMessageHandler {
class EditHandler : AbstractNewMessageHandler<FLocal.Common.URL.forum.board.thread.post.Edit> {
override protected string templateName {
get {
@ -19,7 +19,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificNewMessageData(WebContext context) {
Post post = Post.LoadById(int.Parse(context.requestParts[1]));
Post post = this.url.post;
return new XElement[] {
post.thread.board.exportToXml(context, Board.SubboardsOptions.None),

@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Core;
using FLocal.Common;
using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class LegacyPHPHandler : RedirectGetHandler {
protected override string getRedirectUrl(WebContext context) {
string[] scriptParts = context.requestParts[0].Split('.');
if(scriptParts.Length != 2) {
//throw new FLocalException("wrong url");
throw new WrongUrlException();
}
if(scriptParts[1].ToLower() != "php") {
//throw new FLocalException("wrong url");
throw new WrongUrlException();
}
switch(scriptParts[0].ToLower()) {
case "showflat":
case "ashowflat":
Post post = Post.LoadById(int.Parse(context.httprequest.QueryString["Number"]));
return "/Thread/" + post.thread.id.ToString() + "/p" + post.id.ToString();
case "showthreaded":
case "ashowthreaded":
return "/Post/" + int.Parse(context.httprequest.QueryString["Number"]).ToString() + "/";
case "postlist":
return "/Board/" + Board.LoadByLegacyName(context.httprequest.QueryString["Board"]).id.ToString() + "/";
case "showprofile":
return "/User/" + User.LoadByName(context.httprequest.QueryString["User"]).id.ToString() + "/";
default:
//throw new NotImplementedException("unknown script " + scriptParts[0]);
throw new WrongUrlException();
}
}
}
}

@ -1,36 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Core;
using FLocal.Common;
namespace FLocal.IISHandler.handlers.response {
class LegacyUploadHandler : RedirectGetHandler {
protected override string getRedirectUrl(WebContext context) {
if(context.requestParts.Length != 3) throw new WrongUrlException();// throw new FLocalException("wrong url");
string[] parts = context.requestParts[2].Split('.');
if(parts.Length != 2) throw new WrongUrlException();// throw new FLocalException("wrong url");
if(parts[0].PHPSubstring(0, 4).ToLower() != "file") throw new WrongUrlException();// throw new FLocalException("wrong url");
int rawFileNum = int.Parse(parts[0].PHPSubstring(4));
int fileNum;
switch(parts[1].ToLower()) {
case "jpg":
fileNum = rawFileNum;
break;
case "gif":
fileNum = 500000 + rawFileNum;
break;
case "png":
fileNum = 600000 + rawFileNum;
break;
default:
//throw new FLocalException("wrong url");
throw new WrongUrlException();
}
return "/Upload/Item/" + fileNum + "/";
}
}
}

@ -11,7 +11,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class LocalNetworksListHandler : AbstractGetHandler {
class LocalNetworksListHandler : AbstractGetHandler<FLocal.Common.URL.maintenance.LocalNetworks> {
override protected string templateName {
get {

@ -8,7 +8,7 @@ using System.Xml.Linq;
using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class LoginHandler : AbstractGetHandler {
class LoginHandler : AbstractGetHandler<FLocal.Common.URL.my.login.Login> {
protected override string templateName {
get {

@ -8,7 +8,7 @@ using System.Xml.Linq;
using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class MigrateAccountHandler : AbstractGetHandler {
class MigrateAccountHandler : AbstractGetHandler<FLocal.Common.URL.my.login.Migrate> {
protected override string templateName {
get {
@ -21,10 +21,10 @@ namespace FLocal.IISHandler.handlers.response {
if(context.httprequest.Form["username"] != null && context.httprequest.Form["username"] != "") {
username = context.httprequest.Form["username"];
} else {
if(context.requestParts.Length != 4) {
if(string.IsNullOrEmpty(this.url.remainder)) {
throw new CriticalException("Username is not specified");
}
username = context.requestParts[3];
username = this.url.remainder;
}
Account account = Account.LoadByName(username);
if(!account.needsMigration) throw new FLocalException("Already migrated");

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class PMReplyHandler : AbstractNewMessageHandler {
class PMReplyHandler : AbstractNewMessageHandler<FLocal.Common.URL.my.conversations.Reply> {
override protected string templateName {
get {
@ -19,7 +19,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificNewMessageData(WebContext context) {
PMMessage message = PMMessage.LoadById(int.Parse(context.requestParts[3]));
PMMessage message = this.url.pm;
string quoted = UBBParser.StripQuotes(message.bodyUBB).Trim();
return new XElement[] {
message.exportToXml(context),

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class PMReplyToPostHandler : AbstractNewMessageHandler {
class PMReplyToPostHandler : AbstractNewMessageHandler<FLocal.Common.URL.forum.board.thread.post.PMReply> {
override protected string templateName {
get {
@ -20,7 +20,7 @@ namespace FLocal.IISHandler.handlers.response {
override protected IEnumerable<XElement> getSpecificNewMessageData(WebContext context) {
Post post = Post.LoadById(int.Parse(context.requestParts[1]));
Post post = this.url.post;
Account receiver = Account.LoadByUser(post.poster);
if(receiver.needsMigration) throw new ApplicationException("User is not migrated");

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class PMSendHandler : AbstractNewMessageHandler {
class PMSendHandler : AbstractNewMessageHandler<FLocal.Common.URL.my.conversations.NewPM> {
override protected string templateName {
get {
@ -19,8 +19,8 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificNewMessageData(WebContext context) {
if(context.requestParts.Length > 3) {
Account receiver = Account.LoadById(int.Parse(context.requestParts[3]));
if(!string.IsNullOrEmpty(this.url.remainder)) {
Account receiver = Account.LoadById(int.Parse(this.url.remainder));
if(receiver.needsMigration) throw new ApplicationException("User is not migrated");
return new XElement[] {
new XElement("receiver", receiver.exportToXml(context)),

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class PollHandler : AbstractGetHandler {
class PollHandler : AbstractGetHandler<FLocal.Common.URL.polls.Info> {
override protected string templateName {
get {
@ -21,7 +21,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
Poll poll = Poll.LoadById(int.Parse(context.requestParts[1]));
Poll poll = this.url.poll;
return new XElement[] {
poll.exportToXmlWithVotes(context)
};

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class PunishHandler : AbstractNewMessageHandler {
class PunishHandler : AbstractNewMessageHandler<FLocal.Common.URL.forum.board.thread.post.Punish> {
override protected string templateName {
get {
@ -19,7 +19,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificNewMessageData(WebContext context) {
Post post = Post.LoadById(int.Parse(context.requestParts[1]));
Post post = this.url.post;
if(!Moderator.isModerator(context.account, post.thread)) throw new FLocalException(context.account.id + " is not a moderator in board " + post.thread.board.id);

@ -7,10 +7,10 @@ using FLocal.Common;
using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class QuickLinkHandler : RedirectGetHandler {
class QuickLinkHandler : RedirectGetHandler<FLocal.Common.URL.QuickLink> {
protected override string getRedirectUrl(WebContext context) {
return QuickLink.LoadByName(context.requestParts[1]).url;
return this.url.link.url;
}
}

@ -5,7 +5,7 @@ using System.Text;
using System.Xml.Linq;
namespace FLocal.IISHandler.handlers.response {
abstract class RedirectGetHandler : AbstractGetHandler {
abstract class RedirectGetHandler<TUrl> : AbstractGetHandler<TUrl> where TUrl : FLocal.Common.URL.AbstractUrl {
protected override string templateName {
get {

@ -7,7 +7,7 @@ using FLocal.Core;
using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class RegisterByInviteHandler : AbstractGetHandler {
class RegisterByInviteHandler : AbstractGetHandler<FLocal.Common.URL.my.login.RegisterByInvite> {
protected override string templateName {
get {
@ -16,8 +16,9 @@ namespace FLocal.IISHandler.handlers.response {
}
protected override IEnumerable<XElement> getSpecificData(WebContext context) {
int inviteId = int.Parse(context.requestParts[3]);
string code = context.requestParts[4];
string[] parts = this.url.remainder.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
int inviteId = int.Parse(parts[0]);
string code = parts[1];
Invite invite = Invite.LoadById(inviteId);
if(invite.isUsed) throw new FLocalException("Invite is already used");
if(invite.code != code) throw new FLocalException("Code mismatch");

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class ReplyHandler : AbstractNewMessageHandler {
class ReplyHandler : AbstractNewMessageHandler<FLocal.Common.URL.forum.board.thread.post.Reply> {
override protected string templateName {
get {
@ -20,7 +20,7 @@ namespace FLocal.IISHandler.handlers.response {
override protected IEnumerable<XElement> getSpecificNewMessageData(WebContext context) {
Post post = Post.LoadById(int.Parse(context.requestParts[1]));
Post post = this.url.post;
string quoted = context.httprequest.Form["data"];
if(quoted != null) quoted = quoted.Trim();

@ -8,18 +8,22 @@ using System.IO;
using FLocal.Core;
namespace FLocal.IISHandler.handlers.response {
class RobotsHandler : ISpecificHandler {
class RobotsHandler : AbstractGetHandler<FLocal.Common.URL.Robots> {
public RobotsHandler() {
protected override string templateName {
get {
return null;
}
}
public void Handle(WebContext context) {
protected override IEnumerable<System.Xml.Linq.XElement> getSpecificData(WebContext context) {
context.httpresponse.ContentType = "text/plain";
context.httpresponse.WriteLine("User-agent: *");
context.httpresponse.WriteLine("Disallow: /");
foreach(var subnet in context.remoteHost.matchingSubnets) {
context.httpresponse.WriteLine(subnet.ToString());
}
throw new SkipXsltTransformException();
}
}

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class SettingsHandler : AbstractGetHandler {
class SettingsHandler : AbstractGetHandler<FLocal.Common.URL.my.Settings> {
override protected string templateName {
get {

@ -0,0 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.IISHandler.handlers.response {
class SkipXsltTransformException : ApplicationException {
}
}

@ -10,7 +10,7 @@ using FLocal.Core.DB;
using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class UploadHandler : AbstractGetHandler {
class UploadHandler : RedirectGetHandler<FLocal.Common.URL.upload.Item> {
protected override string templateName {
get {
@ -18,9 +18,8 @@ namespace FLocal.IISHandler.handlers.response {
}
}
protected override IEnumerable<XElement> getSpecificData(WebContext context) {
Upload upload = Upload.LoadById(int.Parse(context.requestParts[2]));
throw new RedirectException(Config.instance.UploaderUrl + "Data/" + upload.hash + "." + upload.extension);
protected override string getRedirectUrl(WebContext context) {
return Config.instance.UploaderUrl + "Data/" + this.url.upload.hash + "." + this.url.upload.extension;
}
}

@ -10,7 +10,7 @@ using FLocal.Core.DB;
using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class UploadListHandler : AbstractGetHandler {
class UploadListHandler : AbstractGetHandler<FLocal.Common.URL.upload.List> {
protected override string templateName {
get {
@ -20,7 +20,7 @@ namespace FLocal.IISHandler.handlers.response {
protected override IEnumerable<XElement> getSpecificData(WebContext context) {
if(context.session == null) throw new AccessViolationException();
PageOuter pageOuter = PageOuter.createFromGet(context.requestParts, context.userSettings.uploadsPerPage, 2);
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.uploadsPerPage);
List<Upload> uploads = Upload.LoadByIds(
from stringId in Config.instance.mainConnection.LoadIdsByConditions(
Upload.TableSpec.instance,

@ -10,7 +10,7 @@ using FLocal.Core.DB;
using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class UploadNewHandler : AbstractGetHandler {
class UploadNewHandler : AbstractGetHandler<FLocal.Common.URL.upload.New> {
protected override string templateName {
get {

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class UserDataHandler : AbstractGetHandler {
class UserDataHandler : AbstractGetHandler<FLocal.Common.URL.my.UserData> {
override protected string templateName {
get {

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class UserInfoHandler : AbstractUserGetHandler {
class UserInfoHandler : AbstractUserGetHandler<FLocal.Common.URL.users.user.Info> {
override protected string templateName {
get {

@ -10,7 +10,7 @@ using FLocal.Core.DB;
namespace FLocal.IISHandler.handlers.response {
class UserListHandler : AbstractGetHandler {
class UserListHandler : AbstractGetHandler<FLocal.Common.URL.users.All> {
override protected string templateName {
get {
@ -19,7 +19,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getSpecificData(WebContext context) {
PageOuter pageOuter = PageOuter.createFromGet(context.requestParts, context.userSettings.usersPerPage, 2);
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.usersPerPage);
IEnumerable<User> users = User.getUsers(pageOuter, pageOuter.ascendingDirection);
return new XElement[] {
new XElement("users",

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class UserPollsParticipatedHandler : AbstractUserGetHandler {
class UserPollsParticipatedHandler : AbstractUserGetHandler<FLocal.Common.URL.users.user.PollsParticipated> {
override protected string templateName {
get {
@ -21,11 +21,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getUserSpecificData(WebContext context, User user) {
PageOuter pageOuter = PageOuter.createFromGet(
context.requestParts,
context.userSettings.postsPerPage,
4
);
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.postsPerPage);
IEnumerable<Poll.Vote> votes = Poll.Vote.LoadByIds(
from stringId in Config.instance.mainConnection.LoadIdsByConditions(
Poll.Vote.TableSpec.instance,

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class UserPostsHandler : AbstractUserGetHandler {
class UserPostsHandler : AbstractUserGetHandler<FLocal.Common.URL.users.user.Posts> {
override protected string templateName {
get {
@ -21,11 +21,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getUserSpecificData(WebContext context, User user) {
PageOuter pageOuter = PageOuter.createFromGet(
context.requestParts,
context.userSettings.postsPerPage,
4
);
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.postsPerPage);
IEnumerable<Post> posts = user.getPosts(pageOuter, pageOuter.descendingDirection);
return new XElement[] {

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class UserRepliesHandler : AbstractUserGetHandler {
class UserRepliesHandler : AbstractUserGetHandler<FLocal.Common.URL.users.user.Replies> {
override protected string templateName {
get {
@ -21,11 +21,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getUserSpecificData(WebContext context, User user) {
PageOuter pageOuter = PageOuter.createFromGet(
context.requestParts,
context.userSettings.postsPerPage,
4
);
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.postsPerPage);
IEnumerable<Post> posts = user.getReplies(pageOuter, pageOuter.descendingDirection);
return new XElement[] {

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class UserThreadsHandler : AbstractUserGetHandler {
class UserThreadsHandler : AbstractUserGetHandler<FLocal.Common.URL.users.user.Threads> {
override protected string templateName {
get {
@ -21,11 +21,7 @@ namespace FLocal.IISHandler.handlers.response {
}
override protected IEnumerable<XElement> getUserSpecificData(WebContext context, User user) {
PageOuter pageOuter = PageOuter.createFromGet(
context.requestParts,
context.userSettings.postsPerPage,
4
);
PageOuter pageOuter = PageOuter.createFromUrl(this.url, context.userSettings.postsPerPage);
IEnumerable<Thread> threads = user.getThreads(pageOuter, pageOuter.descendingDirection);
return new XElement[] {

@ -12,7 +12,7 @@ using FLocal.Core.DB.conditions;
namespace FLocal.IISHandler.handlers.response {
class WhoIsOnlineHandler : AbstractGetHandler {
class WhoIsOnlineHandler : AbstractGetHandler<FLocal.Common.URL.users.Online> {
override protected string templateName {
get {

@ -10,7 +10,7 @@ using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response.maintenance {
class CleanCacheHandler : AbstractGetHandler {
class CleanCacheHandler : AbstractGetHandler<FLocal.Common.URL.maintenance.CleanCache> {
override protected string templateName {
get {

@ -52,7 +52,7 @@
</tr>
<tr>
<td class="lighttable">
<form method="post" action="/My/Login/MigrateAccount/">
<form method="post" action="/My/Login/Migrate/">
<xsl:text>Ëîãèí</xsl:text><br />
<input type="text" name="username" class="formboxes" /><br/>
<input type="submit" name="buttlogin" value="Äàëåå" class="buttons" />

@ -51,7 +51,7 @@
</tr>
<tr>
<td class="lighttable">
<form method="post" action="/My/Login/MigrateAccount/">
<form method="post" action="/My/Login/Migrate/">
<xsl:text>Ëîãèí</xsl:text><br />
<input type="text" name="username" class="formboxes" /><br/>
<input type="submit" name="buttlogin" value="Äàëåå" class="buttons" />

Loading…
Cancel
Save