Skip to content

Instantly share code, notes, and snippets.

/state.diff Secret

Created January 10, 2016 04:15
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 anonymous/59caa04092e502378b65 to your computer and use it in GitHub Desktop.
Save anonymous/59caa04092e502378b65 to your computer and use it in GitHub Desktop.
diff --git a/lib/Mojo/Channel/HTTP.pm b/lib/Mojo/Channel/HTTP.pm
index 1f2cded..a580555 100644
--- a/lib/Mojo/Channel/HTTP.pm
+++ b/lib/Mojo/Channel/HTTP.pm
@@ -8,13 +8,10 @@ sub is_server {undef}
sub write {
my $self = shift;
- # Client starts writing right away
- my $tx = $self->{tx};
- $tx->{state} ||= 'write' unless my $server = $self->is_server;
-
# Nothing written yet
+ my $tx = $self->{tx};
$tx->{$_} ||= 0 for qw(offset write);
- my $msg = $server ? $tx->res : $tx->req;
+ my $msg = (my $server = $self->is_server) ? $tx->res : $tx->req;
@$tx{qw(http_state write)} = ('start_line', $msg->start_line_size)
unless $tx->{http_state};
@@ -43,11 +40,11 @@ sub _body {
if (defined $buffer) { delete $self->{delay} }
# Delayed
- elsif (delete $tx->{delay}) { $tx->{state} = 'read' }
+ elsif (delete $tx->{delay}) { $tx->reading }
else { $tx->{delay} = 1 }
# Finished
- $tx->{state} = $finish ? 'finished' : 'read'
+ $finish ? $tx->closing : $tx->reading
if $tx->{write} <= 0 || defined $buffer && $buffer eq '';
return defined $buffer ? $buffer : '';
@@ -68,7 +65,7 @@ sub _headers {
$tx->{offset} = 0;
# Response without body
- if ($head && $tx->is_empty) { $tx->{state} = 'finished' }
+ if ($head && $tx->is_empty) { $tx->closing }
# Body
else {
diff --git a/lib/Mojo/Channel/HTTP/Client.pm b/lib/Mojo/Channel/HTTP/Client.pm
index 6c5e724..8b808df 100644
--- a/lib/Mojo/Channel/HTTP/Client.pm
+++ b/lib/Mojo/Channel/HTTP/Client.pm
@@ -29,8 +29,7 @@ sub read {
return unless $res->parse($chunk)->is_finished;
# Unexpected 1xx response
- return $tx->{state} = 'finished'
- if !$res->is_status_class(100) || $res->headers->upgrade;
+ return $tx->closing if !$res->is_status_class(100) || $res->headers->upgrade;
$tx->res($res->new)->emit(unexpected => $res);
return if (my $leftovers = $res->content->leftovers) eq '';
$self->read($leftovers);
diff --git a/lib/Mojo/Channel/HTTP/Server.pm b/lib/Mojo/Channel/HTTP/Server.pm
index f47bcf8..3ea77c4 100644
--- a/lib/Mojo/Channel/HTTP/Server.pm
+++ b/lib/Mojo/Channel/HTTP/Server.pm
@@ -7,10 +7,9 @@ sub read {
my ($self, $chunk) = @_;
# Parse request
- my $tx = $self->{tx};
+ my $tx = $self->{tx}->read_first(1);
my $req = $tx->req;
$req->parse($chunk) unless $req->error;
- $tx->{state} ||= 'read';
# Generate response
$tx->emit('request') if $req->is_finished && !$tx->{handled}++;
diff --git a/lib/Mojo/Channel/WebSocket.pm b/lib/Mojo/Channel/WebSocket.pm
index 87e795c..5892716 100644
--- a/lib/Mojo/Channel/WebSocket.pm
+++ b/lib/Mojo/Channel/WebSocket.pm
@@ -24,7 +24,7 @@ sub write {
my $tx = $self->{tx};
unless (length($tx->{write} // '')) {
- $tx->{state} = $tx->is_closing ? 'finished' : 'read';
+ $tx->is_closing ? $tx->closing : $tx->reading;
$tx->emit('drain');
}
diff --git a/lib/Mojo/Server/Daemon.pm b/lib/Mojo/Server/Daemon.pm
index dfdee7e..125c5e6 100644
--- a/lib/Mojo/Server/Daemon.pm
+++ b/lib/Mojo/Server/Daemon.pm
@@ -132,7 +132,7 @@ sub _finish {
= Mojo::Channel::WebSocket->new(tls => $c->{tls}, tx => $ws);
weaken $self;
$ws->on(resume => sub { $self->_write($id) });
- $ws->opened;
+ $ws->established;
}
# Failed upgrade
diff --git a/lib/Mojo/Transaction.pm b/lib/Mojo/Transaction.pm
index c2824dc..1d76014 100644
--- a/lib/Mojo/Transaction.pm
+++ b/lib/Mojo/Transaction.pm
@@ -5,12 +5,14 @@ use Carp 'croak';
use Mojo::Message::Request;
use Mojo::Message::Response;
-has [
- qw(kept_alive local_address local_port original_remote_address remote_port)];
+has [qw(kept_alive local_address local_port original_remote_address)];
+has [qw(read_first remote_port)];
has req => sub { Mojo::Message::Request->new };
has res => sub { Mojo::Message::Response->new };
-sub closed { shift->_state(qw(finished finish)) }
+sub closed { shift->closing->emit('finish') }
+
+sub closing { shift->_state('finished') }
sub connection {
my $self = shift;
@@ -24,7 +26,11 @@ sub is_finished { (shift->{state} // '') eq 'finished' }
sub is_websocket {undef}
-sub is_writing { (shift->{state} // 'write') eq 'write' }
+sub is_writing {
+ ($_[0]->{state} // ($_[0]->read_first ? 'read' : 'write')) eq 'write';
+}
+
+sub reading { shift->_state('read') }
sub remote_address {
my $self = shift;
@@ -38,15 +44,13 @@ sub remote_address {
: $self->original_remote_address;
}
-sub resume { shift->_state(qw(write resume)) }
+sub resume { shift->_state('write')->emit('resume') }
sub success { $_[0]->error ? undef : $_[0]->res }
-sub _state {
- my ($self, $state, $event) = @_;
- $self->{state} = $state;
- return $self->emit($event);
-}
+sub writing { shift->_state('write') }
+
+sub _state { $_[0]{state} = $_[1] and return $_[0] }
1;
diff --git a/lib/Mojo/Transaction/WebSocket.pm b/lib/Mojo/Transaction/WebSocket.pm
index 7c31eea..781721b 100644
--- a/lib/Mojo/Transaction/WebSocket.pm
+++ b/lib/Mojo/Transaction/WebSocket.pm
@@ -49,13 +49,14 @@ sub build_message {
}
sub closed {
- my $self = shift;
- $self->{state} = 'finished';
+ my $self = shift->closing;
return $self->emit(finish => $self->{close} ? (@{$self->{close}}) : 1006);
}
sub connection { shift->handshake->connection }
+sub established { shift->{open}++ }
+
sub finish {
my $self = shift;
@@ -86,8 +87,6 @@ sub new {
return $self;
}
-sub opened { shift->{open}++ }
-
sub protocol { shift->res->headers->sec_websocket_protocol }
sub remote_address { shift->handshake->remote_address }
@@ -376,6 +375,12 @@ transaction.
Connection identifier.
+=head2 established
+
+ $ws->established;
+
+Low-level signal that the underlying connection has been established.
+
=head2 finish
$ws = $ws->finish;
@@ -436,12 +441,6 @@ Construct a new L<Mojo::Transaction::WebSocket> object and subscribe to
L</"frame"> event with default message parser, which also handles C<PING> and
C<CLOSE> frames automatically.
-=head2 opened
-
- $ws->opened;
-
-Low-level signal that the underlying connection has been established.
-
=head2 protocol
my $proto = $ws->protocol;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment