holic/redirect.name

Support for POST, PUT, etc?

Closed this issue · 4 comments

I'm not sure if this is beyond the goals of this project, but how about supporting redirecting other http methods?

For (a rather silly) example, if I have the following:

thing-service.mydomain.com    IN CNAME    alias.redirect.name
_redirect.things-service.mydomain.com    IN TXT    Redirect from /* to https://my-app.herokuapp.com/*

I'd like POST thing-service.mydomain.com/things to be forwarded to https://my-app.herokuapp.com/things with the same post body. Using a status code of 307 when redirecting should do the trick - I can put up a pull request, but I just first wanted to make sure it aligned with this project's goals.

holic commented

Thanks, Ken! I really dig a solid suggestion with PR + tests! 💯
(And sorry for the delayed reply, I've been out of town the last week.)

Do you know what the implications are for making this change? What kind of browser support is available and what is the usability like? I haven't used 307/308 redirects in practice, so I'm not sure if there are specifics I should be worried (or not worried) about - security, browser support, SEO, or otherwise.

(See also a bit of discussion here: https://github.com/kennethreitz/requests/issues/1084)

Well, some good news and some bad news. But first, as far as I've read, using redirects shouldn't impact SEO at all, and 307/308 seems to be a correction to poorly implemented 302/303s. So now onto the news...

Setup: I have hk.kenrg.co aliased using this tool to infinite-reaches-89066.herokuapp.com, which is a super crappy "thing-storage-service".

I tested my changes with that python library you linked by

import requests
requests.post('http://localhost:8081/things', json={'id': 123, 'name': 'Ken'}, headers={'Host': 'hk.kenrg.co'})
r = requests.get('http:localhost:8081/things/123', headers={'Host': 'hk.kenrg.co'})
print r.json()

and got {u'thing': {u'id': 123, u'name': u'Ken'}}; the expected output. So that python library works.

Next I tried superagent with:

var superuser = require('superuser');

superuser
  .post('http://localhost:8081/things')
  .set('Host', 'hk.kenrg.co')
  .send({ id: 1234, name: 'Meg' })
  .end(function(err, res) {
    console.log(res);
  });

superuser
  .get('http://localhost:8081/things/1234')
  .set('Host', 'hk.kenrg.co')
  .end(function(err, res) {
    console.log(res.body);
  });

and got { thing: { id: 1234, name: 'Meg' } }; again, expected.

Using curl works too, but I won't write that all out here.
So that's all good.

Then I tried using RestTemplate, and I started to run into problems. I got this page, most likely because RestTemplate doesn't set the Host header, or at least not in the same way as the other libraries do. However, RestTemplate doesn't correctly handle GETs either, so I don't think this has anything to do with the code I added (sorry).

So.... sorry for the wall of text. But, I'm not sure where we want to go from here. Thoughts?

holic commented

Thanks for testing across those libraries! I guess I'm less concerned about them and more concerned about actual browser implementations of 307/308 status codes. This project is targeted at and used mostly by browser based requests rather than libraries, so I would like to ensure we don't break anything in browsers.

I'm not sure I know how to test that... I mostly make requests in the web using libraries like superagent (or just plain fetch), after webpacking them together (which is why I tested superagent). If you're thinking about native browser capabilities (without javascript), the only thing I can think of is a form. I tried making this:

<form action="http://localhost:8081/things" method="post">
    Id:<br>
    <input type="number" name="id" value="123"><br>
    Name:<br>
    <input type="text" name="name" value="Ken"><br>
    <input type="submit" value="Submit">
</form>

but since I can't manually add the 'Host' header to the http request the form will make, there's no way for redirect.name to pick up on it. So I don't really know of a way to test this locally.