[livejournal] r19521: LJSUP-9334: New auth system for external...
Committer: amyshkin
LJSUP-9334: New auth system for external domains (livejournal.sg)U trunk/cgi-bin/Apache/LiveJournal.pm U trunk/cgi-bin/LJ/Request.pm U trunk/cgi-bin/LJ/S2/HeadContent.pm U trunk/cgi-bin/LJ/Session.pm U trunk/cgi-bin/weblib.pl
Modified: trunk/cgi-bin/Apache/LiveJournal.pm
===================================================================
--- trunk/cgi-bin/Apache/LiveJournal.pm 2011-07-25 08:18:56 UTC (rev 19520)
+++ trunk/cgi-bin/Apache/LiveJournal.pm 2011-07-25 09:50:49 UTC (rev 19521)
@@ -93,7 +93,7 @@
{
my $class = ();
my $r = shift; #
-
+
LJ::Request->free();
LJ::Request->init($r);
@@ -145,7 +145,7 @@
}
LJ::Request->header_in('X-Forwarded-For', join(", ", @hosts));
}
-
+
# and now, deal with getting the right Host header
if ($_ = LJ::Request->header_in('X-Host')) {
LJ::Request->header_in('Host', $_);
@@ -206,11 +206,11 @@
ignore_ip => 1
);
- if( !$session && $LJ::CACHE_REMOTE_BOUNCE_URL ) {
+ if( !$session && $LJ::CACHE_REMOTE_BOUNCE_URL ) {
return redir($LJ::CACHE_REMOTE_BOUNCE_URL);
}
}
- }
+ }
LJ::Request->set_handlers(PerlTransHandler => [ \&trans ]);
@@ -295,21 +295,21 @@
return LJ::Request::HTTP_PRECONDITION_FAILED;
}
-sub trans
-{
+sub trans {
{
my $r = shift;
LJ::Request->init($r);
}
+ # don't deal with subrequests or OPTIONS
return LJ::Request::DECLINED
- if ! LJ::Request->is_main || LJ::Request->method_number == LJ::Request->M_OPTIONS; # don't deal with subrequests or OPTIONS
+ if ! LJ::Request->is_main || LJ::Request->method_number == LJ::Request->M_OPTIONS;
my $uri = LJ::Request->uri;
my $args = LJ::Request->args;
- my $args_wq = $args ? "?$args" : "";
- my $host = LJ::Request->header_in("Host");
+ my $args_wq = $args ? "?$args" : '';
+ my $host = LJ::Request->header_in('Host');
$host =~ s/(:\d+)$//;
my ($hostport) = $1 || "";
$host =~ s/\.$//; ## 'www.livejournal.com.' is a valid DNS hostname
@@ -337,29 +337,30 @@
# add server mark
my ($aws_id) = $LJ::HARDWARE_SERVER_NAME =~ /\-(.+)$/;
- LJ::Request->header_out("X-AWS-Id" => $aws_id || 'unknown');
+ LJ::Request->header_out('X-AWS-Id' => $aws_id || 'unknown');
my $lang = $LJ::DEFAULT_LANG || $LJ::LANGS[0];
BML::set_language($lang, \&LJ::Lang::get_text);
- my $is_ssl = $LJ::IS_SSL = LJ::run_hook("ssl_check");
+ my $is_ssl = $LJ::IS_SSL = LJ::run_hook('ssl_check');
$LJ::IS_BOT_USERAGENT = BotCheck->is_bot( LJ::Request->header_in('User-Agent') );
# process controller
# if defined
if( LJ::Request->notes('controller') ) {
+ my $cookie_str = LJ::Request->header_in('Cookie');
- my $cookie_str = LJ::Request->header_in("Cookie");
if ($cookie_str =~ /\blangpref=(\w{2,10})\/\d+\b/) { # simplified code from BML::decide_language
my $lang = $1;
+
# Attention! LJ::Lang::ml uses BML::ml in web context, so we must do full BML language initialization
BML::set_language($lang, \&LJ::Lang::get_text);
}
my @args = split (/\//, LJ::Request->uri);
-
+
my $response = LJ::Request->notes('controller')->process([@args[1 .. @args-1]]);
- LJ::Request->handler("perl-script");
+ LJ::Request->handler('perl-script');
LJ::Request->set_handlers(PerlHandler => sub {
# show error page if controller didn't return response object
unless($response) {
@@ -387,16 +388,21 @@
my $bml_handler = sub {
my $filename = shift;
- LJ::Request->handler("perl-script");
- LJ::Request->notes("bml_filename" => $filename);
+ LJ::Request->handler('perl-script');
+ LJ::Request->notes('bml_filename' => $filename);
LJ::Request->set_handlers(PerlHandler => \&Apache::BML::handler);
return LJ::Request::OK;
};
if (LJ::Request->is_initial_req) {
# delete cookies if there are any we want gone
- if (my $cookie = $LJ::DEBUG{"delete_cookie"}) {
- LJ::Session::set_cookie($cookie => 0, delete => 1, domain => $LJ::DOMAIN, path => "/");
+ if (my $cookie = $LJ::DEBUG{'delete_cookie'}) {
+ LJ::Session::set_cookie(
+ $cookie => 0,
+ delete => 1,
+ domain => $LJ::DOMAIN,
+ path => '/',
+ );
}
# handle uniq cookies
@@ -408,17 +414,19 @@
# apply sysban block if applicable
if (LJ::UniqCookie->sysban_should_block) {
- LJ::Request->handler("perl-script");
+ LJ::Request->handler('perl-script');
LJ::Request->set_handlers(PerlHandler => sub { blocked_bot('sysban_should_block', @_) } );
return LJ::Request::OK;
}
}
- } else {
+ }
+ else {
# on error we do internal redirect to error page
LJ::Request->pnotes ('error' => 'e404');
LJ::Request->pnotes ('remote' => LJ::get_remote());
+
if (LJ::Request->status == 404) {
- my $fn = $LJ::PAGE_404 || "404-error.html";
+ my $fn = $LJ::PAGE_404 || '404-error.html';
return $bml_handler->("$LJ::HOME/htdocs/" . $fn);
}
}
@@ -428,54 +436,61 @@
unless ( $LJ::BLOCKED_BOT_URI && index( $uri, $LJ::BLOCKED_BOT_URI ) == 0 ) {
foreach my $ip (@req_hosts) {
if (LJ::sysban_check('ip', $ip)) {
- LJ::Request->handler("perl-script");
+ LJ::Request->handler('perl-script');
LJ::Request->set_handlers(PerlHandler => sub { blocked_bot('sysban-ip: ' . $ip, @_) } );
return LJ::Request::OK;
}
}
- if (LJ::run_hook("forbid_request")) {
- LJ::Request->handler("perl-script");
+
+ if (LJ::run_hook('forbid_request')) {
+ LJ::Request->handler('perl-script');
LJ::Request->set_handlers(PerlHandler => sub { blocked_bot('forbid_request', @_) } );
return LJ::Request::OK
}
}
-
+
if(LJ::Request->headers_in->{Accept} eq 'application/xrds+xml'){
LJ::Request->header_out('X-XRDS-Location' => 'http://api.' . $LJ::DOMAIN .'/xrds');
}
-
+
# only allow certain pages over SSL
if ($is_ssl) {
if ($uri =~ m!^/interface/! || $uri =~ m!^/__rpc_!) {
# handled later
- } elsif ($LJ::SSLDOCS && $uri !~ m!(\.\.|\%|\.\/)!) {
- if ($uri =~ m#^/img/userinfo.gif#) {
+ }
+ elsif ($LJ::SSLDOCS && $uri !~ m!(\.\.|\%|\.\/)!) {
+ if ($uri =~ m|^/img/userinfo.gif|) {
my $remote = LJ::get_remote();
+
if ($remote) {
my $custom_userhead = $remote->custom_usericon;
require URI;
my $uri = URI->new ($custom_userhead);
my $res = send_files ($uri->path);
- LJ::Request->content_type ("image/gif");
+ LJ::Request->content_type ('image/gif');
return ($res == LJ::Request::OK) ? LJ::Request::DONE : $res;
}
}
my $file = "$LJ::SSLDOCS/$uri";
+
unless (-e $file) {
# no such file. send them to the main server if it's a GET.
return LJ::Request->method eq 'GET' ? redir("$LJ::SITEROOT$uri$args_wq") : 404;
}
- if (-d _) { $file .= "/index.bml"; }
+
+ if (-d _) { $file .= '/index.bml'; }
$file =~ s!/{2,}!/!g;
LJ::Request->filename($file);
- $LJ::IMGPREFIX = "/img";
- $LJ::STATPREFIX = "/stc";
+ $LJ::IMGPREFIX = '/img';
+ $LJ::STATPREFIX = '/stc';
return LJ::Request::OK
- } else {
+ }
+ else {
return LJ::Request::FORBIDDEN;
}
- } elsif (LJ::run_hook("set_alternate_statimg")) {
+ }
+ elsif (LJ::run_hook('set_alternate_statimg')) {
# do nothing, hook did it.
} else {
$LJ::DEBUG_HOOK{'pre_restore_bak_stats'}->() if $LJ::DEBUG_HOOK{'pre_restore_bak_stats'};
@@ -526,12 +541,14 @@
# anti-squatter checking
if ($LJ::DEBUG{'anti_squatter'} && LJ::Request->method eq "GET") {
my $ref = LJ::Request->header_in("Referer");
+
if ($ref && index($ref, $LJ::SITEROOT) != 0) {
# FIXME: this doesn't anti-squat user domains yet
if ($uri !~ m!^/404!) {
# So hacky! (see note below)
$LJ::SQUAT_URL = "http://$host$hostport$uri$args_wq";
- } else {
+ }
+ else {
# then Apache's 404 handler takes over and we get here
# FIXME: why?? why doesn't it just work to return OK
# the first time with the handlers pushed? nothing
@@ -539,6 +556,7 @@
LJ::Request->handler("perl-script");
LJ::Request->set_handlers(PerlHandler => \&anti_squatter);
}
+
return LJ::Request::OK
}
}
@@ -566,20 +584,21 @@
$opts->{'user'} = LJ::canonical_username($opts->{'user'});
my $u = LJ::load_user($opts->{'user'});
my $remote = LJ::get_remote();
- unless ($u) {
+
+ unless ( $u ) {
LJ::Request->pnotes('error' => 'baduser');
LJ::Request->pnotes('remote' => $remote);
return LJ::Request::NOT_FOUND;
- }
-
+ }
+
LJ::Request->notes("journalid" => $u->{userid});
## check that request URL is canonical (i.e. it starts with $u->journal_base)
- ## if not, construct canonical URL and redirect there
+ ## if not, construct canonical URL and redirect there
## (redirect cases: old http://community.lj.com/name URL, upper-case URLs, hyphen/underscore in usernames etc)
{
## warning: $uri from outer scope has stripped <user> part from http://users.livejournal.com/<user> URLs
- my $uri = LJ::Request->uri;
+ my $uri = LJ::Request->uri;
my $current_url = "http://$host$uri";
my $journal_base = $u->journal_base;
if (substr($current_url, 0, length($journal_base)) ne $journal_base) {
@@ -594,7 +613,7 @@
if ($u->is_community) {
LJ::run_hook('vertical_tags', $remote, $u);
}
-
+
# check if this entry or journal contains adult content
if (LJ::is_enabled('content_flag')) {
# force remote to be checked
@@ -734,8 +753,10 @@
# journals. This ensures redirects work sensibly for all valid paths
# under a given username, without sprinkling redirects everywhere.
my $u = LJ::load_user($user);
+
if ($u && $u->is_renamed) {
my $renamedto = $u->prop('renamedto');
+
if ($renamedto ne '') {
my $redirect_url = ($renamedto =~ m!^https?://!) ? $renamedto : LJ::journal_base($renamedto, $vhost) . $uuri . $args_wq;
return redir($redirect_url, 301);
@@ -752,6 +773,7 @@
if ($uuri =~ m#^/(\d+)\.html$#) { #
my $u = LJ::load_user($user);
+
unless ($u) {
LJ::Request->pnotes ('error' => 'baduser');
LJ::Request->pnotes ('remote' => LJ::get_remote());
@@ -759,15 +781,18 @@
}
$ljentry = LJ::Entry->new($u, ditemid => $1);
- if ($GET{'mode'} eq "reply" || $GET{'replyto'} || $GET{'edit'}) {
+
+ if ( $GET{'mode'} eq "reply" || $GET{'replyto'} || $GET{'edit'} ) {
$mode = "reply";
} else {
$mode = "entry";
}
- } elsif ($uuri =~ m#^/(\d\d\d\d)(?:/(\d\d)(?:/(\d\d))?)?(/?)$#) {
+ }
+ elsif ( $uuri =~ m|^/(\d\d\d\d)(?:/(\d\d)(?:/(\d\d))?)?(/?)$| ) {
my ($year, $mon, $day, $slash) = ($1, $2, $3, $4);
- unless ($slash) {
+
+ unless ( $slash ) {
my $u = LJ::load_user($user)
or return LJ::Request::NOT_FOUND;
my $proper = $u->journal_base . "/$year";
@@ -781,20 +806,22 @@
# that's how it used to do it, when the pathextra was /day[/yyyy/mm/dd]
$pe = $uuri;
- if (defined $day) {
+ if ( defined $day ) {
$mode = "day";
- } elsif (defined $mon) {
+ }
+ elsif ( defined $mon ) {
$mode = "month";
- } else {
+ }
+ else {
$mode = "calendar";
}
-
- } elsif ($uuri =~ m!
+ }
+ elsif ( $uuri =~ m!
/([a-z\_]+)? # optional /<viewname>
(.*) # path extra: /FriendGroup, for example
- !x && ($1 eq "" || defined $LJ::viewinfo{$1}))
+ !x && ($1 eq "" || defined $LJ::viewinfo{$1}) )
{
- ($mode, $pe) = ($1, $2);
+ ( $mode, $pe ) = ($1, $2);
$mode ||= "" unless length $pe; # if no pathextra, then imply 'lastn'
# redirect old-style URLs to new versions:
@@ -802,37 +829,45 @@
my $newuri = $uri;
$newuri =~ s!$mode/(\d\d\d\d)!$1!;
return redir(LJ::journal_base($user) . $newuri);
- } elsif ($mode eq 'rss') {
+ }
+ elsif ( $mode eq 'rss' ) {
# code 301: moved permanently, update your links.
return redir(LJ::journal_base($user) . "/data/rss$args_wq", 301);
- } elsif ($mode eq 'pics' && $LJ::REDIRECT_ALLOWED{$LJ::FB_DOMAIN}) {
+ }
+ elsif ( $mode eq 'pics' && $LJ::REDIRECT_ALLOWED{$LJ::FB_DOMAIN} ) {
# redirect to a user's gallery
my $url = "$LJ::FB_SITEROOT/$user";
return redir($url);
- } elsif ($mode eq 'tag') {
+ }
+ elsif ( $mode eq 'tag' ) {
# tailing slash on here to prevent a second redirect after this one
return redir(LJ::journal_base($user) . "$uri/") unless $pe;
- if ($pe eq '/') {
+
+ if ( $pe eq '/' ) {
# tag list page
$mode = 'tag';
$pe = undef;
- } else {
+ }
+ else {
# filtered lastn page
$mode = 'lastn';
# prepend /tag so that lastn knows to do tag filtering
$pe = "/tag$pe";
}
- } elsif ($mode eq 'security') {
+ }
+ elsif ( $mode eq 'security' ) {
# tailing slash on here to prevent a second redirect after this one
return redir(LJ::journal_base($user) . "$uri/") unless $pe;
- if ($pe eq '/') {
+
+ if ( $pe eq '/' ) {
# do a 404 for now
LJ::request->pnotes ('error' => 'e404');
LJ::Request->pnotes ('remote' => LJ::get_remote());
return LJ::Request::NOT_FOUND;
- } else {
+ }
+ else {
# filtered lastn page
$mode = 'lastn';
@@ -840,14 +875,17 @@
$pe = "/security$pe";
}
}
- } elsif (($vhost eq "users" || $vhost =~ /^other:/) &&
+ }
+ elsif ( ($vhost eq "users" || $vhost =~ /^other:/ ) &&
$uuri eq "/robots.txt") {
$mode = "robots_txt";
- } else {
+ }
+ else {
my $key = $uuri;
$key =~ s!^/!!;
my $u = LJ::load_user($user);
- unless ($u) {
+
+ unless ( $u ) {
LJ::Request->pnotes ('error' => 'baduser');
LJ::Request->pnotes ('remote' => LJ::get_remote());
return LJ::Request::NOT_FOUND;
@@ -859,9 +897,11 @@
undef, $u->{userid}, $key);
if ($type eq "L") {
$ljentry = LJ::Entry->new($u, ditemid => $nodeid);
+
if ($GET{'mode'} eq "reply" || $GET{'replyto'} || $GET{'edit'}) {
$mode = "reply";
- } else {
+ }
+ else {
$mode = "entry";
}
}
@@ -875,12 +915,12 @@
}
return $journal_view->({
- 'vhost' => $vhost,
- 'mode' => $mode,
- 'args' => $args,
+ 'vhost' => $vhost,
+ 'mode' => $mode,
+ 'args' => $args,
'pathextra' => $pe,
- 'user' => $user,
- 'ljentry' => $ljentry,
+ 'user' => $user,
+ 'ljentry' => $ljentry,
});
};
@@ -891,12 +931,12 @@
## special case:
## www.test.livejournal.com --(redirect)--> test.livejournal.com
- if ($host =~ /^w{1,4}\.([\w\-]{1,15})\.\Q$LJ::USER_DOMAIN\E$/) {
+ if ( $host =~ /^w{1,4}\.([\w\-]{1,15})\.\Q$LJ::USER_DOMAIN\E$/ ) {
return redir("http://$1.$LJ::USER_DOMAIN$uri$args_wq");
}
# user domains:
- if (($LJ::USER_VHOSTS || $LJ::ONLY_USER_VHOSTS) &&
+ if ( ($LJ::USER_VHOSTS || $LJ::ONLY_USER_VHOSTS ) &&
$host =~ /^([\w\-]{1,15})\.\Q$LJ::USER_DOMAIN\E$/ &&
$1 ne "www" &&
@@ -909,42 +949,40 @@
# see if the "user" is really functional code
my $func = $LJ::SUBDOMAIN_FUNCTION{$user};
- if ($func eq "normal") {
+ if ( $func eq "normal" ) {
# site admin wants this domain to be ignored and treated as if it
# were "www", so set this flag so the custom "OTHER_VHOSTS" check
# below fails.
$skip_domain_checks = 1;
- } elsif ($func eq "cssproxy") {
-
+ }
+ elsif ( $func eq "cssproxy" ) {
return $bml_handler->("$LJ::HOME/htdocs/extcss/index.bml");
-
- } elsif ($func eq 'portal') {
+ }
+ elsif ( $func eq 'portal' ) {
# if this is a "portal" subdomain then prepend the portal URL
return redir("$LJ::SITEROOT/portal/");
-
- } elsif ($func eq 'support') {
+ }
+ elsif ( $func eq 'support' ) {
return redir("$LJ::SITEROOT/support/");
-
- } elsif (ref $func eq "ARRAY" && $func->[0] eq "changehost") {
-
+ }
+ elsif ( ref $func eq "ARRAY" && $func->[0] eq "changehost" ) {
return redir("http://$func->[1]$uri$args_wq");
-
- } elsif ($uri =~ m!^/(?:talkscreen|delcomment)\.bml!) {
+ }
+ elsif ( $uri =~ m!^/(?:talkscreen|delcomment)\.bml! ) {
# these URLs need to always work for the javascript comment management code
# (JavaScript can't do cross-domain XMLHttpRequest calls)
return LJ::Request::DECLINED
-
- } elsif ($func eq "journal") {
-
+ }
+ elsif ( $func eq "journal" ) {
# Temporary block. Just for one-time verification. LJSUP-7700
if ($uri eq '/yandex_58d720848324d318.txt') {
LJ::Request->handler("perl-script");
LJ::Request->set_handlers(PerlHandler => sub{ return LJ::Request::OK; });
return LJ::Request::OK;
- }
-# end of temporary block
- elsif ($uri !~ m!^/([\w\-]{1,15})(/.*)?$!) {
+ }
+# end of temporary block
+ elsif ( $uri !~ m!^/([\w\-]{1,15})(/.*)?$! ) {
return LJ::Request::DECLINED if $uri eq "/favicon.ico";
my $redir = LJ::run_hook("journal_subdomain_redirect_url",
$host, $uri);
@@ -953,53 +991,61 @@
LJ::Request->pnotes ('remote' => LJ::get_remote());
return LJ::Request::NOT_FOUND;
}
+
($user, $uri) = ($1, $2);
$uri ||= "/";
# redirect them to their canonical URL if on wrong host/prefix
- if (my $u = LJ::load_user($user)) {
+ if ( my $u = LJ::load_user($user) ) {
my $canon_url = $u->journal_base;
+
unless ($canon_url =~ m!^http://$host!i || $LJ::DEBUG{'user_vhosts_no_wronghost_redirect'}) {
return redir("$canon_url$uri$args_wq");
}
+
LJ::set_active_journal($u); #for Wishlist2, communities
}
-
+
my $view = $determine_view->($user, "safevhost", $uri);
return $view if defined $view;
- } elsif ($func eq 'api') {
+ }
+ elsif ( $func eq 'api' ) {
Apache::LiveJournal::Interface::Api->load;
LJ::Request->handler("perl-script");
LJ::Request->push_handlers(PerlHandler => \&Apache::LiveJournal::Interface::Api::handler);
return LJ::Request::OK;
-
+
LJ::Request->pnotes ('error' => 'e404');
LJ::Request->pnotes ('remote' => LJ::get_remote());
return LJ::Request::NOT_FOUND;
- } elsif ($func eq "games") {
+ }
+ elsif ( $func eq "games" ) {
LJ::get_remote();
return redir(LJ::Session->setdomsess_handler()) if LJ::Request->uri eq "/__setdomsess";
return LJ::URI->bml_handler($LJ::AJAX_URI_MAP{$1}) if (LJ::Request->uri =~ /^\/__rpc_((?:ljapp|lj_times|ctxpopup|close|get).*)$/);
- return remote_domsess_bounce() if LJ::remote_bounce_url();
+ return remote_domsess_bounce() if LJ::remote_bounce_url();
return $bml_handler->("$LJ::HOME/htdocs/games/game.bml");
- } elsif ($func) {
+ }
+ elsif ( $func ) {
my $code = {
'userpics' => \&userpic_trans,
'files' => \&files_trans,
};
return $code->{$func}->(LJ::Request->r) if $code->{$func};
+
LJ::Request->pnotes ('error' => 'e404');
LJ::Request->pnotes ('remote' => LJ::get_remote());
return LJ::Request::NOT_FOUND; # bogus ljconfig
- } else {
- ##
+ }
+ else {
my $u = LJ::load_user($user);
LJ::set_active_journal($u) if $u;
my $view = $determine_view->($user, "users", $uri);
return $view if defined $view;
+
LJ::Request->pnotes ('error' => 'e404');
LJ::Request->pnotes ('remote' => LJ::get_remote());
return LJ::Request::NOT_FOUND;
@@ -1007,12 +1053,15 @@
}
# custom used-specified domains
- if ($LJ::OTHER_VHOSTS && !$skip_domain_checks &&
- $host ne $LJ::DOMAIN_WEB &&
- $host ne $LJ::DOMAIN && $host =~ /\./ &&
- $host =~ /[^\d\.]/)
+ if ($LJ::OTHER_VHOSTS
+ && !$skip_domain_checks
+ && $host ne $LJ::DOMAIN_WEB
+ && $host ne $LJ::DOMAIN
+ && $host =~ /\./
+ && $host =~ /[^\d\.]/ )
{
my $u = LJ::User->new_from_external_domain($host);
+
unless ($u) {
LJ::Request->pnotes ('error' => 'baduser');
LJ::Request->pnotes ('remote' => LJ::get_remote());
@@ -1189,7 +1238,7 @@
){
# maps uri to dir
my $uri = LJ::Request->uri;
-
+
## forbids ANY .. in uri
if ($uri =~ /\.\./) {
LJ::Request->pnotes ('error' => 'e404');
@@ -1226,11 +1275,11 @@
{
if (LJ::Request->uri eq '/crossdomain.xml') {
- LJ::Request->handler("perl-script");
- LJ::Request->set_handlers(PerlHandler => \&crossdomain_content);
+ LJ::Request->handler("perl-script");
+ LJ::Request->set_handlers(PerlHandler => \&crossdomain_content);
return LJ::Request::OK;
}
-
+
LJ::Request->pnotes (error => 'e404') unless LJ::Request->uri =~ m!^/(?:userpic/)?(\d+)/(\d+)$!;
return LJ::Request::NOT_FOUND unless LJ::Request->uri =~ m!^/(?:userpic/)?(\d+)/(\d+)$!;
my ($picid, $userid) = ($1, $2);
@@ -1284,7 +1333,7 @@
return LJ::Request::OK
}
-sub crossdomain_content
+sub crossdomain_content
{
my $crossdomain = '<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
@@ -1687,7 +1736,7 @@
LJ::run_hooks("after_journal_content_created", $opts, \$html);
return redir($opts->{'redir'}) if $opts->{'redir'};
-
+
if (defined $opts->{'handler_return'}) {
if ($opts->{'handler_return'} =~ /^(\d+)/) {
return $1;
@@ -1715,7 +1764,7 @@
}
if ($RQ{'mode'} eq "entry" || $RQ{'mode'} eq "reply") {
- my $filename = $RQ{'mode'} eq "entry"
+ my $filename = $RQ{'mode'} eq "entry"
? ( $GET{talkread2}
? "$LJ::HOME/htdocs/talkread2.bml"
: "$LJ::HOME/htdocs/talkread.bml"
@@ -1897,7 +1946,7 @@
$length = length($html);
LJ::Request->header_out('Content-Encoding', 'gzip');
}
-
+
# other headers
my $html_md5 = md5_base64($html);
LJ::Request->header_out(ETag => $html_md5);
@@ -2176,14 +2225,14 @@
## All our functions take signle hashref as an argument.
## Moreover, we use $req->{'props'} for our tracking purposes
- $req = {} unless ref $req eq "HASH";
+ $req = {} unless ref $req eq "HASH";
# get rid of the UTF8 flag in scalars
while (my ($k, $v) = each %$req) {
$req->{$k} = Encode::encode_utf8($v) if Encode::is_utf8($v);
}
$req->{'props'}->{'interface'} = "xml-rpc";
-
+
my $res = LJ::Protocol::do_request($method, $req, \$error);
if ($error) {
die SOAP::Fault
@@ -2243,17 +2292,17 @@
## Without eval/warn/die there will be no error message in our logs,
## since XMLRPC::Transport::HTTP::Apache will send the error to client.
my $res = eval { LJ::Protocol::xmlrpc_method($method, @_) };
- if ($@) {
+ if ($@) {
## Do not log XMLRPC exceptions with exception number:
## 305: Client error: Action forbidden; account is suspended. at
## They are useless for Ops, but, yes, they can be useful for engineering debug.
##
- warn "LJ::XMLRPC::$method died: $@"
+ warn "LJ::XMLRPC::$method died: $@"
if $@ !~ /^\d+?\s*:/
and $@ ne "Account not validated."
- and $@ ne "Unknown username.";
+ and $@ ne "Unknown username.";
- die $@;
+ die $@;
}
return $res;
Modified: trunk/cgi-bin/LJ/Request.pm
===================================================================
--- trunk/cgi-bin/LJ/Request.pm 2011-07-25 08:18:56 UTC (rev 19520)
+++ trunk/cgi-bin/LJ/Request.pm 2011-07-25 09:50:49 UTC (rev 19521)
@@ -209,7 +209,6 @@
my ($class, $key, $value, %opts) = @_;
$class->_parse_cookies;
-
$opts{'path'} ||= $LJ::COOKIE_PATH;
$opts{'domain'} ||= $LJ::COOKIE_DOMAIN;
$opts{'expires'} ||= 0;
@@ -230,23 +229,23 @@
my $header = '';
$header .= LJ::Text->eurl($key) . '=' . LJ::Text->eurl($value);
- $header .= "; expires=$expires_dump" if $opts{'expires'};
- $header .= "; path=$opts{'path'}" if $opts{'path'};
+ $header .= "; expires=$expires_dump" if $opts{'expires'};
+ $header .= "; path=$opts{'path'}" if $opts{'path'};
$header .= "; domain=$opts{'domain'}" if $opts{'domain'};
- $header .= "; HttpOnly" if $opts{'http_only'};
+ $header .= "; HttpOnly" if $opts{'http_only'};
## Only one cookie with same name
@cookie_set = grep { $_->{name} ne $key } @cookie_set;
push @cookie_set, {
- 'name' => $key,
- 'value' => $value,
- 'expires' => $opts{'expires'},
+ 'name' => $key,
+ 'value' => $value,
+ 'expires' => $opts{'expires'},
'expires_dump' => $expires_dump,
- 'path' => $opts{'path'},
- 'domain' => $opts{'domain'},
- 'http_only' => $opts{'http_only'},
- 'header' => $header,
+ 'path' => $opts{'path'},
+ 'domain' => $opts{'domain'},
+ 'http_only' => $opts{'http_only'},
+ 'header' => $header,
};
push @{$cookie{$key}}, $value;
@@ -256,9 +255,11 @@
sub delete_cookie {
my ($class, $key, %opts) = @_;
- $class->set_cookie($key, undef, time - 86400,
- 'domain' => $opts{'domain'},
- 'path' => $opts{'path'},
+ $class->set_cookie(
+ $key => undef,
+ 'expires' => time - 86400,
+ 'domain' => $opts{'domain'},
+ 'path' => $opts{'path'},
);
delete $cookie{$key};
}
Modified: trunk/cgi-bin/LJ/S2/HeadContent.pm
===================================================================
--- trunk/cgi-bin/LJ/S2/HeadContent.pm 2011-07-25 08:18:56 UTC (rev 19520)
+++ trunk/cgi-bin/LJ/S2/HeadContent.pm 2011-07-25 09:50:49 UTC (rev 19521)
@@ -120,9 +120,6 @@
$head_content .= LJ::res_includes() . $extra_js;
LJ::run_hooks( 'head_content', \$head_content );
- $head_content .= qq(<script type='text/javascript'>\n);
- $head_content .= qq(Site = window.Site || {};\n);
- $head_content .= qq(</script>\n);
my $get = $opts->{'getargs'};
my $need_block_robots = $opts->{entry_block_robots};
Modified: trunk/cgi-bin/LJ/Session.pm
===================================================================
--- trunk/cgi-bin/LJ/Session.pm 2011-07-25 08:18:56 UTC (rev 19520)
+++ trunk/cgi-bin/LJ/Session.pm 2011-07-25 09:50:49 UTC (rev 19521)
@@ -133,8 +133,6 @@
$sess->{'sessid'} = $id;
$sess->{'userid'} = $u->{'userid'};
- clear_all_ljpta();
-
# clean up old sessions
my $old = $udbh->selectcol_arrayref("SELECT sessid FROM sessions WHERE ".
"userid=$u->{'userid'} AND ".
@@ -283,41 +281,6 @@
return domsess_cookie_string(@_);
}
-# value for 'ljpta' cookie
-# 'ljpta' stands for LiveJournal Pass Throught Authorization
-# options:
-# share_id - uniq value, default is to generate it
-# host, default is to take it from request
-# ts - timestamp for the secret, default is to use current time
-# returns array: (share_id, cookie, auth)
-sub ljpta_cookie_string {
- my $opts = shift;
-
- my $share_id = $opts->{share_id} || Digest::MD5::md5_hex( rand() . $$ . {} . time() );
- my $host = $opts->{host} || LJ::Request->header_in("Host");
- my $ts = $opts->{ts} || scalar(time());
- my $secret = LJ::get_secret($ts);
-
- my $auth = Digest::MD5::md5_hex("$share_id:$host:$ts:$secret");
- return ($share_id, "$share_id:$ts:$auth", $auth);
-}
-
-# check validity of 'ljpta' cookie
-# returns 'share_id' field
-sub valid_ljpta_cookie {
- my $cookie = shift;
-
- return undef unless $cookie;
- my ($have_share_id, $have_ts, $have_auth) = split /:/, $cookie;
-
- my ($share_id, $calc_cookie, $calc_auth) = ljpta_cookie_string({ share_id => $have_share_id, ts => $have_ts });
-
- return undef if $calc_cookie ne $cookie; # unused fields in $have cookie?
- return undef if $calc_auth ne $have_auth; # may be wrong host, may be wrong cookie...
-
- return $have_share_id; # cookie is ok
-}
-
# sets new ljmastersession cookie given the session object
sub update_master_cookie {
my ($sess) = @_;
@@ -473,74 +436,45 @@
# NOTE: internal function REQUIRES trusted input
sub helper_url {
- my ($class, $dest, $ljpta) = @_;
+ my ($class, $dest) = @_;
return unless $dest;
my $u = LJ::get_remote();
- if ($ljpta) { # foreign domain case
-
- my $host;
- if ($dest =~ m!^http://([\w.-]+)/?!) {
- $host = $1;
- }
- my $host_u = LJ::User->new_from_external_domain($host);
- return unless $host_u;
-
- my @cookies = grep { $_ } @{ $BML::COOKIE{'ljpta[]'} || [] };
-
- my ($share_id, $cookie, $auth);
- foreach my $try_cookie (@cookies) {
- my $s_id = valid_ljpta_cookie($try_cookie);
- next unless $s_id;
-
- $share_id = $s_id;
- $cookie = $try_cookie;
- last;
- }
- ($share_id, $cookie, $auth) = ljpta_cookie_string() unless $share_id;
-
- # here we have values for main site cookie
- set_cookie(ljpta => $cookie,
- domain => $LJ::DOMAIN_WEB,
- path => '/',
- http_only => 1);
-
- # share secret of authentication with all other host-aliases
- my ($uid, $sessid);
- $uid = $u->userid if $u;
- $sessid = $u->session->{sessid} if $u and $u->session;
- LJ::MemCache::set("pta:$share_id", ($u ? "$uid:$sessid" : 'unlogged'), 24 * 60 * 60);
-
- # redirect to __setdomsess and put synchonized ljpta cookie
-
- # calculate cookie for different domain
- ($share_id, $cookie, $auth) = ljpta_cookie_string({ share_id => $share_id, host => $host });
-
- return "http://$host/__setdomsess?dest=" . LJ::eurl($dest) . "&k=ljpta&v=" . LJ::eurl($cookie);
- }
-
unless ($u) {
LJ::Session->clear_master_cookie;
return;
}
+ # check if $dest is our domain
+ return unless LJ::User->new_from_url($dest);
+
my $domcook = LJ::Session->domain_cookie($dest) or
return;
+ my $sess = $u->session;
+ my $cookie = $sess->domsess_cookie_string($domcook);
+
if ($dest =~ m!^(https?://)([^/]*?)\.\Q$LJ::USER_DOMAIN\E/?([a-z0-9\-_]*)!i) {
my $url = "$1$2.$LJ::USER_DOMAIN/";
+
if ($LJ::SUBDOMAIN_FUNCTION{lc($2)} eq "journal") {
$url .= "$3/" if $3 && ($3 ne '/'); # 'http://community.livejournal.com/name/__setdomsess'
}
- my $sess = $u->session;
- my $cookie = $sess->domsess_cookie_string($domcook);
return $url . "__setdomsess?dest=" . LJ::eurl($dest) .
"&k=" . LJ::eurl($domcook) . "&v=" . LJ::eurl($cookie);
}
+ elsif ( $dest =~ m!^https?://(.+?)(/.*)$! ) {
+ $dest =~ m!^https?://(?:www\.)?(.+?)(/.*)$!;
+ return "${dest}__setdomsess?dest="
+ . LJ::eurl($dest)
+ . "&k=" . LJ::eurl($domcook)
+ . "&v=" . LJ::eurl($cookie)
+ if exists $LJ::DOMAIN_JOURNALS_REVERSE{$1};
+ }
return;
}
@@ -552,14 +486,15 @@
my ($subdomain, $user) = LJ::Session->domain_journal($url);
# undef: not on a user-subdomain
- return undef
+ return undef
unless defined $subdomain;
# on a user subdomain, or shared subdomain
if ($user ne "") {
$user =~ s/-/_/g; # URLs may be - or _, convert to _ which is what usernames contain
return "ljdomsess.$subdomain.$user";
- } else {
+ }
+ else {
return "ljdomsess.$subdomain";
}
}
@@ -570,8 +505,8 @@
# in scalar context, userame is always the canonical username (no hypens/capitals)
sub domain_journal {
my ($class, $url) = @_;
-
$url ||= _current_url();
+
return undef unless
$url =~ m!^https?://(.+?)(/.*)$!;
@@ -584,18 +519,26 @@
$host eq lc($LJ::DOMAIN) ||
$host eq lc($LJ::SSLDOMAIN);
+ $host =~ s/^www\.//;
+
return undef unless
- $host =~ m!^([\w-\.]{1,50})\.\Q$LJ::USER_DOMAIN\E$!;
+ $host =~ m!^([\w-\.]{1,50})\.\Q$LJ::USER_DOMAIN\E$! or exists $LJ::DOMAIN_JOURNALS_REVERSE{$host};
my $subdomain = lc($1);
+
if ($LJ::SUBDOMAIN_FUNCTION{$subdomain} eq "journal") {
return undef unless $path =~ m!^/(\w{1,15})\b!;
+
my $user = lc($1);
return wantarray ? ($subdomain, $user) : $user;
}
- # where $subdomain is actually a username:
- return wantarray ? ($subdomain, "") : LJ::canonical_username($subdomain);
+ if( $subdomain ) {
+ # where $subdomain is actually a username:
+ return wantarray ? ($subdomain, "") : LJ::canonical_username($subdomain);
+ }
+
+ return wantarray ? ( '__external', "") : '__external';
}
sub url_owner {
@@ -623,52 +566,54 @@
return undef unless LJ::Request->is_inited;
my $sessobj;
-
my $host = LJ::Request->header_in("Host");
- unless ($host =~ /\.$LJ::DOMAIN(:\d+)?$/) { # foreign domain case
- return LJ::Session->session_from_ljpta_cookie(\%getopts, @{ $BML::COOKIE{'ljpta[]'} || [] });
+ my $domain_cookie = LJ::Session->domain_cookie;
+
+ # foreign domain case
+ unless ( $host =~ /\.$LJ::DOMAIN(:\d+)?$/ ) {
+ return LJ::Session->session_from_external_cookie(\%getopts, @{ $BML::COOKIE{"$domain_cookie\[\]"} || [] });
}
- my $domain_cookie = LJ::Session->domain_cookie;
if ($domain_cookie) {
# journal domain
$sessobj = LJ::Session->session_from_domain_cookie(\%getopts, @{ $BML::COOKIE{"$domain_cookie\[\]"} || [] });
- } else {
+ }
+ else {
# this is the master cookie at "www.livejournal.com" or "livejournal.com";
my @cookies = @{ $BML::COOKIE{'ljmastersession[]'} || [] };
+
# but support old clients who are just sending an "ljsession" cookie which they got
# from ljprotocol's "generatesession" mode.
unless (@cookies) {
@cookies = @{ $BML::COOKIE{'ljsession[]'} || [] };
$getopts{old_cookie} = 1;
}
+
$sessobj = LJ::Session->session_from_master_cookie(\%getopts, @cookies);
}
return $sessobj;
}
-# CLASS METHOD
-# -- but not called directly. usually called by LJ::Session->session_from_cookies above
-# foreign domain case
-# idea: we have synchonized (same 'share_id' field) 'ljpta' cookie on all domains
-# and store assosiated userid:sessionid pair in memcache
-# redirects work same as in journal domain case
-sub session_from_ljpta_cookie {
+sub session_from_external_cookie {
my $class = shift;
my $opts = ref $_[0] ? shift() : {};
my $no_session = sub {
my $reason = shift;
-
- ## Hack: don't redirect crawlers to get_domain_session.bml.
- ## Otherwise, sites like 'omgadget.ru' are not indexed by yandex,
- ## and many crawlers (that don't accept cookies) get into endless redirect cycle.
- return undef if $LJ::IS_BOT_USERAGENT;
-
my $rr = $opts->{redirect_ref};
+
if ($rr) {
- $$rr = "$LJ::SITEROOT/misc/get_domain_session.bml?ljpta=1&return=" . LJ::eurl(_current_url());
+ my $curl = _current_url();
+ $curl =~ m|^https?://(.+?)/|i;
+ my $domain = $1;
+
+ set_cookie(
+ 'ljdomsess.__external' => '',
+ path => '/',
+ http_only => 1,
+ domain => $domain,
+ );
}
return undef;
};
@@ -676,25 +621,12 @@
my @cookies = grep { $_ } @_;
return $no_session->("no cookies") unless @cookies;
+ my $domcook = LJ::Session->domain_cookie;
+
foreach my $cookie (@cookies) {
- my $share_id = valid_ljpta_cookie($cookie);
- next unless $share_id;
+ my $sess = valid_domain_cookie($domcook, $cookie, undef, {ignore_li_cook=>1,});
- my $status = LJ::MemCache::get("pta:$share_id");
- next unless $status;
-
- return undef if $status eq 'unlogged'; # without redirect, we already know: this user is anonymous
-
- my ($uid, $sessid) = split /:/, $status;
-
- my $u = LJ::load_userid($uid);
- next unless $u;
-
- my $sess = $u->session($sessid);
next unless $sess;
-
- # the master session can't be expired or ip-bound to wrong IP
- next unless $sess->valid;
return $sess;
}
@@ -714,9 +646,11 @@
my $no_session = sub {
my $reason = shift;
my $rr = $opts->{redirect_ref};
+
if ($rr) {
$$rr = "$LJ::SITEROOT/misc/get_domain_session.bml?return=" . LJ::eurl(_current_url());
}
+
return undef;
};
@@ -869,20 +803,6 @@
return 1;
}
-# delete all memcache values for ljpta
-# so connection will be invalid on next use
-# must be called: on login (any!) and logout
-sub clear_all_ljpta {
- # clear logged-in/out status of pass through auth from memcache
- my @cookies = grep { $_ } @{ $BML::COOKIE{'ljpta[]'} || [] };
- foreach my $try_cookie (@cookies) {
- my $share_id = valid_ljpta_cookie($try_cookie);
- next unless $share_id;
-
- LJ::MemCache::delete("pta:$share_id");
- }
-}
-
# class method
sub destroy_sessions {
my ($class, $u, @sessids) = @_;
@@ -900,8 +820,6 @@
LJ::MemCache::delete(_memkey($u, $id));
}
- clear_all_ljpta();
-
return 1;
}
@@ -953,20 +871,18 @@
my $dest = $get{'dest'};
my $domcook = $get{'k'};
my $cookie = $get{'v'};
-
my $expires = $LJ::DOMSESS_EXPIRATION || 0; # session-cookie only
- my $path = '/'; # By default cookie path is root
+ my $path = '/'; # By default cookie path is root
- if ($domcook eq 'ljpta') { # foreign domain case
+ my $curl = _current_url();
+ $curl =~ m|^https?://(.+?)/|i;
+ my $domain = $1;
- my $share_id = valid_ljpta_cookie($cookie);
- return $LJ::SITEROOT unless $share_id;
+ if ($domcook eq 'ljdomsess.__external') { # foreign domain case
+ return $LJ::SITEROOT unless valid_domain_cookie($domcook, $cookie, undef, { ignore_li_cook => 1,});
+ }
+ else { # livejournal domain case
- my $status = LJ::MemCache::get("pta:$share_id");
- return $LJ::SITEROOT unless $status;
-
- } else { # livejournal domain case
-
return "$LJ::SITEROOT" unless valid_destination($dest);
return $dest unless valid_domain_cookie($domcook, $cookie, $BML::COOKIE{'ljloggedin'});
@@ -985,10 +901,13 @@
}
}
- set_cookie($domcook => $cookie,
- path => $path,
- http_only => 1,
- expires => $expires);
+ set_cookie(
+ $domcook => $cookie,
+ path => $path,
+ http_only => 1,
+ expires => $expires,
+ domain => $domain ? $domain : '',
+ );
# add in a trailing slash, if URL doesn't have at least two slashes.
# otherwise the path on the cookie above (which is like /community/)
@@ -1052,10 +971,10 @@
return unless LJ::Request->is_inited;
my $http_only = delete $opts{http_only};
- my $domain = delete $opts{domain};
- my $path = delete $opts{path};
- my $expires = delete $opts{expires};
- my $delete = delete $opts{delete};
+ my $domain = delete $opts{domain};
+ my $path = delete $opts{path};
+ my $expires = delete $opts{expires};
+ my $delete = delete $opts{delete};
croak("Invalid cookie options: " . join(", ", keys %opts)) if %opts;
# Mac IE 5 can't handle HttpOnly, so filter it out
@@ -1099,6 +1018,7 @@
# session's uid/sessid
sub valid_domain_cookie {
my ($domcook, $val, $li_cook, $opts) = @_;
+
$opts ||= {};
my ($cookie, $gen) = split m!//!, $val;
Modified: trunk/cgi-bin/weblib.pl
===================================================================
--- trunk/cgi-bin/weblib.pl 2011-07-25 08:18:56 UTC (rev 19520)
+++ trunk/cgi-bin/weblib.pl 2011-07-25 09:50:49 UTC (rev 19521)
@@ -762,11 +762,11 @@
$qrhtml .= "<b>".BML::ml('/talkpost.bml.opt.subject')."</b></td>";
$qrhtml .= "<td colspan='2' align='left'>";
$qrhtml .= "<input class='textbox' type='text' size='50' maxlength='100' name='subject' id='subject' value='' tabindex='10' />";
-
+
$qrhtml .= "<div id=\"subjectCaptionText\">" . $text_hint . "</div>" if $text_hint;
-
+
$qrhtml .= "</td></tr>";
-
+
$qrhtml .= "<tr valign='top'>";
$qrhtml .= "<td align='right'><b>".BML::ml('/talkpost.bml.opt.message')."</b></td>";
$qrhtml .= "<td colspan='3' style='width: 90%'>";
@@ -1142,7 +1142,7 @@
$req->{'prop_opt_lockcomments'} ||= $POST->{'comment_settings'} eq 'lockcomments' ? 1 : 0;
$req->{"prop_opt_noemail"} ||= $POST->{'comment_settings'} eq "noemail" ? 1 : 0;
$req->{'prop_opt_backdated'} = $POST->{'prop_opt_backdated'} ? 1 : 0;
- $req->{'prop_copyright'} = $POST->{'prop_copyright'} ? 'P' : 'C' if LJ::is_enabled('default_copyright', LJ::get_remote())
+ $req->{'prop_copyright'} = $POST->{'prop_copyright'} ? 'P' : 'C' if LJ::is_enabled('default_copyright', LJ::get_remote())
&& $POST->{'defined_copyright'};
if ( my $reposted_from = $POST->{'reposted_from'} ) {
@@ -1204,7 +1204,7 @@
# process site-specific options
LJ::run_hooks('decode_entry_form', $POST, $req);
-
+
return $req;
}
@@ -1284,7 +1284,7 @@
my $code = shift;
die "Bogus include type: $type"
- unless $type =~ m!^(js|css|js_link|css_link|html)$!;
+ unless $type =~ m!^(?:js|css|js_link|css_link|html)$!;
push @LJ::INCLUDE_RAW => [$type, $code];
}
@@ -1305,16 +1305,17 @@
# use correct root and prefixes for SSL pages
my ($siteroot, $imgprefix, $statprefix, $jsprefix, $wstatprefix);
if ($LJ::IS_SSL) {
- $siteroot = $LJ::SSLROOT;
- $imgprefix = $LJ::SSLIMGPREFIX;
- $statprefix = $LJ::SSLSTATPREFIX;
- $jsprefix = $LJ::SSLJSPREFIX;
+ $siteroot = $LJ::SSLROOT;
+ $imgprefix = $LJ::SSLIMGPREFIX;
+ $statprefix = $LJ::SSLSTATPREFIX;
+ $jsprefix = $LJ::SSLJSPREFIX;
$wstatprefix = $LJ::SSLWSTATPREFIX;
- } else {
- $siteroot = $LJ::SITEROOT;
- $imgprefix = $LJ::IMGPREFIX;
- $statprefix = $LJ::STATPREFIX;
- $jsprefix = $LJ::JSPREFIX;
+ }
+ else {
+ $siteroot = $LJ::SITEROOT;
+ $imgprefix = $LJ::IMGPREFIX;
+ $statprefix = $LJ::STATPREFIX;
+ $jsprefix = $LJ::JSPREFIX;
$wstatprefix = $LJ::WSTATPREFIX;
}
@@ -1322,8 +1323,9 @@
unless ( $only_needed ) {
# find current journal
my $journal_base = '';
- my $journal = '';
+ my $journal = '';
my $ju;
+
if (LJ::Request->is_inited) {
my $journalid = LJ::Request->notes('journalid');
@@ -1359,36 +1361,38 @@
my $ljentry = LJ::Request->notes('ljentry') || ''; # url
my %site = (
- imgprefix => "$imgprefix",
- siteroot => "$siteroot",
- statprefix => "$statprefix",
- currentJournalBase => "$journal_base",
- currentJournal => "$journal",
- currentEntry => $ljentry,
- has_remote => $hasremote,
+ imgprefix => "$imgprefix",
+ siteroot => "$siteroot",
+ statprefix => "$statprefix",
+ currentJournalBase => "$journal_base",
+ currentJournal => "$journal",
+ currentEntry => $ljentry,
+ has_remote => $hasremote,
remote_can_track_threads => $remote && $remote->get_cap('track_thread'),
- remote_is_suspended => $remote_is_suspended,
- remote_is_maintainer => $remote_is_maintainer,
- ctx_popup => $ctxpopup,
- inbox_update_poll => $inbox_update_poll,
- media_embed_enabled => $embeds_enabled,
- esn_async => $esn_async,
- server_time => time(),
- remoteJournalBase => $remote && $remote->journal_base,
- remoteUser => $remote && $remote->user,
- );
+ remote_is_suspended => $remote_is_suspended,
+ remote_is_maintainer => $remote_is_maintainer,
+ ctx_popup => $ctxpopup,
+ inbox_update_poll => $inbox_update_poll,
+ media_embed_enabled => $embeds_enabled,
+ esn_async => $esn_async,
+ server_time => time(),
+ remoteJournalBase => $remote && $remote->journal_base,
+ remoteUser => $remote && $remote->user,
+ );
$site{default_copyright} = $default_copyright if LJ::is_enabled('default_copyright', $remote);
$site{is_dev_server} = 1 if $LJ::IS_DEV_SERVER;
$site{inbox_unread_count} = $remote->notification_inbox->unread_count if $remote and LJ::is_enabled('inbox_unread_count_in_head');
-
+
LJ::run_hooks('add_to_site_js', \%site);
my $site_params = LJ::js_dumper(\%site);
my %journal_info;
+
if (my $journalu = LJ::get_active_journal()) {
%journal_info = $journalu->info_for_js;
}
+
my $journal_info_json = LJ::JSON->to_json(\%journal_info);
my $jsml_out = LJ::JSON->to_json(\%LJ::JSML);
$ret .= qq {
@@ -1415,8 +1419,68 @@
1; ## include them as is.
}
} @LJ::NEEDED_RES;
- } ## / unless $only_needed
+ } ## / unless $only_needed
+ my $host = LJ::Request->header_in("Host");
+
+ # foreign domain case
+ unless ($host =~ /\.$LJ::DOMAIN(:\d+)?$/) {
+ my $remote = LJ::get_remote();
+
+ #first part of cross-domain auth
+ if ( $remote ) {
+ $ret .= qq|
+ <script type="text/javascript">
+ lj_user = $remote->{_session}->{userid};
+ </script>
+ |;
+ }
+ else {
+ $ret .= qq|
+ <script type="text/javascript">
+ lj_user = 0;
+ </script>
+ |;
+ }
+
+ $ret .= qq|
+ <script src="$siteroot/misc/get_auth_js.bml"></script>
+ |;
+
+ my $curl = LJ::Session::_current_url();
+ $curl =~ m|^https?://(.+?)/|i;
+
+ my $domain = $1;
+ $curl = LJ::eurl($curl);
+
+ $ret .= qq|
+ <script type="text/javascript">
+ // case 2
+ var redir = 0;
+
+ // case 1
+ if( lj_user == 0 && !lj_master_user==0 ) {
+ redir = 1;
+ }
+ // case 3
+ else if( !lj_user == 0 && lj_master_user==0 ) {
+ window.location = "http://$domain/misc/clear_domain_session.bml?return=$curl";
+ }
+ // case 4
+ else if( !lj_user == 0 && !lj_master_user==0 ) {
+ if( !lj_user == lj_master_user ) {
+ redir = 1;
+ }
+ }
+
+ // redirect to pta
+ if( redir ) {
+ window.location = "${LJ::SITEROOT}/misc/get_domain_session.bml?return=$curl";
+ }
+ </script>
+ |;
+ }
+
my $now = time();
my %list; # type -> condition -> args -> [list of files];
my %oldest; # type -> condition -> args -> $oldest
@@ -1426,7 +1490,7 @@
$opts ||= {};
my $condition = $opts->{condition};
$condition ||= ''; ## by default, no condtion is present
-
+
my $args = $opts->{args};
$args ||= '';
@@ -1465,9 +1529,11 @@
if ($path =~ m!^js/(.+)!) {
$add->('js', $1, $mtime, $LJ::NEEDED_RES{$key});
- } elsif ($path =~ /\.css$/ && $path =~ m!^(w?)stc/(.+)!) {
+ }
+ elsif ($path =~ /\.css$/ && $path =~ m!^(w?)stc/(.+)!) {
$add->("${1}stccss", $2, $mtime, $LJ::NEEDED_RES{$key});
- } elsif ($path =~ /\.js$/ && $path =~ m!^(w?)stc/(.+)!) {
+ }
+ elsif ($path =~ /\.js$/ && $path =~ m!^(w?)stc/(.+)!) {
$add->("${1}stcjs", $2, $mtime, $LJ::NEEDED_RES{$key});
}
}
@@ -1475,13 +1541,13 @@
my $tags = sub {
my ($type, $template) = @_;
return unless $list{$type};
-
+
foreach my $cond (sort {length($a) <=> length($b)} keys %{ $list{$type} }) {
foreach my $args (sort {length($a) <=> length($b)} keys %{ $list{$type}{$cond} }) {
my $list = $list{$type}{$cond}{$args};
my $start = ($cond) ? "<!--[if $cond]>" : "";
my $end = ($cond) ? "<![endif]-->\n" : "\n";
-
+
if ($do_concat) {
my $csep = join(',', @$list);
$csep .= "?v=" . $oldest{$type}{$cond}{$args};
@@ -1489,7 +1555,8 @@
$inc =~ s/__+/??$csep/;
$inc =~ s/##/$args/;
$ret .= $start . $inc . $end;
- } else {
+ }
+ else {
foreach my $item (@$list) {
my $inc = $template;
$inc =~ s/__+/$item/;
@@ -1501,7 +1568,7 @@
}
};
- ## To ensure CSS files are downloaded in parallel, always include external CSS before external JavaScript.
+ ## To ensure CSS files are downloaded in parallel, always include external CSS before external JavaScript.
## (C) http://code.google.com/speed/page-speed/
##
$tags->("stccss", "<link rel=\"stylesheet\" type=\"text/css\" href=\"$statprefix/___\" ##/>");
@@ -1519,13 +1586,17 @@
if ($type eq 'js'){
$ret .= qq|<script type="text/javascript">\r\n$code</script>\r\n|;
- } elsif ($type eq 'css'){
+ }
+ elsif ($type eq 'css'){
$ret .= qq|<style>\r\n$code</style>\n|;
- } elsif ( $type eq 'js_link' ) {
+ }
+ elsif ( $type eq 'js_link' ) {
$ret .= qq{<script type="text/javascript" src="$code"></script>\r\n};
- } elsif ( $type eq 'css_link' ) {
+ }
+ elsif ( $type eq 'css_link' ) {
$ret .= qq{<link rel="stylesheet" type="text/css" href="$code" />};
- } elsif ( $type eq 'html' ) {
+ }
+ elsif ( $type eq 'html' ) {
$ret .= $code;
}
}
@@ -1721,23 +1792,26 @@
my @divids = map { "ad_$_" } (1 .. $count);
my %adcall = (
- u => join(',', map { $adcount } @divids), # how many ads to show in each
- r => rand(),
- q => $query,
- id => join(',', @divids),
- p => 'lj',
- add => 'lj_content_ad',
- remove => 'lj_inactive_ad',
- );
+ u => join(',', map { $adcount } @divids), # how many ads to show in each
+ r => rand(),
+ q => $query,
+ id => join(',', @divids),
+ p => 'lj',
+ add => 'lj_content_ad',
+ remove => 'lj_inactive_ad',
+ );
if ($remote) {
$adcall{user} = $remote->id;
}
- my $adparams = LJ::encode_url_string(\%adcall,
- [ sort { length $adcall{$a} <=> length $adcall{$b} }
- grep { length $adcall{$_} }
- keys %adcall ] );
+ my $adparams = LJ::encode_url_string(\%adcall,
+ [
+ sort { length $adcall{$a} <=> length $adcall{$b} }
+ grep { length $adcall{$_} }
+ keys %adcall
+ ]
+ );
# allow 24 bytes for escaping overhead
$adparams = substr($adparams, 0, 1_000);
@@ -1772,7 +1846,7 @@
# modifies list of interests (appends tags of sponsored questions to the list)
# sponsored question may be taken
-# 1. from argument of function: $opts = { extra => {qotd => ...} },
+# 1. from argument of function: $opts = { extra => {qotd => ...} },
# 2. from URL args of /update.bml page (/update.bml?qotd=123)
# 3. from first displayed entry on the page
sub modify_interests_for_adcall {
@@ -1791,7 +1865,7 @@
$qotd = $entry->prop("qotdid");
}
}
-
+
if ($qotd) {
$qotd = LJ::QotD->get_single_question($qotd) unless ref $qotd;
my $tags = LJ::QotD->remove_default_tags($qotd->{tags});
@@ -1802,7 +1876,7 @@
}
# this function will filter out blocked interests, as well filter out interests which
-# cause the
+# cause the
sub interests_for_adcall {
my $u = shift;
my %opts = @_;
@@ -1818,15 +1892,15 @@
modify_interests_for_adcall(\%opts, \@interest_list);
return join(',',
- grep {
+ grep {
# not a blocked interest
- ! defined $LJ::AD_BLOCKED_INTERESTS{$_} &&
+ ! defined $LJ::AD_BLOCKED_INTERESTS{$_} &&
# and we've not already got over 768 bytes of interests
# -- +1 is for comma
($int_len += length($_) + 1) <= $max_len;
-
+
} @interest_list
);
}
@@ -1871,372 +1945,12 @@
return $ret;
}
-sub control_strip
-{
- return $LJ::DISABLED{control_strip_new} ? control_strip_old(@_) : control_strip_new(@_);
-}
-
-sub control_strip_new
-{
+sub control_strip {
my %opts = @_;
return LJ::ControlStrip->render($opts{user});
}
-sub control_strip_old
-{
- my %opts = @_;
- my $user = delete $opts{user};
-
- my $journal = LJ::load_user($user);
- my $show_strip = 1;
- if (LJ::are_hooks("show_control_strip")) {
- $show_strip = LJ::run_hook("show_control_strip", { user => $user });
- }
-
- return "" unless $show_strip;
-
- my $remote = LJ::get_remote();
- my $uri = LJ::eurl( LJ::Request->current_page_url );
- my $create_link = LJ::run_hook("override_create_link_on_navstrip", $journal) || "<a href='$LJ::SITEROOT/create.bml'>" . BML::ml('web.controlstrip.links.create', {'sitename' => $LJ::SITENAMESHORT}) . "</a>";
-
- # Build up some common links
- my %links = (
- 'login' => "<a href='$LJ::SITEROOT/?returnto=$uri'>$BML::ML{'web.controlstrip.links.login'}</a>",
- 'home' => "<a href='$LJ::SITEROOT/'>" . $BML::ML{'web.controlstrip.links.home'} . "</a> ",
- 'recent_comments' => "<a href='$LJ::SITEROOT/tools/recent_comments.bml'>$BML::ML{'web.controlstrip.links.recentcomments'}</a>",
- 'manage_friends' => "<a href='$LJ::SITEROOT/friends/'>$BML::ML{'web.controlstrip.links.managefriends'}</a>",
- 'manage_entries' => "<a href='$LJ::SITEROOT/editjournal.bml'>$BML::ML{'web.controlstrip.links.manageentries'}</a>",
- 'invite_friends' => "<a href='$LJ::SITEROOT/friends/invite.bml'>$BML::ML{'web.controlstrip.links.invitefriends'}</a>",
- 'create_account' => $create_link,
- 'syndicated_list' => "<a href='$LJ::SITEROOT/syn/list.bml'>$BML::ML{'web.controlstrip.links.popfeeds'}</a>",
- 'learn_more' => LJ::run_hook('control_strip_learnmore_link') || "<a href='$LJ::SITEROOT/'>$BML::ML{'web.controlstrip.links.learnmore'}</a>",
- 'explore' => "<a href='$LJ::SITEROOT/explore/'>" . BML::ml('web.controlstrip.links.explore', { sitenameabbrev => $LJ::SITENAMEABBREV }) . "</a>",
- );
-
- if ($remote && $remote->is_person) {
- $links{'post_journal'} = "<a href='$LJ::SITEROOT/up...
(truncated) 