HTTP::Daemon(3pm)
π HTTP::Daemon π
sooo bestie, welcome to the manual page for HTTP::Daemon β that's HTTP::Daemon(3pm) in the Perl User Contributed Perl Documentation corner of the universe π«Ά β and it is literally described as A simple http server class. That's the whole NAME situation. Iconic. Simple. A whole http server, in a class, bestie. π
β¨ VERSION β¨
This is version 6.17, no cap. π
πΈ SYNOPSIS πΈ
okay so here's the vibe check β this is what using it actually looks like:
use HTTP::Daemon;
use HTTP::Status;
my $d = HTTP::Daemon->new || die;
print "Please contact me at: <URL:", $d->url, ">\n";
while (my $c = $d->accept) {
while (my $r = $c->get_request) {
if ($r->method eq 'GET' and $r->uri->path eq "/xyzzy") {
# remember, this is *not* recommended practice :-)
$c->send_file_response("/etc/passwd");
}
else {
$c->send_error(RC_FORBIDDEN)
}
}
$c->close;
undef($c);
}
π¨ bestie, do NOT miss that comment in there:# remember, this is *not* recommended practice :-)β serving up/etc/passwdis giving chaos gremlin, not giving secure server. The original author put that smiley there for a reason. π
lowkey the whole flow is: spin up a daemon with HTTP::Daemon->new, yell your $d->url into the group chat, then sit in $d->accept catching connections, and for every $c->get_request you check the method and path and either $c->send_file_response(...) or $c->send_error(RC_FORBIDDEN), then $c->close and undef($c) to let it go. π¦
to be continued, bestie β there's more coming, don't go anywhere β¨
β¨ DESCRIPTION β¨
okay bestie, listen up π an HTTP::Daemon object is basically an HTTP/1.1 server that sits on a socket waiting for people (clients) to slide into its DMs (requests). And because HTTP::Daemon is a subclass of IO::Socket::IP, you can absolutely just do socket stuff directly on it too. two jobs, one icon. π
quick lore drop tho: HTTP::Daemon used to be a subclass of IO::Socket::INET. to support IPv6, it switched its parent class over to IO::Socket::IP at version 6.05. go read the "IPv6 SUPPORT" section below for the whole story. π¦
so the accept() method? it returns the moment a client connection is available. and what you get back is an HTTP::Daemon::ClientConn object β which is another IO::Socket::IP subclass, she's got range. call get_request() on that object and it reads data from the client and hands you an HTTP::Request object. the ClientConn object also has methods for sending responses back, so she's giving both sides of the conversation. π
π¨ real talk: this HTTP daemon does notfork(2)for you. your app β like, you, the user ofHTTP::Daemonβ is the one responsible for forking if that's what you want. also you are responsible for generating responses that actually conform to the HTTP/1.1 protocol. the vibes are on you, bestie. π
the following methods of HTTP::Daemon are new (or enhanced) compared to the IO::Socket::IP base class:
$d = HTTP::Daemon->new,$d = HTTP::Daemon->new( %opts )β the constructor takes the same arguments as theIO::Socket::IPconstructor, but unlike its base class it can also be called with no arguments at all. when you do that, the daemon sets up a listen queue of 5 connections and allocates some random port number. iconic. a server that wants to bind to some specific address on the standard HTTP port gets built like this:
$d = HTTP::Daemon->new(
LocalAddr => 'www.thisplace.com',
LocalPort => 80,
);
and yeah, go check out IO::Socket::IP for the tea on the other arguments you can use to configure the daemon during construction. π
$c = $d->accept,$c = $d->accept( $pkg ),($c, $peer_addr) = $d->acceptβ works exactly like the one the base class gives you, except it returns anHTTP::Daemon::ClientConnreference by default. if you hand it a package name as an argument, the returned object gets blessed into that class instead. and ngl, it's probably a good idea to make that class a subclass ofHTTP::Daemon::ClientConn. π the accept method returnsundefif timeouts have been enabled and no connection shows up within the given time. thetimeout()method is described over inIO::Socket::IP. in list context you get both the client object and the peer address back β see the description of the accept method ofIO::Socketfor the deets.$d->urlβ returns a URL string you can use to access the server root. cute, functional, we love her. β¨$d->product_tokensβ returns the name this server uses to identify itself. this is the string that gets sent with theServerresponse header. the main reason this method exists is so subclasses can override it if they wanna rep a different product name. the default is the stringlibwww-perl-daemon/#.##where#.##gets replaced with the version number of this module. π«Ά
okay so now for the other half of the duo: HTTP::Daemon::ClientConn is a subclass of IO::Socket::IP. instances of this class are what the accept() method of HTTP::Daemon hands back to you. here's everything she can do:
$c->get_request,$c->get_request( $headers_only )β reads data from the client and turns it into anHTTP::Requestobject, which it returns. returnsundefif the reading fails. and if it does fail, then thatHTTP::Daemon::ClientConnobject ($c) should be discarded β do not try to call this method on it again. the$c->reasonmethod might give you some info about why$c->get_requestflopped. π normallyget_request()won't return until the whole request has been received from the client. that might not be what you want if the request is an upload of a large file (and with chunked transfer encoding, HTTP can even support infinite request messages β uploading live audio, for instance, which is wild fr). if you pass a TRUE value as the$headers_onlyargument, thenget_request()returns immediately after parsing the request headers, and you are responsible for reading the rest of the request content. and if you're gonna call$c->get_requestagain on that same connection, you better read the correct number of bytes, no cap. π$c->read_buffer,$c->read_buffer( $new_value )β bytes read by$c->get_requestthat didn't get used are placed in the read buffer. the next time$c->get_requestis called, it'll consume the bytes in this buffer before reading more data from the network connection itself. heads up: the read buffer is invalid after$c->get_requesthas failed. π if you handle reading the request content yourself, you need to empty this buffer before you read more, and you need to place unconsumed bytes here. you also need this buffer if you implement services like 101 Switching Protocols. this method always returns the old buffer content, and it can optionally replace the buffer content if you pass it an argument.$c->reasonβ when$c->get_requestreturnsundef, you can grab a short string describing why that happened by calling$c->reason. the diagnostics bestie. π$c->proto_ge( $proto )β returns TRUE if the client announced a protocol with a version number greater than or equal to the given argument. the$protoargument can be a string likeHTTP/1.1or just1.1. flexible queen. π$c->antique_clientβ returns TRUE if the client speaks the HTTP/0.9 protocol. no status code and no headers should be returned to such a client. this should be the same as!$c->proto_ge("HTTP/1.0"). yes she's vintage, no we are not sending her headers. π°οΈ$c->head_requestβ returns TRUE if the last request was aHEADrequest. no content body must be generated for these requests. periodt. π«$c->force_last_requestβ makes sure that$c->get_requestwill not try to read more requests off this connection. if you generate a response that isn't self-delimiting, then you should signal that fact by calling this method. this attribute gets turned on automatically if the client announces protocol HTTP/1.0 or worse and doesn't include aConnection: Keep-Aliveheader. it's also turned on automatically when HTTP/1.1 or better clients send theConnection: closerequest header. automatic, like magic β¨$c->send_status_line,$c->send_status_line( $code ),$c->send_status_line( $code, $mess ),$c->send_status_line( $code, $mess, $proto )β sends the status line back to the client. if$codeis omitted, 200 is assumed. if$messis omitted, then a message corresponding to$codegets inserted. if$protois missing, the content of the$HTTP::Daemon::PROTOvariable is used.$c->send_crlfβ sends the CRLF sequence to the client. short, sweet, essential. π$c->send_basic_header,$c->send_basic_header( $code ),$c->send_basic_header( $code, $mess ),$c->send_basic_header( $code, $mess, $proto )β sends the status line plus theDate:andServer:headers back to the client. this header is assumed to be continued and does not end with an empty CRLF line, jsyk. for the description of the accepted arguments, see the write-up onsend_status_line(). π$c->send_header( $field, $value ),$c->send_header( $field1, $value1, $field2, $value2, ... )β sends one or more header lines. go off, send a whole stack of them. π₯$c->send_response( $res )β writes anHTTP::Responseobject to the client as a response. we try so hard to make sure the response is self-delimiting so the connection can stay persistent for further request/response exchanges. the content attribute of theHTTP::Responseobject can be a normal string or a subroutine reference. if it's a subroutine, then whatever that callback routine returns gets written back to the client as the response content. the routine will be called until it returns an undefined or empty value. and if the client is HTTP/1.1 aware, then we'll use chunked transfer encoding for the response. π β¨$c->send_redirect( $loc ),$c->send_redirect( $loc, $code ),$c->send_redirect( $loc, $code, $entity_body )β sends a redirect response back to the client. the location ($loc) can be an absolute or relative URL. the$codemust be one of the redirect status codes, and it defaults to301 Moved Permanently. bye girl, we're going elsewhere π$c->send_error,$c->send_error( $code ),$c->send_error( $code, $error_message )β sends an error response back to the client. if the$codeis missing, aBad Requesterror is reported. the$error_messageis a string that gets incorporated into the body of the HTML entity. sad girl hours but make it informative π$c->send_file_response( $filename )β sends back a response with the specified$filenameas content. and if the file is a directory, we try to generate an HTML index of it. thoughtful! π§$c->send_file( $filename ),$c->send_file( $fd )β copies the file to the client. the file can be a string (which gets interpreted as a filename) or a reference to anIO::Handleor glob. returns the number of bytes copied on success, orundefif the filename form failed to open. an empty file returns the string'0E0'(zero numerically, true in boolean context) so that callers usingsend_file or diecan tell an open failure apart from a successful zero-byte transfer. clever, right? π
π¨ ok important safety briefing, bestie, pay attention: the filename form uses Perl's 3-argumentopenwith an explicit<mode, so the path is no longer interpreted as a 2-argumentopenshell-magic shape like| cmd,cmd |, or> path. seeCVE-2026-8450(https://www.cve.org/CVERecord?id=CVE-2026-8450) for the prior 2-argumentopenbehaviour this replaces.
β οΈ but listen: this fix only neutralises 2-argumentopenshell-magic. callers remain responsible for validating attacker-influenced paths.send_filewill still happily open symlinks, character/block devices (e.g./dev/zero,/dev/stdin), named pipes (which may block the worker), and files outside an intended document root. if$filenamecan be derived from request input, validate it β canonicalise, reject..segments, require-f _and a vetted prefix β before passing it in. do not skip this step. π
$c->daemonβ returns a reference to the correspondingHTTP::Daemonobject. like, the parent. the origin. the main character. π
π IPv6 SUPPORT π
since version 6.05, HTTP::Daemon is a subclass of IO::Socket::IP rather than IO::Socket::INET, which means she supports IPv6. glow up complete. π
for some reasons (we don't ask, we respect the choice), you may want to force HTTP::Daemon to listen on IPv4 addresses only. in that case, pass the Family argument to HTTP::Daemon->new:
use HTTP::Daemon;
use Socket 'AF_INET';
my $d = HTTP::Daemon->new(Family => AF_INET);
and that's the vibe check on IPv4-only mode. π¦
π SEE ALSO
bestie if u wanna go deeper, these are the required readings fr:
- RFC 2616 β the whole HTTP/1.1 situation, the blueprint, the sacred text π
IO::Socket::IPβ for when u want ur sockets to speak IPv6 like a boss πIO::Socketβ the OG, the blueprint's blueprint, the whole reason any of this works π«Ά
π«Ά GIVING THANKS
okay so if this module came through for u and u wanna say thank u (and honestly? u should, it's giving generosity), here's the move:
- drop a +1 on MetaCPAN at https://metacpan.org/dist/HTTP-Daemon β¨
- and a star on GitHub at https://github.com/libwww-perl/HTTP-Daemon β
that's it. that's the whole ask. no cap, it's free and it means everything π
π SUPPORT
found a bug? bestie, pls do NOT suffer in silence, submit it through:
https://github.com/libwww-perl/HTTP-Daemon/issues
there's also a mailing list for everyone using this distribution, over at:
mailto:libwww@perl.org
and if u wanna vibe in real time, there's an irc channel for users of this distribution too, it's #lwp on irc.perl.org:
irc://irc.perl.org/#lwp
come through, the group chat is open π
π AUTHOR
Gisle Aas <gisle@activestate.com>
the legend. the moment. the origin story π
π§ CONTRIBUTORS
these absolute icons showed up and made it better, every single one of them:
- Olaf Alders <olaf@wundersolutions.com>
- Ville SkyttΓ€ <ville.skytta@iki.fi>
- Graham Knop <haarg@haarg.org>
- dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
- Karen Etheridge <ether@cpan.org>
- Mark Stosberg <MARKSTOS@cpan.org>
- Shoichi Kaji <skaji@cpan.org>
- Chase Whitener <capoeirab@cpan.org>
- Theo van Hoesel <tvanhoesel@perceptyx.com>
- Julien Fiegehenn <simbabque@cpan.org>
- Slaven Rezic <slaven@rezic.de>
- Petr PΓsaΕ <ppisar@redhat.com>
- Zefram <zefram@fysh.org>
- Alexey Tourbin <at@altlinux.ru>
- Bron Gondwana <brong@fastmail.fm>
- Michal Josef Ε paΔek <mspacek@redhat.com>
- Mike Schilli <mschilli@yahoo-inc.com>
- Tom Hukins <tom@eborcom.com>
- Adam Kennedy <adamk@cpan.org>
- Adam Sjogren <asjo@koldfront.dk>
- Alex Kapranoff <ka@nadoby.ru>
- amire80 <amir.aharoni@gmail.com>
- Andreas J. Koenig <andreas.koenig@anima.de>
- Bill Mann <wfmann@alum.mit.edu>
- Daniel Hedlund <Daniel.Hedlund@eprize.com>
- David E. Wheeler <david@justatheory.com>
- DAVIDRW <davidrw@cpan.org>
- Father Chrysostomos <sprout@cpan.org>
- Ferenc Erki <erkiferenc@gmail.com>
- FWILES <FWILES@cpan.org>
- Gavin Peters <gpeters@deepsky.com>
- Graeme Thompson <Graeme.Thompson@mobilecohesion.com>
- Hans-H. Froehlich <hfroehlich@co-de-co.de>
- Ian Kilgore <iank@cpan.org>
- Jacob J <waif@chaos2.org>
- jefflee <shaohua@gmail.com>
- john9art <john9art@yahoo.com>
- murphy <murphy@genome.chop.edu>
- Ondrej Hanak <ondrej.hanak@ubs.com>
- Perlover <perlover@perlover.com>
- Peter Rabbitson <ribasushi@cpan.org>
- phrstbrn <phrstbrn@gmail.com>
- Robert Stone <talby@trap.mtview.ca.us>
- Rolf Grossmann <rg@progtech.net>
- ruff <ruff@ukrpost.net>
- sasao <sasao@yugen.org>
- Sean M. Burke <sburke@cpan.org>
- Spiros Denaxas <s.denaxas@gmail.com>
- Steve Hay <SteveHay@planit.com>
- Todd Lipcon <todd@amiestreet.com>
- Tony Finch <dot@dotat.at>
- Toru Yamaguchi <zigorou@cpan.org>
- Yuri Karaban <tech@askold.net>
every one of them. we see u. we appreciate u. πβ¨
π COPYRIGHT AND LICENCE
this software is copyright (c) 1995 by Gisle Aas.
it's free software bestie π«Ά u can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. that's the deal, that's the vibe, periodt.
and that's the whole page!! this lil beauty is from perl v5.42.2 and was dated 2026-05-20 β aka HTTP::Daemon(3pm) β so go build something iconic with it, u got this π
β¨π
π¦ where this page comes from
- fedora 43: perl-HTTP-Daemon 6.17-1.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- fedora 44: perl-HTTP-Daemon 6.17-1.fc44 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms