[tbb-commits] [tor-browser-bundle/master] Add the update responses script

gk at torproject.org gk at torproject.org
Fri Sep 26 14:15:31 UTC 2014


commit c2b76dcc4a854d7cecb44acac2bea1cf23cf51e6
Author: Nicolas Vigier <boklm at mars-attacks.org>
Date:   Thu Sep 25 19:39:19 2014 +0200

    Add the update responses script
    
    Add the update responses script in directory tools/update-responses.
    
    This adds the content of commit 2c3625507a5c12b4c15b6681a8b694114a0cfb7b
    from https://github.com/boklm/tb-update-response.
---
 tools/update-responses/.gitignore           |    1 +
 tools/update-responses/README.md            |   45 +++++++
 tools/update-responses/config.yml           |   16 +++
 tools/update-responses/htdocs/no-update.xml |    2 +
 tools/update-responses/update_responses     |  169 +++++++++++++++++++++++++++
 5 files changed, 233 insertions(+)

diff --git a/tools/update-responses/.gitignore b/tools/update-responses/.gitignore
new file mode 100644
index 0000000..c077014
--- /dev/null
+++ b/tools/update-responses/.gitignore
@@ -0,0 +1 @@
+htdocs
diff --git a/tools/update-responses/README.md b/tools/update-responses/README.md
new file mode 100644
index 0000000..ee21bac
--- /dev/null
+++ b/tools/update-responses/README.md
@@ -0,0 +1,45 @@
+Tor Browser Update Responses script
+===================================
+
+This repository contains a script to generate responses for Tor Browser
+updater.
+
+See ticket [#12622](https://trac.torproject.org/projects/tor/ticket/12622)
+for details.
+
+
+Dependencies
+------------
+
+The following perl modules need to be installed to run the script:
+  FindBin YAML File::Slurp Digest::SHA XML::Writer
+
+On Debian / Ubuntu you can install them with:
+
+```
+  # apt-get install libfindbin-libs-perl libyaml-perl libfile-slurp-perl \
+                    libdigest-sha-perl libxml-writer-perl
+```
+
+On Red Hat / Fedora you can install them with:
+
+```
+  # for module in FindBin YAML File::Slurp Digest::SHA XML::Writer
+    do yum install "perl($module)"; done
+```
+
+
+URL Format
+----------
+
+The URL format is:
+  https://something/$channel/$build_target/$tb_version/$lang?force=1
+
+'build_target' is the OS for which the browser was built. The correspo
+ndance between the build target and the OS name that we use in archive
+files is defined in the config.yml file.
+
+'tb_version' is the Tor Browser version.
+
+'lang' is the locale.
+
diff --git a/tools/update-responses/config.yml b/tools/update-responses/config.yml
new file mode 100644
index 0000000..8b5475a
--- /dev/null
+++ b/tools/update-responses/config.yml
@@ -0,0 +1,16 @@
+---
+build_targets:
+    linux32: Linux_x86-gcc3
+    linux64: Linux_x86_64-gcc3
+    win32: WINNT_x86-gcc3
+    osx32: Darwin_x86-gcc3
+channels:
+    alpha: 4.0-alpha-3
+versions:
+    4.0-alpha-3:
+        platformVersion: 24.8.1
+        detailsURL: https://www.torproject.org/projects/torbrowser.html.en
+        download_url: https://www.torproject.org/dist/torbrowser/4.0-alpha-3
+#       osx32:
+#          minSupportedOSVersion: 10.7
+#          unsupported: 1
diff --git a/tools/update-responses/htdocs/no-update.xml b/tools/update-responses/htdocs/no-update.xml
new file mode 100644
index 0000000..910e99d
--- /dev/null
+++ b/tools/update-responses/htdocs/no-update.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<updates></updates>
diff --git a/tools/update-responses/releases/.directory b/tools/update-responses/releases/.directory
new file mode 100644
index 0000000..e69de29
diff --git a/tools/update-responses/update_responses b/tools/update-responses/update_responses
new file mode 100755
index 0000000..e082592
--- /dev/null
+++ b/tools/update-responses/update_responses
@@ -0,0 +1,169 @@
+#!/usr/bin/perl -w
+
+use strict;
+use FindBin;
+use YAML qw(LoadFile);
+use File::Slurp;
+use Digest::SHA;
+use XML::Writer;
+
+my $htdocsdir = "$FindBin::Bin/htdocs";
+my $config = LoadFile("$FindBin::Bin/config.yml");
+my %htdocsfiles = ( '.' => 1, '..' => 1, 'no-update.xml' => 1 );
+
+sub exit_error {
+    print STDERR "Error: ", $_[0], "\n";
+    exit (exists $_[1] ? $_[1] : 1);
+}
+
+sub build_target_by_os {
+    $config->{build_targets}{$_[0]} ? $config->{build_targets}{$_[0]} : $_[0];
+}
+
+sub write_htdocs {
+    my ($file, $content) = @_;
+    mkdir $htdocsdir unless -d $htdocsdir;
+    write_file("$htdocsdir/$file", $content);
+    $htdocsfiles{$file} = 1;
+}
+
+sub clean_htdocs {
+    opendir(my $d, $htdocsdir);
+    my @files = grep { ! $htdocsfiles{$_} } readdir $d;
+    closedir $d;
+    unlink map { "$htdocsdir/$_" } @files;
+}
+
+sub get_sha512_hex_of_file {
+    my ($file) = @_;
+    my $sha = Digest::SHA->new("512");
+    $sha->addfile($file);
+    return $sha->hexdigest;
+}
+
+sub get_version_files {
+    my ($config, $version) = @_;
+    return if $config->{versions}{$version}{files};
+    my $files = {};
+    my $vdir = "$FindBin::Bin/releases/$version";
+    opendir(my $d, $vdir) or exit_error "Error opening directory $vdir";
+    foreach my $file (readdir $d) {
+        next unless -f "$vdir/$file";
+        if ($file =~ m/^tor-browser-([^-]+)-${version}_(.+)\.mar$/) {
+            my ($os, $lang) = ($1, $2);
+            $files->{$os}{$lang}{complete} = {
+                type => 'complete',
+                URL => "$config->{versions}{$version}{download_url}/$file",
+                size => -s "$vdir/$file",
+                hashFunction => 'SHA512',
+                hashValue => get_sha512_hex_of_file("$vdir/$file"),
+            };
+            next;
+        }
+        if ($file =~ m/^tor-browser-([^-]+)-([^-]+)-${version}_(.+)\.mar$/) {
+            my ($os, $from_version, $lang) = ($1, $2, $3);
+            $files->{$os}{$lang}{partial}{$from_version} = {
+                type => 'partial',
+                URL => "$config->{versions}{$version}{download_url}/$file",
+                size => -s "$vdir/$file",
+                hashFunction => 'SHA512',
+                hashValue => get_sha512_hex_of_file("$vdir/$file"),
+            }
+        }
+    }
+    closedir $d;
+    $config->{versions}{$version}{files} = $files;
+}
+
+sub get_config {
+    my ($config, $version, $os, $name) = @_;
+    return $config->{versions}{$version}{$os}{$name}
+        // $config->{versions}{$version}{$name}
+        // $config->{$name};
+}
+
+sub get_response {
+    my ($config, $version, $os, @patches) = @_;
+    my $res;
+    my $writer = XML::Writer->new(OUTPUT => \$res, ENCODING => 'UTF-8');
+    $writer->xmlDecl;
+    $writer->startTag('updates');
+    if (get_config($config, $version, $os, 'unsupported')) {
+        $writer->startTag('update',
+            unsupported => 'true',
+            detailsURL => get_config($config, $version, $os, 'detailsURL'),
+        );
+        goto CLOSETAGS;
+    }
+    my $minversion = get_config($config, $version, $os, 'minSupportedOSVersion');
+    $writer->startTag('update',
+        type => 'minor',
+        displayVersion => $version,
+        appVersion => $version,
+        platformVersion => get_config($config, $version, $os, 'platformVersion'),
+        buildID => '20000101000000',
+        detailsURL => get_config($config, $version, $os, 'detailsURL'),
+        defined $minversion ? ( minSupportedOSVersion => $minversion ) : (),
+    );
+    foreach my $patch (@patches) {
+        $writer->startTag('patch', %$patch);
+        $writer->endTag('patch');
+    }
+    CLOSETAGS:
+    $writer->endTag('update');
+    $writer->endTag('updates');
+    $writer->end;
+    return $res;
+}
+
+sub write_responses {
+    my ($config) = @_;
+    foreach my $version (values %{$config->{channels}}) {
+        get_version_files($config, $version);
+        my $files = $config->{versions}{$version}{files};
+        foreach my $os (keys %$files) {
+            foreach my $lang (keys %{$files->{$os}}) {
+                my $resp = get_response($config, $version, $os,
+                                $files->{$os}{$lang}{complete});
+                write_htdocs("$version-$os-$lang.xml", $resp);
+                foreach my $from_version (keys %{$files->{$os}{$lang}{partial}}) {
+                    $resp = get_response($config, $version, $os,
+                                $files->{$os}{$lang}{complete},
+                                $files->{$os}{$lang}{partial}{$from_version});
+                    write_htdocs("$from_version-$version-$os-$lang.xml", $resp);
+                }
+            }
+        }
+    }
+}
+
+sub write_htaccess {
+    my ($config) = @_;
+    my $htaccess = "RewriteEngine On\n";
+    my $flags = "[last]";
+    foreach my $channel (keys %{$config->{channels}}) {
+        my $version = $config->{channels}{$channel};
+        my $files = $config->{versions}{$version}{files};
+        $htaccess .= "RewriteRule "
+                  .  "^$channel/[^\/]+/$version/ "
+                  .  "no-update.xml $flags\n";
+        foreach my $os (keys %$files) {
+            my $bt = build_target_by_os($os);
+            foreach my $lang (keys %{$files->{$os}}) {
+                foreach my $from_version (keys %{$files->{$os}{$lang}{partial}}) {
+                    $htaccess .= "RewriteRule ^$channel/$bt/$from_version/$lang "
+                              .  "$from_version-$version-$os-$lang.xml $flags\n";
+                }
+                $htaccess .= "RewriteRule ^$channel/$bt/[^\/]+/$lang "
+                          .  "$version-$os-$lang.xml $flags\n";
+            }
+            $htaccess .= "RewriteRule ^$channel/$bt "
+                      .  "$version-$os-en-US.xml $flags\n";
+        }
+    }
+    write_htdocs('.htaccess', $htaccess);
+}
+
+write_responses($config);
+write_htaccess($config);
+clean_htdocs;



More information about the tbb-commits mailing list