8
8
ServeConfig ,
9
9
LOGGER_DIR ,
10
10
IONIC_LAB_URL ,
11
- IOS_PLATFORM_PATH ,
12
- ANDROID_PLATFORM_PATH
11
+ IOS_PLATFORM_PATHS ,
12
+ ANDROID_PLATFORM_PATHS
13
13
} from './serve-config' ;
14
14
import { Logger } from '../logger/logger' ;
15
15
import * as proxyMiddleware from 'proxy-middleware' ;
@@ -36,7 +36,7 @@ export function createHttpServer(config: ServeConfig): express.Application {
36
36
// Lab routes
37
37
app . use ( IONIC_LAB_URL + '/static' , express . static ( path . join ( __dirname , '..' , '..' , 'lab' , 'static' ) ) ) ;
38
38
app . get ( IONIC_LAB_URL , LabAppView ) ;
39
- app . get ( IONIC_LAB_URL + '/api/v1/cordova' , ApiCordovaProject ) ;
39
+ app . get ( IONIC_LAB_URL + '/api/v1/cordova' , ApiCordovaProject ) ;
40
40
app . get ( IONIC_LAB_URL + '/api/v1/app-config' , ApiPackageJson ) ;
41
41
42
42
app . get ( '/cordova.js' , servePlatformResource , serveMockCordovaJS ) ;
@@ -52,7 +52,7 @@ export function createHttpServer(config: ServeConfig): express.Application {
52
52
53
53
function setupProxies ( app : express . Application ) {
54
54
if ( getBooleanPropertyValue ( Constants . ENV_READ_CONFIG_JSON ) ) {
55
- getProjectJson ( ) . then ( function ( projectConfig : IonicProject ) {
55
+ getProjectJson ( ) . then ( function ( projectConfig : IonicProject ) {
56
56
for ( const proxy of projectConfig . proxies || [ ] ) {
57
57
let opts : any = url . parse ( proxy . proxyUrl ) ;
58
58
if ( proxy . proxyNoAgent ) {
@@ -74,7 +74,7 @@ function setupProxies(app: express.Application) {
74
74
/**
75
75
* http responder for /index.html base entrypoint
76
76
*/
77
- function serveIndex ( req : express . Request , res : express . Response ) {
77
+ function serveIndex ( req : express . Request , res : express . Response ) {
78
78
const config : ServeConfig = req . app . get ( 'serveConfig' ) ;
79
79
80
80
// respond with the index.html file
@@ -108,37 +108,64 @@ function serveMockCordovaJS(req: express.Request, res: express.Response) {
108
108
/**
109
109
* Middleware to serve platform resources
110
110
*/
111
- function servePlatformResource ( req : express . Request , res : express . Response , next : express . NextFunction ) {
111
+ async function servePlatformResource ( req : express . Request , res : express . Response , next : express . NextFunction ) {
112
112
const config : ServeConfig = req . app . get ( 'serveConfig' ) ;
113
113
const userAgent = req . header ( 'user-agent' ) ;
114
- let resourcePath = config . wwwDir ;
115
114
116
115
if ( ! config . isCordovaServe ) {
117
116
return next ( ) ;
118
117
}
119
118
119
+ let root = await getResourcePath ( req . url , config , userAgent ) ;
120
+ if ( root ) {
121
+ res . sendFile ( req . url , { root } ) ;
122
+ } else {
123
+ next ( ) ;
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Determines the appropriate resource path, and checks if the specified url
129
+ *
130
+ * @returns string of the resource path or undefined if there is no match
131
+ */
132
+ async function getResourcePath ( url : string , config : ServeConfig , userAgent : string ) : Promise < string > {
133
+ let searchPaths : string [ ] = [ config . wwwDir ] ;
120
134
if ( isUserAgentIOS ( userAgent ) ) {
121
- resourcePath = path . join ( config . rootDir , IOS_PLATFORM_PATH ) ;
135
+ searchPaths = IOS_PLATFORM_PATHS . map ( resourcePath => path . join ( config . rootDir , resourcePath ) ) ;
122
136
} else if ( isUserAgentAndroid ( userAgent ) ) {
123
- resourcePath = path . join ( config . rootDir , ANDROID_PLATFORM_PATH ) ;
137
+ searchPaths = ANDROID_PLATFORM_PATHS . map ( resourcePath => path . join ( config . rootDir , resourcePath ) ) ;
124
138
}
125
139
126
- fs . stat ( path . join ( resourcePath , req . url ) , ( err , stats ) => {
127
- if ( err ) {
128
- return next ( ) ;
129
- }
130
- res . sendFile ( req . url , { root : resourcePath } ) ;
131
- } ) ;
140
+ for ( let i = 0 ; i < searchPaths . length ; i ++ ) {
141
+ let checkPath = path . join ( searchPaths [ i ] , url ) ;
142
+ try {
143
+ let result = await checkFile ( checkPath ) ;
144
+ return searchPaths [ i ] ;
145
+ } catch ( e ) { }
146
+ }
132
147
}
133
148
149
+ /**
150
+ * Checks if a file exists (responds to stat)
151
+ */
152
+ function checkFile ( filePath : string ) : Promise < void > {
153
+ return new Promise ( ( resolve , reject ) => {
154
+ fs . stat ( filePath , ( err : Error , stats : any ) => {
155
+ if ( err ) {
156
+ return reject ( ) ;
157
+ }
158
+ resolve ( ) ;
159
+ } ) ;
160
+ } ) ;
161
+ }
134
162
135
-
136
- function isUserAgentIOS ( ua : string ) {
163
+ function isUserAgentIOS ( ua : string ) : boolean {
137
164
ua = ua . toLowerCase ( ) ;
138
165
return ( ua . indexOf ( 'iphone' ) > - 1 || ua . indexOf ( 'ipad' ) > - 1 || ua . indexOf ( 'ipod' ) > - 1 ) ;
139
166
}
140
167
141
- function isUserAgentAndroid ( ua : string ) {
168
+ function isUserAgentAndroid ( ua : string ) : boolean {
142
169
ua = ua . toLowerCase ( ) ;
143
170
return ua . indexOf ( 'android' ) > - 1 ;
144
171
}
0 commit comments