-
-
Notifications
You must be signed in to change notification settings - Fork 7
feat: collect app download statistics #634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,13 @@ RewriteRule "^package/download/(keyboard/)?([^/]+)$" "package/download.php?type= | |
| # keyboard/id/share | ||
| RedirectMatch "/go/keyboard/([^/?]+)/share$" "/keyboards/share/$1" | ||
|
|
||
| # | ||
| # go/app/download | ||
| # | ||
|
|
||
| # download-app?url=... | ||
| RewriteRule "^app/download/([^/?]+)/([^/?]+)/(.*)" "app/download.php?product=$1&version=$2&tier=$3" [END,QSA] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| # | ||
| # Non-app-specific endpoints | ||
| # | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| <?php | ||
| declare(strict_types=1); | ||
|
|
||
| namespace Keyman\Site\com\keyman; | ||
|
|
||
| require __DIR__ . '/../../_includes/autoload.php'; | ||
|
|
||
| const DEBUG=0; | ||
|
|
||
| use Keyman\Site\com\keyman\KeymanComSentry; | ||
| use Keyman\Site\com\keyman\Validation; | ||
| use Keyman\Site\Common\KeymanHosts; | ||
| use Keyman\Site\Common\JsonApiFailure; | ||
|
|
||
| $env = getenv(); | ||
| KeymanComSentry::init(); | ||
|
|
||
| AppDownloadPage::redirect_to_file( | ||
| isset($_REQUEST['url']) ? $_REQUEST['url'] : null, | ||
| isset($_REQUEST['product']) ? $_REQUEST['product'] : null, | ||
| isset($_REQUEST['version']) ? $_REQUEST['version'] : null, | ||
| isset($_REQUEST['tier']) ? $_REQUEST['tier'] : null, | ||
| // TODO: should we? or just leave it encoded in URL for now? | ||
| // isset($_REQUEST['bcp47']) ? $_REQUEST['bcp47'] : null, | ||
| // isset($_REQUEST['update']) ? $_REQUEST['update'] : null | ||
| ); | ||
|
|
||
| class AppDownloadPage { | ||
|
|
||
| public static function redirect_to_file($url, $product, $version, $tier) { | ||
| if(empty($url)) { | ||
| JsonApiFailure::InvalidParameters("url"); | ||
| } | ||
|
|
||
| if(empty($product)) { | ||
| $product = 'unknown'; | ||
| } | ||
|
|
||
| if(empty($version)) { | ||
| $version = '0.0'; | ||
| } | ||
|
|
||
| if(empty($tier)) { | ||
| $tier = 'stable'; | ||
| } | ||
|
|
||
| $tier = Validation::validate_tier($tier, 'stable'); | ||
|
|
||
| $url_e = htmlentities($url); | ||
|
|
||
| if(DEBUG) { | ||
| header('Content-Type: text/plain'); | ||
| } | ||
|
|
||
| if(KeymanHosts::Instance()->Tier() !== KeymanHosts::TIER_TEST) { | ||
| self::report_app_download_event($product, $version, $tier); | ||
|
|
||
| if(DEBUG) { | ||
| echo "\n\nLocation: $url\n"; | ||
| exit; | ||
| } | ||
|
|
||
| // We don't do a redirect for Test tier because a test instance of the | ||
| // downloads server is not available and so it gives us an error | ||
| header("HTTP/1.1 302 Found"); | ||
| header("Cache-Control: no-store"); | ||
| header("Location: $url"); | ||
| } | ||
|
|
||
| echo "<a href='$url_e'>Download Link</a>"; | ||
| } | ||
|
|
||
| private static function report_app_download_event($product, $version, $tier) { | ||
| global $env; | ||
| $url = KeymanHosts::Instance()->SERVER_api_keyman_com . "/app-downloads-increment/".rawurlencode($product). | ||
| "/".rawurlencode($version)."/".rawurlencode($tier); | ||
|
|
||
| if(KeymanHosts::Instance()->Tier() !== KeymanHosts::TIER_TEST) { | ||
| if(KeymanHosts::Instance()->Tier() === KeymanHosts::TIER_DEVELOPMENT) | ||
| $key = 'local'; | ||
| else | ||
| $key = $env['API_KEYMAN_COM_INCREMENT_DOWNLOAD_KEY']; | ||
|
|
||
| $c = curl_init($url); | ||
| curl_setopt($c, CURLOPT_HEADER, 0); | ||
| curl_setopt($c, CURLOPT_POSTFIELDS, 'key='.rawurlencode($key)); | ||
| curl_setopt($c, CURLOPT_RETURNTRANSFER, TRUE); | ||
| curl_setopt($c, CURLOPT_USERAGENT , "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)"); | ||
| $data = curl_exec($c); | ||
| curl_close($c); | ||
|
|
||
| if(DEBUG) { | ||
| var_dump("app-downloads-increment ($url):",$data); | ||
| } | ||
| } else | ||
| $data = TRUE; | ||
| return $data !== FALSE; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -117,48 +117,3 @@ private static function report_download_event($id, $platform, $tier, $bcp47, $up | |
| return $data !== FALSE; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Returns a GUIDv4 string | ||
| * | ||
| * Uses the best cryptographically secure method | ||
| * for all supported pltforms with fallback to an older, | ||
| * less secure version. | ||
| * https://www.php.net/manual/en/function.com-create-guid.php#119168 | ||
| * | ||
| * @param bool $trim | ||
| * @return string | ||
| */ | ||
| function GUIDv4 ($trim = true) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function was unused, just noticed when cloning into go/app/download.php |
||
| { | ||
| // Windows | ||
| if (function_exists('com_create_guid') === true) { | ||
| if ($trim === true) | ||
| return trim(com_create_guid(), '{}'); | ||
| else | ||
| return com_create_guid(); | ||
| } | ||
|
|
||
| // OSX/Linux | ||
| if (function_exists('openssl_random_pseudo_bytes') === true) { | ||
| $data = openssl_random_pseudo_bytes(16); | ||
| $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100 | ||
| $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10 | ||
| return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); | ||
| } | ||
|
|
||
| // Fallback (PHP 4.2+) | ||
| mt_srand((double)microtime() * 10000); | ||
| $charid = strtolower(md5(uniqid(rand(), true))); | ||
| $hyphen = chr(45); // "-" | ||
| $lbrace = $trim ? "" : chr(123); // "{" | ||
| $rbrace = $trim ? "" : chr(125); // "}" | ||
| $guidv4 = $lbrace. | ||
| substr($charid, 0, 8).$hyphen. | ||
| substr($charid, 8, 4).$hyphen. | ||
| substr($charid, 12, 4).$hyphen. | ||
| substr($charid, 16, 4).$hyphen. | ||
| substr($charid, 20, 12). | ||
| $rbrace; | ||
| return $guidv4; | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.