Cookies

The cookies plugin allows for the cookies to be kept in and used from the session:

http = HTTPX.plugin(:cookies)
response = http.get("https://example.com/setscookies") #=> "302 ... Location: https://example.com/another ... Set-Cookie: aadm...."
response = http.get(response.headers["location"]) => Sends the cookie information

This plugin also works seamlessly with the follow_redirects plugin, in the redirections setting a session cookie will be respected:

http = HTTPX.plugin(:cookies).plugin(:follow_redirects)
response = http.get("https://example.com/setscookies") #=> will redirect to "https://example.com/another" with cookies

:cookies

A user can also initiate the cookie jar when starting the session as well.

You can do so using the :cookies option. This can be:

  1. pairs of cookie name and values (and extra options);
  2. an array of options (where :name (and :value) is defined);
  3. a cookie jar from another session;
# 1.
http = HTTPX.plugin(:cookies).with_cookies("foo" => "bar")
http.get("https://example.com")
# 2.
http = HTTPX.plugin(:cookies).with_cookies([{name: "foo", value: "bar"}])
http.get("https://example.com")
# 3.
http = HTTPX.plugin(:cookies)
response = http.get("https://example.com/setscookies")
# ... after a while
other_http = HTTPX.plugin(:cookies)
other_http.with_cookies(http.cookies)
other_http.get("https://example.com")

The extra options when defining a cookie correspond to the supported cookie attributes as per RFC6265:

  • secure: The “Secure” attribute, can be true or false (false by default);
  • path: The “Path” attribute ("/" by default);
  • domain: The “Domain” attribute (when not set, it’ll be sent in all session requests);
  • max_age: The “Max-Age” attribute, can an integer (seconds) setting a lifetime for the cookie (when cookie expires, it’ll be dropped from the jar);
  • expires: The “Expires” attribute, can be a Time object, setting the moment after which the cookie is expired and is dropped from the jar);

Notes

If you are using a version of httpx lower than 0.10.0, you must install the http-cookie gem to use this feature. More recent versions do not require it anymore.

Why?

http-cookie was very helpful in the first iteration of the :cookies plugin, and it mostly “just works”. It was also bit of a heavy dependency:

  • It depends on other 2 gems (domain_name and unf, all by the same maintainer);
  • It requires compilation of native extensions, although the compile code isn’t exercised since ruby 2.2;
  • Does a lot of things that a scraper like Mechanize needs, but an HTTP client might not need (debatable, I guess);

However, while preparing support for ruby 3, I’ve learned that the latest version of unf was released 3 years ago, and it doesn’t compile in ruby 3. The “master” branch seems to work though, but the whole thing leads me to believe that the projects aren’t maintained anymore, which led me to “roll my own”.

This is therefore a not-so-exhaustive list of features that aren’t supported anymore in the cookies implementation of httpx (if this way important to you, please drop an issue):

  • Netscape cookies.txt format as cookie store;
  • Mozilla cookie.sqlite format as cookie store;
  • eTLD-based cookie rejection;

Next: Compression