question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add option to match relative URLs without computing isIndirectPathRequest()

See original GitHub issue

The following commit prevents us from upgrading: https://github.com/httptoolkit/mockttp/commit/ef2e0a88574afa8fb37dac834dcecc67e8a21426

This may be a breaking change if you are sending requests to a Mockttp server directly, using a hostname for the server that isn’t ‘localhost’ or one of its ip addresses. That traffic will now be treated as having an absolute URL.

We will be able to get around the issue, but I thought that describing our use case could help you if you wanted to change the design.

Our use case is system testing of an app container which sometimes makes requests to an external_webservice. Our tests are run by another container named tester, which makes requests to the app container and checks the response. We have been using mockttp to mock external_webservice. A typical test inside tester would be:

describe('The APP container on /route1', () => {
  before(async () => {
    await mockServer.start(process.env.MOCK_PORT);
    await mockServer.get('/external_api').thenReply(200, "something that external_webservice should respond");
  });
  after(async () => {
    await mockServer.stop();
  });
  it('always calls the external_api and returns OK', async () => {
    const response = await request(`${process.env.APP_URL}/route1`);
    expect(response).to.equal('OK');
    const externalRequests = await mockServer.getSeenRequests();
    expect(externalRequests.length).to.equal(1);
  });
}

Our containers run with docker-compose, with something like this;

app:
  environment:
    EXTERNAL_API_URL: http://tester:7500/external_api
tester:
  environment:
    MOCK_PORT: 7500

As you can see, the host that mockttp will receive is tester not localhost. After upgrading, this is the error message:

No rules were found matching this request.
This request was: GET request to http://tester:7500/external_api with headers: ...
The configured rules are:
Match requests making GETs for /external_api, and then respond with status 200 and body "something that external_webservice should respond".
You can fix this by adding a rule to match this request, for example:
mockServer.get("/external_api").thenReply(200, "your response");

Note that the suggestion is incorrect, because this is precisely the route that we specified.

We can get around the issue in multiple ways. But maybe mockttp could be improved in one of the following ways:

  • add a disableProxy option to MockttpOptions
  • add a noHostChecking option to MockttpOptions
  • create a mockServer.proxyUrl, which would be different from mockServer.url (maybe appending a fingerprint like /.well-kown/mockttp-proxy)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:12 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
pimterrycommented, Aug 19, 2019

This has now been released as v0.17.0, so I’ll close this.

Thanks again for the report, discussion & testing, this was really useful! Let me know if you have any more issues in future.

1reaction
pimterrycommented, Jul 29, 2019

Interesting! That’s very useful, thanks, I wasn’t sure whether this case was one that anybody would hit - clearly it is 😃.

In the short term, you should be able to match this request by changing your rule to use the absolute form:

await mockServer.get('http://tester:7500/external_api').thenReply(...);

Does that work for you?

You could inject tester:7500 through an env var if you’d prefer, or alternatively make this independent of host entirely with a regex (get(/https?:\/\/[^\/]+\/external_api/)).

In the medium term, I agree this makes that case difficult, and it is a case I’d like to support properly. That said, I’m cautious of solving it with new configuration options or by separating the proxied & direct request cases unnecessarily, since they’re fundamentally very similar, and it’s occasionally even useful to do both at the same time.

There’s an argument to be made that the issue here is simply in how path matching works perhaps? This could be changed so that absolute URL matchers check the host, whilst any relative URLs only check the path etc, and match for all hosts.

That would mean the host information is still available for matching when that’s useful, but the simpler option still works too, which seems fairly intuitive to me.

Given that, both get('http://tester:7500/external_api') and get('/external_api') would match. Currently only the former does, and previously only the latter.

What do you think?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Javascript: REGEX to change all relative Urls to Absolute
I'd use a real parser, not a regex. There are html parsers for node. – thejh. Sep 25, 2011 at 12:50. Add ......
Read more >
Edge redirector - Relative redirect option. - Akamai Community
When playing around with edge redirect realized that we have a relative redirect option so we do not need to match the host...
Read more >
Absolute and Relative URLs - ActiveX Data Objects (ADO)
A relative URL locates a resource using an absolute URL as a ... only of the path, and optionally, the resource, but no...
Read more >
HTML and URLs
HTML documents utilize URLs for specifying hypertext links. The following provides a ... The relative URL in the following markup for a hypertext...
Read more >
How To Use Relative URLs For Website Links - YouTube
This video walks you though how to use relative URLs for website design. ... Web Hosting Options and How to Set Up New...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found