@@ -2,8 +2,11 @@ import * as express from 'express';
2
2
import * as cors from 'cors' ;
3
3
import { createProxyMiddleware , Options } from 'http-proxy-middleware' ;
4
4
import { logger , parsePort } from '../../helpers' ;
5
- import { Agent , IncomingMessage } from 'http' ;
5
+ import { Agent } from 'http' ;
6
+ import * as fs from 'fs' ;
6
7
import { addAsync } from '@awaitjs/express' ;
8
+ import * as chokidar from 'chokidar' ;
9
+ import * as jsoncParser from 'jsonc-parser' ;
7
10
8
11
export const V2_POX_MIN_AMOUNT_USTX_ENV_VAR = 'V2_POX_MIN_AMOUNT_USTX' ;
9
12
@@ -40,6 +43,40 @@ export function createCoreNodeRpcProxyRouter(): express.Router {
40
43
maxTotalSockets : 400 ,
41
44
} ) ;
42
45
46
+ const PROXY_CACHE_CONTROL_FILE = '.proxy-cache-control.json' ;
47
+ const cacheControlFileWatcher = chokidar . watch ( PROXY_CACHE_CONTROL_FILE ) ;
48
+ let pathCacheOptions = new Map < RegExp , string | null > ( ) ;
49
+
50
+ const updatePathCacheOptions = ( ) => {
51
+ try {
52
+ const configContent : { paths : Record < string , string > } = jsoncParser . parse (
53
+ fs . readFileSync ( PROXY_CACHE_CONTROL_FILE , 'utf8' )
54
+ ) ;
55
+ pathCacheOptions = new Map (
56
+ Object . entries ( configContent . paths ) . map ( ( [ k , v ] ) => [ RegExp ( k ) , v ] )
57
+ ) ;
58
+ } catch ( error ) {
59
+ pathCacheOptions . clear ( ) ;
60
+ logger . error ( `Error reading changes from ${ PROXY_CACHE_CONTROL_FILE } ` , error ) ;
61
+ }
62
+ } ;
63
+ updatePathCacheOptions ( ) ;
64
+ cacheControlFileWatcher . on ( 'all' , ( eventName , path , stats ) => {
65
+ updatePathCacheOptions ( ) ;
66
+ } ) ;
67
+
68
+ const getCacheControlHeader = ( statusCode : number , url : string ) : string | null => {
69
+ if ( statusCode < 200 || statusCode > 299 ) {
70
+ return null ;
71
+ }
72
+ for ( const [ regexp , cacheControl ] of pathCacheOptions . entries ( ) ) {
73
+ if ( cacheControl && regexp . test ( url ) ) {
74
+ return cacheControl ;
75
+ }
76
+ }
77
+ return null ;
78
+ } ;
79
+
43
80
router . getAsync ( '/pox' , async ( req , res , next ) => {
44
81
const overrideVal = getPoxOverride ( ) ;
45
82
if ( ! overrideVal ) {
@@ -48,12 +85,16 @@ export function createCoreNodeRpcProxyRouter(): express.Router {
48
85
}
49
86
logger . info ( `Overriding /v2/pox 'min_amount_ustx' with ${ overrideVal } ` ) ;
50
87
const poxRes = await fetch ( `http://${ stacksNodeRpcEndpoint } ${ req . originalUrl } ` ) ;
51
- res . setHeader ( 'content-type' , poxRes . headers . get ( 'content-type' ) as string ) ;
88
+ res . header ( 'content-type' , poxRes . headers . get ( 'content-type' ) as string ) ;
52
89
res . status ( poxRes . status ) ;
53
90
const poxResString = await poxRes . text ( ) ;
54
91
try {
55
92
const resJson : { min_amount_ustx : number } = JSON . parse ( poxResString ) ;
56
93
resJson . min_amount_ustx = overrideVal ;
94
+ const header = getCacheControlHeader ( res . statusCode , req . originalUrl ) ;
95
+ if ( header ) {
96
+ res . header ( 'Cache-Control' , header ) ;
97
+ }
57
98
res . json ( resJson ) ;
58
99
} catch ( error ) {
59
100
res . send ( poxResString ) ;
@@ -64,6 +105,12 @@ export function createCoreNodeRpcProxyRouter(): express.Router {
64
105
agent : httpAgent ,
65
106
target : `http://${ stacksNodeRpcEndpoint } ` ,
66
107
changeOrigin : true ,
108
+ onProxyRes : ( proxyRes , req , res ) => {
109
+ const header = getCacheControlHeader ( res . statusCode , req . url ) ;
110
+ if ( header ) {
111
+ proxyRes . headers [ 'Cache-Control' ] = header ;
112
+ }
113
+ } ,
67
114
onError : ( error , req , res ) => {
68
115
const msg =
69
116
( error as any ) . code === 'ECONNREFUSED'
0 commit comments