diff --git a/index.html b/index.html index 3f21364..48a8430 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,7 @@ +
diff --git a/src/server.ts b/src/server.ts index 601390f..66ce27e 100644 --- a/src/server.ts +++ b/src/server.ts @@ -17,13 +17,14 @@ import { DocumentAccessor, UserAccessor, TagAccessor } from './model/mod'; import { createComicWatcher } from './diff/watcher/comic_watcher'; import { getTagRounter } from './route/tags'; + class ServerApplication{ readonly userController: UserAccessor; readonly documentController: DocumentAccessor; readonly tagController: TagAccessor; readonly diffManger: DiffManager; readonly app: Koa; - private index_html:Buffer; + private index_html:string; private constructor(controller:{ userController: UserAccessor, documentController:DocumentAccessor, @@ -34,7 +35,7 @@ class ServerApplication{ this.diffManger = new DiffManager(this.documentController); this.app = new Koa(); - this.index_html = readFileSync("index.html"); + this.index_html = readFileSync("index.html","utf-8"); } private async setup(){ const setting = get_setting(); @@ -66,7 +67,8 @@ class ServerApplication{ router.use('/api/diff',diff_router.routes()); router.use('/api/diff',diff_router.allowedMethods()); - + + this.serve_with_meta_index(router); this.serve_index(router); this.serve_static_file(router); @@ -119,6 +121,61 @@ class ServerApplication{ serveindex('/setting'); serveindex('/tags'); } + private serve_with_meta_index(router:Router){ + const DocMiddleware = async (ctx: Koa.ParameterizedContext)=>{ + const docId = Number.parseInt(ctx.params["id"]); + const doc = await this.documentController.findById(docId,true); + let meta; + if(doc === undefined){ + ctx.status = 404; + meta = NotFoundContent(); + } + else { + ctx.status = 200; + meta = createOgTagContent(doc.title,doc.tags.join(", "), + `https://aeolian.prelude.duckdns.org/api/doc/${docId}/comic/thumbnail`); + } + const html = makeMetaTagInjectedHTML(this.index_html,meta); + serveHTML(ctx,html); + } + router.get('/doc/:id(\\d+)',DocMiddleware); + + function NotFoundContent(){ + return createOgTagContent("Not Found Doc","Not Found",""); + } + function makeMetaTagInjectedHTML(html:string,tagContent:string){ + return html.replace("",tagContent); + } + function serveHTML(ctx: Koa.Context, file: string){ + ctx.type = 'html'; ctx.body = file; + const setting = get_setting(); + ctx.set('x-content-type-options','no-sniff'); + if(setting.mode === "development"){ + ctx.set('cache-control','no-cache'); + } + else{ + ctx.set('cache-control','public, max-age=3600'); + } + } + + function createMetaTagContent(key: string, value:string){ + return ``; + } + function createOgTagContent(title:string,description: string, image: string){ + return [createMetaTagContent("og:title",title), + createMetaTagContent("og:type","website"), + createMetaTagContent("og:description",description), + createMetaTagContent("og:image",image), + //createMetaTagContent("og:image:width","480"), + //createMetaTagContent("og:image","480"), + //createMetaTagContent("og:image:type","image/png"), + createMetaTagContent("twitter:card","summary_large_image"), + createMetaTagContent("twitter:title",title), + createMetaTagContent("twitter:description",description), + createMetaTagContent("twitter:image",image), + ].join("\n"); + } + } private serve_static_file(router: Router){ const static_file_server = (path:string,type:string) => { router.get('/'+path,async (ctx,next)=>{