sobota 22. januára 2011

Ako som sa vysporiadal s HTTPS výsledkami Google vyhľadávania

Vyhľadával som určitú frázu na slovenskom Googli a vo výsledkoch sa zobrazil odkaz na článok na mojich stránkach. Keď som na neho klikol, zobrazila sa odporná výstražná stránka Firefoxu s upozornením o nebezpečenstve návštevy mojej stránky. Niečo o tom, že nebol nájdený žiaden certifikát pri pripájaní sa na server cez HTTPS. O čom to je toto? Moja osobná stránka je založená na CMS systéme Joomla! a neposkytujem žiadnu užívateľskú sekciu, ani nemám žiadnu zabezpečenú zónu, v ktorej by užívatelia komunikovali cez protokol HTTPS.
Zázračne, Google v niekoľkých prípadoch uvádza vo svojich výsledkoch hľadania odkazy na správne stránky pod nesprávnym protokolom.
Upozorňujem, že tento článok sa týka len tých, čo majú stránky podávané Apache Web Server-om.
Keďže pochybujem, že by náhodný návštevník chcel pridávať bezpečnostnú výnimku do svojho prehliadača pre moju stránku, prv než ju navštívi, som presvedčený o tom, že ma takéto výsledky vyhľadávania penalizujú na návštevnosti mojej stránky. Bolo treba s tým niečo robiť. Príčinu som síce nezistil, ale so symptómami som si poradil. A to nasledovne:
Aby sa mi Google, či iné roboty, nešplhali po stránkach cez https, pridal som na svoje stránky sekundárny súbor robots.txt, s názvom robots_ssl.txt.
Obsah tohto súboru je jednoduchý:
User-agent: *
Disallow: /
Zakážeme všetkým robotom prístup k celej stránke. Zadaním lomítka by mala byť nedostupná celá stránka, jej hlavný adresár, aj všetky podadresáre.
Ako však povedať robotom prichádzajúcim cez HTTPS na súbor robots.txt, aby si pozreli moju alternatívnu verziu robots_ssl.txt? Zavŕtame sa do .htaccess súboru a pozrieme, či je zapnutý RewriteEngine, ak nie, potrebujeme pridať tieto riadky:
RewriteEngine On
RewriteBase /
Pridáme RewriteRule pre Apache, pomocou ktorého roboty prichádzajúce cez port využívaný pri komunikácii HTTPS protokolom budú presmerované na správny robots.txt súbor, teda v mojom prípade robots_ssl.txt vyhradený práve pre tieto roboty:
RewriteCond %{SERVER_PORT} ^443$
RewriteRule ^robots.txt$ robots_ssl.txt
Toto pravidlo ich nasmeruje na správne miesto, odkiaľ by už nemali pokračovať v prehľadávaní mojich stránok, pretože som nastavil Disallow: / Takto nastavené robots.txt súbory by v budúcnosti mali zabrániť tomu, aby sa vo výsledkoch hľadania zobrazovali linky na stránky s HTTPS protokolom. No čo s tými, čo Google už má vo svojom indexe a stále zobrazuje ľuďom pri hľadaní?
V mojom prípade to bolo celkom jednoduché, keďže na stránkach naozaj nemám žiadnu zabezpečenú sekciu, do ktorej by hostia pristupovali cez HTTPS. Stačí len pridať ešte jeden RewriteRule do .htaccess súboru:
RewriteCond %{SERVER_PORT} ^443$
RewriteRule .* http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Toto pravidlo v podstate presmeruje každý prístup na moju stránku cez port 443 na tú istú požadovanú stránku, ale cez HTTP protokol (port 80). V hranatej zátvorke za pravidlom uvedieme ešte R=301 (pošlime nazad response code 301 - "moved permanently" trvalo premiestnené) a písmeno L, ktorým označíme toto presmerovacie pravidlo ako posledné (Last), aby Apache nemusel testovať, či daný request spĺňa podmienky iných pravidiel.
Časom by sa hádam aj Google mal polepšiť a všimnúť si, že všetko https://... je permanentne presunuté na http://
Každopádne, teraz keď kliknem na HTTPS odkaz z výsledkov Google hľadania, som automaticky presmerovaný na správnu stránku cez HTTP protokol.
Ak by ste mali problém s vašim .htaccess súborom (napríklad ja, akonáhle som použil súbor .htaccess, celá moja stránka prestala fungovať) budete musieť trochu pogoogliť, v čom to môže byť. Možno váš web host nepovoľuje používanie týchto súborov, možno to však bude spôsobené, ako v mojom prípade, riadkom, ktorý zvyčajne nájdete v šablónach .htaccess súborov:
Options +FollowSymLinks
Tento riadok môže spôsobovať problém pri niektorých serverových konfiguráciách. Tento riadok je nutný pre modul mod_rewrite, ale môže byť už predošle nastavený vašim serverovým administrátorom tak, že sa nedá nastaviť (zmeniť) vo vašom .htaccess súbore.

