11const express = require ( 'express' ) ,
22 router = express . Router ( ) ,
3- axios = require ( 'axios' ) ,
4- htmlparser = require ( 'htmlparser2' ) ,
5- cache = require ( 'memory-cache' ) ,
6- config = require ( '../../config/config' ) ,
73 morgan = require ( '../../config/middlewares/morgan' ) ( ) ,
8- logger = require ( './../../config/log' ) ( )
4+ logger = require ( './../../config/log' ) ( ) ,
5+ PageMetaService = require ( '../services/page_meta' )
96
10- const CACHE_TIMEOUT = 1000 * 60 * 60 * 24
7+ const pageMetaService = new PageMetaService ( )
118
129module . exports = function ( app ) {
1310 app . use ( '/api/remote' , router )
@@ -40,53 +37,13 @@ module.exports = function (app) {
4037
4138 if ( ! url || ! url . length ) return res . makeError ( 400 , 'No url given' )
4239
43- function sendTitle ( t ) {
44- cache . put ( url , t , CACHE_TIMEOUT )
45- return res . send ( { title : t } )
46- }
47-
48- const cachedValue = cache . get ( url )
49- if ( cachedValue ) return sendTitle ( cachedValue )
50- else if ( cache . keys ( ) . includes ( url ) ) return sendTitle ( null )
51-
52- cache . put ( url , null , CACHE_TIMEOUT ) // prevent redirect loops
53-
54- axios ( {
55- method : 'head' ,
56- url : url ,
57- headers : { 'Accept' : 'text/html' }
58- } ) . then ( ( response ) => {
59- const contentType = response . headers [ 'content-type' ]
60- const contentLenth = parseInt ( response [ 'content-length' ] ) / 1000
61- if ( ! contentType . includes ( 'text/html' ) && ( ! contentLenth || contentLenth > config . maxHtmlSizeKb ) ) {
62- sendTitle ( null )
63- return null
64- }
65- return axios ( {
66- method : 'get' ,
67- url : url ,
68- headers : { 'Accept' : 'text/html' }
40+ pageMetaService . fetchTitle ( url )
41+ . then ( ( title ) => {
42+ return res . send ( { title } )
6943 } )
70- } ) . then ( ( response ) => {
71- if ( ! response ) return
72- const contentType = response . headers [ 'content-type' ]
73- if ( ! contentType . startsWith ( 'text/html' ) ) return sendTitle ( null )
74- const handler = new htmlparser . DomHandler ( ( error , dom ) => {
75- if ( error ) return res . makeError ( 404 , 'Not found' )
76- const htmlNode = dom . filter ( ( n ) => { return n . type === 'tag' && n . name === 'html' } ) [ 0 ]
77- const headNode = htmlNode . children . filter ( ( n ) => { return n . type === 'tag' && n . name === 'head' } ) [ 0 ]
78- const titleNode = headNode . children . filter ( ( n ) => { return n . type === 'tag' && n . name === 'title' } ) [ 0 ]
79- let title = titleNode . children [ 0 ] . data . trim ( )
80- title = title . replace ( / & # ( \d + ) ; / g, ( match , dec ) => {
81- return String . fromCharCode ( dec )
82- } ) . replace ( / & .+ ; / g, '' )
83- return sendTitle ( title )
44+ . catch ( ( err ) => {
45+ logger . error ( `Failed to resolve title for URL ${ url } - ${ err } ` )
46+ return res . makeError ( 404 , 'Not found' )
8447 } )
85- const parser = new htmlparser . Parser ( handler )
86- parser . parseComplete ( response . data )
87- } ) . catch ( ( err ) => {
88- logger . error ( `Failed to resolve title for URL ${ url } - ${ err } ` )
89- return res . makeError ( 404 , 'Not found' )
90- } )
9148 } )
9249}
0 commit comments