You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axkit-dev@xml.apache.org by ma...@sergeant.org on 2006/08/01 05:12:41 UTC
[SVN] [24] Support connection notes fields
Revision: 24
Author: matt
Date: 2006-08-01 03:12:17 +0000 (Tue, 01 Aug 2006)
Log Message:
-----------
Support connection notes fields
Support POST/PUT data via body_data callbacks
Support potential for persistent (keep-alive) connections
Modified Paths:
--------------
trunk/lib/AxKit2/Client.pm
trunk/lib/AxKit2/Connection.pm
trunk/lib/AxKit2/Plugin.pm
Modified: trunk/lib/AxKit2/Client.pm
===================================================================
--- trunk/lib/AxKit2/Client.pm 2006-07-31 21:24:27 UTC (rev 23)
+++ trunk/lib/AxKit2/Client.pm 2006-08-01 03:12:17 UTC (rev 24)
@@ -143,4 +143,19 @@
}
}
+sub hook_body_data {
+ my $self = shift;
+ my ($ret, $out) = $self->run_hooks('body_data', @_);
+ if ($ret == DECLINED) {
+ $self->process_request();
+ return;
+ }
+ elsif ($ret == OK) {
+ return 1;
+ }
+ else {
+ # TODO: output error stuff?
+ }
+}
+
1;
\ No newline at end of file
Modified: trunk/lib/AxKit2/Connection.pm
===================================================================
--- trunk/lib/AxKit2/Connection.pm 2006-07-31 21:24:27 UTC (rev 23)
+++ trunk/lib/AxKit2/Connection.pm 2006-08-01 03:12:17 UTC (rev 24)
@@ -18,6 +18,7 @@
ditch_leading_rn
server_config
http_headers_sent
+ notes
);
use constant CLEANUP_TIME => 5; # every N seconds
@@ -41,6 +42,7 @@
$self->{headers_string} = '';
$self->{ditch_leading_rn} = 0; # TODO - work out how to set that...
$self->{server_config} = $servconf;
+ $self->{notes} = {};
$self->log(LOGINFO, "Connection from " . $self->peer_addr_string);
# allow connect hook to disconnect us
@@ -57,6 +59,13 @@
return $self->{server_config};
}
+sub notes {
+ my AxKit2::Connection $self = shift;
+ my $key = shift;
+ @_ and $self->{notes}->{$key} = shift;
+ $self->{notes}->{$key};
+}
+
sub max_idle_time { 30 }
sub max_connect_time { 180 }
sub event_err { my AxKit2::Connection $self = shift; $self->close("Error") }
@@ -64,6 +73,14 @@
sub event_read {
my AxKit2::Connection $self = shift;
+ $self->{alive_time} = time;
+
+ if ($self->{headers_in}) {
+ # already got the headers... do we get a body too?
+ my $bref = $self->read(8192);
+ return $self->close($!) unless defined $bref;
+ return $self->hook_body_data($bref);
+ }
my $to_read = MAX_HTTP_HEADER_LENGTH - length($self->{headers_string});
my $bref = $self->read($to_read);
return $self->close($!) unless defined $bref;
@@ -108,7 +125,7 @@
$self->{ditch_leading_rn} = 0;
- $self->process_request();
+ $self->process_request() if $self->{headers_in}->request_method =~ /GET|HEAD/;
}
sub headers_out {
@@ -151,9 +168,58 @@
$self->hook_xmlresponse(AxKit2::Processor->new($hd->filename))
|| $self->hook_response($hd);
- $self->close();
+ $self->http_response_sent();
}
+# called when we've finished writing everything to a client and we need
+# to reset our state for another request. returns 1 to mean that we should
+# support persistence, 0 means we're discarding this connection.
+sub http_response_sent {
+ my AxKit2::Connection $self = $_[0];
+
+ # close if we're supposed to
+ if (
+ ! defined $self->{headers_out} ||
+ ! $self->{headers_out}->res_keep_alive($self->{headers_in})
+ )
+ {
+ # do a final read so we don't have unread_data_waiting and RST
+ # the connection. IE and others send an extra \r\n after POSTs
+ my $dummy = $self->read(5);
+
+ # close if we have no response headers or they say to close
+ $self->close("no_keep_alive");
+ return 0;
+ }
+
+ # if they just did a POST, set the flag that says we might expect
+ # an unadvertised \r\n coming from some browsers. Old Netscape
+ # 4.x did this on all POSTs, and Firefox/Safari do it on
+ # XmlHttpRequest POSTs.
+ if ($self->{headers_in}->request_method eq "POST") {
+ $self->{ditch_leading_rn} = 1;
+ }
+
+ # now since we're doing persistence, uncork so the last packet goes.
+ # we will recork when we're processing a new request.
+ # TODO: Disabled because this seemed mostly relevant to Perlbal...
+ #$self->tcp_cork(0);
+
+ # reset state
+ $self->{alive_time} = $self->{create_time} = time;
+ $self->{headers_string} = '';
+ $self->{headers_in} = undef;
+ $self->{headers_out} = undef;
+ $self->{http_headers_sent} = 0;
+
+ # NOTE: because we only speak 1.0 to clients they can't have
+ # pipeline in a read that we haven't read yet.
+ $self->watch_read(1);
+ $self->watch_write(0);
+ return 1;
+}
+
+
# Cleanup routine to get rid of timed out sockets
sub _do_cleanup {
my $now = time;
Modified: trunk/lib/AxKit2/Plugin.pm
===================================================================
--- trunk/lib/AxKit2/Plugin.pm 2006-07-31 21:24:27 UTC (rev 23)
+++ trunk/lib/AxKit2/Plugin.pm 2006-08-01 03:12:17 UTC (rev 24)
@@ -9,7 +9,7 @@
# more or less in the order they will fire
our @hooks = qw(
logging config pre-connection connect post_read_request
- uri_translation access_control authentication authorization
+ body_data uri_translation access_control authentication authorization
fixup xmlresponse response disconnect error
);
our %hooks = map { $_ => 1 } @hooks;