czwartek, 20 września 2012

Pytanie rekrutacyjne - ciekawy pomysł

Ostatnio natrafiłem na ofertę pracy dla sys admin-a z ciekawym zapisem. W treści ogłoszenia było zadanie zapisane w base64:

Mile widziane
  - aHR0cDovL3d3dy5leGFtcGxlLnBsL2l3YW5hY29va2llCg==
Zapis zmieniony w stosunku do ogłoszenia.

Po odkodowaniu tego za pomocą base64:

echo aHR0cDovL3d3dy5leGFtcGxlLnBsL2l3YW5hY29va2llCg==  |  base64 -d

Otrzymałem:
   http://www.example.pl/iwanacookie


Za pomocą curl-a:

 curl -v  -s http://www.example.pl/iwanacookie

Otrzymałem nagłówki:

 HTTP/1.1 302 Found
 Date: Thu, 20 Sep 2012 11:26:54 GMT
 Server: Apache
 Set-Cookie: question=YmVnaW4gNjQ0IHRlc3QKTTBFSUguMyUhNjI5MzY3T1k7PVQhMDRRX19fQS1gIU8iMzcwJjVKRCYpJUZcIiVOKiMqNzBTPF0pNVU8UApNYC9QImBdRkkoYCI0Q0BgYGBgYGBgVGBgIzBgI1UjMCxAXElCIUgjMkhgIjhgYDMhLGBgJDo+QSxgRjNgCk1gYCImOmAvXVBgYDAoYGAkKjlYQihgQihAYCIoSCpgXEFJRiYsUydUMUpJPkk7UF1UTzQsMFlcXEgwMCYKTTkhPlNBI1JYVS1RWVRWJE5AVEA4VV1QMEArJ01WTDhMWCRZJVZcKl9eUUEyWDknSytRLiFVXkReLFEpLwpNLFlCNCRQKTtUV0tEMEUuUlBfMyI0RjYsK1VgXUZbMyNDMz5RTzJASFpJTyJDTEJbUDBgYDAoYGAkLydECio3PEQ0WDQpIVteNlc9YGBgCmAKZW5kCg==; Expires=Tue, 01 Jan 2013 00:00:00 GMT
Content-Length: 203
Content-Type: text/html; charset=iso-8859-1
Z tego wyciągnąłem cookie i ponownie puściłem przez base64:

echo "[base64 z question]" | base64 -d
 W wyniku otrzymałem:
 begin 644 test
M0EIH.3%!629367OY;=T!04Q___A-`!O"370&5JD&)%F\"%N*#*70S<])5U
M`/P"`]FI(`"4C@```````T``#0`#U#0,@\IB!H#2H`"8``3!,``$:>A,`F3`
M``"&:`/]P``0(``$*9XB(`B(@`"(H*`\AIF&,S'T1JI>I;P]TO4,0Y\\H00&
M9!>SA#RXU-QYTV$N@T@8U]P0@+'MVL8LX$Y%V\*_^QA2X9'K+Q.!U^D^,Q)/
M,YB4$P);TWKD0E.RP_3"4F6,+U`]F[3#C3>QO2@HZIO"CLB[P0``0(``$/'D
*7`
end
Czyli plik "uuencoded":

echo "[base64 z question]" | base64 -d  |  uudecode

W wyniku otrzymałem plik binary "test" o długości 235 znaków.

file test
# test: bzip2 compressed data, block size = 900k
Dalej:
bzip2 -d -c test >test.1
file test.1
# test.1: gzip compressed data, from Unix, max compression
Pliczek wynikowy miał 11 MB. Niezła kompresja (235 -> 11MB).
I ostatecznie:
 gzip -d -c test.1
Dało w wyniku:
(let* (
    (x  '( (1 2 (3 4 5) 6)  7  8  (9 10) ) )
  )
  ; use car/caaa..r/cd..r here to get 4 from x, append solution to your job application
)
Czyli kod w Lisp.

Co do działania tego kodu to:

http://stackoverflow.com/questions/12510086/lisp-code-how-to-run-this-example

Odpowiedzi:

(car (cdr (car (cdr (cdr (car x))))))

(let* ((x '((1 2 (3 4 5) 6) 7 8 (9 10))))
   (cadr (caddar x)))
Podsumowując. Super zadanie :)

sobota, 15 września 2012

Moje boje z Varnish-em

 

 Wprowadzenie


 Post ten ma na celu gromadzenie wiedzy związanej z Varnish-em.
Wpis ten otyczy wersji 3.x Varnisha. Będę tu gromadził rozwiązania, które sam opracowałem, linki do blogów czy innej dokumentacji.

 

Źródła zewnętrzene

 

https://www.varnish-cache.org/docs/trunk/  - dokumentacja
https://www.varnish-software.com/static/book/  - podręcznik
http://planet.varnish-cache.org/ - agregator blogów na temat Varnisha.


SHMLOG

 

Log warto utrzymywać na ramdysku. Rozmiar w zależności od wielkości bufora dla logów. Konfiguracja dla fstab:

tmpfs                   /var/lib/varnish        tmpfs   defaults,noatime,size=100M 0 0


Błędy LostHeader 


Ostatnio napotkałem problem z backendem, który (w wyniku błędu) generował dużą ilość nagłówków. W wyniku poszukiwań rozwiązania tego problemu opiszę parametry konfiguracyjne, które mogą się przydać przy tym błędzie. Błąd LostHeader jest spowodowany przekroczeniem domyślnych ustawień (pamięć), które są przeznaczone na potrzeby przetwarzania zapytań i odpowiedzi HTTP.

Parametry konfiguracyjne można ustawiać z linii poleceń przy uruchamianiu Varnisha za pomocą parametry -p lub z poziomu interfejsu CLI (varnishadm lub varnish w trybie debug).

sess_workspace - ilość pamięci (w bajtach) przeznaczona na potrzeby komunikacji HTTP (nagłówki) i operacji związanych z nagłówkami. Domyślnie 65536. Na chwilę obecną przy żadnym projekcie nie musiałem zwiększać tego parametru.

http_resp_hdr_len - maksymalna długość nagłówka (całej linii ze znakami końca wiersza). Domyślnie 8192

http_resp_size - maksymalna ilość pamięci przeznaczonej do obsługi odpowiedzi (do przetwarzania nagłówków). Odpowiedź backendu (włącznie do pustej linii oddzielającej nagłówki od danych) nie może przekroczyć tego rozmiaru. Domyślna wartość to 32768.

http_max_hdr - maksymalna liczba obsługiwanych nagłówków w zapytaniach od klienta lub odpowiedziach z backendów. Domyślna wartość to 64 linie. Pierwsza linia odpowiedzi (np. "HTTP/1.1 200 OK") zajmuję 5 linii (pól nagłówków). Zmiana tej wartości pozwoliła na na rozwiązanie problemu z błędem LostHeader (przy czym kod w backendzie został poprawiony również).

Przykłady konfiguracji:
 
-p sess_workspace=262144  -p http_resp_size=65536 -p http_resp_hdr_len=8192 -p http_max_hdr=128

Źródła zewnętrzne opisujące podobne problemy:

Device detect (mobile)


Rozwiązanie na poziomie Varnish-a (VCL) wykrywające rodzaj urządzenia (przeglądarki).
https://github.com/varnish/varnish-devicedetect/
Wykorzystuję to w jednym z produkcyjnych projektów i na razie nie mam zastrzeżeń.
Przykład użycia w vcl_recv():
        if(req.http.host == "www.domena.pl") {
                call devicedetect;
                if(!req.http.referer ~ "(^http://m.domena.pl|^http://www.domena.pl)") {
                        if (req.http.X-UA-Device ~ "^mobile" || req.http.X-UA-device ~ "^tablet") {
                                error 750 "http://m.domena.pl/";
                        }
                }
        }
Powyższy kod działa w oparciu o logikę:
Jeśli następuję wejście na stronę główną i urządzenia mobilnego i nie jest to odwołanie ze strony mobilnej lub głównej to przekieruj na stronę mobilną.
 Powyższe wykorzystaniu modułu było oparte o już istniejącej logice zaimplementowanej po stronie backendu (PHP).


Procedura błędu


Wykorzystuję funkcję error do wykonywania przekierowań i generowania własnych stron odpowiedzi.

sub vcl_error {
        if (obj.status == 750) {
                // Redirection
                set obj.http.Location=obj.response;
                set obj.http.Content-Type="Content-Type: text/html";
                set obj.status=302;
                set obj.response="Moved Temporarily";
                return(deliver);
        } elseif (obj.status == 751) {
                // Synthetic page generation
                set obj.http.Content-Type="Content-Type: text/html; charset=utf-8";
                set obj.status=200;
                synthetic obj.response;
                set obj.response="OK";
                return(deliver);
        } elseif (obj.status == 503) {
                set obj.http.Content-Type="Content-Type: text/html; charset=utf-8";
                synthetic "Technical Difficulties";
                set obj.response="Internal Server Error";
                return(deliver);
        }
}
Wywołania:

# Przekierowanie
error 750 "http://www.domena.pl" + req.url;

# Generacja odpowiedzi
error 751 "kod htmlKomunikat";
Ostania cześć powyższego kodu odpowiada za generację prostego komunikatu o błędzie zamiast domyślnego generowanego przez Varnish-a.

ESI


Przy przetwarzaniu ESI w logu pojawią się komunikat błędu:

"No ESI processing, first char not"

Rozwiązanie to dodanie parametru esi_syntax=0x1 (np. -p esi_syntax=0x1)

 

Wydajność w Linuxie


http://www.mail-archive.com/varnish-misc@projects.linpro.no/msg01571.html