Skip to content

Instantly share code, notes, and snippets.

@hoelzro
Created August 26, 2014 01:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hoelzro/671912c49b0efcc8d2aa to your computer and use it in GitHub Desktop.
Save hoelzro/671912c49b0efcc8d2aa to your computer and use it in GitHub Desktop.
HTTP User Agent Example
#| Abstract representation of an HTTP connection
role HTTPConnection {
method send(Buf $bytes) { ... }
}
# Stub classes that are HTTPConnections, just to illustrate the kind of things
# you could do. They will probably wrap each other, something like this:
#
# SSLConnection.new(ConnectProxyConnection.new(:host<...>, :port(...)));
#| Raw TCP connection; useful for direct http:// URLs
class RawConnection does HTTPConnection { ... }
#| HTTP over SSL; useful for https://
class SSLConnection does HTTPConnection { ... }
#| Useful if you need to go over a SOCKS proxy
class SOCKSConnection does HTTPConnection { ... }
#| Go over a network proxy using the CONNECT verb
class ConnectProxyConnection does HTTPConnection { ... }
#| Go over an HTTP proxy without using CONNECT
class ProxyConnection does HTTPConnection { ... }
class ConnectionManager {
#| Returns an HTTPConnection object appropriate for C<$req>.
method connect(Request $req) returns HTTPConnection {
...
}
}
# The UserAgent itself
class UserAgent {
has $.connection-manager is rw handles 'connect' = ConnectionManager.new; # this could be a different object (you could even provide a fake one for testing)
method send-request(Request $req) {
self.*before-request($req);
my $conn = $.connect($req);
my $res = $conn.send($req.Buf);
$res = Response.parse($res);
self.*after-request($req, $res);
$res
}
method GET($url) {
$.send-request(Request.new(:method<GET>, :$url))
}
}
# An example middleware
role CookieBehavior {
method before-request(Request $req) {
# XXX insert cookies for domain
}
method after-request(Request $, Response $res) {
# XXX store cookies for domain
}
}
# Another middleware
role AuthBasicBehavior {
method before-request(Request $req) {
# XXX insert username/password into $req
}
}
# Example:
my $ua = UserAgent.new does (CookieBehavior, AuthBasicBehavior); # there would probably be some internal sugar for this in UserAgent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment