Forráskód Böngészése

Fix the api, do see-alsos

George S. Baugh 3 éve
szülő
commit
6a160ffb64
3 módosított fájl, 49 hozzáadás és 36 törlés
  1. 4 1
      lib/TCMS.pm
  2. 16 13
      lib/Trog/Routes/HTML.pm
  3. 29 22
      lib/Trog/Routes/JSON.pm

+ 4 - 1
lib/TCMS.pm

@@ -43,6 +43,9 @@ my %routes = %Trog::Routes::HTML::routes;
 @routes{keys(%roots)} = values(%roots);
 
 my %aliases = $data->aliases();
+
+# XXX this is built progressively across the forks, leading to inconsistent behavior.
+# This should eventually be pre-filled from DB.
 my %etags;
 
 #1MB chunks
@@ -72,8 +75,8 @@ sub app {
     # Check eTags.  If we don't know about it, just assume it's good and lazily fill the cache
     # XXX yes, this allows cache poisoning
     if ($env->{HTTP_IF_NONE_MATCH}) {
+        return [304, [], ['']] if $env->{HTTP_IF_NONE_MATCH} eq ($etags{$env->{REQUEST_URI}} || '');
         $etags{$env->{REQUEST_URI}} = $env->{HTTP_IF_NONE_MATCH} unless exists $etags{$env->{REQUEST_URI}};
-        return [304, [], ['']] if $env->{HTTP_IF_NONE_MATCH} eq $etags{$env->{REQUEST_URI}};
     }
 
     my $last_fetch = 0;

+ 16 - 13
lib/Trog/Routes/HTML.pm

@@ -325,6 +325,12 @@ sub badrequest (@args) {
     return _generic_route('badrequest', 400, "Bad Request", @args);
 }
 
+=head2 redirect, redirect_permanent, see_also
+
+Redirects to the provided page.
+
+=cut
+
 sub redirect ($to) {
     return [302, ["Location" => $to],['']]
 }
@@ -333,6 +339,10 @@ sub redirect_permanent ($to) {
     return [301, ["Location" => $to], ['']];
 }
 
+sub see_also ($to) {
+    return [303, ["Location" => $to], ['']];
+}
+
 =head1 NORMAL ROUTES
 
 These are expected to either return a 200, or redirect to something which does.
@@ -376,7 +386,7 @@ sub login ($query) {
     $query->{to} //= $query->{route};
     $query->{to} = '/config' if $query->{to} eq '/login';
     if ($query->{user}) {
-        return $routes{$query->{to}}{callback}->($query);
+        return see_also($query->{to});
     }
 
     #Check and see if we have no users.  If so we will just accept whatever creds are passed.
@@ -608,7 +618,7 @@ sub themeclone ($query) {
         $query->{failure} = 0;
         $query->{message} = "Successfully cloned theme '$theme' as '$newtheme'.";
     }
-    return config($query);
+    return see_also('/config');
 }
 
 =head2 post_save
@@ -636,12 +646,8 @@ sub post_save ($query) {
     # Ensure there are no null tags
     @{$query->{tags}} = grep { defined $_ } @{$query->{tags}};
 
-    $query->{failure} = $data->add($query);
-    $query->{to} = $to;
-    $query->{acls} = $acls;
-    $query->{message} = $query->{failure} ? "Failed to add post!" : "Successfully added Post";
-    delete $query->{id};
-    return posts($query);
+    $data->add($query) and die "Could not add post";
+    return see_also($to);
 }
 
 =head2 profile
@@ -674,11 +680,8 @@ deletes posts.
 sub post_delete ($query) {
     return forbidden($query) unless grep { $_ eq 'admin' } @{$query->{acls}};
 
-    $query->{failure} = $data->delete($query);
-    $query->{to} = $query->{to};
-    $query->{message} = $query->{failure} ? "Failed to delete post $query->{id}!" : "Successfully deleted Post $query->{id}";
-    delete $query->{id};
-    return posts($query);
+    $data->delete($query) and die "Could not delete post";
+    return see_also($query->{to});
 }
 
 =head2 series

+ 29 - 22
lib/Trog/Routes/JSON.pm

@@ -4,9 +4,9 @@ use strict;
 use warnings;
 
 no warnings 'experimental';
-use feature qw{signatures};
+use feature qw{signatures state};
 
-use Digest::SHA();
+use Clone qw{clone};
 use JSON::MaybeXS();
 use Trog::Config();
 
@@ -27,39 +27,46 @@ our %routes = (
         callback       => \&webmanifest,
         parameters     => [],
     },
+    '/api/version' => {
+        method     => 'GET',
+        callback   => \&version,
+        parameters => [],
+    },
 );
 
-my $headers = ['Content-type' => "application/json"];
+# Clone / redact for catalog
+my $cloned = clone(\%routes);
+foreach my $r (keys(%$cloned)) {
+    delete $cloned->{$r}{callback}
+}
 
-sub catalog ($query) {
-    my $enc = JSON::MaybeXS->new( utf8 => 1 );
-    my %rcopy = %{\%routes};
-    foreach my $r (keys(%rcopy)) {
-        delete $rcopy{$r}{callback}
-    }
-    # Make the ETag the sha256 of the routes
-    my $content = $enc->encode(\%rcopy);
-    my $state = Digest::SHA->new(256);
-    my $hash = $state->add($content);
+my $enc = JSON::MaybeXS->new( utf8 => 1 );
 
-    push(@$headers, ETag => $state->hexdigest);
-    return [200,$headers,[$content]];
+# Note to authors, don't forget to update this
+sub _version () {
+    return '1.0';
+}
+
+sub version ($query) {
+    state $ret = [200, ['Content-type' => "application/json", ETag => 'version-'._version()],[_version()]];
+    return $ret;
+}
+
+sub catalog ($query) {
+    state $ret = [200, ['Content-type' => "application/json", ETag => 'catalog-'._version()], [$enc->encode($cloned)]];
+    return $ret;
 }
 
 sub webmanifest ($query) {
-    my $enc = JSON::MaybeXS->new( utf8 => 1 );
-    my %manifest = (
+    state $headers = ['Content-type' => "application/json", ETag => 'manifest-'._version()];
+    state %manifest = (
         "icons" => [
             { "src" => "$theme_dir/img/icon/favicon-192.png", "type" => "image/png", "sizes" => "192x192" },
             { "src" => "$theme_dir/img/icon/favicon-512.png", "type" => "image/png", "sizes" => "512x512" },
         ],
     );
-    # Make the ETag the sha256 of the routes
-    my $content = $enc->encode(\%manifest);
-    my $state = Digest::SHA->new(256);
-    my $hash = $state->add($content);
+    state $content = $enc->encode(\%manifest);
 
-    push(@$headers, ETag => $state->hexdigest);
     return [ 200, $headers, [$content] ];
 }