Skip to content

Timeout for OSRM && headers#10

Open
yanngv29 wants to merge 15 commits intoProject-OSRM:masterfrom
yanngv29:master
Open

Timeout for OSRM && headers#10
yanngv29 wants to merge 15 commits intoProject-OSRM:masterfrom
yanngv29:master

Conversation

@yanngv29
Copy link
Copy Markdown

@yanngv29 yanngv29 commented May 27, 2021

add timeout case when calling OSRM
add headers capabilities when, for example, you need to pass some credentials to the OSRM server

some dependencies update.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for request headers and improves timeout handling when calling an OSRM server, along with dependency/build updates.

Changes:

  • Add configurable default headers (headers) on the OSRM client and forward them into HTTP(S) requests.
  • Rework request execution to use http(s).request() with timeout handling.
  • Update package version/dependencies and adjust tests/build scripts.

Reviewed changes

Copilot reviewed 3 out of 7 changed files in this pull request and generated 9 comments.

File Description
src/osrm.js Adds headers support and refactors HTTP request creation + timeout handling.
test/test.js Updates expected match coordinates and adds debug logging in the tile test.
package.json Bumps version/dev deps and changes the build (prepub) script.
package-lock.json Introduces lockfile reflecting updated dependency graph.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +40 to +60
this._get = function(url, callback,timeoutCb) {
var parsedUrl = Url.parse(url);
var options = {
protocol : parsedUrl.protocol,
hostname : parsedUrl.hostname,
port : parsedUrl.port,
path : parsedUrl.path,
headers : this._headers,
timeout : this._timeout
};
if (protocol === "http:")
{
return http.get(url, callback);
var clientRequest = http.request(options, callback);
clientRequest.setTimeout(this._timeout,timeoutCb);
return clientRequest;
}
else if (protocol == "https:")
{
return https.get(url, callback);
var clientRequest = https.request(options, callback);
clientRequest.setTimeout(this._timeout,timeoutCb);
return clientRequest;
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request.setTimeout(...) is being registered twice: once inside _get via clientRequest.setTimeout(this._timeout, timeoutCb) and again in request() via .setTimeout(this._timeout, ...). On a socket timeout, both listeners can fire and invoke the user callback twice, and the _get timeout handler also doesn’t abort/destroy the request. Consider consolidating timeout handling in one place (preferably in request()), ensuring the request is destroyed/aborted, and guarding all completion paths so callback can only be called once.

Copilot uses AI. Check for mistakes.
}
});
},function () {
console.error("osrm TIMEOUT detected -> returning an error");
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout callback passed to _get logs to stderr (console.error(...)). Since this is library code, this will produce unexpected noisy output for consumers and can’t be controlled. Prefer returning the timeout error via the callback only, and let the caller decide how/where to log.

Suggested change
console.error("osrm TIMEOUT detected -> returning an error");

Copilot uses AI. Check for mistakes.
Comment on lines 111 to 117
var timedout;
var request = this._get(url, function (response) {
var body = '';

response.on('data', function(data) {
body += data;
});
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timeout handling now sets timedout = true and calls callback, but the response handlers later in request() don’t check timedout before calling callback (e.g., in the response 'end' path). This can lead to the callback being invoked more than once if the server responds after the timeout. Add a single “done”/once guard that all success/error/timeout paths use before invoking the callback.

Copilot uses AI. Check for mistakes.
Comment on lines +40 to 57
this._get = function(url, callback,timeoutCb) {
var parsedUrl = Url.parse(url);
var options = {
protocol : parsedUrl.protocol,
hostname : parsedUrl.hostname,
port : parsedUrl.port,
path : parsedUrl.path,
headers : this._headers,
timeout : this._timeout
};
if (protocol === "http:")
{
return http.get(url, callback);
var clientRequest = http.request(options, callback);
clientRequest.setTimeout(this._timeout,timeoutCb);
return clientRequest;
}
else if (protocol == "https:")
{
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_get builds options from parsedUrl, but selects the HTTP client (http vs https) based on the outer protocol parsed from this._url, not parsedUrl.protocol. If a full URL with a different protocol is ever passed in (or this._url changes), this can send requests with the wrong module. Prefer branching on parsedUrl.protocol (or options.protocol) to match the request being made.

Copilot uses AI. Check for mistakes.
Comment on lines 24 to +27
this._url = arg.url || this._url;
this._profile = arg.profile || this._profile;
this._timeout = arg.timeout || this._timeout;
this._headers = arg.headers || this._headers;
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Option defaults in the constructor use || (e.g., this._timeout = arg.timeout || this._timeout). This prevents callers from intentionally setting falsy values like timeout: 0 (often used to disable timeouts) or headers: {} vs null. Consider using an explicit undefined check (e.g., if ('timeout' in arg) ...) so valid falsy values can be provided.

Suggested change
this._url = arg.url || this._url;
this._profile = arg.profile || this._profile;
this._timeout = arg.timeout || this._timeout;
this._headers = arg.headers || this._headers;
if (arg.url !== undefined) this._url = arg.url;
if (arg.profile !== undefined) this._profile = arg.profile;
if (arg.timeout !== undefined) this._timeout = arg.timeout;
if (arg.headers !== undefined) this._headers = arg.headers;

Copilot uses AI. Check for mistakes.
Comment on lines 142 to 146
}).setTimeout(this._timeout, function() {
request.abort();
timedout = true;
callback(new Error("Request timed out"));
});
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timeout handler uses request.abort(). In modern Node.js this is deprecated in favor of request.destroy() (and abort() has slightly different semantics/events). Consider switching to destroy() and ensuring the timeout error path can only fire once (especially given the additional timeout listener added in _get).

Copilot uses AI. Check for mistakes.
Comment on lines +156 to +157
console.log("ratio : "+ ratio);
console.log("result : "+JSON.stringify(result));
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tile test now logs ratio and the full result buffer to stdout. This will add noisy output to normal test runs and CI logs, and JSON.stringify(result) can be very large. Please remove these console.log lines (or gate them behind an explicit debug flag if needed).

Suggested change
console.log("ratio : "+ ratio);
console.log("result : "+JSON.stringify(result));

Copilot uses AI. Check for mistakes.
},
"scripts": {
"prepub": "browserify -d src/osrm.js -s osrm > dist/osrm.raw.js && uglifyjs dist/osrm.raw.js -c -m --source-map=dist/osrm.js.map -o dist/osrm.js",
"prepub": "browserify -d src/osrm.js -s osrm > dist/osrm.raw.js && uglifyjs dist/osrm.raw.js -c -m -o dist/osrm.js",
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prepub no longer generates a source map, but the repo currently contains dist/osrm.js.map. This can leave the committed map stale/out-of-sync (or missing after running the script). Either keep generating the map in prepub or remove/update the committed .map artifact so dist/ stays consistent.

Suggested change
"prepub": "browserify -d src/osrm.js -s osrm > dist/osrm.raw.js && uglifyjs dist/osrm.raw.js -c -m -o dist/osrm.js",
"prepub": "browserify -d src/osrm.js -s osrm > dist/osrm.raw.js && uglifyjs dist/osrm.raw.js -c -m --source-map dist/osrm.js.map -o dist/osrm.js",

Copilot uses AI. Check for mistakes.
Comment on lines 9 to 13
this._url = 'https://router.project-osrm.org';
this._profile = 'driving';
this._timeout = 10000; // 10 seconds
this._headers = {};

Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New behavior for request headers (this._headers forwarded into request options) and timeout handling is not covered by tests. Consider adding tests that spin up a local HTTP server to (1) assert incoming headers match arg.headers and (2) delay responses to assert the callback receives a timeout error and is invoked only once.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants