[PATCH] AnyEvent::HTTP: on_raw_header callback
Chris Novakovic
chris at chrisn.me.uk
Fri Sep 8 22:02:35 CEST 2017
Apparently I did something terrible in a previous life and I'm having to
atone for it now by working with a closed-source API server that doesn't
implement HTTP/1.1 properly: one of the responses it sends is a 302
redirect containing a body ("Redirecting to <URL>") but no
Content-Length header. AnyEvent::HTTP can't handle this, hanging on line
1113: $len is undefined because $hdr{"content-length"} is undefined on
line 1008, so it (sensibly) expects to read nothing from the handle and
immediately hit an EPIPE error that never arrives because the unexpected
response body is sitting in the buffer.
None of this is AnyEvent::HTTP's fault, of course, but it means that I
can't use it in its current state to interact with this godawful API.
I've attached a patch --- one I don't necessarily expect to be merged in
its current state, or at all, but one that might help others who have
similar difficulties in future --- that implements an "on_raw_header"
callback. Similar to the "on_header" callback, it gives the caller an
opportunity to inspect the (mostly) raw headers in the HTTP response
before AnyEvent::HTTP uses them to decide how (and whether) to process
the response body coming from the handle; again, like "on_header",
retuning a non-true value in that callback aborts the request. In my
case, I used it to check whether the response was a 302, and pull the
"Location" header and send a request to it manually using another call
to http_request before returning false to abort the original request.
Marc, I know you're busy, so if you think this might be useful to a
broader audience and want me to clean up this patch and/or document it
properly, let me know.
-------------- next part --------------
diff -Naur a/HTTP.pm b/HTTP.pm
--- a/HTTP.pm 2017-09-08 20:36:33.551427098 +0100
+++ b/HTTP.pm 2017-09-08 20:36:51.195178754 +0100
@@ -890,6 +890,12 @@
%hdr = (%$hdr, @pseudo);
}
+ if (exists $arg{on_raw_header}) {
+ unless ($arg{on_raw_header}->(\%hdr)) {
+ return _error %state, $cb, { @pseudo, Status => 598, Reason => "Request cancelled by on_raw_header" };
+ }
+ }
+
# redirect handling
# relative uri handling forced by microsoft and other shitheads.
# we give our best and fall back to URI if available.
More information about the anyevent
mailing list