Diff -- /var/www/vhosts/3dshawn.com/abforge.3dshawn.com/t.cgi
Diff

/var/www/vhosts/3dshawn.com/abforge.3dshawn.com/t.cgi

added on local at 2026-07-01 16:01:40

Added
+125
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 71f4f31554a0
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1#!/usr/bin/perl
2#======================================================================
3# ABForge -- anonymous pageview tracker (1x1 GIF beacon).
4# Included from the marketing wrapper. Skips logged-in users + bots.
5# Captures pre-signup paths only; admin_funnels.cgi reads anon_sessions
6# + anon_pageviews to render the Top Acquisition Paths panel.
7#======================================================================
8use strict;
9use warnings;
10use lib '/var/www/vhosts/3dshawn.com/abforge.3dshawn.com';
11use CGI;
12use MODS::DBConnect;
13use Digest::SHA qw(sha1_hex);
14
15my $q = CGI->new;
16my $db = MODS::DBConnect->new;
17
18# Logged-in user? Skip silently — those pages aren't part of the funnel.
19my $auth_cookie = $q->cookie('abforge_session') || '';
20if (length($auth_cookie) >= 16) { _ok_noop(); }
21
22# Cheap bot guard
23my $ua = $ENV{HTTP_USER_AGENT} || '';
24if ($ua =~ /bot|crawl|spider|slurp|wget|curl|headless|preview|monitor/i) {
25 _ok_noop();
26}
27
28# Read/mint session token (40-hex chars, 365-day cookie)
29my $token = $q->cookie('_anon_tk') || '';
30$token =~ s/[^a-f0-9]//g;
31my $is_new = 0;
32if (length($token) != 40) {
33 my @hex = ('0'..'9','a'..'f');
34 $token = '';
35 $token .= $hex[int(rand(@hex))] for 1..40;
36 $is_new = 1;
37}
38
39# Inputs
40my $path = $q->param('p') || $ENV{HTTP_REFERER} || '/';
41$path =~ s{^https?://[^/]+}{};
42$path = substr($path, 0, 500);
43$path =~ s/[\x00-\x1f]//g;
44
45my $ref_full = $q->param('r') || $ENV{HTTP_REFERER} || '';
46my $ref_host = '';
47if ($ref_full =~ m{^https?://([^/]+)}) { $ref_host = lc($1); }
48$ref_host = substr($ref_host, 0, 191);
49
50my $utm_source = substr(($q->param('us') || ''), 0, 120);
51my $utm_medium = substr(($q->param('um') || ''), 0, 120);
52my $utm_campaign = substr(($q->param('uc') || ''), 0, 120);
53
54my $ua_hash = sha1_hex($ua);
55my $ip = $ENV{HTTP_X_FORWARDED_FOR} || $ENV{REMOTE_ADDR} || '';
56$ip =~ s/,.*$//; $ip =~ s/\s+//g;
57my $ip_hash = sha1_hex($ip);
58
59my $token_q = $token;
60my $path_q = _q($path);
61my $ref_q = _q($ref_host);
62my $us_q = _q($utm_source);
63my $um_q = _q($utm_medium);
64my $uc_q = _q($utm_campaign);
65my $ua_q = _q($ua_hash);
66my $ip_q = _q($ip_hash);
67
68my $dbh = $db->db_connect() or _ok_noop();
69
70my $existing = $db->db_readwrite($dbh, qq~
71 SELECT id, page_count FROM anon_sessions WHERE session_token='$token_q' LIMIT 1
72~, $ENV{SCRIPT_NAME}, __LINE__);
73
74my ($sid, $seq);
75if ($existing && $existing->{id}) {
76 $sid = $existing->{id} + 0;
77 $seq = ($existing->{page_count} || 0) + 0;
78 $db->db_readwrite($dbh, qq~
79 UPDATE anon_sessions
80 SET last_seen_at=NOW(), page_count=page_count+1
81 WHERE id='$sid'
82 ~, $ENV{SCRIPT_NAME}, __LINE__);
83} else {
84 my $r = $db->db_readwrite($dbh, qq~
85 INSERT INTO anon_sessions
86 (session_token, first_seen_at, last_seen_at, end_reason,
87 referer_host, utm_source, utm_medium, utm_campaign,
88 landing_path, user_agent_hash, ip_hash, page_count)
89 VALUES
90 ('$token_q', NOW(), NOW(), 'active',
91 '$ref_q', '$us_q', '$um_q', '$uc_q',
92 '$path_q', '$ua_q', '$ip_q', 1)
93 ~, $ENV{SCRIPT_NAME}, __LINE__);
94 $sid = $r ? ($r->{mysql_insertid} || 0) + 0 : 0;
95 $seq = 0;
96}
97
98if ($sid) {
99 $db->db_readwrite($dbh, qq~
100 INSERT INTO anon_pageviews (session_id, sequence, page_path, occurred_at)
101 VALUES ('$sid', '$seq', '$path_q', NOW())
102 ~, $ENV{SCRIPT_NAME}, __LINE__);
103}
104
105$db->db_disconnect($dbh);
106
107print "Status: 200 OK\nContent-Type: image/gif\n";
108if ($is_new) {
109 print "Set-Cookie: _anon_tk=$token; Path=/; Max-Age=31536000; SameSite=Lax; HttpOnly\n";
110}
111print "Cache-Control: no-store, no-cache, must-revalidate, max-age=0\nPragma: no-cache\n\n";
112print pack('H*', '47494638396101000100800000ffffff00000021f90401000001002c00000000010001000002024401003b');
113exit;
114
115sub _q {
116 my $s = shift // '';
117 $s =~ s/\\/\\\\/g;
118 $s =~ s/'/''/g;
119 return $s;
120}
121sub _ok_noop {
122 print "Status: 200 OK\nContent-Type: image/gif\nCache-Control: no-store\n\n";
123 print pack('H*', '47494638396101000100800000ffffff00000021f90401000001002c00000000010001000002024401003b');
124 exit;
125}
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help