sobota 8. januára 2011

C# - Navrátené objekty anonymného typu.
Čo s nimi?

Jedna z novších čŕt jazyku C# (od C# 3.0) sú anonymné typy (vytváranie objektov neznámeho typu, respektíve objektov žiadneho deklarovaného typu). Sú vynikajúce pri použití s technológiou LINQ, no je problém s konzumovaním týchto objektov po navrátení z funkcie. Anonymné objekty sa dajú navrátiť jedine ako typu object, ktorý potom však nemáme ako využiť bez toho aby sme ho explicitne pretypovali (explicit cast). No do akého typu - ako - chceme pretypovať objekt, keď je anonymný a jeho typ bol vytvorený takzvane on-the-fly (za behu)?

(Neviem sa tu veľmi spriateliť s formátovaním článkov na Google blogu. Kuknite na to na mojej stránke, kde to občas aj updateujem)

Okrem argumentu, že by sme sa o to nemali radšej ani pokúšať, že anonymné objekty sa nemajú navrácať z metód a mali by sa použiť priamo v metóde kde boli vytvorené (všetko veľmi dobré a opodstatnené rady), sa nám poskytuje ešte niekoľko možností. Na jednu konkrétne zaujímavú som naďabil nedávno a chcel by som sa o nej zmieniť:

Pokiaľ tvoríme aplikáciu pre ".NET Framework 4" profil a nie ".NET Framework 4 Client Profile", môžeme využiť jeden typ z namespace-u System.Web.Routing (knižnica System.Web.dll). V nastaveniach projektu zmeníme profil na .NET Framework 4 (implikácie čoho nám musia byť jasné), aby sme mohli pridať do projektu referenciu na knižnicu System.Web.dll

V našom projekte potom stačí pridať jednu "using" klauzulu:

using System.Web.Routing;

A na nasledujúcej ukážke malého programíku vám ukážem čo a ako s anonymným objektom navráteným z nejakej funkcie:

class Program
{
  static void Main(string[] args)
  {
    object anonym = Metoda_Vracia_Objekt_Anonymneho_Typu(); //CO S TYM?

    //Uz viem! Pouzijem RouteValueDictionary zo System.Web.dll
    RouteValueDictionary rvd = new RouteValueDictionary(anonym);

    //a dalej je vsetko vesele :-)
    Console.WriteLine("Ahoj, volám sa {0} a pracujem ako {1}", rvd["Meno"], rvd["Povolanie"]);
  }
 
  private static object Metoda_Vracia_Objekt_Anonymneho_Typu()
  {
    return new { Id = 1, Meno = "Peter Perhác", Povolanie = "softwareový vývojár" };
  }
}

Tento program, ako sa dá očakávať, produkuje nasledovnú vetu (číročistá pravda):
Ahoj, volám sa Peter Perháč a pracujem ako softwareový vývojár

Ta fasa, ňe?

Načo je nám toto dobré?

Nuž... ako som vravel, vyhúť sa navracaniu anonymných objektov z metód je dobrá rada. Vyhnite sa tomu ak môžete. Ja som narazil na potrebu kontrolovania stavu anonymných objektov pri testovaní ASP.NET MVC2 webovej aplikácie.

Niektoré z action methods mojich kontrolerov navracali JsonResult. V JSON notácii som tam mal nejaké DATA, ktoré som do JSON formy dával cez anonymné objekty. V mojom Unit teste som chcel potom overiť, či navrátený ActionResult po zavolaní action method na kontroleri naozaj navracia JsonResult objekt a či teda Data object toho JsonResult-u má správne nastavené hodnoty svojich vlastností.

Toto sa dá celkom jednoducho, takto v kontext ASP.NET MVC2 webovej aplikácie, pretože správny profil je už zvolený, referencia na System.Web.dll je už v projekte (teda nemusí byť za sekundu si ju môžeme pridať), stačí len naimportovať správny namespace System.Web.Routing a z neho použiť triedu RouteValueDictionary.

Tento anonymný objekt, JSON Data, môžeme podať RouteValueDictionary v jej konštruktore a potom už len vyťahovať jednotlivé vlastnosti anonymného objektu zo slovníka použitím jeho indexer-u.

Myslím si, že zbytočne veľa slov o niečom, čo vidíte najjednoduchšie z hore-uvedeného príkladu.

Veselé kódovanie a veľa Wow! pocitov