diff --git a/boxs.html b/geometries-zml.html similarity index 100% rename from boxs.html rename to geometries-zml.html diff --git a/box.html b/geometries.html similarity index 56% rename from box.html rename to geometries.html index 165104c..1844e68 100644 --- a/box.html +++ b/geometries.html @@ -6,11 +6,8 @@ - - Hello World! + + 几何体
diff --git a/node-run.bat b/node-run.bat index 1b54821..b8dd417 100644 --- a/node-run.bat +++ b/node-run.bat @@ -1,2 +1,2 @@ -start http://localhost:8080/index.html +start http://localhost:1234/box.html node server.cjs \ No newline at end of file diff --git a/run.bat b/run.bat new file mode 100644 index 0000000..1a0ee49 --- /dev/null +++ b/run.bat @@ -0,0 +1,2 @@ +start http://localhost:1234/index.html +php -S localhost:1234 \ No newline at end of file diff --git a/server.cjs b/server.cjs new file mode 100644 index 0000000..2ded846 --- /dev/null +++ b/server.cjs @@ -0,0 +1,246 @@ +/*eslint-env node*/ +/* eslint-disable no-unused-vars */ +/* eslint-disable global-require */ +"use strict"; +(function () { + const express = require("express"); + const compression = require("compression"); + const fs = require("fs"); + const url = require("url"); + const request = require("request"); + + const gzipHeader = Buffer.from("1F8B08", "hex"); + + const yargs = require("yargs").options({ + port: { + default: 8080, + description: "Port to listen on.", + }, + public: { + type: "boolean", + description: "Run a public server that listens on all interfaces.", + }, + "upstream-proxy": { + description: + 'A standard proxy server that will be used to retrieve data. Specify a URL including port, e.g. "http://proxy:8000".', + }, + "bypass-upstream-proxy-hosts": { + description: + 'A comma separated list of hosts that will bypass the specified upstream_proxy, e.g. "lanhost1,lanhost2"', + }, + help: { + alias: "h", + type: "boolean", + description: "Show this help.", + }, + }); + const argv = yargs.argv; + + if (argv.help) { + return yargs.showHelp(); + } + + // eventually this mime type configuration will need to change + // https://github.com/visionmedia/send/commit/d2cb54658ce65948b0ed6e5fb5de69d022bef941 + // *NOTE* Any changes you make here must be mirrored in web.config. + const mime = express.static.mime; + mime.define( + { + "application/json": ["czml", "json", "geojson", "topojson"], + "application/wasm": ["wasm"], + "image/crn": ["crn"], + "image/ktx": ["ktx"], + "model/gltf+json": ["gltf"], + "model/gltf-binary": ["bgltf", "glb"], + "application/octet-stream": [ + "b3dm", + "pnts", + "i3dm", + "cmpt", + "geom", + "vctr", + ], + "text/plain": ["glsl"], + }, + true + ); + + const app = express(); + app.use(compression()); + app.use(function (req, res, next) { + res.header("Access-Control-Allow-Origin", "*"); + res.header( + "Access-Control-Allow-Headers", + "Origin, X-Requested-With, Content-Type, Accept" + ); + next(); + }); + + function checkGzipAndNext(req, res, next) { + const reqUrl = url.parse(req.url, true); + const filePath = reqUrl.pathname.substring(1); + + const readStream = fs.createReadStream(filePath, { start: 0, end: 2 }); + readStream.on("error", function (err) { + next(); + }); + + readStream.on("data", function (chunk) { + if (chunk.equals(gzipHeader)) { + res.header("Content-Encoding", "gzip"); + } + next(); + }); + } + + const knownTilesetFormats = [ + /\.b3dm/, + /\.pnts/, + /\.i3dm/, + /\.cmpt/, + /\.glb/, + /\.geom/, + /\.vctr/, + /tileset.*\.json$/, + ]; + app.get(knownTilesetFormats, checkGzipAndNext); + + app.use(express.static(__dirname)); + + function getRemoteUrlFromParam(req) { + let remoteUrl = req.params[0]; + if (remoteUrl) { + // add http:// to the URL if no protocol is present + if (!/^https?:\/\//.test(remoteUrl)) { + remoteUrl = "http://" + remoteUrl; + } + remoteUrl = url.parse(remoteUrl); + // copy query string + remoteUrl.search = url.parse(req.url).search; + } + return remoteUrl; + } + + const dontProxyHeaderRegex = /^(?:Host|Proxy-Connection|Connection|Keep-Alive|Transfer-Encoding|TE|Trailer|Proxy-Authorization|Proxy-Authenticate|Upgrade)$/i; + + function filterHeaders(req, headers) { + const result = {}; + // filter out headers that are listed in the regex above + Object.keys(headers).forEach(function (name) { + if (!dontProxyHeaderRegex.test(name)) { + result[name] = headers[name]; + } + }); + return result; + } + + const upstreamProxy = argv["upstream-proxy"]; + const bypassUpstreamProxyHosts = {}; + if (argv["bypass-upstream-proxy-hosts"]) { + argv["bypass-upstream-proxy-hosts"].split(",").forEach(function (host) { + bypassUpstreamProxyHosts[host.toLowerCase()] = true; + }); + } + + app.get("/proxy/*", function (req, res, next) { + // look for request like http://localhost:8080/proxy/http://example.com/file?query=1 + let remoteUrl = getRemoteUrlFromParam(req); + if (!remoteUrl) { + // look for request like http://localhost:8080/proxy/?http%3A%2F%2Fexample.com%2Ffile%3Fquery%3D1 + remoteUrl = Object.keys(req.query)[0]; + if (remoteUrl) { + remoteUrl = url.parse(remoteUrl); + } + } + + if (!remoteUrl) { + return res.status(400).send("No url specified."); + } + + if (!remoteUrl.protocol) { + remoteUrl.protocol = "http:"; + } + + let proxy; + if (upstreamProxy && !(remoteUrl.host in bypassUpstreamProxyHosts)) { + proxy = upstreamProxy; + } + + // encoding : null means "body" passed to the callback will be raw bytes + + request.get( + { + url: url.format(remoteUrl), + headers: filterHeaders(req, req.headers), + encoding: null, + proxy: proxy, + }, + function (error, response, body) { + let code = 500; + + if (response) { + code = response.statusCode; + res.header(filterHeaders(req, response.headers)); + } + + res.status(code).send(body); + } + ); + }); + + const server = app.listen( + argv.port, + argv.public ? undefined : "localhost", + function () { + if (argv.public) { + console.log( + "Cesium development server running publicly. Connect to http://localhost:%d/", + server.address().port + ); + } else { + console.log( + "Cesium development server running locally. Connect to http://localhost:%d/", + server.address().port + ); + } + } + ); + + server.on("error", function (e) { + if (e.code === "EADDRINUSE") { + console.log( + "Error: Port %d is already in use, select a different port.", + argv.port + ); + console.log("Example: node server.cjs --port %d", argv.port + 1); + } else if (e.code === "EACCES") { + console.log( + "Error: This process does not have permission to listen on port %d.", + argv.port + ); + if (argv.port < 1024) { + console.log("Try a port number higher than 1024."); + } + } + console.log(e); + process.exit(1); + }); + + server.on("close", function () { + console.log("Cesium development server stopped."); + }); + + let isFirstSig = true; + process.on("SIGINT", function () { + if (isFirstSig) { + console.log("Cesium development server shutting down."); + server.close(function () { + process.exit(0); + }); + isFirstSig = false; + } else { + console.log("Cesium development server force kill."); + process.exit(1); + } + }); +})();