Search code examples
httpurl-rewritingurl-routinghttp-redirecthttp-referer

Why Twitter's t.co shows up in Referer, but no URL shorteners ever do?


I've noticed a whole bunch of Referer links like t.co/oPQO7Xdz in my access_log files, but no other URL shorteners ever show up. Why?


Solution

  • The URL shorteners never show up because HTTP 301 Moved Permanently et al redirects in HTTP are not designed to influence the Referer HTTP Request Header (apparently, not even if the header is blank, potentially due to the fact that it'll cause inconsistency in behaviour otherwise).

    However, Twitter does not issue 301 Moved Permanently redirects with its t.co service if it sees what it deems is a popular desktop or mobile User-Agent. As the redirect is thus done outside of the HTTP stack, the Referer field in the subsequent brand-new HTTP Request would then be composed to include the prior HTML page that was responsible for the redirection, causing a t.co entry to appear in access_log.

    % curl -v -A"iPhone;" t.co/oPQO7Xdz
    * About to connect() to t.co port 80 (#0)
    *   Trying 104.244.42.5...
    * connected
    * Connected to t.co (104.244.42.5) port 80 (#0)
    > GET /oPQO7Xdz HTTP/1.1
    > User-Agent: iPhone;
    > Host: t.co
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < cache-control: private,max-age=300
    < content-length: 258
    < content-security-policy: referrer always;
    < content-type: text/html; charset=utf-8
    < date: Thu, 07 Jul 2016 05:24:16 GMT
    < expires: Thu, 07 Jul 2016 05:29:16 GMT
    < server: tsa_o
    < set-cookie: muc=1f43e292-e319-4818-ba81-f12d16e5b629; Expires=Tue, 19 Jun 2018 05:24:16 UTC; Domain=t.co
    < x-connection-hash: 0dc5a2a6a7e83ac2d7fb207eb0cedf84
    < x-response-time: 115
    < x-xss-protection: 1; mode=block
    <
    * Connection #0 to host t.co left intact
    <head><meta name="referrer" content="always"><noscript><META http-equiv="refresh" content="0;URL=http://mdoc.su/n/curl"></noscript><title>http://mdoc.su/n/curl</title></head><script>window.opener = null; location.replace("http:\/\/mdoc.su\/n\/curl")</script>* Closing connection #0
    

    Compare this to what were to occur otherwise (and which is the only way that most other URL shorteners redirect, which would preserve whichever Referer appears when the HTTP request first hits the HTTP stack of the browser):

    % curl -v t.co/oPQO7Xdz
    * About to connect() to t.co port 80 (#0)
    *   Trying 104.244.42.69...
    * connected
    * Connected to t.co (104.244.42.69) port 80 (#0)
    > GET /oPQO7Xdz HTTP/1.1
    > User-Agent: curl/7.26.0
    > Host: t.co
    > Accept: */*
    >
    < HTTP/1.1 301 Moved Permanently
    < cache-control: private,max-age=300
    < content-length: 0
    < date: Thu, 07 Jul 2016 05:24:40 GMT
    < expires: Thu, 07 Jul 2016 05:29:40 GMT
    < location: http://mdoc.su/n/curl
    < server: tsa_o
    < set-cookie: muc=2c727b50-311f-4043-9861-9f703996a8a8; Expires=Tue, 19 Jun 2018 05:24:40 UTC; Domain=t.co
    < x-connection-hash: 5583cc49ddbcefe8fac9ba392ca868fd
    < x-response-time: 103
    <
    * Connection #0 to host t.co left intact
    * Closing connection #0