2023-01-23 22:20:08 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const url = require( "url" );
|
|
|
|
const fs = require( "fs" );
|
|
|
|
const getRawBody = require( "raw-body" );
|
2023-02-01 12:48:35 +00:00
|
|
|
const multiparty = require( "multiparty" );
|
2023-01-23 22:20:08 +00:00
|
|
|
|
|
|
|
let cspLog = "";
|
2017-08-01 16:52:45 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Keep in sync with /test/mock.php
|
|
|
|
*/
|
2021-04-13 20:13:48 +00:00
|
|
|
function cleanCallback( callback ) {
|
|
|
|
return callback.replace( /[^a-z0-9_]/gi, "" );
|
|
|
|
}
|
|
|
|
|
2023-01-23 22:20:08 +00:00
|
|
|
const mocks = {
|
2017-08-01 16:52:45 +00:00
|
|
|
contentType: function( req, resp ) {
|
|
|
|
resp.writeHead( 200, {
|
|
|
|
"content-type": req.query.contentType
|
|
|
|
} );
|
|
|
|
resp.end( req.query.response );
|
|
|
|
},
|
|
|
|
wait: function( req, resp ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
const wait = Number( req.query.wait ) * 1000;
|
2017-08-01 16:52:45 +00:00
|
|
|
setTimeout( function() {
|
|
|
|
if ( req.query.script ) {
|
|
|
|
resp.writeHead( 200, { "content-type": "text/javascript" } );
|
|
|
|
} else {
|
|
|
|
resp.writeHead( 200, { "content-type": "text/html" } );
|
2019-02-18 18:02:38 +00:00
|
|
|
resp.end( "ERROR <script>QUnit.assert.ok( true, \"mock executed\" );</script>" );
|
2017-08-01 16:52:45 +00:00
|
|
|
}
|
|
|
|
}, wait );
|
|
|
|
},
|
|
|
|
name: function( req, resp, next ) {
|
|
|
|
resp.writeHead( 200 );
|
|
|
|
if ( req.query.name === "foo" ) {
|
|
|
|
resp.end( "bar" );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
getBody( req ).then( function( body ) {
|
|
|
|
if ( body === "name=peter" ) {
|
|
|
|
resp.end( "pan" );
|
|
|
|
} else {
|
|
|
|
resp.end( "ERROR" );
|
|
|
|
}
|
|
|
|
}, next );
|
|
|
|
},
|
|
|
|
xml: function( req, resp, next ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
const content = "<math><calculation>5-2</calculation><result>3</result></math>";
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.writeHead( 200, { "content-type": "text/xml" } );
|
|
|
|
|
|
|
|
if ( req.query.cal === "5-2" ) {
|
|
|
|
resp.end( content );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
getBody( req ).then( function( body ) {
|
|
|
|
if ( body === "cal=5-2" ) {
|
|
|
|
resp.end( content );
|
|
|
|
} else {
|
|
|
|
resp.end( "<error>ERROR</error>" );
|
|
|
|
}
|
|
|
|
}, next );
|
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
atom: function( _req, resp ) {
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.writeHead( 200, { "content-type": "atom+xml" } );
|
|
|
|
resp.end( "<root><element /></root>" );
|
|
|
|
},
|
|
|
|
script: function( req, resp ) {
|
2023-09-18 16:39:00 +00:00
|
|
|
const headers = {};
|
2017-08-01 16:52:45 +00:00
|
|
|
if ( req.query.header === "ecma" ) {
|
2023-09-18 16:39:00 +00:00
|
|
|
headers[ "content-type" ] = "application/ecmascript";
|
2021-01-11 17:20:36 +00:00
|
|
|
} else if ( "header" in req.query ) {
|
2023-09-18 16:39:00 +00:00
|
|
|
headers[ "content-type" ] = "text/javascript";
|
2017-08-01 16:52:45 +00:00
|
|
|
} else {
|
2023-09-18 16:39:00 +00:00
|
|
|
headers[ "content-type" ] = "text/html";
|
2017-08-01 16:52:45 +00:00
|
|
|
}
|
2020-09-22 15:30:18 +00:00
|
|
|
|
|
|
|
if ( req.query.cors ) {
|
2023-09-18 16:39:00 +00:00
|
|
|
headers[ "access-control-allow-origin" ] = "*";
|
|
|
|
}
|
|
|
|
|
2024-02-08 22:52:19 +00:00
|
|
|
resp.writeHead( 200, headers );
|
2020-09-22 15:30:18 +00:00
|
|
|
|
|
|
|
if ( req.query.callback ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
resp.end( `${ cleanCallback( req.query.callback ) }(${ JSON.stringify( {
|
2020-09-22 15:30:18 +00:00
|
|
|
headers: req.headers
|
2023-01-23 22:20:08 +00:00
|
|
|
} ) })` );
|
2020-09-22 15:30:18 +00:00
|
|
|
} else {
|
|
|
|
resp.end( "QUnit.assert.ok( true, \"mock executed\" );" );
|
|
|
|
}
|
2017-08-01 16:52:45 +00:00
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
testbar: function( _req, resp ) {
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.writeHead( 200 );
|
|
|
|
resp.end(
|
|
|
|
"this.testBar = 'bar'; " +
|
|
|
|
"jQuery('#ap').html('bar'); " +
|
2019-02-18 18:02:38 +00:00
|
|
|
"QUnit.assert.ok( true, 'mock executed');"
|
2017-08-01 16:52:45 +00:00
|
|
|
);
|
|
|
|
},
|
|
|
|
json: function( req, resp ) {
|
2024-02-08 22:52:19 +00:00
|
|
|
const headers = {};
|
2017-08-01 16:52:45 +00:00
|
|
|
if ( req.query.header ) {
|
2024-02-08 22:52:19 +00:00
|
|
|
headers[ "content-type" ] = "application/json";
|
2017-08-01 16:52:45 +00:00
|
|
|
}
|
2020-07-27 17:15:57 +00:00
|
|
|
if ( req.query.cors ) {
|
2024-02-08 22:52:19 +00:00
|
|
|
headers[ "access-control-allow-origin" ] = "*";
|
2020-07-27 17:15:57 +00:00
|
|
|
}
|
2024-02-08 22:52:19 +00:00
|
|
|
resp.writeHead( 200, headers );
|
2017-08-01 16:52:45 +00:00
|
|
|
if ( req.query.array ) {
|
|
|
|
resp.end( JSON.stringify(
|
|
|
|
[ { name: "John", age: 21 }, { name: "Peter", age: 25 } ]
|
|
|
|
) );
|
|
|
|
} else {
|
|
|
|
resp.end( JSON.stringify(
|
|
|
|
{ data: { lang: "en", length: 25 } }
|
|
|
|
) );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
jsonp: function( req, resp, next ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
let callback;
|
Tests: Fix flakiness in the "jQuery.ajax() - JSONP - Same Domain" test
The "jQuery.ajax() - JSONP - Same Domain" test is firing a request with
a duplicate "callback" parameter, something like (simplified):
```
mock.php?action=jsonp&callback=jQuery_1&callback=jQuery_2
```
There was a difference in how the PHP & Node.js implementations of the jsonp
action in the mock server handled situations like that. The PHP implementation
was using the latest parameter while the Node.js one was turning it into an
array but the code didn't handle this situation. Because of how JavaScript
stringifies arrays, while the PHP implementation injected the following code:
```js
jQuery_2(payload)
```
the Node.js one was injecting the following one:
```js
jQuery_1,jQuery_2(payload)
```
This is a comma expression in JavaScript; it so turned out that in the majority
of cases both callbacks were identical so it was more like:
```js
jQuery_1,jQuery_1(payload)
```
which evaluates to `jQuery_1(payload)` when `jQuery_1` is defined, making the
test go as expected. In many cases, though, especially on Travis, the callbacks
were different, triggering an `Uncaught ReferenceError` error & requiring
frequent manual re-runs of Travis builds.
This commit fixes the logic in the mock Node.js server, adding special handling
for arrays.
Closes gh-4687
2020-04-27 18:22:39 +00:00
|
|
|
if ( Array.isArray( req.query.callback ) ) {
|
|
|
|
callback = Promise.resolve( req.query.callback[ req.query.callback.length - 1 ] );
|
|
|
|
} else if ( req.query.callback ) {
|
2017-08-01 16:52:45 +00:00
|
|
|
callback = Promise.resolve( req.query.callback );
|
|
|
|
} else if ( req.method === "GET" ) {
|
2020-09-02 16:42:52 +00:00
|
|
|
callback = Promise.resolve( req.url.match( /^.+\/([^\/?]+)\?.+$/ )[ 1 ] );
|
2017-08-01 16:52:45 +00:00
|
|
|
} else {
|
|
|
|
callback = getBody( req ).then( function( body ) {
|
|
|
|
return body.trim().replace( "callback=", "" );
|
|
|
|
} );
|
|
|
|
}
|
2023-01-23 22:20:08 +00:00
|
|
|
const json = req.query.array ?
|
2017-08-01 16:52:45 +00:00
|
|
|
JSON.stringify(
|
|
|
|
[ { name: "John", age: 21 }, { name: "Peter", age: 25 } ]
|
|
|
|
) :
|
|
|
|
JSON.stringify(
|
|
|
|
{ data: { lang: "en", length: 25 } }
|
|
|
|
);
|
|
|
|
callback.then( function( cb ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
resp.end( `${ cleanCallback( cb ) }(${ json })` );
|
2017-08-01 16:52:45 +00:00
|
|
|
}, next );
|
|
|
|
},
|
|
|
|
xmlOverJsonp: function( req, resp ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
const callback = req.query.callback;
|
|
|
|
const body = fs.readFileSync( `${ __dirname }/data/with_fries.xml` ).toString();
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.writeHead( 200 );
|
2023-01-23 22:20:08 +00:00
|
|
|
resp.end( `${ cleanCallback( callback ) }(${ JSON.stringify( body ) })\n` );
|
2017-08-01 16:52:45 +00:00
|
|
|
},
|
2023-02-01 12:48:35 +00:00
|
|
|
formData: function( req, resp, next ) {
|
|
|
|
const prefix = "multipart/form-data; boundary=--";
|
|
|
|
const contentTypeValue = req.headers[ "content-type" ];
|
|
|
|
resp.writeHead( 200 );
|
|
|
|
if ( ( prefix || "" ).startsWith( prefix ) ) {
|
|
|
|
getMultiPartContent( req ).then( function( { fields = {} } ) {
|
|
|
|
resp.end( `key1 -> ${ fields.key1 }, key2 -> ${ fields.key2 }` );
|
|
|
|
}, next );
|
|
|
|
} else {
|
|
|
|
resp.end( `Incorrect Content-Type: ${ contentTypeValue
|
|
|
|
}\nExpected prefix: ${ prefix }` );
|
|
|
|
}
|
|
|
|
},
|
2017-08-01 16:52:45 +00:00
|
|
|
error: function( req, resp ) {
|
|
|
|
if ( req.query.json ) {
|
|
|
|
resp.writeHead( 400, { "content-type": "application/json" } );
|
|
|
|
resp.end( "{ \"code\": 40, \"message\": \"Bad Request\" }" );
|
|
|
|
} else {
|
|
|
|
resp.writeHead( 400 );
|
|
|
|
resp.end( "plain text message" );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
headers: function( req, resp ) {
|
2023-09-18 16:39:00 +00:00
|
|
|
const headers = {
|
2017-08-01 16:52:45 +00:00
|
|
|
"Sample-Header": "Hello World",
|
|
|
|
"Empty-Header": "",
|
2018-11-26 17:00:41 +00:00
|
|
|
"Sample-Header2": "Hello World 2",
|
|
|
|
"List-Header": "Item 1",
|
|
|
|
"list-header": "Item 2",
|
|
|
|
"constructor": "prototype collision (constructor)"
|
2023-09-18 16:39:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Use resp.append in express to
|
|
|
|
// avoid overwriting List-Header
|
|
|
|
if ( resp.append ) {
|
|
|
|
|
|
|
|
for ( const key in headers ) {
|
|
|
|
resp.append( key, headers[ key ] );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
resp.writeHead( 200, headers );
|
|
|
|
}
|
2017-08-01 16:52:45 +00:00
|
|
|
req.query.keys.split( "|" ).forEach( function( key ) {
|
2019-05-13 19:39:56 +00:00
|
|
|
if ( key.toLowerCase() in req.headers ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
resp.write( `${ key }: ${ req.headers[ key.toLowerCase() ] }\n` );
|
2017-08-01 16:52:45 +00:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
resp.end();
|
|
|
|
},
|
|
|
|
echoData: function( req, resp, next ) {
|
|
|
|
getBody( req ).then( function( body ) {
|
|
|
|
resp.end( body );
|
|
|
|
}, next );
|
|
|
|
},
|
|
|
|
echoQuery: function( req, resp ) {
|
|
|
|
resp.end( req.parsed.search.slice( 1 ) );
|
|
|
|
},
|
|
|
|
echoMethod: function( req, resp ) {
|
|
|
|
resp.end( req.method );
|
|
|
|
},
|
|
|
|
echoHtml: function( req, resp, next ) {
|
|
|
|
resp.writeHead( 200, { "Content-Type": "text/html" } );
|
2023-01-23 22:20:08 +00:00
|
|
|
resp.write( `<div id='method'>${ req.method }</div>` );
|
|
|
|
resp.write( `<div id='query'>${ req.parsed.search.slice( 1 ) }</div>` );
|
2017-08-01 16:52:45 +00:00
|
|
|
getBody( req ).then( function( body ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
resp.write( `<div id='data'>${ body }</div>` );
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.end( body );
|
|
|
|
}, next );
|
|
|
|
},
|
|
|
|
etag: function( req, resp ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
const hash = Number( req.query.ts ).toString( 36 );
|
|
|
|
const etag = `W/"${ hash }"`;
|
2017-08-01 16:52:45 +00:00
|
|
|
if ( req.headers[ "if-none-match" ] === etag ) {
|
|
|
|
resp.writeHead( 304 );
|
|
|
|
resp.end();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
resp.writeHead( 200, {
|
|
|
|
"Etag": etag
|
|
|
|
} );
|
|
|
|
resp.end();
|
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
ims: function( req, resp ) {
|
|
|
|
const ts = req.query.ts;
|
2017-08-01 16:52:45 +00:00
|
|
|
if ( req.headers[ "if-modified-since" ] === ts ) {
|
|
|
|
resp.writeHead( 304 );
|
|
|
|
resp.end();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
resp.writeHead( 200, {
|
|
|
|
"Last-Modified": ts
|
|
|
|
} );
|
|
|
|
resp.end();
|
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
status: function( req, resp ) {
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.writeHead( Number( req.query.code ) );
|
|
|
|
resp.end();
|
|
|
|
},
|
|
|
|
testHTML: function( req, resp ) {
|
|
|
|
resp.writeHead( 200, { "Content-Type": "text/html" } );
|
2023-01-23 22:20:08 +00:00
|
|
|
const body = fs
|
|
|
|
.readFileSync( `${ __dirname }/data/test.include.html` )
|
|
|
|
.toString()
|
|
|
|
.replace( /{{baseURL}}/g, req.query.baseURL );
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.end( body );
|
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
cspFrame: function( _req, resp ) {
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.writeHead( 200, {
|
|
|
|
"Content-Type": "text/html",
|
2023-01-23 22:20:08 +00:00
|
|
|
"Content-Security-Policy": "default-src 'self'; require-trusted-types-for 'script'; " +
|
|
|
|
"report-uri /base/test/data/mock.php?action=cspLog"
|
2017-08-01 16:52:45 +00:00
|
|
|
} );
|
2023-01-23 22:20:08 +00:00
|
|
|
const body = fs.readFileSync( `${ __dirname }/data/csp.include.html` ).toString();
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.end( body );
|
|
|
|
},
|
2019-01-14 18:29:54 +00:00
|
|
|
cspNonce: function( req, resp ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
const testParam = req.query.test ? `-${ req.query.test }` : "";
|
2019-01-14 18:29:54 +00:00
|
|
|
resp.writeHead( 200, {
|
|
|
|
"Content-Type": "text/html",
|
2023-01-23 22:20:08 +00:00
|
|
|
"Content-Security-Policy": "script-src 'nonce-jquery+hardcoded+nonce'; " +
|
|
|
|
"report-uri /base/test/data/mock.php?action=cspLog"
|
2019-01-14 18:29:54 +00:00
|
|
|
} );
|
2023-01-23 22:20:08 +00:00
|
|
|
const body = fs.readFileSync(
|
|
|
|
`${ __dirname }/data/csp-nonce${ testParam }.html` ).toString();
|
2019-01-14 18:29:54 +00:00
|
|
|
resp.end( body );
|
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
cspAjaxScript: function( _req, resp ) {
|
2020-08-25 19:28:30 +00:00
|
|
|
resp.writeHead( 200, {
|
|
|
|
"Content-Type": "text/html",
|
2023-01-23 22:20:08 +00:00
|
|
|
"Content-Security-Policy": "script-src 'self'; " +
|
|
|
|
"report-uri /base/test/data/mock.php?action=cspLog"
|
2020-08-25 19:28:30 +00:00
|
|
|
} );
|
2023-01-23 22:20:08 +00:00
|
|
|
const body = fs.readFileSync(
|
|
|
|
`${ __dirname }/data/csp-ajax-script.html` ).toString();
|
2020-08-25 19:28:30 +00:00
|
|
|
resp.end( body );
|
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
cspLog: function( _req, resp ) {
|
2017-08-01 16:52:45 +00:00
|
|
|
cspLog = "error";
|
|
|
|
resp.writeHead( 200 );
|
|
|
|
resp.end();
|
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
cspClean: function( _req, resp ) {
|
2017-08-01 16:52:45 +00:00
|
|
|
cspLog = "";
|
|
|
|
resp.writeHead( 200 );
|
|
|
|
resp.end();
|
2019-04-26 14:25:08 +00:00
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
trustedHtml: function( _req, resp ) {
|
2021-09-30 14:00:24 +00:00
|
|
|
resp.writeHead( 200, {
|
|
|
|
"Content-Type": "text/html",
|
2023-01-23 22:20:08 +00:00
|
|
|
"Content-Security-Policy": "require-trusted-types-for 'script'; " +
|
|
|
|
"report-uri /base/test/data/mock.php?action=cspLog"
|
2021-09-30 14:00:24 +00:00
|
|
|
} );
|
2023-01-23 22:20:08 +00:00
|
|
|
const body = fs.readFileSync( `${ __dirname }/data/trusted-html.html` ).toString();
|
2021-09-30 14:00:24 +00:00
|
|
|
resp.end( body );
|
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
trustedTypesAttributes: function( _req, resp ) {
|
2021-11-01 17:10:23 +00:00
|
|
|
resp.writeHead( 200, {
|
|
|
|
"Content-Type": "text/html",
|
2023-01-23 22:20:08 +00:00
|
|
|
"Content-Security-Policy": "require-trusted-types-for 'script'; " +
|
|
|
|
"report-uri /base/test/data/mock.php?action=cspLog"
|
2021-11-01 17:10:23 +00:00
|
|
|
} );
|
2023-01-23 22:20:08 +00:00
|
|
|
const body = fs.readFileSync(
|
|
|
|
`${ __dirname }/data/trusted-types-attributes.html` ).toString();
|
2021-11-01 17:10:23 +00:00
|
|
|
resp.end( body );
|
|
|
|
},
|
2019-04-26 14:25:08 +00:00
|
|
|
errorWithScript: function( req, resp ) {
|
|
|
|
if ( req.query.withScriptContentType ) {
|
|
|
|
resp.writeHead( 404, { "Content-Type": "application/javascript" } );
|
|
|
|
} else {
|
2021-04-13 20:13:48 +00:00
|
|
|
resp.writeHead( 404, { "Content-Type": "text/html; charset=UTF-8" } );
|
2019-04-26 14:25:08 +00:00
|
|
|
}
|
|
|
|
if ( req.query.callback ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
resp.end( `${ cleanCallback( req.query.callback )
|
|
|
|
}( {"status": 404, "msg": "Not Found"} )` );
|
2019-04-26 14:25:08 +00:00
|
|
|
} else {
|
|
|
|
resp.end( "QUnit.assert.ok( false, \"Mock return erroneously executed\" );" );
|
|
|
|
}
|
2017-08-01 16:52:45 +00:00
|
|
|
}
|
|
|
|
};
|
2023-01-23 22:20:08 +00:00
|
|
|
const handlers = {
|
2017-08-01 16:52:45 +00:00
|
|
|
"test/data/mock.php": function( req, resp, next ) {
|
|
|
|
if ( !mocks[ req.query.action ] ) {
|
|
|
|
resp.writeHead( 400 );
|
|
|
|
resp.end( "Invalid action query.\n" );
|
|
|
|
console.log( "Invalid action query:", req.method, req.url );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
mocks[ req.query.action ]( req, resp, next );
|
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
"test/data/support/csp.log": function( _req, resp ) {
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.writeHead( 200 );
|
|
|
|
resp.end( cspLog );
|
|
|
|
},
|
2023-01-23 22:20:08 +00:00
|
|
|
"test/data/404.txt": function( _req, resp ) {
|
2017-08-01 16:52:45 +00:00
|
|
|
resp.writeHead( 404 );
|
|
|
|
resp.end( "" );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Connect-compatible middleware factory for mocking server responses.
|
|
|
|
* Used by Ajax unit tests when run via Karma.
|
|
|
|
*
|
|
|
|
* Despite Karma using Express, it uses Connect to deal with custom middleware,
|
|
|
|
* which passes the raw Node Request and Response objects instead of the
|
|
|
|
* Express versions of these (e.g. no req.path, req.query, resp.set).
|
|
|
|
*/
|
|
|
|
function MockserverMiddlewareFactory() {
|
2023-01-23 22:20:08 +00:00
|
|
|
|
2017-08-01 16:52:45 +00:00
|
|
|
/**
|
|
|
|
* @param {http.IncomingMessage} req
|
|
|
|
* @param {http.ServerResponse} resp
|
|
|
|
* @param {Function} next Continue request handling
|
|
|
|
*/
|
|
|
|
return function( req, resp, next ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
const parsed = url.parse( req.url, /* parseQuery */ true );
|
|
|
|
let path = parsed.pathname.replace( /^\/base\//, "" );
|
|
|
|
const query = parsed.query;
|
|
|
|
const subReq = Object.assign( Object.create( req ), {
|
|
|
|
query: query,
|
|
|
|
parsed: parsed
|
|
|
|
} );
|
2017-08-01 16:52:45 +00:00
|
|
|
|
2023-09-18 16:39:00 +00:00
|
|
|
if ( /^\/?test\/data\/mock.php\/?/.test( path ) ) {
|
2023-01-23 22:20:08 +00:00
|
|
|
|
2017-08-01 16:52:45 +00:00
|
|
|
// Support REST-like Apache PathInfo
|
|
|
|
path = "test\/data\/mock.php";
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !handlers[ path ] ) {
|
|
|
|
next();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-18 16:39:00 +00:00
|
|
|
// console.log( "Mock handling", req.method, parsed.href );
|
2017-08-01 16:52:45 +00:00
|
|
|
handlers[ path ]( subReq, resp, next );
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function getBody( req ) {
|
|
|
|
return req.method !== "POST" ?
|
|
|
|
Promise.resolve( "" ) :
|
|
|
|
getRawBody( req, {
|
|
|
|
encoding: true
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
2023-02-01 12:48:35 +00:00
|
|
|
function getMultiPartContent( req ) {
|
|
|
|
return new Promise( function( resolve ) {
|
|
|
|
if ( req.method !== "POST" ) {
|
|
|
|
resolve( "" );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const form = new multiparty.Form();
|
|
|
|
form.parse( req, function( _err, fields, files ) {
|
|
|
|
resolve( { fields, files } );
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
2017-08-01 16:52:45 +00:00
|
|
|
module.exports = MockserverMiddlewareFactory;
|