summaryrefslogtreecommitdiffstats
path: root/ComicRackWebViewer/Bootstrapper.cs
blob: 1bcfa33629b69e926bf4674c9109520395a473b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using BCR;
using Nancy;
using Nancy.Authentication.Stateless;
using Nancy.Bootstrapper;
using Nancy.Conventions;
using Nancy.Diagnostics;
using Nancy.TinyIoc;
using System;
using System.IO;

namespace ComicRackWebViewer
{
  /*
  public class LoggingErrorHandler : IErrorHandler
  {
      public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context)
      {
          return true;//statusCode == HttpStatusCode.InternalServerError;
      }
  
      public void Handle(HttpStatusCode statusCode, NancyContext context)
      {
        
          object errorObject;
          context.Items.TryGetValue(NancyEngine.ERROR_EXCEPTION, out errorObject);
          var error = errorObject as Exception;
          
  

      }
  }
  */

    public class Bootstrapper : DefaultNancyBootstrapper
    {
        private MyRootPathProvider myRootPathProvider;
        
        protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
        {
            base.ApplicationStartup(container, pipelines);
            
            // Increase size of JSON responses as 100K is way too small for a large comic collection. Make it 10M.
            // Also, for some reason I don't get InvalidOperationException ("Nancy.Json.JsonSettings.MaxJsonLength exceeded")
            // Instead Nancy generates a response with status OK and content length 0.
            Nancy.Json.JsonSettings.MaxJsonLength = Int32.MaxValue;
            Nancy.Json.JsonSettings.RetainCasing = true;

            // Case sensitivity is buggy in Nancy, so disable it. Or maybe I should generate/parse GUIDs correctly......
            StaticConfiguration.CaseSensitive = false;
            
            
            StaticConfiguration.EnableRequestTracing = Database.Instance.GlobalSettings.nancy_request_tracing;
            
            if (Database.Instance.GlobalSettings.nancy_diagnostics_password == "")
              DiagnosticsHook.Disable(pipelines);
            
            // Make sure static content isn't cached, because this really messes up the ipad browsers (Atomic Browser specifically) 
            // when the app is frequently updated.
          pipelines.AfterRequest.AddItemToEndOfPipeline(
            ctx => {
              ctx.Response.Headers["Cache-Control"] = "no-cache";
            });
        }
       
        protected override IRootPathProvider RootPathProvider
        {
          get { return this.myRootPathProvider ?? (this.myRootPathProvider = new MyRootPathProvider()); }
        }

        protected override void ConfigureConventions(NancyConventions conventions)
	      {
	        base.ConfigureConventions(conventions);
	 
	        conventions.StaticContentsConventions.Add(
              StaticContentConventionBuilder.AddDirectory(Database.Instance.GlobalSettings.url_base, "/tablet")
        	);
	      }
        
        protected override DiagnosticsConfiguration DiagnosticsConfiguration
        {
          get { return new DiagnosticsConfiguration { Password = Database.Instance.GlobalSettings.nancy_diagnostics_password }; }
        }
        

        
        protected override void RequestStartup(TinyIoCContainer requestContainer, IPipelines pipelines, NancyContext context)
        {
            // At request startup we modify the request pipelines to
            // include stateless authentication
            //
            // Configuring stateless authentication is simple. Just use the 
            // NancyContext to get the apiKey. Then, use the apiKey to get 
            // your user's identity.
            var configuration =
                new StatelessAuthenticationConfiguration(nancyContext =>
                    {
                        // For now, we will get the apiKey from a cookie.
                        // If there's no cookie, check the query string.
                        
                        try
                        {
                          string apiKey = "";
                          if (!nancyContext.Request.Cookies.TryGetValue("BCR_apiKey", out apiKey))
                          {
                            apiKey = (string) nancyContext.Request.Query.ApiKey.Value;
                          }
                          
                          return BCR.UserDatabase.GetUserFromApiKey(apiKey);
                        }
                        catch (Exception e)
                        {
                          System.Windows.Forms.MessageBox.Show("Error while initializing the user data:\n" + e.ToString(), "BCR Error");
                          Console.WriteLine(e.ToString());
                        }
                                                
                        return null;
                    });

            AllowAccessToConsumingSite(pipelines);

            StatelessAuthentication.Enable(pipelines, configuration);
        }

        static void AllowAccessToConsumingSite(IPipelines pipelines)
        {
            pipelines.AfterRequest.AddItemToEndOfPipeline(x =>
                {
                    x.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                    x.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT,OPTIONS");
                });
        }
    
    }

    public class MyRootPathProvider : IRootPathProvider
    {
        private readonly string BASE_PATH;

        public MyRootPathProvider()
        {
            var path = typeof(Bootstrapper).Assembly.Location;
            BASE_PATH = path.Substring(0, path.Length - Path.GetFileName(path).Length);
        }

        public string GetRootPath()
        {
            return BASE_PATH;
        }
    }

    
}